diff --git a/content/docs/_index.md b/content/docs/_index.md index 89096f0..7c1f369 100644 --- a/content/docs/_index.md +++ b/content/docs/_index.md @@ -12,4 +12,5 @@ Documentation for the DCM project. ## Documentation Sections - **[Getting Started](getting-started/)** - Set up and run DCM on your local machine. +- **[User Guide](user-guide/)** - Manage DCM resources using the CLI. - **[Enhancements](enhancements/)** - Enhancement proposals documenting new features, architectural decisions, and significant changes to the DCM project. diff --git a/content/docs/user-guide/_index.md b/content/docs/user-guide/_index.md new file mode 100644 index 0000000..a7774ad --- /dev/null +++ b/content/docs/user-guide/_index.md @@ -0,0 +1,17 @@ +--- +title: User Guide +type: docs +sidebar: + open: true +weight: 2 +--- + +Learn how to manage DCM resources using the CLI. + +- **[CLI Configuration](cli-configuration/)** — Configure the CLI, global flags, output formats, and shell completion. +- **[Providers](providers/)** — View registered service providers and their health status. +- **[Service Types](service-types/)** — Browse available service type definitions. +- **[Catalog Items](catalog-items/)** — Create and manage reusable resource templates. +- **[Policies](policies/)** — Define placement policies that control where instances are deployed. +- **[Catalog Item Instances](catalog-item-instances/)** — Deploy, manage, and monitor resource instances. +- **[Service Provider Resources](service-provider-resources/)** — View resources managed by service providers. diff --git a/content/docs/user-guide/catalog-item-instances.md b/content/docs/user-guide/catalog-item-instances.md new file mode 100644 index 0000000..64b324f --- /dev/null +++ b/content/docs/user-guide/catalog-item-instances.md @@ -0,0 +1,181 @@ +--- +title: Catalog Item Instances +type: docs +weight: 6 +--- + +Catalog item instances represent deployed resources created from a [catalog item](../catalog-items/). When you create an instance, DCM evaluates policies to validate the input and select a provider, then provisions the resource on that provider. Instances can override fields allowed by the catalog item's `fields` via `user_values`. + +## Creating an Instance + +To create an instance, define its configuration in a YAML or JSON file and pass it to the CLI: + +```bash +dcm catalog instance create --from-file instance.yaml +``` + +To specify a custom identifier instead of letting DCM generate one: + +```bash +dcm catalog instance create --from-file instance.yaml --id my-instance +``` + +### Example YAML + +Below is a complete instance definition that creates a virtual machine from an existing catalog item, overriding the vCPU count, setting the O/S type and adding name and labels to the metadata: + +```yaml +api_version: v1alpha1 +display_name: "My Dev VM" +spec: + catalog_item_id: small-vm + user_values: + - path: metadata + value: + name: "demo" + labels: + env: "dev" + - path: vcpu.count + value: 1 + - path: guest_os.type + value: fedora +``` + +### Key Fields + +| Field | Purpose | +|-------|---------| +| `display_name` | An optional human-readable name shown in listings and the UI. | +| `spec.catalog_item_id` | References the UID of an existing catalog item to deploy from. | +| `spec.user_values` | Sets of overrides for fields allowed by the catalog item's `fields` array. Only fields with `editable: true` can be customized here. | +| `spec.user_values[].path` | Path corresponding to the `path` key in the `catalog_item`'s `fields` item | + +> **Note:** Each value provided in `user_values` will be validated against its corresponding item in the catalog item's `fields` list. If the `field` is not editable (`editable=false`) or the `value` does not pass the `validation_schema` the request will be rejected. + +### Verifying the Instance + +After creating an instance, confirm it was provisioned successfully: + +```bash +dcm catalog instance get INSTANCE_ID +``` + +## Listing Instances + +Use `dcm catalog instance list` to view all instances: + +```bash +dcm catalog instance list +``` + +Example output: + +``` +UID DISPLAY NAME CATALOG ITEM RESOURCE ID CREATED +b2d4f6a8-1c3e-5678-9abc-def012345678 My VM Instance f4a8b3c1-d2e5-6789-abcd-ef0123456789 r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2 2026-04-01T10:30:00Z +c5e7a9b1-2d4f-6789-0abc-123456789def Dev Database a7c2d9e4-b1f3-4567-89ab-cdef01234567 r-3b5d7f90-c1e3-4a26-98b0-d4f6a8c2e0a1 2026-04-03T14:15:00Z +``` + +> **Note:** The Resource ID refers to the ID of the corresponding [Service Type Resource](../service-provider-resources). + +### Filtering by Catalog Item + +To show only instances created from a specific catalog item: + +```bash +dcm catalog instance list --catalog-item-id f4a8b3c1-d2e5-6789-abcd-ef0123456789 +``` + +### Pagination + +For environments with many instances, use pagination flags: + +```bash +dcm catalog instance list --page-size 10 +``` + +To fetch the next page, pass the token returned by the previous response: + +```bash +dcm catalog instance list --page-size 10 --page-token "eyJvZmZzZXQiOjEwfQ==" +``` + +## Getting Instance Details + +Use `dcm catalog instance get` to retrieve the full details of an instance: + +```bash +dcm catalog instance get b2d4f6a8-1c3e-5678-9abc-def012345678 +``` + +To view the output in JSON format: + +```bash +dcm catalog instance get b2d4f6a8-1c3e-5678-9abc-def012345678 -o json +``` + +Example JSON output: + +```json +{ + "api_version": "v1alpha1", + "create_time": "2026-04-15T18:38:19.968231Z", + "display_name": "My Dev VM", + "path": "catalog-item-instances/7f4aca9b-5a2f-46aa-94c4-cd8309a86bf5", + "resource_id": "d828d392-47ee-468b-ac61-b71927049efc", + "spec": { + "catalog_item_id": "small-vm", + "user_values": [ + { + "path": "metadata", + "value": { + "labels": { + "env": "dev" + }, + "name": "demo" + } + }, + { + "path": "vcpu.count", + "value": 1 + }, + { + "path": "guest_os.type", + "value": "fedora" + } + ] + }, + "uid": "7f4aca9b-5a2f-46aa-94c4-cd8309a86bf5", + "update_time": "2026-04-15T18:38:19.968231Z" +} +``` + +## Rehydrating an Instance + +Use `dcm catalog instance rehydrate` to re-trigger the provisioning flow for an existing instance: + +```bash +dcm catalog instance rehydrate b2d4f6a8-1c3e-5678-9abc-def012345678 +``` + +Rehydration refreshes an instance by running the provisioning process again. This is useful when: + +- A provider has recovered from a failure and the resource needs to be re-provisioned. +- The underlying resource needs to be recreated or updated. +- Placement policies have changed and you want the instance to be re-evaluated against the current configuration. + +> **Note:** Rehydration will first provision the new resource before trying to delete the old one. Make sure to update any references (e.g. DNS) if needed + +## Deleting an Instance + +To remove an instance: + +```bash +dcm catalog instance delete b2d4f6a8-1c3e-5678-9abc-def012345678 +``` + +> **Note:** Deleting an instance also triggers cleanup of the underlying resource on the provider. The provisioned resource will be removed as part of the deletion process. + +--- + +For a step-by-step walkthrough, see [Create Instance of Small VM Catalog Item](../../getting-started/create-small-vm-instance/). diff --git a/content/docs/user-guide/catalog-items.md b/content/docs/user-guide/catalog-items.md new file mode 100644 index 0000000..c61e76b --- /dev/null +++ b/content/docs/user-guide/catalog-items.md @@ -0,0 +1,218 @@ +--- +title: Catalog Items +type: docs +weight: 4 +--- + +Catalog items are reusable templates that define a deployable resource. Each catalog item references a [service type](../service-types/) and may specify whether a resource configuration is editable while setting a preset, a default value and/or a validation schema for the user values — for example, CPU, memory, and storage for a virtual machine. + +## Creating a Catalog Item + +To create a catalog item, define its configuration in a YAML or JSON file and pass it to the CLI: + +```bash +dcm catalog item create --from-file item.yaml +``` + +To specify a custom identifier instead of letting DCM generate one: + +```bash +dcm catalog item create --from-file item.yaml --id my-small-vm +``` + +### Example YAML + +Below is a complete catalog item definition for a small virtual machine: + +```yaml +api_version: v1alpha1 +display_name: "Small VM" +spec: + service_type: vm + fields: + - path: metadata + editable: true + - path: vcpu.count + display_name: "CPU Count" + editable: true + default: 2 + validation_schema: + type: integer + minimum: 1 + maximum: 4 + - path: memory.size + display_name: "Memory (GB)" + editable: false + default: "2GB" + - path: storage.disks + display_name: "Storage (GB)" + editable: false + default: + - name: boot + capacity: "20GB" + validation_schema: + type: array + - path: guest_os.type + display_name: "Guest OS" + editable: true + validation_schema: + type: string + enum: + - fedora + - centos + - ubuntu +``` + +### Key Sections + +| Section | Purpose | +|---------|---------| +| `api_version` | Ties the catalog item to a specific schema version (e.g., `v1alpha1`). | +| `display_name` | A human-readable name shown in listings and the UI. | +| `spec.service_type` | Corresponding service type | +| `spec.fields` | List of fields with const or user values | +| `spec.fields[].path` | Path of the field within the `service_type` specification | +| `spec.fields[].display_name` | A human-readable name shown in listings and the UI | +| `spec.fields[].editable` | Specify whether the user may edit the value | +| `spec.fields[].default` | Default value for the field. When `editable` is `false` this becomes the actual value | +| `spec.fields[].validation_schema` | JSON Schema rules to validate input. See: https://json-schema.org/ | + +### Verifying the Catalog Item + +After creating a catalog item, confirm it was registered successfully: + +```bash +dcm catalog item get CATALOG_ITEM_ID +``` + +## Listing Catalog Items + +Use `dcm catalog item list` to view all catalog items: + +```bash +dcm catalog item list +``` + +Example output: + +``` +UID DISPLAY NAME SERVICE TYPE CREATED +small-vm Small VM vm 2026-03-10T08:15:00Z +a7c2d9e4-b1f3-4567-89ab-cdef01234567 Large VM vm 2026-03-12T14:30:00Z +web-server Web Server container 2026-03-15T09:45:00Z +``` + +### Filtering by Service Type + +To show only catalog items for a specific service type: + +```bash +dcm catalog item list --service-type "vm" +``` + +### Pagination + +For environments with many catalog items, use pagination flags: + +```bash +dcm catalog item list --page-size 10 +``` + +To fetch the next page, pass the token returned by the previous response: + +```bash +dcm catalog item list --page-size 10 --page-token "eyJvZmZzZXQiOjEwfQ==" +``` + +## Getting Catalog Item Details + +Use `dcm catalog item get` to retrieve the full definition of a catalog item: + +```bash +dcm catalog item get f4a8b3c1-d2e5-6789-abcd-ef0123456789 +``` + +To view the output in JSON format: + +```bash +dcm catalog item get f4a8b3c1-d2e5-6789-abcd-ef0123456789 -o json +``` + +Example JSON output: + +```json +{ + "api_version": "v1alpha1", + "create_time": "2026-04-15T18:06:02.434302Z", + "display_name": "Small VM", + "path": "catalog-items/small-vm", + "spec": { + "fields": [ + { + "editable": true, + "path": "metadata" + }, + { + "default": 2, + "display_name": "CPU Count", + "editable": true, + "path": "vcpu.count", + "validation_schema": { + "maximum": 4, + "minimum": 1, + "type": "integer" + } + }, + { + "default": "2GB", + "display_name": "Memory (GB)", + "path": "memory.size" + }, + { + "default": [ + { + "capacity": "20GB", + "name": "boot" + } + ], + "display_name": "Storage (GB)", + "path": "storage.disks", + "validation_schema": { + "type": "array" + } + }, + { + "default": "fedora", + "display_name": "Guest OS", + "editable": true, + "path": "guest_os.type", + "validation_schema": { + "enum": [ + "fedora", + "centos", + "ubuntu" + ], + "type": "string" + } + } + ], + "service_type": "vm" + }, + "uid": "small-vm", + "update_time": "2026-04-15T18:06:02.434302Z" +} +``` + +## Deleting a Catalog Item + +To remove a catalog item: + +```bash +dcm catalog item delete f4a8b3c1-d2e5-6789-abcd-ef0123456789 +``` + +> **Note:** Deleting a catalog item with instances that were already created from it will fail. Remove all existing instances before deleting the item. + +--- + +For a step-by-step walkthrough, see [Create Small VM Catalog Item](../../getting-started/create-small-vm-catalog-item/). diff --git a/content/docs/user-guide/cli-configuration.md b/content/docs/user-guide/cli-configuration.md new file mode 100644 index 0000000..fcc019a --- /dev/null +++ b/content/docs/user-guide/cli-configuration.md @@ -0,0 +1,88 @@ +--- +title: CLI Configuration +type: docs +weight: 1 +--- + +The DCM CLI (`dcm`) connects to the DCM API gateway to manage resources. It can be configured through command-line flags, environment variables, or a configuration file. + +For installation instructions, see [Setting Up the CLI](../../getting-started/local-setup/#setting-up-the-cli). + +## Configuration File + +The CLI reads its configuration from `~/.dcm/config.yaml` by default. Here is an example with all available fields: + +```yaml +api-gateway-url: http://localhost:9080 +output-format: table +timeout: 30 +tls-ca-cert: "" +tls-client-cert: "" +tls-client-key: "" +tls-skip-verify: false +``` + +## Configuration Priority + +Settings are resolved in the following order (highest priority first): + +1. Command-line flags +2. Environment variables (prefixed with `DCM_`) +3. Configuration file +4. Built-in defaults + +## Global Flags + +The following flags are available on all commands: + +| Flag | Short | Default | Description | +|------|-------|---------|-------------| +| `--api-gateway-url` | | `http://localhost:9080` | URL of the DCM API gateway | +| `--output` | `-o` | `table` | Output format (`table`, `json`, `yaml`) | +| `--timeout` | | `30` | Request timeout in seconds | +| `--config` | | `~/.dcm/config.yaml` | Path to configuration file | + +## TLS Configuration + +To connect to a TLS-secured API gateway, use the following flags: + +| Flag | Description | +|------|-------------| +| `--tls-ca-cert` | Path to CA certificate file for TLS verification | +| `--tls-client-cert` | Path to client certificate file for mutual TLS | +| `--tls-client-key` | Path to client private key file for mutual TLS | +| `--tls-skip-verify` | Skip TLS certificate verification (not recommended for production) | + +## Output Formats + +All commands support three output formats via the `-o` flag: + +- **`table`** (default) — Human-readable tabular output. +- **`json`** — Structured JSON output, useful for scripting and automation. +- **`yaml`** — YAML output. + +For example, to list providers as JSON: + +```bash +dcm sp provider list -o json +``` + +## Shell Completion + +Generate shell completion scripts with the `dcm completion` command: + +```bash +# Bash +source <(dcm completion bash) + +# Zsh +source <(dcm completion zsh) + +# Fish +dcm completion fish | source + +# PowerShell +dcm completion powershell | Out-String | Invoke-Expression +``` + +To make completion persistent, add the appropriate command to your shell profile (e.g., `~/.bashrc`, `~/.zshrc`). diff --git a/content/docs/user-guide/policies.md b/content/docs/user-guide/policies.md new file mode 100644 index 0000000..afd9b20 --- /dev/null +++ b/content/docs/user-guide/policies.md @@ -0,0 +1,257 @@ +--- +title: Policies +type: docs +weight: 5 +--- + +Policies are [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) rules (the OPA policy language) that validate service provider resources and control where they are placed. During the placement flow, DCM evaluates all enabled policies in priority order (lower number = evaluated first). A policy can reject a request or select a specific provider for it. It may also alter or set values. + +## Creating a Policy + +Define the policy in a YAML file and use `dcm policy create` to submit it. + +Here is an example policy file: + +```yaml +# policy.yaml +display_name: Provider +policy_type: GLOBAL +priority: 1 +rego_code: | + package provider.selector + + import rego.v1 + + spm_url := "http://service-provider-manager:8080/api/v1alpha1/providers" + + main := {"rejected": true, "rejection_reason": "spec.service_type is required"} if { + not input.spec.service_type + } + + main := result if { + service_type := input.spec.service_type + response := http.send({ + "method": "GET", + "url": sprintf("%s?type=%s", [spm_url, service_type]), + "headers": {"Accept": "application/json"}, + }) + providers := response.body.providers + ready_providers := [p | some p in providers; p.health_status == "ready"] + result := _providers_result(ready_providers, service_type) + } + + _providers_result(providers, service_type) := {"rejected": true, "rejection_reason": msg} if { + count(providers) == 0 + msg := sprintf("no ready providers found for service type '%s'", [service_type]) + } + + _providers_result(providers, _) := {"rejected": false, "selected_provider": provider} if { + count(providers) > 0 + sorted_names := sort([p.name | some p in providers]) + provider := sorted_names[0] + } +``` + +> **Note:** This Rego code assumes it can access the `service-provider-manager` to get the list of providers. Then, it filters only the `ready` ones, sorts alphabetically and returns the first one + +### Field Reference + +| Field | Description | +|-------|-------------| +| `display_name` | A human-readable name for the policy. | +| `policy_type` | The scope of policy (e.g., `GLOBAL`). | +| `priority` | Evaluation order. Lower numbers are evaluated first. | +| `enabled` | Whether the policy is active (`true` or `false`). | +| `rego_code` | The Rego source code. Must define a `main` rule with `rejected`, and either `rejection_reason` or `selected_provider` fields. | +| `label_selector` | `key:value` pairs used to match between the policy and the `metadata.labels` field of the provisioned resource | + +> **Note:** `label_selector` may also use the `service_type` key to match based on the resource's `service_type` + +### Rego Rule Structure + +The `main` rule receives an `input` object and must return an output object. + +#### Input + +The `input` object includes: + +| Field | Description | +|-------|-------------| +| `spec` | The current (patched) request payload. While policies do not have to be specific for service types, they will need to know the expected content. | +| `constraints` | The accumulated constraints context from prior policies in the chain. | +| `provider` | The currently selected service provider (empty string initially, populated as policies are evaluated). | +| `service_provider_constraints` | The accumulated service-provider constraints from prior policies. | + +#### Output + +The `main` rule must return an object with the following fields: + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `rejected` | boolean | Yes | Set to `true` to reject the placement request. Requests are approved by default. | +| `rejection_reason` | string | No | A human-readable reason when the request is rejected. | +| `selected_provider` | string | No | The name of the service provider chosen to fulfill the request. | +| `service_provider_constraints` | object | No | Constraints on which service providers are allowed. Contains `allow_list` (list of allowed provider names) and `patterns` (list of regex patterns for matching allowed providers). | +| `patch` | map | No | A dictionary of values to set or override in the request payload. | +| `constraints` | map | No | Field constraints for subsequent policies, following [JSON Schema (draft 2020-12)](https://json-schema.org/draft/2020-12/json-schema-validation). Supports `const` (immutable), numeric constraints (`minimum`, `maximum`, `multipleOf`), string patterns (`pattern`, `minLength`, `maxLength`), enumerations (`enum`), array constraints (`minItems`, `maxItems`), and conditional logic (`if`/`then`/`else`). | + +> **Note:** While no single policy is required to set the `selected_provider` field, the combination of all processed policies must set one; otherwise, placement will fail. + +### Create Command + +```bash +dcm policy create --from-file policy.yaml +``` + +To specify a custom ID for the policy: + +```bash +dcm policy create --from-file policy.yaml --id prefer-provider-a +``` + +Verify the policy was created: + +```bash +dcm policy get prefer-provider-a +``` + +## Listing Policies + +Use `dcm policy list` to view all policies: + +```bash +dcm policy list +``` + +Sample output: + +``` +ID DISPLAY NAME TYPE PRIORITY ENABLED CREATED +prefer-provider-a Prefer Provider A GLOBAL 10 true 2026-04-10T08:30:00Z +deny-large-vms Deny Large VMs GLOBAL 20 true 2026-04-11T14:22:00Z +dev-only-policy Dev Only USER 30 false 2026-04-12T09:15:00Z +``` + +### Optional Flags + +| Flag | Description | +|------|-------------| +| `--filter` | A CEL filter expression to narrow results. | +| `--order-by` | Field and direction to sort by (e.g., `"priority asc"`). | +| `--page-size` | Maximum number of results per page (int32). | +| `--page-token` | Token for retrieving the next page of results. | + +### Filter and Sort Examples + +List only placement policies: + +```bash +dcm policy list --filter "policy_type='PLACEMENT'" +``` + +Sort by priority in ascending order: + +```bash +dcm policy list --order-by "priority asc" +``` + +Combine filter and sort with pagination: + +```bash +dcm policy list --filter "enabled=true" --order-by "priority asc" --page-size 10 +``` + +## Getting Policy Details + +Use `dcm policy get` with the policy ID to retrieve full details: + +```bash +dcm policy get prefer-provider-a +``` + +Example JSON output (using `-o json`): + +```bash +dcm policy get prefer-provider-a -o json +``` + +```json +{ + "create_time": "2026-04-15T18:38:13.990296Z", + "display_name": "Provider", + "enabled": true, + "id": "7eff7e73-4c14-4311-8673-e03916b00ece", + "path": "policies/7eff7e73-4c14-4311-8673-e03916b00ece", + "policy_type": "GLOBAL", + "priority": 1, + "rego_code": "package provider.selector\n\nimport rego.v1\n\nspm_url := \"http://service-provider-manager:8080/api/v1alpha1/providers\"\n\nmain := {\"rejected\": true, \"rejection_reason\": \"spec.service_type is required\"} if {\n not input.spec.service_type\n}\n\nmain := result if {\n service_type := input.spec.service_type\n response := http.send({\n \"method\": \"GET\",\n \"url\": sprintf(\"%s?type=%s\", [spm_url, service_type]),\n \"headers\": {\"Accept\": \"application/json\"},\n })\n providers := response.body.providers\n ready_providers := [p | some p in providers; p.health_status == \"ready\"]\n result := _providers_result(ready_providers, service_type)\n}\n\n_providers_result(providers, service_type) := {\"rejected\": true, \"rejection_reason\": msg} if {\n count(providers) == 0\n msg := sprintf(\"no ready providers found for service type '%s'\", [service_type])\n}\n\n_providers_result(providers, _) := {\"rejected\": false, \"selected_provider\": provider} if {\n count(providers) \u003e 0\n sorted_names := sort([p.name | some p in providers])\n provider := sorted_names[0]\n}\n", + "update_time": "2026-04-15T18:38:13.990296Z" +} +``` + +## Updating a Policy + +Use `dcm policy update` with a patch file. The update uses **JSON Merge Patch** semantics -- only fields present in the patch file are modified; all other fields remain unchanged. + +For example, to change the priority and disable a policy: + +```yaml +# patch.yaml +priority: 5 +enabled: false +``` + +```bash +dcm policy update prefer-provider-a --from-file patch.yaml +``` + +Verify the update: + +```bash +dcm policy get prefer-provider-a +``` + +> **Note:** You do not need to include every field in the patch file. Only the fields you want to change should be present. + +## Deleting a Policy + +Use `dcm policy delete` with the policy ID: + +```bash +dcm policy delete prefer-provider-a +``` + +> **Note:** Deleting a policy is permanent. Ensure the policy is no longer needed before deleting it. + +## Policy Priority and Evaluation + +During instance placement, DCM evaluates all **enabled** policies that match the request (based on the `label_selector`). If no matching policies are found, the request succeeds without policy evaluation. + +### Evaluation Order + +Policies are sorted by **level** first, then by **priority** within each level: + +1. **Global** policies run first. +2. **User** policies run last. + +Within each level, policies are sorted by `priority` in ascending order (lower number = evaluated first). + +> **Note:** Choose priority values with gaps (e.g., 10, 20, 30) so you can insert new policies between existing ones without renumbering. + +### Evaluation Pipeline + +For each policy in order, the engine performs the following steps: + +1. **Evaluate** the policy's Rego code. The `input` object includes the current patched `spec`, the accumulated `constraints`, the currently `selected_provider` (empty string initially), and the accumulated `service_provider_constraints`. +2. **Check rejection.** If the policy sets `rejected` to `true`, the placement request is denied immediately and the `rejection_reason` is returned to the caller. No further policies are evaluated. +3. **Validate constraints.** A lower-level policy cannot relax or remove a constraint set by a higher-level policy. If it attempts to do so, the request is aborted with a policy conflict error. +4. **Merge constraints.** New `constraints` from the policy are merged into the accumulated constraint context for subsequent policies. +5. **Validate patch.** The policy's `patch` is validated against the accumulated constraint context. For example, if a prior policy marked a field as immutable using a `const` constraint, any attempt to patch that field causes a policy conflict error. +6. **Apply patch.** Valid patches are applied to the request payload. +7. **Validate service provider.** If the policy returned a `selected_provider` and `service_provider_constraints` exist from prior policies, the selected provider is validated against those constraints. + +After all policies have been evaluated, the engine returns the final payload, the selected provider, and the evaluation status to the Placement Manager. The status is `APPROVED` if the payload was not modified, or `MODIFIED` if any patches were applied. + +--- + +For a step-by-step walkthrough, see [Create Placement Policy](../../getting-started/create-placement-policy/). diff --git a/content/docs/user-guide/providers.md b/content/docs/user-guide/providers.md new file mode 100644 index 0000000..4c716ec --- /dev/null +++ b/content/docs/user-guide/providers.md @@ -0,0 +1,85 @@ +--- +title: Providers +type: docs +weight: 2 +--- + +Providers are infrastructure endpoints registered by service provider instances. Each provider represents a backend system — such as a KubeVirt-enabled Kubernetes cluster — that can host virtual machines or other resources managed through DCM. + +Providers are **read-only** in the CLI. They are created automatically when a service provider instance connects to DCM and registers its available infrastructure. + +## Listing Providers + +Use `dcm sp provider list` to display all registered providers: + +```bash +dcm sp provider list +``` + +Example output: + +``` +ID NAME SERVICE TYPE STATUS HEALTH CREATED +3f8a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c kubevirt-cluster-01 vm REGISTERED HEALTHY 2026-01-15T08:30:00Z +a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d kubevirt-cluster-02 vm REGISTERED HEALTHY 2026-02-20T14:45:00Z +``` + +### Filtering by Service Type + +Use the `--type` flag to show only providers of a specific service type: + +```bash +dcm sp provider list --type vm +``` + +### Pagination + +For environments with many providers, use pagination flags to control the output: + +- `--page-size` — Maximum number of providers to return per page (int32). +- `--page-token` — Token for retrieving the next page of results (returned in the previous response). + +```bash +dcm sp provider list --page-size 10 +``` + +## Getting Provider Details + +Use `dcm sp provider get` to retrieve detailed information about a single provider: + +```bash +dcm sp provider get 3f8a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c +``` + +To view the full details as JSON: + +```bash +dcm sp provider get 3f8a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c -o json +``` + +Example JSON output: + +```json +{ + "create_time": "2026-04-15T18:37:45.550963Z", + "endpoint": "http://kubevirt-service-provider-main:8081/api/v1alpha1/vms", + "health_status": "ready", + "status": "registered", + "id": "9a0d35e0-4ed5-4728-a78e-c6ad61cdaab4", + "name": "kubevirt-main", + "schema_version": "v1alpha1", + "service_type": "vm", + "update_time": "2026-04-17T12:12:51.214419Z" +} +``` + +## Provider Status and Health + +Each provider exposes two key fields: + +- **STATUS** — Reflects the provider's registration state within DCM. A status of `registered` means the provider has been successfully registered and is recognized by the system. +- **HEALTH** — Reflects the result of the provider's last health check. A health value of `ready` indicates that the provider is reachable and operating normally. + +These fields are updated automatically as service provider instances report to DCM. + +> **Note:** See [Register Another Provider](../../getting-started/register-another-provider/) for a walkthrough of adding a new provider. diff --git a/content/docs/user-guide/service-provider-resources.md b/content/docs/user-guide/service-provider-resources.md new file mode 100644 index 0000000..18e9112 --- /dev/null +++ b/content/docs/user-guide/service-provider-resources.md @@ -0,0 +1,149 @@ +--- +title: Service Provider Resources +type: docs +weight: 7 +--- + +Service provider resources are the actual infrastructure resources — such as virtual machines, containers, or other services — created on [providers](../providers/) when [catalog item instances](../catalog-item-instances/) are provisioned. For example, when you deploy a catalog item instance for a VM on a KubeVirt provider, the service provider manager creates a KubeVirt VirtualMachine resource. That underlying resource is the SP resource. + +SP resources are managed entirely by the service provider manager and are **read-only** in the CLI. Each SP resource is linked to a specific catalog item instance and the provider where it was provisioned. + +> **Note:** You cannot create, update, or delete SP resources directly. They are created and cleaned up automatically as part of the catalog item instance lifecycle. + +## Listing Resources + +Use `dcm sp resource list` to view all service provider resources: + +```bash +dcm sp resource list +``` + +Example output: + +``` +ID PROVIDER STATUS CREATED +r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2 kubevirt-provider-1 READY 2026-04-01T10:30:00Z +r-3b5d7f90-c1e3-4a26-98b0-d4f6a8c2e0a1 kubevirt-provider-2 READY 2026-04-03T14:15:00Z +r-9e1a3c5d-7f20-4b68-a0c2-e4d6f8b1a3c5 container-provider-1 PENDING 2026-04-10T09:00:00Z +``` + +### Filtering by Provider + +To show only resources on a specific provider, use the `--provider` flag: + +```bash +dcm sp resource list --provider kubevirt-provider-1 +``` + +### Showing Deleted Resources + +By default, deleted resources are hidden. Use `--show-deleted` to include them in the output. This adds a DELETION STATUS column: + +```bash +dcm sp resource list --show-deleted +``` + +Example output: + +``` +ID PROVIDER STATUS DELETION STATUS CREATED +r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2 kubevirt-provider-1 READY 2026-04-01T10:30:00Z +r-3b5d7f90-c1e3-4a26-98b0-d4f6a8c2e0a1 kubevirt-provider-2 READY PENDING 2026-04-03T14:15:00Z +r-9e1a3c5d-7f20-4b68-a0c2-e4d6f8b1a3c5 container-provider-1 PENDING 2026-04-10T09:00:00Z +``` + +### Pagination + +For environments with many resources, use pagination flags to control the output: + +```bash +dcm sp resource list --page-size 10 +``` + +To fetch the next page, pass the token returned by the previous response: + +```bash +dcm sp resource list --page-size 10 --page-token "eyJvZmZzZXQiOjEwfQ==" +``` + +## Getting Resource Details + +Use `dcm sp resource get` to retrieve the full details of a single resource: + +```bash +dcm sp resource get r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2 +``` + +To view the output in JSON format: + +```bash +dcm sp resource get r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2 -o json +``` + +Example JSON output: + +```json +{ + "create_time": "2026-04-15T19:10:19.616508Z", + "id": "e4deb2bc-6c61-44b6-9bc9-6a8e5b813c0d", + "path": "service-type-instances/e4deb2bc-6c61-44b6-9bc9-6a8e5b813c0d", + "provider_name": "kubevirt-main", + "spec": { + "access": {}, + "guest_os": { + "type": "fedora" + }, + "memory": { + "size": "2GB" + }, + "metadata": { + "labels": { + "env": "dev" + }, + "name": "demo" + }, + "service_type": "vm", + "storage": { + "disks": [ + { + "capacity": "20GB", + "name": "boot" + } + ] + }, + "vcpu": { + "count": 1 + } + }, + "status": "Scheduling", + "update_time": "2026-04-15T19:17:01.990818Z" +} +``` + +To include deletion details for a resource that may have been deleted: + +```bash +dcm sp resource get r-3b5d7f90-c1e3-4a26-98b0-d4f6a8c2e0a1 --show-deleted +``` + +## Resource Lifecycle + +SP resources follow the lifecycle of the catalog item instances they belong to: + +1. **Creation** — When a catalog item instance is provisioned, the service provider manager automatically creates the corresponding SP resource on the selected provider. +2. **Active state** — The STATUS field reflects the current state of the resource on the provider (e.g., PENDING while being created, READY when fully provisioned). +3. **Rehydration** - When a catalog item instance is rehydrated, a new resource will be created and upon success, the old one will be scheduled for deletion. +4. **Deletion** — When a catalog item instance is deleted, the corresponding SP resource is cleaned up by the service provider manager. +5. **Viewing deleted resources** — Deleted resources are hidden by default but can still be viewed using the `--show-deleted` flag, which adds a DELETION STATUS column to the output. + +> **Note:** Deleted items will show while they are scheduled for deletion. Once they are removed from the SP they will no longer exist + +## Relationship to Catalog Item Instances + +Each [catalog item instance](../catalog-item-instances/) results in one SP resource on the provider selected during placement. The `resource_id` field on a catalog item instance links directly to the corresponding SP resource's ID. + +For example, if a catalog item instance has `resource_id: r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2`, you can inspect the underlying provider resource with: + +```bash +dcm sp resource get r-7a9c2e41-b3d5-4f68-80a1-e2c4d6f8a0b2 +``` diff --git a/content/docs/user-guide/service-types.md b/content/docs/user-guide/service-types.md new file mode 100644 index 0000000..462697d --- /dev/null +++ b/content/docs/user-guide/service-types.md @@ -0,0 +1,85 @@ +--- +title: Service Types +type: docs +weight: 3 +--- + +Service types define the kinds of services that DCM can manage. Each service type represents a specific resource category — for example, virtual machines or containers. + +Service types define the schema that [catalog items](../catalog-items/) must conform to, ensuring that resources are created with valid configurations. + +> **Note:** Currently, service types cannot be created or modified through the CLI. They are pre-registered by the Catalog Manager. + +## Listing Service Types + +Use `dcm catalog service-type list` to view all registered service types: + +```bash +dcm catalog service-type list +``` + +Example output: + +``` +UID SERVICE TYPE API VERSION CREATED +cluster cluster v1alpha1 2026-04-15T17:34:21.225163Z +container container v1alpha1 2026-04-15T17:34:21.225003Z +three-tier-app-demo three-tier-app-demo v1alpha1 2026-04-15T17:34:21.224575Z +vm vm v1alpha1 2026-04-15T17:34:21.224901Z +``` + +The table columns are: + +| Column | Description | +|--------|-------------| +| `UID` | Unique identifier for the service type | +| `SERVICE TYPE` | The type name, typically in a `group/Kind` format | +| `API VERSION` | Schema version of the service type | +| `CREATED` | Timestamp when the service type was registered | + +### Pagination + +For environments with many service types, use pagination flags to control the output: + +```bash +dcm catalog service-type list --page-size 10 +``` + +To fetch the next page, pass the token returned by the previous response: + +```bash +dcm catalog service-type list --page-size 10 --page-token "eyJvZmZzZXQiOjEwfQ==" +``` + +## Getting Service Type Details + +Use `dcm catalog service-type get` to retrieve details for a specific service type: + +```bash +dcm catalog service-type get a1b2c3d4-e5f6-7890-abcd-ef1234567890 +``` + +To get the full details in JSON format: + +```bash +dcm catalog service-type get a1b2c3d4-e5f6-7890-abcd-ef1234567890 -o json +``` + +Example JSON output: + +```json +{ + "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "service_type": "kubevirt.io/VirtualMachine", + "api_version": "v1alpha1", + "create_time": "2026-01-15T10:30:00Z" +} +``` + +## How Service Types Relate to Other Resources + +Service types sit at the foundation of the DCM resource model: + +- **Catalog items** reference a service type and must conform to its schema. See [Catalog Items](../catalog-items/). +- **Providers** register with a specific service type, indicating what kinds of resources they can host. See [Providers](../providers/). +- **Catalog item instances** are ultimately deployed according to the schema defined by the service type. See [Catalog Item Instances](../catalog-item-instances/).