Edit

Purpose: For developers, maintainers, explains what happens when opencenter cluster validate runs.

This document describes the code path and validation layers used by:

opencenter cluster validate
opencenter cluster validate <cluster>
opencenter cluster validate <organization>/<cluster>
opencenter cluster validate --config-file <path>
opencenter cluster validate --validation online
opencenter cluster validate --manifests

Only v2 configs with schema_version: "2.0" are supported.

Main Code Path

| File | Responsibility | | --- | --- | | cmd/cluster_validate.go | Cobra command, validation-mode resolution, active-cluster fallback, output selection. | | cmd/cluster_validate_manifests.go | Alternate --manifests path for generated GitOps manifest checks. | | internal/cluster/validate_service.go | Config path resolution, v2 loading, readiness checks, mode-gated online checks, debug config export. | | internal/cluster/validation_formatter.go | Text and JSON formatting from the operator report and structured validation issues. | | internal/config/v2/loader.go | Native v2 load pipeline: YAML parsing, normalization, defaults, reference resolution, schema validation. | | internal/config/v2/readiness.go | Offline deployment-readiness rules for provider config, GitOps auth, and enabled-service secrets. | | internal/cloud/openstack/discovery.go | Live OpenStack catalog discovery used only by online validation. |

Command Flow

opencenter cluster validate
        |
        v
cmd/cluster_validate.go
        |
        +-- if --manifests:
        |      runClusterValidateManifests(...)
        |
        +-- resolve input source:
        |      --config-file path, positional cluster, or active cluster
        |
        +-- resolve validation mode:
        |      --validation, behavior.validation, or offline default
        +-- build cluster.ValidateOptions
        |
        v
internal/cluster.ValidateService.Validate(...)
        |
        +-- resolve named cluster path, if needed
        +-- load v2 config exactly once
        +-- run offline readiness checks
        +-- run local GitOps checks
        +-- if mode is online:
        |      run provider connectivity, provider discovery, and Git remote checks
        +-- build operator report
        +-- optionally export debug config
        |
        v
format grouped text or JSON

The command no longer preloads named-cluster configs to discover the provider. The service owns config loading and stores the active provider on ValidationResult.Provider, so --config-file and named-cluster mode follow the same validation path.

Config Source Resolution

--config-file validates the provided file directly. The service checks file existence, loads the file through the v2 loader, and reports load/schema failures as validation issues.

Named cluster mode is used when no config file is supplied. The identifier is selected in this order:

  1. Positional argument, if supplied.

  2. Active cluster from OPENCENTER_CLUSTER, shell session state, or the persistent active marker.

Identifiers can be cluster or organization/cluster.

  • organization/cluster resolves through PathResolver.Resolve.

  • cluster resolves through PathResolver.ResolveWithFallback, which searches organization directories.

If no positional argument and no active cluster are available, the command returns:

no cluster name provided and no active cluster set

Validation Layers

1. Native v2 Loading

ValidateService builds a v2 loader with the defaults registry and calls:

cfg, err := loader.LoadFromFile(configPath)

The loader performs:

  • YAML parsing with known-field enforcement.

  • Schema version validation for schema_version: "2.0".

  • Input normalization.

  • Reference resolution for supported $\{ref:…​}, $\{env:…​}, and $\{file:…​} values.

  • Defaults hydration.

  • Struct tag validation through go-playground/validator.

  • Existing v2 business rules, such as OpenTofu backend shape.

Loader errors are converted to structured issues with category schema.

2. Offline Readiness Validation

After a config loads successfully, internal/config/v2.ValidateReadiness runs deterministic checks that do not contact cloud APIs, Git remotes, or Kubernetes.

Each issue has:

  • severity: error or warning

  • category: schema, provider, gitops, services, or connectivity

  • path: config path, when available

  • message

  • suggestion, when available

Any error makes ValidationResult.Valid false. Warnings are reported without failing validation.

OpenStack Offline Checks

When opencenter.infrastructure.provider is openstack, readiness validation requires:

  • opencenter.infrastructure.cloud.openstack.auth_url

  • region

  • project_id

  • image_id

  • application credential ID and secret

  • network_id or network_name

  • master flavor when master_count > 0

  • worker flavor when worker_count > 0

  • Windows worker flavor when worker_count_windows > 0

  • bastion flavor when bastion is enabled

  • each additional worker-pool flavor when the pool count is greater than zero

It also:

  • warns when the OpenStack auth URL uses plain HTTP

  • errors on empty or CHANGEME OpenStack credential values

  • errors when inactive provider cloud sections are present alongside OpenStack

GitOps Checks

opencenter.gitops.repository.url is required.

For HTTPS repository URLs:

  • token auth must be configured

  • gitops.auth.token.token or gitops.auth.token.token_file must be set

  • token provider must match the repository host:

  • github.com requires github

  • GitLab hosts require gitlab

  • other HTTPS Git hosts require gitea

For SSH repository URLs:

  • SSH auth must be configured

  • gitops.auth.ssh.private_key must be set

  • gitops.auth.ssh.public_key must be set

Configuring both SSH auth and token auth for the same repository is an error.

Enabled-Service Secret Checks

Only enabled services are checked. Empty strings and CHANGEME are treated as missing.

The v2-native secret map currently covers:

  • Keycloak admin password whenever Keycloak is enabled

  • Keycloak and Headlamp OIDC client secrets when OIDC is external; internal Keycloak OIDC generates them during bootstrap

  • Grafana admin password when kube-prometheus-stack is enabled

  • Loki Swift or S3 credentials when the selected storage mode requires them

  • Tempo Swift or S3 credentials when the selected storage mode requires them

  • cert-manager Route53 or Cloudflare DNS credentials

  • Weave GitOps password or password hash

  • alert-proxy account/device credentials

  • vSphere CSI credentials when the vSphere CSI service or storage plugin is enabled

3. Online Connectivity Checks

behavior.validation: online or --validation online enables checks that can contact external systems. For OpenStack, it validates that the Keystone auth URL is syntactically valid and reachable. Server-side 5xx responses fail connectivity validation; auth-oriented responses such as 401 or method responses do not fail the URL reachability check by themselves.

Connectivity findings use category connectivity and set ValidationResult.ConnectivityValid false when they are errors.

4. Online Live Provider Checks

Online validation authenticates and discovers a provider catalog through internal/cloud/openstack.DiscoveryClient for OpenStack.

The live catalog check validates configured:

  • images and image names

  • master, worker, Windows worker, bastion, and worker-pool flavors

  • networks and network names

  • subnet IDs

  • floating IP pools and external networks

  • availability zones

  • Designate availability when Designate is enabled

OpenStack API, auth, discovery, or missing-resource failures are returned as structured provider issues. No live provider checks run during offline validation.

ValidationResult Fields

ValidateService.Validate returns ValidationResult.

Important fields:

| Field | Meaning | | --- | --- | | Valid | False when any error-severity issue exists. | | ConfigValid | False for schema, GitOps, service, and other config-readiness errors. | | ConnectivityValid | False for connectivity errors. | | ProviderValid | False for provider config or live provider errors. | | Provider | Active provider from the loaded config. | | SchemaVersion | Normalized schema identifier, currently v2. | | Issues | Structured validation findings. | | Errors | Backward-compatible string errors derived from error issues. | | Warnings | Backward-compatible string warnings derived from warning issues. | | Suggestions | Deduplicated suggestions shown in text and JSON output. | | DebugConfigPath | Path to .opencenter-v2.yaml when debug export is requested. |

Output

Text output groups errors by config section and shows validation status for configuration, connectivity, and provider checks.

JSON output includes:

  • valid

  • summary

  • details

  • errors

  • errors_by_section

  • warnings

  • suggestions

  • issues

  • schema_version

  • debug_config_path, when generated

The formatter uses ValidationResult.Issues when present. It falls back to legacy string parsing for older callers that only populate Errors.

Debug Config Export

When --generate-debug-config is passed, or OPENCENTER_DEBUG is set, the service exports the effective config after defaults and reference resolution:

<output-dir>/.opencenter-v2.yaml

The export uses file mode 0600. Export failures become warnings rather than command-level errors.

Manifest Validation Mode

--manifests exits the normal config-readiness path and calls runClusterValidateManifests. That mode validates generated GitOps manifests rather than the cluster config itself.

Manifest validation should not be treated as a substitute for config readiness validation. Use both when checking a deployment pipeline end to end.