Skip to content

CNTRLPLANE-2711: add vault kms plug configuration api#2805

Open
flavianmissi wants to merge 6 commits intoopenshift:masterfrom
flavianmissi:CNTRLPLANE-2711-kms-api-2
Open

CNTRLPLANE-2711: add vault kms plug configuration api#2805
flavianmissi wants to merge 6 commits intoopenshift:masterfrom
flavianmissi:CNTRLPLANE-2711-kms-api-2

Conversation

@flavianmissi
Copy link
Copy Markdown
Member

No description provided.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Apr 15, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Apr 15, 2026

@flavianmissi: This pull request references CNTRLPLANE-2711 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 15, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 15, 2026

Hello @flavianmissi! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@openshift-ci openshift-ci Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Apr 15, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Removed the KMSEncryptionProvider feature gate, its test YAML, and its feature-gate registration. Replaced AWS KMS provider with a Vault-only model: added spec.encryption.kms.type: "Vault" and spec.encryption.kms.vault with fields including vaultAddress, kmsPluginImage, approleSecret, transitKey, and optional tls, transitMount, and vaultNamespace. Updated Go API annotations and CRD/x-validation to reference KMSEncryption and adjusted payload feature-gate manifests accordingly.

🚥 Pre-merge checks | ✅ 10 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Microshift Test Compatibility ⚠️ Warning Generated Ginkgo e2e tests reference the APIServer CRD from config.openshift.io API group, which is not available on MicroShift. Add [apigroup:config.openshift.io] tag to test specifications in VaultKMS.yaml to ensure MicroShift CI automatically skips these tests.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description explaining the purpose, scope, and rationale for migrating from AWS KMS to Vault KMS provider configuration.
✅ Passed checks (10 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a Vault KMS plugin configuration API, which is the central focus across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All Ginkgo test names are static and descriptive, with no dynamic values like timestamps, UUIDs, or generated identifiers.
Test Structure And Quality ✅ Passed PR does not include Ginkgo test code; test files are YAML CRD validation specifications, not Go unit tests.
Single Node Openshift (Sno) Test Compatibility ✅ Passed This pull request does not add any Ginkgo e2e tests. The VaultKMS.yaml file is a YAML-based API schema validation test specification, not a Ginkgo e2e test.
Topology-Aware Scheduling Compatibility ✅ Passed PR exclusively modifies API type definitions, CRD schemas, and feature gates without introducing deployment manifests or topology-unaware scheduling constructs.
Ote Binary Stdout Contract ✅ Passed The pull request does not introduce code that writes non-JSON data to stdout at the process level. Module-level initialization uses only data structure setup and error handling via panics (stderr) or error returns.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. Changes consist of API type definitions, CRD schemas, and YAML validation specs without IPv4 or external connectivity assumptions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

Error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented
The command is terminated due to an error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented


Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 15, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign deads2k for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@flavianmissi flavianmissi force-pushed the CNTRLPLANE-2711-kms-api-2 branch from 0e6ccdb to 9204eb8 Compare April 15, 2026 14:50
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 67-73: Add explicit Kubernetes validation markers to enforce the
documented bounds: annotate VaultNamespace, TransitMount, and TransitKey with
kubebuilder validation comments before each field (e.g. //
+kubebuilder:validation:MinLength=1 and //
+kubebuilder:validation:MaxLength=256) and keep the existing json tag
(json:"...,omitempty"). This ensures the CRD rejects empty strings and overly
long values for the VaultNamespace, TransitMount, and TransitKey fields.
- Around line 57-65: The VaultAddress field currently allows both http and
https; update its validation to require HTTPS only by changing the kubebuilder
XValidation rule on VaultAddress to match '^https://', update the validation
message to say "vaultAddress must be a valid URL starting with 'https://'...",
and ensure the example and any documentation reference use https (e.g.,
'https://vault.example.com:8200'); modify the comment and the
+kubebuilder:validation:XValidation line for VaultAddress in
types_kmsencryption.go accordingly.
- Around line 5-24: The change removed AWS KMS support and will break upgrades
for clusters with persisted AWS configs; restore backward compatibility by
either reintroducing AWS as a deprecated union member on KMSConfig (add
AWSKMSProvider value to KMSProviderType and an AWSKMSConfig struct as a
+unionMember with deprecation tags) and implement conversion logic in the API
conversion/webhook handlers to migrate existing AWSKMSConfig to the new model,
or implement and wire a documented controller migration path that detects
existing KMSConfig entries with AWS data and converts them to the new Vault-only
shape (or marks them as exempt) during upgrade; touch KMSConfig,
KMSProviderType, VaultKMSConfig, and add AWSKMSConfig/AWSKMSProvider identifiers
and ensure feature-gate annotations and validation rules account for
preserved/deprecated AWS entries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 31c84276-1bd6-44d1-aef1-c88652b3bb69

📥 Commits

Reviewing files that changed from the base of the PR and between 464776f and 0e6ccdb.

⛔ Files ignored due to path filters (10)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryptionProvider.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (17)
  • config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml
  • config/v1/tests/apiservers.config.openshift.io/KMSEncryptionProvider.yaml
  • config/v1/types_apiserver.go
  • config/v1/types_kmsencryption.go
  • features.md
  • features/features.go
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
💤 Files with no reviewable changes (12)
  • config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • features/features.go
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • features.md
  • config/v1/tests/apiservers.config.openshift.io/KMSEncryptionProvider.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml

Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go
Comment thread config/v1/types_kmsencryption.go
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
config/v1/types_kmsencryption.go (2)

67-73: ⚠️ Potential issue | 🟠 Major

Add the length validators promised by the API contract.

The documentation states bounds for vaultNamespace (1-256), transitMount (1-128), and transitKey (1-128), but the kubebuilder markers are missing. This allows empty strings and arbitrarily long values to pass schema validation, causing runtime failures instead of admission-time rejection.

Suggested fix for vaultNamespace (lines 67-73)
 	// vaultNamespace specifies the Vault namespace where the Transit secrets engine is mounted.
 	// This is only applicable for Vault Enterprise installations.
 	// The value can be between 1 and 256 characters.
 	// When this field is not set, no namespace is used.
 	//
+	// +kubebuilder:validation:MinLength=1
+	// +kubebuilder:validation:MaxLength=256
 	// +optional
 	VaultNamespace string `json:"vaultNamespace,omitempty"`
Suggested fix for transitMount (lines 128-134)
 	// transitMount specifies the mount path of the Vault Transit engine.
 	// The value can be between 1 and 128 characters.
 	// When this field is not set, it defaults to "transit".
 	//
+	// +kubebuilder:validation:MinLength=1
+	// +kubebuilder:validation:MaxLength=128
 	// +kubebuilder:default="transit"
 	// +optional
 	TransitMount string `json:"transitMount,omitempty"`
Suggested fix for transitKey (lines 136-141)
 	// transitKey specifies the name of the encryption key in Vault's Transit engine.
 	// This key is used to encrypt and decrypt data.
 	// The value must be between 1 and 128 characters.
 	//
+	// +kubebuilder:validation:MinLength=1
+	// +kubebuilder:validation:MaxLength=128
 	// +required
 	TransitKey string `json:"transitKey,omitempty"`

Also applies to: 128-141

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/v1/types_kmsencryption.go` around lines 67 - 73, Add kubebuilder
validation markers to enforce the documented length bounds on the three Vault
fields: annotate VaultNamespace with +kubebuilder:validation:MinLength=1 and
+kubebuilder:validation:MaxLength=256, annotate TransitMount with
+kubebuilder:validation:MinLength=1 and +kubebuilder:validation:MaxLength=128,
and annotate TransitKey with +kubebuilder:validation:MinLength=1 and
+kubebuilder:validation:MaxLength=128 so the API server rejects empty or overly
long values at admission time; ensure the markers appear immediately above the
corresponding struct fields VaultNamespace, TransitMount, and TransitKey.

57-65: ⚠️ Potential issue | 🟠 Major

Require HTTPS for the Vault endpoint.

Allowing http:// enables cleartext transmission of AppRole credentials and KMS traffic. The tlsVerify: SkipVerify option already covers insecure testing scenarios without disabling transport encryption entirely.

Suggested fix
-	// vaultAddress specifies the address of the HashiCorp Vault instance.
-	// The value must be a valid URL with scheme (http:// or https://) and can be up to 512 characters.
+	// vaultAddress specifies the address of the HashiCorp Vault instance.
+	// The value must be a valid HTTPS URL and can be up to 512 characters.
 	// Example: https://vault.example.com:8200
 	//
-	// +kubebuilder:validation:XValidation:rule="self.matches(r'^https?://')",message="vaultAddress must be a valid URL starting with 'http://' or 'https://' (e.g., 'https://vault.example.com:8200')."
+	// +kubebuilder:validation:XValidation:rule="self.matches(r'^https://')",message="vaultAddress must be a valid HTTPS URL (e.g., 'https://vault.example.com:8200')."
 	// +kubebuilder:validation:MaxLength=512
 	// +kubebuilder:validation:MinLength=1
 	// +required
 	VaultAddress string `json:"vaultAddress,omitempty"`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/v1/types_kmsencryption.go` around lines 57 - 65, The VaultAddress
field currently allows both http and https; change its validation to require
HTTPS only by updating the kubebuilder XValidation rule for VaultAddress
(symbol: VaultAddress) to match r'^https://', adjust the validation message to
state "vaultAddress must be a valid HTTPS URL starting with 'https://'" and keep
the MaxLength/MinLength/required tags intact so the API rejects non-HTTPS Vault
endpoints.
🧹 Nitpick comments (2)
payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml (1)

342-346: Validation message references KMSEncryption feature gate but rule doesn't enforce it.

The message says "kms config is required when encryption type is KMS and KMSEncryption feature gate is enabled" but the CEL rule itself doesn't check the feature gate state—it just validates kms presence based on type == 'KMS'. This is likely correct behavior (the feature gate controls schema presence, not this runtime rule), but the message is potentially misleading.

Consider simplifying the message to match the actual rule behavior:

-- message: kms config is required when encryption type is KMS and
-    KMSEncryption feature gate is enabled, and forbidden otherwise
+- message: kms config is required when encryption type is KMS, and forbidden otherwise
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml`
around lines 342 - 346, The validation message is misleading because it mentions
the KMSEncryption feature gate while the CEL rule only checks self.type and
self.kms; update the x-kubernetes-validations.message to reflect the actual rule
(e.g., "kms config is required when encryption type is 'KMS' and forbidden
otherwise") so it matches the rule for x-kubernetes-validations.rule that
evaluates has(self.type) && self.type == 'KMS' ? has(self.kms) : !has(self.kms);
adjust only the message string associated with that rule.
payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml (1)

342-346: Same validation message inconsistency as CustomNoUpgrade CRD.

The message mentions "KMSEncryption feature gate is enabled" but the CEL rule doesn't actually check feature gate state. Consider the same simplification suggested for the CustomNoUpgrade variant.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml`
around lines 342 - 346, The validation message for the x-kubernetes-validations
entry in the apiservers-TechPreviewNoUpgrade CRD is inconsistent with the CEL
rule: the message references "KMSEncryption feature gate is enabled" but the
rule only checks self.type and self.kms. Update the message to match the rule
(e.g., "kms config is required when encryption type is KMS and forbidden
otherwise") or, if you intend to gate on a feature flag, modify the CEL rule to
include that feature check; edit the x-kubernetes-validations -> message and/or
the rule that uses has(self.type) && self.type == 'KMS' ? has(self.kms) :
!has(self.kms) so they are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 48-55: The validation regex for VaultKMSPluginImage rejects
repository names containing underscores; update the kubebuilder XValidation rule
on VaultKMSPluginImage to allow underscores in the repository path by changing
the character class for the path portion from [a-zA-Z0-9./-]+ to include
underscores (e.g., [a-zA-Z0-9._/-]+) so OCI-compliant names like
"registry.example.com/my_project/vault_plugin@sha256:..." pass validation while
preserving the rest of the pattern and MinLength/MaxLength constraints.

---

Duplicate comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 67-73: Add kubebuilder validation markers to enforce the
documented length bounds on the three Vault fields: annotate VaultNamespace with
+kubebuilder:validation:MinLength=1 and +kubebuilder:validation:MaxLength=256,
annotate TransitMount with +kubebuilder:validation:MinLength=1 and
+kubebuilder:validation:MaxLength=128, and annotate TransitKey with
+kubebuilder:validation:MinLength=1 and +kubebuilder:validation:MaxLength=128 so
the API server rejects empty or overly long values at admission time; ensure the
markers appear immediately above the corresponding struct fields VaultNamespace,
TransitMount, and TransitKey.
- Around line 57-65: The VaultAddress field currently allows both http and
https; change its validation to require HTTPS only by updating the kubebuilder
XValidation rule for VaultAddress (symbol: VaultAddress) to match r'^https://',
adjust the validation message to state "vaultAddress must be a valid HTTPS URL
starting with 'https://'" and keep the MaxLength/MinLength/required tags intact
so the API rejects non-HTTPS Vault endpoints.

---

Nitpick comments:
In
`@payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml`:
- Around line 342-346: The validation message is misleading because it mentions
the KMSEncryption feature gate while the CEL rule only checks self.type and
self.kms; update the x-kubernetes-validations.message to reflect the actual rule
(e.g., "kms config is required when encryption type is 'KMS' and forbidden
otherwise") so it matches the rule for x-kubernetes-validations.rule that
evaluates has(self.type) && self.type == 'KMS' ? has(self.kms) : !has(self.kms);
adjust only the message string associated with that rule.

In
`@payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml`:
- Around line 342-346: The validation message for the x-kubernetes-validations
entry in the apiservers-TechPreviewNoUpgrade CRD is inconsistent with the CEL
rule: the message references "KMSEncryption feature gate is enabled" but the
rule only checks self.type and self.kms. Update the message to match the rule
(e.g., "kms config is required when encryption type is KMS and forbidden
otherwise") or, if you intend to gate on a feature flag, modify the CEL rule to
include that feature check; edit the x-kubernetes-validations -> message and/or
the rule that uses has(self.type) && self.type == 'KMS' ? has(self.kms) :
!has(self.kms) so they are consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b8d09f5-f990-4d5b-8bf2-27856efe1d7c

📥 Commits

Reviewing files that changed from the base of the PR and between 0e6ccdb and 9204eb8.

⛔ Files ignored due to path filters (8)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (12)
  • config/v1/types_kmsencryption.go
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
💤 Files with no reviewable changes (8)
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
✅ Files skipped from review due to trivial changes (1)
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml

Comment thread config/v1/types_kmsencryption.go Outdated
@flavianmissi flavianmissi force-pushed the CNTRLPLANE-2711-kms-api-2 branch from 9204eb8 to adcbfe4 Compare April 16, 2026 12:16
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
config/v1/types_kmsencryption.go (1)

5-24: ⚠️ Potential issue | 🔴 Critical

Preserve an upgrade path for existing aws KMS configs.

This change removes aws from the public kms union and provider enum without a deprecated member or any migration path in the API surface. Clusters that already persisted spec.encryption.kms.aws under the previous gate will be rejected on upgrade once this validation becomes authoritative.

Also applies to: 27-33

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/v1/types_kmsencryption.go` around lines 5 - 24, The KMS union removed
the previously allowed "aws" provider with no migration or deprecated field,
which will reject clusters that already have spec.encryption.kms.aws; restore
backward compatibility by reintroducing a deprecated/hidden union member for the
AWS provider (e.g. add an Aws *AWSKMSConfig `json:"aws,omitempty"` with
appropriate +optional and +deprecated markers or a FeatureGate-aware validation
exception) and keep the union discriminator Type KMSProviderType accepting the
old "aws" enum value (or add a deprecated enum entry) so existing persisted
KMSConfig objects with Type == "AWS" and the Aws member continue to validate
during upgrade while new API users are prevented from creating new AWS configs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 37-79: The CRD manifests are out of sync with the VaultKMSConfig
Go type: the Go struct now uses kmsPluginImage and a nested TLS struct
(VaultTLSConfig with caBundle and serverName) but the published CRDs still
expose vaultKMSPluginImage, flat tlsCA/tlsServerName/tlsVerify and old
http:///length validations; update the CRD schema to match the Go API by
renaming fields (vaultKMSPluginImage -> kmsPluginImage), nesting TLS under tls
with caBundle and serverName fields, removing the old http:// rule and
correcting MinLength/MaxLength rules to match KMSPluginImage and VaultAddress,
then regenerate the CRD manifests (e.g., run your controller-gen/CRD generation
or project make target) so the published YAML matches VaultKMSConfig,
KMSPluginImage, VaultAddress and TLS/VaultTLSConfig definitions.

---

Duplicate comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 5-24: The KMS union removed the previously allowed "aws" provider
with no migration or deprecated field, which will reject clusters that already
have spec.encryption.kms.aws; restore backward compatibility by reintroducing a
deprecated/hidden union member for the AWS provider (e.g. add an Aws
*AWSKMSConfig `json:"aws,omitempty"` with appropriate +optional and +deprecated
markers or a FeatureGate-aware validation exception) and keep the union
discriminator Type KMSProviderType accepting the old "aws" enum value (or add a
deprecated enum entry) so existing persisted KMSConfig objects with Type ==
"AWS" and the Aws member continue to validate during upgrade while new API users
are prevented from creating new AWS configs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 6481d801-9501-491c-91d0-022980739a42

📥 Commits

Reviewing files that changed from the base of the PR and between 9204eb8 and adcbfe4.

⛔ Files ignored due to path filters (8)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (12)
  • config/v1/types_kmsencryption.go
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
💤 Files with no reviewable changes (8)
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml

Comment thread config/v1/types_kmsencryption.go Outdated
@flavianmissi flavianmissi force-pushed the CNTRLPLANE-2711-kms-api-2 branch 2 times, most recently from 42d4c42 to bd0b2a0 Compare April 17, 2026 10:05
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 56-60: The XValidation on vaultAddress (self.matches('^https://'))
only enforces the prefix and allows invalid values like "https://"; update the
validation to either enforce a full URL shape (replace the XValidation rule with
a stronger regex/pattern that requires a host and optional port/path, e.g.
require at least "https://<host>" semantics) or, if you prefer the lighter
check, change the documentation/message to state "must start with 'https://'" to
match the current rule; update the kubebuilder:XValidation rule and the
vaultAddress comment/message accordingly so they are consistent (referencing the
vaultAddress field and its XValidation rule).
- Line 50: The XValidation message still references the old field name
vaultKMSPluginImage; update the validation annotation on the kmsPluginImage
field so the message uses the new field name (kmsPluginImage) and keep the rest
of the guidance unchanged. Locate the kubebuilder XValidation tag shown and
replace "vaultKMSPluginImage" in the message with "kmsPluginImage" so admission
errors point to the correct field.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 55d2598e-91dd-493c-9853-e17140c344fb

📥 Commits

Reviewing files that changed from the base of the PR and between 42d4c42 and bd0b2a0.

⛔ Files ignored due to path filters (8)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (12)
  • config/v1/types_kmsencryption.go
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
💤 Files with no reviewable changes (8)
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml

Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go Outdated
@flavianmissi flavianmissi force-pushed the CNTRLPLANE-2711-kms-api-2 branch from bd0b2a0 to 4e09913 Compare April 17, 2026 10:53
Comment thread config/v1/types_apiserver.go Outdated
Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go
Comment on lines -24 to -25
// AWSKMSConfig defines the KMS config specific to AWS KMS provider
type AWSKMSConfig struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we tombstone the field, we will also need to tombstone this type.

Comment thread config/v1/types_kmsencryption.go Outdated
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=1024
// +default="transit"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For configuration APIs, we normally try to avoid setting default values in this way.

Instead, we make omission of the field mean "no opinion" and have a standard terminology we use like

// When omitted, this means the user has no opinion and the platform is left
// to choose reasonable defaults. These defaults are subject to change over time.

This allows us to modify the underlying default behavior as needed without being contractually tied to a default value.

Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go Outdated
Comment thread config/v1/types_kmsencryption.go
@flavianmissi flavianmissi force-pushed the CNTRLPLANE-2711-kms-api-2 branch 2 times, most recently from 9818cfa to 64253d0 Compare April 24, 2026 08:42
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 24, 2026

@flavianmissi: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/lint 64253d0 link true /test lint
ci/prow/verify-crdify 64253d0 link true /test verify-crdify
ci/prow/verify-crd-schema 64253d0 link true /test verify-crd-schema

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@flavianmissi flavianmissi force-pushed the CNTRLPLANE-2711-kms-api-2 branch from 64253d0 to 3d4bd99 Compare April 24, 2026 10:59
@flavianmissi
Copy link
Copy Markdown
Member Author

flavianmissi commented Apr 24, 2026

/retitle CNTRLPLANE-2711: add vault kms plug configuration api

@openshift-ci openshift-ci Bot changed the title [WIP] CNTRLPLANE-2711: add vault kms plug configuration api CNTRLPLANE-2711: add vault kms plug configuration api Apr 24, 2026
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 24, 2026
@flavianmissi
Copy link
Copy Markdown
Member Author

Looks like the verify-crd* tests fail because of the removal (by tombstoning) of the aws kms plugin related config. I think we might need to override?

@flavianmissi
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
config/v1/types_kmsencryption.go (1)

220-223: ServerName validation message may be misleading.

The validation message says serverName must be a valid DNS hostname but uses format.dns1123Subdomain() validation. DNS subdomains and DNS hostnames have similar but not identical rules. For SNI purposes, this validation is acceptable, but the message could be more precise.

This is a minor terminology inconsistency. The validation will work correctly in practice.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/v1/types_kmsencryption.go` around lines 220 - 223, The validation
message for serverName is misleading: update the XValidation message tied to
format.dns1123Subdomain().validate(self).hasValue() so it refers to a DNS
subdomain/DNS-1123 rule instead of "DNS hostname" (e.g., "serverName must be a
valid DNS subdomain (DNS-1123)"). Locate the kubebuilder annotation on
serverName in types_kmsencryption.go and replace the message text in the
+kubebuilder:validation:XValidation line accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 104-105: The OCI Image name XValidation annotation in
config/v1/types_kmsencryption.go currently only permits a single optional
namespace segment; update the kubebuilder:validation:XValidation rule (the
annotation string that starts with self.split('@')[0].matches(...)) so the
namespace portion allows multiple path segments by replacing the single optional
"/([a-zA-Z0-9-_]{0,61}/)?" segment with a repeating group that permits zero or
more "/segment" components (each segment 1–61 chars of [a-zA-Z0-9-_]) while
keeping the existing hostname[:port] and final image name constraints intact.
Ensure the modified regex still enforces anchors and overall format and retains
the separate XValidation for the "@sha256:..." suffix.

---

Nitpick comments:
In `@config/v1/types_kmsencryption.go`:
- Around line 220-223: The validation message for serverName is misleading:
update the XValidation message tied to
format.dns1123Subdomain().validate(self).hasValue() so it refers to a DNS
subdomain/DNS-1123 rule instead of "DNS hostname" (e.g., "serverName must be a
valid DNS subdomain (DNS-1123)"). Locate the kubebuilder annotation on
serverName in types_kmsencryption.go and replace the message text in the
+kubebuilder:validation:XValidation line accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e0986733-5de8-45b5-b628-182582fb0240

📥 Commits

Reviewing files that changed from the base of the PR and between 42d4c42 and 3d4bd99.

⛔ Files ignored due to path filters (8)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (14)
  • config/v1/tests/apiservers.config.openshift.io/VaultKMS.yaml
  • config/v1/types_apiserver.go
  • config/v1/types_kmsencryption.go
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
💤 Files with no reviewable changes (8)
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml

Comment on lines +104 to +105
// +kubebuilder:validation:XValidation:rule=`(self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$'))`,message="the OCI Image reference must end with a valid '@sha256:<digest>' suffix, where '<digest>' is 64 characters long"
// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]+$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme. Short names are not allowed, the registry hostname must be included."
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the current regex behavior against common OCI image patterns

echo "Testing OCI image patterns against the current regex..."
echo ""

# The current regex pattern from the code
PATTERN='^([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]+$'

# Test cases - valid images that should pass
VALID_IMAGES=(
  "registry.example.com/vault-plugin"
  "registry.example.com/hashicorp/vault-plugin"
  "registry.example.com:5000/vault-plugin"
  "quay.io/hashicorp/vault-plugin"
)

# Test cases - images with deeper paths that may fail
DEEP_PATH_IMAGES=(
  "registry.example.com/org/team/vault-plugin"
  "gcr.io/project-id/subpath/image"
  "registry.example.com/a/b/c/vault-plugin"
)

echo "=== Testing valid single/double path images ==="
for img in "${VALID_IMAGES[@]}"; do
  if echo "$img" | grep -qP "$PATTERN"; then
    echo "✓ PASS: $img"
  else
    echo "✗ FAIL: $img"
  fi
done

echo ""
echo "=== Testing multi-level path images ==="
for img in "${DEEP_PATH_IMAGES[@]}"; do
  if echo "$img" | grep -qP "$PATTERN"; then
    echo "✓ PASS: $img"
  else
    echo "✗ FAIL: $img (may be expected based on regex)"
  fi
done

Repository: openshift/api

Length of output: 621


🏁 Script executed:

cd /tmp && git clone --quiet https://github.com/openshift/api.git && cd api

Repository: openshift/api

Length of output: 119


🏁 Script executed:

head -n 110 config/v1/types_kmsencryption.go | tail -n 10

Repository: openshift/api

Length of output: 994


🏁 Script executed:

# Test the proposed regex fix
python3 << 'EOF'
import re

# Current regex
current = r'^([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]+$'

# Proposed fix
proposed = r'^([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?(/[a-zA-Z0-9-_.]+)+$'

test_cases = [
    # Valid single/double path
    ("registry.example.com/vault-plugin", True),
    ("registry.example.com/hashicorp/vault-plugin", True),
    ("registry.example.com:5000/vault-plugin", True),
    ("quay.io/hashicorp/vault-plugin", True),
    # Multi-level paths
    ("registry.example.com/org/team/vault-plugin", True),
    ("gcr.io/project-id/subpath/image", True),
    ("registry.example.com/a/b/c/vault-plugin", True),
    # Invalid cases that should fail
    ("vault-plugin", False),  # no registry
    ("localhost/vault-plugin", False),  # localhost without port
    ("registry.example.com", False),  # no image name
    ("registry.example.com/", False),  # trailing slash only
    # Edge cases
    ("docker.io/library/alpine", True),
    ("ghcr.io/owner/repo/image", True),
]

print("=" * 80)
print("CURRENT REGEX RESULTS:")
print("=" * 80)
for img, expected in test_cases:
    result = bool(re.match(current, img))
    status = "✓" if result == expected else "✗"
    print(f"{status} {img:50} | Expected: {expected}, Got: {result}")

print("\n" + "=" * 80)
print("PROPOSED REGEX RESULTS:")
print("=" * 80)
for img, expected in test_cases:
    result = bool(re.match(proposed, img))
    status = "✓" if result == expected else "✗"
    print(f"{status} {img:50} | Expected: {expected}, Got: {result}")
EOF

Repository: openshift/api

Length of output: 2555


OCI image regex rejects valid multi-level namespace paths.

The regex at line 105 restricts namespace paths to a single optional segment (/([a-zA-Z0-9-_]{0,61}/)?). This rejects standard OCI images with multiple path components like registry.example.com/org/team/vault-plugin, gcr.io/project-id/subpath/image, and ghcr.io/owner/repo/image.

Update the regex to allow multiple path segments:

Proposed regex fix
-	// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]+$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme. Short names are not allowed, the registry hostname must be included."
+	// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?(/[a-zA-Z0-9-_.]+)+$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme. Short names are not allowed, the registry hostname must be included."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// +kubebuilder:validation:XValidation:rule=`(self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$'))`,message="the OCI Image reference must end with a valid '@sha256:<digest>' suffix, where '<digest>' is 64 characters long"
// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]+$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme. Short names are not allowed, the registry hostname must be included."
// +kubebuilder:validation:XValidation:rule=`(self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$'))`,message="the OCI Image reference must end with a valid '@sha256:<digest>' suffix, where '<digest>' is 64 characters long"
// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?(/[a-zA-Z0-9-_.]+)+$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme. Short names are not allowed, the registry hostname must be included."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/v1/types_kmsencryption.go` around lines 104 - 105, The OCI Image name
XValidation annotation in config/v1/types_kmsencryption.go currently only
permits a single optional namespace segment; update the
kubebuilder:validation:XValidation rule (the annotation string that starts with
self.split('@')[0].matches(...)) so the namespace portion allows multiple path
segments by replacing the single optional "/([a-zA-Z0-9-_]{0,61}/)?" segment
with a repeating group that permits zero or more "/segment" components (each
segment 1–61 chars of [a-zA-Z0-9-_]) while keeping the existing hostname[:port]
and final image name constraints intact. Ensure the modified regex still
enforces anchors and overall format and retains the separate XValidation for the
"@sha256:..." suffix.

Copy link
Copy Markdown
Member

@ardaguclu ardaguclu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From kms feature team point of view this looks nice to me. I've just dropped a few questions for referenced types.

// +unionMember
// +optional
AWS *AWSKMSConfig `json:"aws,omitempty"`
Vault VaultKMSConfig `json:"vault,omitempty,omitzero"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be better to have it referenced type as AWS?

// tls contains the TLS configuration for connecting to the Vault server.
// When this field is not set, system default TLS settings are used.
// +optional
TLS VaultTLSConfig `json:"tls,omitzero"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to have this referenced type?. So that consumers can check it with nil?

// The namespace for the secret referenced by approleSecret is openshift-config.
//
// +required
ApproleSecret VaultSecretReference `json:"approleSecret,omitzero"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to have this referenced type to check with nil for existence?

Copy link
Copy Markdown
Member

@ardaguclu ardaguclu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From kms feature team point of view this looks nice to me. I've just dropped a few questions for referenced types.

@ardaguclu
Copy link
Copy Markdown
Member

Looks like the verify-crd* tests fail because of the removal (by tombstoning) of the aws kms plugin related config. I think we might need to override?

Yes, failures are expected and needs to be overridden.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants