Skip to content

Accept clouds.yaml in OpenstackCreds Secret #1952

Description

@gtherond

Sub-issue 1 — clouds.yaml in OpenstackCreds Secret

Title: Accept clouds.yaml in OpenstackCreds Secret (parser, CRD, Conditions, microversion floor, Secret watch)

Parent: #1951

Labels (suggested): enhancement, area/credentials


Problem

OpenstackCredsSpec requires per-field credentials supplied via individual Kubernetes Secret keys (OS_AUTH_URL, OS_USERNAME, OS_PASSWORD, OS_DOMAIN_NAME, OS_REGION_NAME, OS_TENANT_NAME, OS_INTERFACE, OS_IDENTITY_API_VERSION). Operators with existing clouds.yaml files must re-flatten them into this schema, creating drift potential and locking the credential schema to username/password auth only. Microversion configuration that clouds.yaml carries (compute_api_version, volume_api_version, etc.) is not honored by the controller. Validation status is reported in two flat string fields that cannot represent multiple concurrent status concerns.

Proposal

Accept a clouds.yaml key in the credential Secret, parsed via github.com/gophercloud/utils/openstack/clientconfig. Add a cloudName field to OpenstackCredsSpec to select which cloud entry to use. Existing OS_* keys remain functional (legacy path preserved). Wire per-service *_api_version values from clouds.yaml (compute, volume, image, network, identity) as an operator-configurable floor over internal hardcoded microversion values. Replace the flat OpenStackValidationStatus / OpenStackValidationMessage status fields with a Kubernetes-style status.conditions slice. Watch every referenced Secret so credential rotation is observed automatically.

Scope

  • CRD changes (k8s/migration/api/v1alpha1/openstackcreds_types.go):
    • Add CloudName string \json:"cloudName,omitempty"`` to spec.
    • Replace OpenStackValidationStatus / OpenStackValidationMessage with Conditions []metav1.Condition (kubebuilder +listType=map +listMapKey=type).
    • make generate to refresh zz_generated.deepcopy.go and the CRD YAML.
  • Parser (k8s/migration/pkg/utils/):
    • New clouds_yaml.go wrapping clientconfig.AuthOptions (tmpfile-based for Secret-sourced YAML).
    • Refactor credutils.go ValidateAndGetProviderClient to branch on Secret content (clouds.yaml key present → new path; else → legacy OS_* path unchanged).
    • New conditions.go defining Condition Type / Reason constants per the proposed contract.
  • Microversion floor (v2v-helper/pkg/utils/):
    • New microversion.go exporting MicroversionFloor(configValue, hardcodedValue string) string.
    • Wire into every service client constructor in openstackopsutils.go; per-call hardcoded values (e.g. 2.60 for multi-attach attach) remain as floors over operator config when config is lower.
  • Controller (k8s/migration/internal/controller/openstackcreds_controller.go):
    • Add a Watches(&corev1.Secret{}, ...) mapping Secret events to all OpenstackCreds resources whose SecretRef points to that Secret.
    • Populate status.conditions per reconcile pass.
    • On first reconcile observing legacy flat status populated, clear those fields after writing equivalent Conditions.
    • Schedule a periodic 1-hour requeue for time-sensitive Conditions.

Out of scope (covered in follow-up sub-issues)

Acceptance criteria

  • OpenstackCredsSpec.CloudName field present with godoc documenting the multi-entry selection semantics.
  • OpenstackCredsStatus.Conditions slice present; legacy flat status fields retired.
  • Generated CRD YAML and deepcopy regenerated via make generate; not hand-edited.
  • Parser branches correctly on Secret content; clouds.yaml precedence over OS_* when both present.
  • Single-entry clouds.yaml works without cloudName set; multi-entry without cloudName returns CredentialsParsed=False, Reason=AmbiguousCloudName listing entries.
  • Microversion config from clouds.yaml applies as a floor (operator value wins when higher; hardcoded value wins when configured value is lower or absent). Compute / volume / image / network / identity services all honored.
  • Controller watches referenced Secrets and re-reconciles on change within seconds.
  • Multiple OpenstackCreds resources referencing the same clouds.yaml-backed Secret with different cloudName values reconcile independently; legacy OS_*-backed Secrets retain implicit 1:1 binding.
  • Periodic 1-hour RequeueAfter scheduled for time-sensitive Conditions (relevant for Support v3applicationcredential auth_type in clouds.yaml #1953 but plumbing lands here).
  • Unit tests cover all parser branches, Conditions helpers, microversion floor semantics, and the no-log-redaction posture (no secret material appears in any log line).
  • Existing OS_*-only Secret deployments work without changes after upgrade; flat status fields cleared on first post-upgrade reconcile.
  • Documentation updated (README.md credentials section, new docs/credentials.md operator guide).

Open questions for maintainers

  • Microversion floor semantics: confirm preference for floor-over-hardcoded (operator value wins only when higher), versus alternative options (hardcoded-wins or config-wins).
  • CloudName default behavior: confirm "use the only entry if single; error if multi-entry and unset" instead of e.g., defaulting to "default".
  • Tmpfile vs vendored YAML parser for clouds.yaml content sourced from Secret: tmpfile uses the upstream library directly; vendoring avoids filesystem I/O in the controller pod. Tmpfile preferred unless the project disallows on-disk credential material even transiently.
  • One-time MigratedFromFlatStatus=True Condition tracking the flat→Conditions transition: include or omit.

Branch name

1952-clouds-yaml-credentials (matches repo convention).

Design references (private to contributor)

Detailed design lives in the contributor's private spec/plan workspace and will be linked alongside the PR opened against this issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions