Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add send payload for ceremony, metadata update and sign #620

Merged
merged 13 commits into from
Jun 18, 2024
8 changes: 8 additions & 0 deletions docs/diagrams/repository-service-tuf-cli-C3.puml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ System_Boundary(trs_cli, "Repository Service for TUF CLI") #APPLICATION {
Container(sign, "sign")

}
Container_Boundary(send, "send"){
Container(bootstrap, "bootstrap")
Container(update, "update")
Container(sign, "sign")

}
}
Container_Boundary(key, "key") {
Container(key_generate, "generate")
Expand All @@ -77,12 +83,14 @@ Rel(info, tuf, " ")
Rel(ceremony, api_client, " ")
Rel(metadata, tuf, " ")
Rel(metadata, api_client, " ")
Rel(send, api_client, " ")
Rel(api_client, requests, " ")
Rel(dynaconf, user, " ", $tags="os")
Rel_U(ceremony, click, " ")
Rel_U(key_generate, click, " ")
Rel_U(info, click, " ")
Rel_U(metadata, click, " ")
Rel_U(send, click, " ")
Rel(requests, tuf_repository_service_api, " ")

HIDE_STEREOTYPE()
Expand Down
1 change: 1 addition & 0 deletions docs/source/devel/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Component level
repository_service_tuf
repository_service_tuf.cli
repository_service_tuf.cli.admin
repository_service_tuf.cli.admin.send
repository_service_tuf.cli.artifact
repository_service_tuf.cli.key
repository_service_tuf.helpers
Expand Down
37 changes: 37 additions & 0 deletions docs/source/devel/repository_service_tuf.cli.admin.send.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
repository\_service\_tuf.cli.admin.send package
===============================================

Submodules
----------

repository\_service\_tuf.cli.admin.send.bootstrap module
--------------------------------------------------------

.. automodule:: repository_service_tuf.cli.admin.send.bootstrap
:members:
:undoc-members:
:show-inheritance:

repository\_service\_tuf.cli.admin.send.sign module
---------------------------------------------------

.. automodule:: repository_service_tuf.cli.admin.send.sign
:members:
:undoc-members:
:show-inheritance:

repository\_service\_tuf.cli.admin.send.update module
-----------------------------------------------------

.. automodule:: repository_service_tuf.cli.admin.send.update
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

.. automodule:: repository_service_tuf.cli.admin.send
:members:
:undoc-members:
:show-inheritance:
119 changes: 91 additions & 28 deletions docs/source/guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,16 @@ It executes administrative commands to the Repository Service for TUF.

Administrative Commands

╭─ Options ─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help -h Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ceremony Bootstrap Ceremony to create initial root metadata and RSTUF config. │
│ import-artifacts Import artifacts to RSTUF from exported CSV file. │
│ metadata Metadata management. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --api-server TEXT URL to an RSTUF API. │
│ --help -h Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ceremony Bootstrap Ceremony to create initial root metadata and RSTUF config. │
│ import-artifacts Import artifacts information from exported CSV file and send it to RSTUF API deployment. │
│ metadata Metadata management. │
│ send Send a payload to an existing RSTUF API deployment │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯


.. rstuf-cli-admin-ceremony
Expand All @@ -129,10 +131,10 @@ You can do the Ceremony offline. This means on a disconnected computer

Bootstrap Ceremony to create initial root metadata and RSTUF config.

╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ --save -s FILENAME Write json result to FILENAME (default: 'ceremony-payload.json')
│ --help -h Show this message and exit.
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────╮
│ --out FILENAME Write output json result to FILENAME (default: 'ceremony-payload.json') │
│ --help -h Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯

There are four steps in the ceremony.

Expand Down Expand Up @@ -176,23 +178,79 @@ sign (``sign``)

❯ rstuf admin metadata sign -h

Usage: rstuf admin metadata sign [OPTIONS] [SIGNING_JSON_INPUT_FILE]
Usage: rstuf admin metadata sign [OPTIONS]

Add one signature to root metadata.
There are two ways to use this command:
1) utilizing access to the RSTUF API and signing pending metadata roles
2) provide a local file using the SIGNING_JSON_INPUT_FILE argument
When using method 2:
- 'SIGNING_JSON_INPUT_FILE' must be a file containing the JSON response from the 'GET /api/v1/metadata/sign' API endpoint.
- '--api-server' will be ignored.
- the result of the command will be saved into the 'sign-payload.json' file unless a different name is provided with '--save'.

╭─ Options ────────────────────────────────────────────────────────────────────────────────╮
│ --api-server TEXT URL to an RSTUF API. │
│ --save -s FILENAME Write json result to FILENAME (default: 'sign-payload.json') │
│ --help -h Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --in FILENAME Input file containing the JSON response from the 'GET /api/v1/metadata/sign' RSTUF API endpoint. │
│ --out FILENAME Write output JSON result to FILENAME (default: 'sign-payload.json') │
│ --help -h Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

.. rstuf-cli-admin-send

Send generated payload (``send``)
---------------------------------

.. rstuf-cli-admin-send-bootstrap

send bootstrap (``sign``)
.........................

.. code:: shell

❯ rstuf admin --api-server <api-server-url> send bootstrap --help

Usage: rstuf admin send bootstrap [OPTIONS] BOOTSTRAP_PAYLOAD

Send payload and bootstrap to an existing RSTUF API deployment.
Note: 'BOOTSTRAP_PAYLOAD' argument must be generated by using:
'rstuf admin ceremony' command.

╭─ Options ──────────────────────────────────────────╮
│ --help -h Show this message and exit. │
╰────────────────────────────────────────────────────╯


.. rstuf-cli-admin-send-update

send metadata update (``update``)
.................................

.. code:: shell

❯ rstuf admin --api-server <api-server-url> send update --help

Usage: rstuf admin send update [OPTIONS] METADATA_UPDATE_PAYLOAD

Send metadata update payload to an existing RSTUF API deployment.
Note: 'METADATA_UPDATE_PAYLOAD' argument must be generated by using:
'rstuf admin metadata update' command.

╭─ Options ──────────────────────────────────────────╮
│ --help -h Show this message and exit. │
╰────────────────────────────────────────────────────╯


.. rstuf-cli-admin-send-sign

send sign (``sign``)
....................

.. code:: shell

❯ rstuf admin --api-server <api-server-url> send update --help

Usage: rstuf admin send sign [OPTIONS] SIGN_PAYLOAD

Send sign payload to an existing RSTUF API deployment.
Note: 'SIGN_PAYLOAD' argument must be generated by using:
'rstuf admin metadata sign' command.

╭─ Options ──────────────────────────────────────────╮
│ --help -h Show this message and exit. │
╰────────────────────────────────────────────────────╯


.. rstuf-cli-admin-import-artifacts
Expand Down Expand Up @@ -243,12 +301,17 @@ See the below CSV file example:

❯ rstuf admin import-artifacts -h

Usage: rstuf admin import-artifacts [OPTIONS]
Usage: rstuf admin import-artifacts [OPTIONS]

Import artifacts information from exported CSV file and send it to RSTUF API deployment.
Note: there are two additional requirements for this command:

1) sqlalchemy needs to be installed in order to use this command:
pip install repository-service-tuf[sqlalchemy,psycopg2]

Import artifacts to RSTUF from exported CSV file.
2) '--api-server' admin option or 'SERVER' in RSTUF config set

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --api-server TEXT RSTUF API URL i.e.: http://127.0.0.1 . │
│ * --db-uri TEXT RSTUF DB URI. i.e.: postgresql://postgres:[email protected]:5433 [required] │
│ * --csv TEXT CSV file to import. Multiple --csv parameters are allowed. See rstuf CLI guide for more details. [required] │
│ --skip-publish-artifacts Skip publishing artifacts in TUF Metadata. │
Expand Down
18 changes: 17 additions & 1 deletion repository_service_tuf/cli/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,29 @@
Provides alternative ceremony, metadata update, and sign admin cli commands.

"""
from typing import Optional

from repository_service_tuf.cli import click, rstuf


def _set_settings(context: click.Context, api_server: Optional[str]):
"""Set context.obj['settings'] attributes."""
settings = context.obj["settings"]
if api_server:
settings.SERVER = api_server


@rstuf.group() # type: ignore
def admin():
@click.option(
"--api-server",
help="URL to an RSTUF API.",
required=False,
)
@click.pass_context
def admin(context: click.Context, api_server: Optional[str]):
"""Administrative Commands"""
# Because of tests it has to be in a separate function.
_set_settings(context, api_server) # pragma: no cover


@admin.group()
Expand Down
57 changes: 39 additions & 18 deletions repository_service_tuf/cli/admin/ceremony.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import json
from dataclasses import asdict
from typing import Any, Optional

import click
from rich.markdown import Markdown
Expand Down Expand Up @@ -31,28 +32,38 @@
_online_settings_prompt,
_print_root,
_root_threshold_prompt,
_warn_no_save,
)
from repository_service_tuf.helpers.api_client import (
URL,
send_payload,
task_status,
)

DEFAULT_PATH = "ceremony-payload.json"


@admin.command() # type: ignore
@click.option(
"--save",
"-s",
"--out",
is_flag=False,
flag_value="ceremony-payload.json",
help="Write json result to FILENAME (default: 'ceremony-payload.json')",
flag_value=DEFAULT_PATH,
help=f"Write output json result to FILENAME (default: '{DEFAULT_PATH}')",
type=click.File("w"),
)
def ceremony(save) -> None:
@click.pass_context
def ceremony(context: Any, out: Optional[click.File]) -> None:
"""Bootstrap Ceremony to create initial root metadata and RSTUF config."""
console.print("\n", Markdown("# Metadata Bootstrap Tool"))
settings = context.obj["settings"]
# Running online ceremony requires connection to the server and
# confirmation that the server is indeed ready for bootstap.
if not settings.get("SERVER") and not out:
raise click.ClickException(
"Either '--api-sever'/'SERVER' in RSTUF config or '--out' needed"
)

if not save: # pragma: no cover
_warn_no_save()

# Performs ceremony steps.
root = Root()

###########################################################################
# Configure online role settings
console.print(Markdown("## Online role settings"))
Expand Down Expand Up @@ -95,11 +106,21 @@ def ceremony(save) -> None:
_add_root_signatures_prompt(root_md, None)

###########################################################################
# Dump payload
# TODO: post to API
if save:
metadatas = Metadatas(root_md.to_dict())
settings = Settings(roles)
payload = CeremonyPayload(settings, metadatas)
json.dump(asdict(payload), save, indent=2)
console.print(f"Saved result to '{save.name}'")
metadatas = Metadatas(root_md.to_dict())
roles_settings = Settings(roles)
bootstrap_payload = CeremonyPayload(roles_settings, metadatas)
# Dump payload when the user explicitly wants or doesn't send it to the API
if out:
json.dump(asdict(bootstrap_payload), out, indent=2) # type: ignore
console.print(f"Saved result to '{out.name}'")

if settings.get("SERVER"):
task_id = send_payload(
settings=settings,
url=URL.BOOTSTRAP.value,
payload=asdict(bootstrap_payload),
expected_msg="Bootstrap accepted.",
command_name="Bootstrap",
)
task_status(task_id, settings, "Bootstrap status: ")
console.print("\nCeremony done. 🔐 🎉. Bootstrap completed.")
Loading
Loading