diff --git a/CHANGES/903.doc b/CHANGES/903.doc new file mode 100644 index 000000000..8a0f7251f --- /dev/null +++ b/CHANGES/903.doc @@ -0,0 +1 @@ +Added the the docs structure and populated with existing content diff --git a/CHANGES/pulp-glue/903.doc b/CHANGES/pulp-glue/903.doc new file mode 100644 index 000000000..8a0f7251f --- /dev/null +++ b/CHANGES/pulp-glue/903.doc @@ -0,0 +1 @@ +Added the the docs structure and populated with existing content diff --git a/pulp-glue/staging_docs/dev/reference/common_context.md b/pulp-glue/staging_docs/dev/reference/common_context.md new file mode 100644 index 000000000..f26bc0319 --- /dev/null +++ b/pulp-glue/staging_docs/dev/reference/common_context.md @@ -0,0 +1,3 @@ +# pulp_glue.common.context + +::: pulp_glue.common.context diff --git a/pulp-glue/staging_docs/dev/reference/common_i18n.md b/pulp-glue/staging_docs/dev/reference/common_i18n.md new file mode 100644 index 000000000..d41502f5e --- /dev/null +++ b/pulp-glue/staging_docs/dev/reference/common_i18n.md @@ -0,0 +1,3 @@ +# pulp_glue.common.i18n + +::: pulp_glue.common.i18n diff --git a/pulp-glue/staging_docs/dev/reference/common_openapi.md b/pulp-glue/staging_docs/dev/reference/common_openapi.md new file mode 100644 index 000000000..68796e66b --- /dev/null +++ b/pulp-glue/staging_docs/dev/reference/common_openapi.md @@ -0,0 +1,3 @@ +# pulp_glue.common.openapi + +::: pulp_glue.common.openapi diff --git a/pulp-glue/staging_docs/dev/reference/core_context.md b/pulp-glue/staging_docs/dev/reference/core_context.md new file mode 100644 index 000000000..494786930 --- /dev/null +++ b/pulp-glue/staging_docs/dev/reference/core_context.md @@ -0,0 +1,3 @@ +# pulp_glue.core.context + +::: pulp_glue.core.context diff --git a/staging_docs/dev/guides/contribute.md b/staging_docs/dev/guides/contribute.md new file mode 100644 index 000000000..f4496d926 --- /dev/null +++ b/staging_docs/dev/guides/contribute.md @@ -0,0 +1,77 @@ +# Contribute to the CLI + +There are many ways to contribute to this project, and all are welcome. + +## Get in Touch + +If you want to connect with the Pulp community, ask some not-so-frequently-asked-questions or just leave general feedback, you can reach us in different ways summed up on [pulpproject.org](https://pulpproject.org/get_involved/). + + +## Doc Contributions + +If you see something wrong with the docs, we welcome [documentation PRs](https://github.com/pulp/pulp-cli). + +If you are using the Pulp CLI and have written end-to-end steps for Pulp workflows, we would greatly appreciate if you would contribute docs to the relevant [plugins](https://docs.pulpproject.org/pulpcore/plugins/index.html). + + +## Code Conventions + +If you are interested in contributing code, note that we have styling and formatting +conventions for both the code and our PRs: +* `pulp-cli` utilizes python type annotations and black and isort code formatting. + To run the auto-formatting features, execute `make black`. +* To check for compliance, please, install lint requirements and run lint checks before committing changes: + ``` + pip install -r lint_requirements.txt + make lint + ``` + * This executes the following checks: + * shellcheck + * black + * isort + * flake8 + * mypy +* If your PR is in response to an open issue, add `fixes #` as its own line +in your commit message. If you do **not** have an issue, use `[noissue]`. + +!!!note + + PRs need to pass these checks before they can be merged. + +Also please follow [The seven rules of a great Git commit message](https://chris.beams.io/posts/git-commit/). +And finally, for each new feature, we require corresponding tests. + +## Global Help Accessibility + +In order to be able to access every (sub-)commands help page, +it is necessary that no code outside of the final performing command callback accesses the `api` property of the `PulpContext`. +There are some facilities that perform lazy loading to help with that requirement. +Those include: + + - `PulpContext.api`: When accessed, the `api.json` file for the addressed server will be read or downloaded and processed. + Scheduled version checks will be reevaluated. + - `PulpContext.needs_version`: This function can be used at any time to declear that an operation needs a plugin in a version range. + The actual check will be performed, once `api` was accessed for the first time, or immediately afterwards. + - `PulpEntityContext.entity`: This property can be used to collect lookup attributes for entities by assigining dicts to it. + On read access, the entity lookup will be performed though the `api` property. + - `PulpEntityContext.pulp_href`: This property can be used to specify an entity by its URI. + It will be fetched from the server only at read access. + +## Testing + +Tests are shell scripts in `tests/scripts` with names like `test_*.sh`. +They should should focus on the cli operation and are not a replacement for pulp integration tests; +i.e. make sure the cli translates to the right api calls, but do not care about pulp internals. + +## Running Tests + +In order to run tests, a running instance of pulp with all necessary plugins installed must be +configured in `tests/cli.toml`. + +To run tests: + +``` +make test # all tests +pytest -m pulp_file # tests for pulp_file +pytest -m pulp_file -k test_remote # run tests/scripts/pulp_file/test_remote.sh +``` diff --git a/staging_docs/dev/learn/architecture.md b/staging_docs/dev/learn/architecture.md new file mode 100644 index 000000000..95076be36 --- /dev/null +++ b/staging_docs/dev/learn/architecture.md @@ -0,0 +1,115 @@ +## Architecture + +The Pulp CLI architecture is described in this section. + +### Plugin System + +The Pulp CLI is designed with a plugin structure. Plugins can either live in the pulp-cli package or be shipped independently. +By convention, all parts of the CLI are packages in the open namespace `pulpcore.cli`. +A plugin can register itself with the main app by specifying by specifying its main module as a `pulp_cli.plugins` entrypoint in `setup.py`. + +```python +entry_points={ + "pulp_cli.plugins": [ + "myplugin=pulpcore.cli.myplugin", + ], +} +``` + +The plugin can then attach subcommands to the `pulpcore.cli.common.main` command by providing a `mount` method in the main module. + +```python +from pulpcore.cli.common.generic import pulp_command + +@pulp_command() +def my_command(): + pass + + +def mount(main: click.Group, **kwargs: Any) -> None: + main.add_command(my_command) +``` + +### Contexts + +In `click`, every subcommand is accompanied by a `click.Context`, and objects can be attached to them. +In this CLI we attach a `PulpContext` to the main command. +It acts as an abstraction layer that handles the communication to the pulp server through its `api` property. +Further we encourage the handling of communication with certain endpoints by subclassing the `PulpEntityContext`. +By attaching them to the contexts of certain command groups, they are accessible to commands via the `pass_entity_context` decorator. +Those entity contexts should provide a common interface to the layer of `click` commands that define the user interaction. + +```python +@pulp_group() +@pass_pulp_context +@click.pass_context +def my_command(ctx, pulp_ctx): + ctx.obj = MyEntityContext(pulp_ctx) + + +@my_command.command() +@pass_entity_context +def my_sub_command(entity_ctx): + ... href = ... + entity_ctx.destroy(href) +``` + +### Version dependent code paths + +Each Pulp CLI release is designed to support multiple Pulp server versions and the CLI itself is versioned independently of any version of the Pulp server components. +It is supposed to be able to communicate with different combinations of server component versions at the same time. +Because of this, it might be necessary to guard certain features and workarounds by checking against the available server plugin version. +As a rule of thumb, all necessary workarounds should be implemented in the corresponding `Context` objects to provide a consistent interface to the command callbacks. +To facilitate diverting code paths depending on plugin versions, the `PulpContext` provides the `needs_plugin` and `has_plugin` methods. +While `has_plugin` will evaluete immediately, `needs_plugin` can be seen as a deferred assertion. +It will raise an error, once the first access to the server is attempted. + +```python +class MyEntityContext(PulpEntityContext): + def show(self, href): + if self.pulp_ctx.has_plugin(PluginRequirement("my_content", specifier=">=1.2.3", inverted=True)): + # Versioned workaroud + # see bug-tracker/12345678 + return lookup_my_content_legacy(href) + return super().show(href) + + +@main.command() +@pass_pulp_context +@click.pass_context +def my_command(ctx, pulp_ctx): + pulp_ctx.needs_plugin(PluginRequirement("my_content", specifier=">=1.0.0")) + ctx.obj = MyEntityContext(pulp_ctx) +``` + +The named tuple `PluginRequirement` is used to describe dependence on server components. +It needs the `name` of the plugin and accepts optionally an inclusive `min` version, +an exclusive `max` version, and an `inverted` flag for exclusion of a version range. + +Additionally, the `PulpOption` provides the `needs_plugins` keyword argument. +It accepts a list of `PluginRequirements` to error when used. + +### Generics + +For certain often repeated patterns like listing all entities of a particular kind, +we provide generic commands that use the underlying context objects. + +```python +from pulpcore.cli.common.generic import name_option, show_command, + +lookup_params = [name_option] +my_command.add_command(show_command(decorators=lookup_params)) +``` + +Some of these commands understand extra arguments. +They can be attached by passing a list of `click.Options` via the `decorators` argument. + +```python +from pulpcore.cli.common.generic import list_command, + +filter_params = [ + click.option("--name"), + click.option("--name-contains", "name__contains"), +] +my_command.add_command(list_command(decorators=filter_params)) +``` diff --git a/staging_docs/dev/reference/common_generic.md b/staging_docs/dev/reference/common_generic.md new file mode 100644 index 000000000..09304734c --- /dev/null +++ b/staging_docs/dev/reference/common_generic.md @@ -0,0 +1,3 @@ +# pulpcore.cli.common.generic + +::: pulpcore.cli.common.generic diff --git a/staging_docs/user/guides/advanced_features.md b/staging_docs/user/guides/advanced_features.md new file mode 100644 index 000000000..83ba0fb70 --- /dev/null +++ b/staging_docs/user/guides/advanced_features.md @@ -0,0 +1,60 @@ +# Advanced features + +## Custom CA bundle + +You can specify a custom CA bundle for the connection to a Pulp server by providing a path in one of the following environment variables (ordered by precedence): +`PULP_CA_BUNDLE` ,`REQUESTS_CA_BUNDLE` `CURL_CA_BUNDLE` + +## Shell Completion + +The CLI uses the click package which supports shell completion. +To configure this, check out [click's documentation](https://click.palletsprojects.com/en/8.0.x/shell_completion/). +As an example, here is what to add to your `~/.bashrc` file if you're using bash: + +```bash +eval "$(LC_ALL=C _PULP_COMPLETE=bash_source pulp)" +``` + +!!! note + + When using `click<8.0.0` the command instead reads: + + `eval "$(LC_ALL=C _PULP_COMPLETE=source_bash pulp)"` + +## Interactive shell mode + +* To use the shell mode, you need to install the the extra requirements tagged "shell". * + +Starting the CLI with "pulp shell" drops you into the shell: +```plain +(pulp) [vagrant@pulp3 ~]$ pulp shell +Starting Pulp3 interactive shell... +pulp> help + +Documented commands (type help ): +======================================== +access-policy config export group orphans rpm task +ansible container exporter importer python show user +artifact debug file migration repository status worker + +Undocumented commands: +====================== +exit help quit + +pulp> status +{ + ... +} + +pulp> exit +(pulp) [vagrant@pulp3 ~]$ +``` + +Issuing the command with arguments works as it does currently: +```plain +(pulp) [vagrant@pulp3 ~]$ pulp status +{ + ... +} +(pulp) [vagrant@pulp3 ~]$ +``` diff --git a/staging_docs/user/guides/configure.md b/staging_docs/user/guides/configure.md new file mode 100644 index 000000000..bbb263507 --- /dev/null +++ b/staging_docs/user/guides/configure.md @@ -0,0 +1,81 @@ +# Configure + +The CLI can be configured by using a toml file. +By default the location of this file is `~/.config/pulp/cli.toml`. +However, this can be customized by using the `--config` option. +Any settings supplied as options to a command will override these settings. + +Example file: + +``` +[cli] +base_url = "https://pulp.dev" +verify_ssl = false +format = "json" +``` + +## Config Profiles + +The CLI allows you to configure additional profiles at the same time. +If you add a `[cli-server1]` section to your config, +you can use that set of settings by specifying the `--profile server1` on the pulp command line. +This can be helpful if you need to use different usernames for certain actions, +or if you need to interact with several different Pulp servers. + +## Generating a new configuration + +To generate a new configuration: + +``` +pulp config create --base-url "http://localhost" +pulp config create -e # with an editor (e.g. vim) +pulp config create -i # interactive prompts +``` + +## Validating the configuration + +The easiest way to validate your config is to call a command that interacts with your Pulp server: + +``` +pulp status +``` + +To statically validate your config file (check that it exists, that it has not erroneous values, +etc) use the validate command: + +``` +pulp config validate +pulp config validate --strict # validates that all settings are present +``` + +## Using netrc + +If no user/pass is supplied either in the config file or as an option, +then the CLI will attempt to use `~/.netrc`. +Here is a `.netrc` example for localhost: + +``` +machine localhost +login admin +password password +``` + +## Tips for Katello Users + +If you have a Katello environment and wish to use pulp-cli to connect to Pulp, you'll need to +configure client certificate authentication in your `~/.config/pulp/cli.toml`: + +```toml +[cli] +base_url = "https://" +cert = "/etc/pki/katello/certs/pulp-client.crt" +key = "/etc/pki/katello/private/pulp-client.key" +``` + +Katello content-proxy servers do not possess the certificates required to communicate with Pulp; +therefore you should install pulp-cli only on the primary server, and override the `base_url` setting on the command line when you need to connect to Pulp running on a content-proxy rather than Pulp on the primary Katello server: `--base-url https://capsule.example.com` +It can be helpful to use the `--profile` option here. + +As Katello uses Pulp as a backend, all modifying actions in Pulp should be performed via Katello. +Therefore you are also strongly encourged to set `dry_run = true`, to prevent accidentally calling into dangerous commands. +This setting can in turn be overwritten on the command-line with the `--force` flag. diff --git a/staging_docs/user/guides/installation.md b/staging_docs/user/guides/installation.md new file mode 100644 index 000000000..75895dcd9 --- /dev/null +++ b/staging_docs/user/guides/installation.md @@ -0,0 +1,48 @@ +# Install + +## TL;DR: Get Started Real Fast + +```bash +pip install pulp-cli[pygments] +pulp config create -e +# insert your server configuration here +pulp status +``` + +--- + +The pulp-cli package can be installed from a variety of sources. +After installing, see the next section on how to configure pulp-cli. + +## From PyPI + +To install with minimal dependencies: +```bash +pip install pulp-cli # minimal dependencies +``` + +You can also include optional dependencies for [advanced features](advanced_features.md) with one of the following commands: +```bash +pip install pulp-cli[pygments] # colorized output +pip install pulp-cli[shell] # with interactive shell mode +``` + +If you want to install additional cli plugins, you can follow this example: +```bash +pip install pulp-cli-deb +``` + +## From a source checkout + +If you intend to use unreleased features, or want to contribute to the CLI, you can install from source: +```bash +git clone git@github.com:pulp/pulp-cli.git +pip install -e ./pulp-cli -e ./pulp-cli/pulp-glue --config-settings editable_mode=compat + +# Optionally install plugins from source +git clone git@github.com:pulp/pulp-cli-deb.git +pip install -e ./pulp-cli-deb --config-settings editable_mode=compat + +git clone git@github.com:pulp/pulp-cli-maven.git +pip install -e ./pulp-cli-maven -e ./pulp-cli-maven/pulp-glue-maven --config-settings editable_mode=compat +``` diff --git a/staging_docs/user/index.md b/staging_docs/user/index.md new file mode 100644 index 000000000..29de2341e --- /dev/null +++ b/staging_docs/user/index.md @@ -0,0 +1,28 @@ +# Pulp 3 CLI Docs + +This is the documentation for Pulp 3's command line interface. + +Here you can find information about how to install the Pulp 3 CLI, and general usage and syntax information. + +Currently `pulp-cli` supports pulpcore and 6 of Pulp's plugins: `pulp_ansible`, `pulp-certguard`, `pulp_container`, `pulp_file`, `pulp_python` and `pulp_rpm`. +See section below for information on how to extend the CLI to support other Pulp plugins. + +Check out the [supported workflows section](supported_workflows.md) to learn about the capabilities of the CLI. +You can find more workflow examples for the Pulp 3 CLI throughout the [plugin documentation](https://docs.pulpproject.org/pulpcore/plugins/index.html). +For example, [synchronizing a File repository](https://docs.pulpproject.org/pulp_file/workflows/sync.html). + +Use the links on the left to navigate. + +## CLI Plugins + +The CLI can be extended via external plugins. +See the [installation](installation.md) instructions. + +Known plugins include: + +| Plugin | Description | Source Repository | +| --- | --- | --- | +| `pulp-cli-deb` | Provides the `deb` subcommand group to interact with `pulp_deb`. | [`pulp/pulp-cli-deb`](https://github.com/pulp/pulp-cli-deb) | +| `pulp-cli-gem` | Provides the `gem` subcommand group to interact with `pulp_gem`. | [`pulp/pulp-cli-gem`](https://github.com/pulp/pulp-cli-gem) | +| `pulp-cli-maven` | Provides the `maven` subcommand group to interact with `pulp_maven`. | [`pulp/pulp-cli-maven`](https://github.com/pulp/pulp-cli-maven) | +| `pulp-cli-ostree` | Provides the `ostree` subcommand group to interact with `pulp_ostree`. | [`pulp/pulp-cli-ostree`](https://github.com/pulp/pulp-cli-ostree) | diff --git a/staging_docs/user/reference/basic-usage.md b/staging_docs/user/reference/basic-usage.md new file mode 100644 index 000000000..d80bcf8ec --- /dev/null +++ b/staging_docs/user/reference/basic-usage.md @@ -0,0 +1,43 @@ +# Basic Usage + +## General command syntax + +`pulp [] [--type ] []` + +## Global options + +Global options must be specified between `pulp` and the first subcommand. +Most of these can be represented by a corresponding configuration option. + +| Option | Description | Comment | +| --- | --- | --- | +| --version | Show the version and exit. | No configuration option | +| --help | Show help message and exit. | No configuration option | +| --config PATH | Specify the path of a Pulp CLI settings file to use instead of the default location. | No configuration option | +| -p, --profile TEXT | Select a [config profile](configuration.md#config-profiles) to use. | No configuration option | +| --base-url TEXT | API base url of the pulp server. | | +| --username TEXT | Username on pulp server. | | +| --password TEXT | Password on pulp server. | | +| --cert TEXT | Path to client certificate. | | +| --key TEXT | Path to client private key. Not required if client cert contains this. | | +| --verify-ssl / --no-verify-ssl | Verify SSL connection to the pulp server. | | +| --refresh-api | Invalidate cached API docs. | No configuration option | +| --dry-run / --force | Trace commands without performing any unsafe HTTP calls. | | +| -b, --background | Start tasks in the background instead of awaiting them. | No configuration option | +| -T, --timeout INTEGER | Time to wait for background tasks, set to 0 to wait infinitely. | | +| --format [json\|yaml\|none] | Select an output format for the response. | | +| -v, --verbose | Increase verbosity to explain api calls as they are made. | Repeat up to three times. | + +## Example commands + +`pulp status` + +`pulp file repository list` + +`pulp file repository create --name file_repo1` + +`pulp file repository update --name file_repo1 --description "Contains plain files"` + +`pulp file repository destroy --name file_repo1` + +To learn about the structure of a command, you can use the `--help` option with any (in-)complete command. diff --git a/staging_docs/user/reference/supported_workflows.md b/staging_docs/user/reference/supported_workflows.md new file mode 100644 index 000000000..23b9fac23 --- /dev/null +++ b/staging_docs/user/reference/supported_workflows.md @@ -0,0 +1,169 @@ +# Supported Workflows + +`pulp-cli` is still in beta, so the features and workflows listed here are subject to change. +`pulp-cli` is tested against the five most-recent pulpcore releases as of the date of the pulp-cli +release. It comes with support for five Pulp plugins: `pulp_ansible`, `pulp_container`, `pulp_file`, +`pulp_python` and `pulp_rpm`. Some of Pulp's other plugins can be added to the CLI through CLI +plugins, check out [CLI plugins](index.md#cli-plugins) for more information. + +While pulp-cli currently continues to work against older versions of pulpcore, we're unlikely to +take bug-reports for support of such older versions. + +(NOTE: pulp-cli does not (yet) expose all functionality provided by the REST API of pulpcore and enabled plugins. RFEs and pull-requests for missing features gratefully and cheerfully accepted!) + +## pulpcore + +Pulpcore commands require a minimum version of 3.11. Not every command is supported for all +`pulpcore` versions. Run `pulp status` to check your connection to Pulp and see currently +installed plugins. + +### Workflows + +The CLI currently supports the following workflows: + +* [**Uploading** Artifacts](https://docs.pulpproject.org/pulpcore/workflows/upload-publish.html) +* [**Creating, Syncing, Distributing** Content](https://docs.pulpproject.org/pulpcore/workflows/exposing-content.html) +* [**Exporting** Content](https://docs.pulpproject.org/pulpcore/workflows/import-export.html#exporting) +* [**Labeling** Resources](https://docs.pulpproject.org/pulpcore/workflows/labels.html) + +### Features + +The CLI currently supports the following operations on these `pulpcore` objects +(C = Create, R = Read, U = Update, D = Delete, P = RBAC Permissions): + +* Access Policies - **RU** +* Artifacts - **CR** +* Redirect/RBAC Content Guards - **CRUDP, Assign, Remove** +* Exports Pulp - **CRD** +* Groups - **CRUDP, Add Users, Remove Users** +* Roles - **CRUDP** +* Signing Services - **R** +* Tasks - **RDP, Cancel** +* Users - **CRUDP** + + +## pulp_ansible + +Ansible commands require minimum version of 0.7.0. The commands can be found under the `ansible` +subgroup. + +### Workflows + +The CLI currently supports the following workflows: + +* [**Sync/Upload/Distribute** Role Content](https://docs.pulpproject.org/pulp_ansible/workflows/roles.html) +* [**Sync/Upload/Distribute** Collection Content](https://docs.pulpproject.org/pulp_ansible/workflows/collections.html) + +### Features + +The CLI currently supports the following operations on these `pulp_ansible` objects +(C = Create, R = Read, U = Update, D = Delete): + +* Role/Collection Version/Signature Content - **CR** +* Ansible Distributions - **CRUD** +* Role/Collection Version Remotes - **CRUD** +* Ansible Repositories - **CRUD, Modify, Sync, Sign** + + +## pulp_container + +Container commands require `pulp_container` minimum version of 2.3.0. The commands can be found +under the `container` subgroup. + +### Workflows + +The CLI currently supports the following workflows: + +* [**Sync** Container Images](https://docs.pulpproject.org/pulp_container/workflows/sync.html) +* [**Distribute** Container Images](https://docs.pulpproject.org/pulp_container/workflows/host.html) + +### Features + +The CLI currently supports the following operations on these `pulp_container` objects +(C = Create, R = Read, U = Update, D = Delete, P = RBAC Permissions): + +* Blob/Manifest/Tag Content - **R** +* Container Namespaces - **CRDP** +* Container Distributions - **CRUDP** +* Container Remotes - **CRUDP** +* Container Repositories - **CRUDP, Sync, Tag/Untag, Add/Remove Image** +* Push Repositories - **RP, Tag/Untag, Remove Image** + + +## pulp_file + +File commands require `pulp_file` minimum version of 1.6.0. The commands can be found under the `file` +subgroup. + +### Workflows + +The CLI currently supports the following workflows: + +* [**Sync** File Content](https://docs.pulpproject.org/pulp_file/workflows/sync.html) +* [**Upload** File Content](https://docs.pulpproject.org/pulp_file/workflows/upload.html) +* [**Distribute** File Content](https://docs.pulpproject.org/pulp_file/workflows/publish-host.html) +* [Alternative Content Sources](https://docs.pulpproject.org/pulp_file/workflows/alternate-content-source.html) + +### Features + +The CLI currently supports the following operations on these `pulp_file` objects +(C = Create, R = Read, U = Update, D = Delete, P = RBAC Permissions): + +* File Alternative Content Sources - **CRUDP, Add, Remove, Refresh** +* File Content - **CR** +* File Distributions - **CRUDP** +* File Publications - **CRDP** +* File Remotes - **CRUDP** +* File Repositories - **CRUDP, Modify, Sync** + + +## pulp_python + +Python commands require `pulp_python` minimum version of 3.1.0. The commands can be found under the `python` +subgroup. + +### Workflows + +The CLI currently supports the following workflows: + +* [**Sync** Python Packages](https://docs.pulpproject.org/pulp_python/workflows/sync.html) +* [**Upload** Python Packages](https://docs.pulpproject.org/pulp_python/workflows/upload.html) +* [**Distribute** Python Packages](https://docs.pulpproject.org/pulp_python/workflows/publish.html) + +### Features + +The CLI currently supports the following operations on these `pulp_python` objects +(C = Create, R = Read, U = Update, D = Delete): + +* Python Package Content - **CR** +* Python Distributions - **CRUD** +* Python Publications - **CRD** +* Python Remotes - **CRUD** +* Python Repositories - **CRUD, Modify, Sync** + + +## pulp_rpm + +Python commands require `pulp_rpm` minimum version of 3.9.0. The commands can be found under the `rpm` +subgroup. + +### Workflows + +The CLI currently supports the following workflows: + +* [**Sync and Distribute** RPM Packages](https://docs.pulpproject.org/pulp_rpm/workflows/create_sync_publish.html) +* [**Upload** RPM Packages](https://docs.pulpproject.org/pulp_rpm/workflows/upload.html) + +### Features + +The CLI currently supports the following operations on these `pulp_rpm` objects +(C = Create, R = Read, U = Update, D = Delete): + +* RPM Alternative Content Sources - **CRUD, Add, Remove, Refresh** +* RPM Package/Advisory/ModuleMD Defaults/ModuleMD Content - **CR** +* RPM Distribution Tree/Repo Metadata Content - **R** +* RPM Distributions - **CRUD** +* RPM Publications - **CRD** +* RPM/ULN Remote - **CRUD** +* RPM Repository - **CRUD, Modify, Sync** +