From 3933966c856bbe10cc33322dd823eec6341ae6fc Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 13:42:44 +0200
Subject: [PATCH 01/12] feat(api): add SecretEncryptionStatus types and
EtcdDataEncryptionUpToDate condition
Add API types for tracking etcd data re-encryption after key rotation:
- SecretEncryptionStatus with ActiveKey, TargetKey, and History fields
- SecretEncryptionKeyStatus union type (Azure, AWS, IBMCloud, AESCBC)
- Per-provider key status types (AzureKMSKeyStatus, AWSKMSKeyStatus, etc.)
- EncryptionMigrationHistory and EncryptionMigrationState types
- EtcdDataEncryptionUpToDate condition with 7 reason constants
- SecretEncryption field added to HostedClusterStatus and HCPStatus
- Deprecated backupKey fields on AWSKMSSpec, AzureKMSSpec, AESCBCSpec
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
api/hypershift/v1beta1/aws.go | 19 +
api/hypershift/v1beta1/azure.go | 24 ++
api/hypershift/v1beta1/hosted_controlplane.go | 4 +
.../v1beta1/hostedcluster_conditions.go | 14 +
api/hypershift/v1beta1/hostedcluster_types.go | 145 +++++++
api/hypershift/v1beta1/ibmcloud.go | 35 ++
.../v1beta1/zz_generated.deepcopy.go | 143 +++++++
.../AAA_ungated.yaml | 387 ++++++++++++++++++
.../ClusterUpdateAcceptRisks.yaml | 387 ++++++++++++++++++
.../ClusterVersionOperatorConfiguration.yaml | 387 ++++++++++++++++++
.../ExternalOIDC.yaml | 387 ++++++++++++++++++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 387 ++++++++++++++++++
.../ExternalOIDCWithUpstreamParity.yaml | 387 ++++++++++++++++++
.../GCPPlatform.yaml | 387 ++++++++++++++++++
.../HCPEtcdBackup.yaml | 387 ++++++++++++++++++
...perShiftOnlyDynamicResourceAllocation.yaml | 387 ++++++++++++++++++
.../ImageStreamImportMode.yaml | 387 ++++++++++++++++++
.../KMSEncryptionProvider.yaml | 387 ++++++++++++++++++
.../OpenStack.yaml | 387 ++++++++++++++++++
.../TLSAdherence.yaml | 387 ++++++++++++++++++
.../AAA_ungated.yaml | 387 ++++++++++++++++++
.../ClusterUpdateAcceptRisks.yaml | 387 ++++++++++++++++++
.../ClusterVersionOperatorConfiguration.yaml | 387 ++++++++++++++++++
.../ExternalOIDC.yaml | 387 ++++++++++++++++++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 387 ++++++++++++++++++
.../ExternalOIDCWithUpstreamParity.yaml | 387 ++++++++++++++++++
.../GCPPlatform.yaml | 387 ++++++++++++++++++
.../HCPEtcdBackup.yaml | 387 ++++++++++++++++++
...perShiftOnlyDynamicResourceAllocation.yaml | 387 ++++++++++++++++++
.../ImageStreamImportMode.yaml | 387 ++++++++++++++++++
.../KMSEncryptionProvider.yaml | 387 ++++++++++++++++++
.../OpenStack.yaml | 387 ++++++++++++++++++
.../TLSAdherence.yaml | 387 ++++++++++++++++++
33 files changed, 10446 insertions(+)
diff --git a/api/hypershift/v1beta1/aws.go b/api/hypershift/v1beta1/aws.go
index 3f8f39ede110..a5b9c824274c 100644
--- a/api/hypershift/v1beta1/aws.go
+++ b/api/hypershift/v1beta1/aws.go
@@ -1018,6 +1018,9 @@ type AWSKMSSpec struct {
ActiveKey AWSKMSKeyEntry `json:"activeKey"`
// backupKey defines the old key during the rotation process so previously created
// secrets can continue to be decrypted until they are all re-encrypted with the active key.
+ //
+ // Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ // The system automatically manages the previous key via the status field.
// +optional
BackupKey *AWSKMSKeyEntry `json:"backupKey,omitempty"`
// auth defines metadata about the management of credentials used to interact with AWS KMS
@@ -1082,6 +1085,22 @@ type AWSKMSKeyEntry struct {
ARN string `json:"arn"`
}
+// AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
+// reconstruct the backup sidecar container arguments.
+// +k8s:deepcopy-gen=true
+type AWSKMSKeyStatus struct {
+ // arn is the Amazon Resource Name of the KMS key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=2048
+ ARN string `json:"arn,omitempty"`
+ // region is the AWS region of the KMS key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ Region string `json:"region,omitempty"`
+}
+
// AWSPlatformStatus contains status specific to the AWS platform
type AWSPlatformStatus struct {
// defaultWorkerSecurityGroupID is the ID of a security group created by
diff --git a/api/hypershift/v1beta1/azure.go b/api/hypershift/v1beta1/azure.go
index c95773e13bd7..71f7beea32a4 100644
--- a/api/hypershift/v1beta1/azure.go
+++ b/api/hypershift/v1beta1/azure.go
@@ -856,6 +856,9 @@ type AzureKMSSpec struct {
ActiveKey AzureKMSKey `json:"activeKey"`
// backupKey defines the old key during the rotation process so previously created
// secrets can continue to be decrypted until they are all re-encrypted with the active key.
+ //
+ // Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ // The system automatically manages the previous key via the status field.
// +optional
BackupKey *AzureKMSKey `json:"backupKey,omitempty"`
@@ -902,6 +905,27 @@ type AzureKMSKey struct {
KeyVersion string `json:"keyVersion"`
}
+// AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
+// reconstruct the EncryptionConfiguration read provider.
+// +k8s:deepcopy-gen=true
+type AzureKMSKeyStatus struct {
+ // keyVaultName is the name of the Azure Key Vault.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ KeyVaultName string `json:"keyVaultName,omitempty"`
+ // keyName is the name of the key in the vault.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ KeyName string `json:"keyName,omitempty"`
+ // keyVersion is the version of the key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ KeyVersion string `json:"keyVersion,omitempty"`
+}
+
// AzureAuthenticationType is a discriminated union type that contains the Azure authentication configuration for an
// Azure Hosted Cluster. This type is used to determine which authentication configuration is being used. Valid values
// are "ManagedIdentities" and "WorkloadIdentities".
diff --git a/api/hypershift/v1beta1/hosted_controlplane.go b/api/hypershift/v1beta1/hosted_controlplane.go
index 8486514f0a18..05a2fa60d220 100644
--- a/api/hypershift/v1beta1/hosted_controlplane.go
+++ b/api/hypershift/v1beta1/hosted_controlplane.go
@@ -419,6 +419,10 @@ type HostedControlPlaneStatus struct {
// configuration contains the cluster configuration status of the HostedCluster
// +optional
Configuration *ConfigurationStatus `json:"configuration,omitempty"`
+
+ // secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ // +optional
+ SecretEncryption SecretEncryptionStatus `json:"secretEncryption,omitzero"`
}
// APIEndpoint represents a reachable Kubernetes API endpoint.
diff --git a/api/hypershift/v1beta1/hostedcluster_conditions.go b/api/hypershift/v1beta1/hostedcluster_conditions.go
index 9fda11a60a2c..374e52a4fefc 100644
--- a/api/hypershift/v1beta1/hostedcluster_conditions.go
+++ b/api/hypershift/v1beta1/hostedcluster_conditions.go
@@ -265,6 +265,12 @@ const (
PublicEndpointSharedIngressConfiguredReason = "SharedIngressConfigured"
PublicEndpointTopologyPrivateReason = "TopologyPrivate"
PublicEndpointConvergenceInProgressReason = "ConvergenceInProgress"
+ // EtcdDataEncryptionUpToDate indicates whether all etcd data is encrypted with the
+ // currently active encryption key.
+ // True: all data confirmed encrypted with the active key.
+ // False: re-encryption is in progress or has failed.
+ // Absent: encryption is not configured.
+ EtcdDataEncryptionUpToDate ConditionType = "EtcdDataEncryptionUpToDate"
)
// Reasons.
@@ -349,6 +355,14 @@ const (
AutoNodeNotConfiguredReason = "AutoNodeNotConfigured"
AutoNodeProgressingReason = "AutoNodeProgressing"
AutoNodeEvaluationFailedReason = "AutoNodeEvaluationFailed"
+
+ ReadOnlyRolloutInProgressReason = "ReadOnlyRolloutInProgress"
+ WritePromotionInProgressReason = "WritePromotionInProgress"
+ ReEncryptionInProgressReason = "ReEncryptionInProgress"
+ ReEncryptionCompletedReason = "ReEncryptionCompleted"
+ ReEncryptionFailedReason = "ReEncryptionFailed"
+ ReEncryptionWaitingForKASReason = "ReEncryptionWaitingForKASConvergence"
+ ReEncryptionPersistentFailureReason = "ReEncryptionPersistentFailure"
)
// Messages.
diff --git a/api/hypershift/v1beta1/hostedcluster_types.go b/api/hypershift/v1beta1/hostedcluster_types.go
index 74b50f24ad38..98b7c1e9ba9d 100644
--- a/api/hypershift/v1beta1/hostedcluster_types.go
+++ b/api/hypershift/v1beta1/hostedcluster_types.go
@@ -2073,10 +2073,151 @@ type AESCBCSpec struct {
ActiveKey corev1.LocalObjectReference `json:"activeKey"`
// backupKey defines the old key during the rotation process so previously created
// secrets can continue to be decrypted until they are all re-encrypted with the active key.
+ //
+ // Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ // The system automatically manages the previous key via the status field.
// +optional
BackupKey *corev1.LocalObjectReference `json:"backupKey,omitempty"`
}
+// SecretEncryptionProvider identifies the encryption provider recorded in status.
+// This is a separate type from KMSProvider because the KMSProvider enum does not include AESCBC.
+type SecretEncryptionProvider string
+
+const (
+ SecretEncryptionProviderAzure SecretEncryptionProvider = "Azure"
+ SecretEncryptionProviderAWS SecretEncryptionProvider = "AWS"
+ SecretEncryptionProviderIBMCloud SecretEncryptionProvider = "IBMCloud"
+ SecretEncryptionProviderAESCBC SecretEncryptionProvider = "AESCBC"
+)
+
+// SecretEncryptionStatus tracks the state of secret encryption key rotation and re-encryption.
+// +k8s:deepcopy-gen=true
+// +kubebuilder:validation:MinProperties=1
+type SecretEncryptionStatus struct {
+ // activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ // Updated after successful re-encryption.
+ // +optional
+ ActiveKey SecretEncryptionKeyStatus `json:"activeKey,omitzero"`
+ // targetKey is the key being rolled out during an active rotation. Snapshot from
+ // spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ // (not the current spec) during the rotation, so mid-rotation spec changes are
+ // safely queued until the current rotation completes. Cleared when rotation completes.
+ // +optional
+ TargetKey SecretEncryptionKeyStatus `json:"targetKey,omitzero"`
+ // history contains a list of key rotations applied to this cluster. The newest
+ // entry is first in the list. Entries have state Completed when re-encryption
+ // has finished. The current rotation phase is always history[0].state when
+ // history[0] is not Completed or Interrupted.
+ // +optional
+ // +listType=atomic
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=5
+ History []EncryptionMigrationHistory `json:"history,omitempty"`
+}
+
+// SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
+// instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+// +k8s:deepcopy-gen=true
+// +kubebuilder:validation:XValidation:rule="self.provider == 'Azure' ? has(self.azure) : !has(self.azure)",message="azure is required when provider is Azure, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.provider == 'AWS' ? has(self.aws) : !has(self.aws)",message="aws is required when provider is AWS, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.provider == 'IBMCloud' ? has(self.ibmCloud) : !has(self.ibmCloud)",message="ibmCloud is required when provider is IBMCloud, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.provider == 'AESCBC' ? has(self.aescbc) : !has(self.aescbc)",message="aescbc is required when provider is AESCBC, and forbidden otherwise"
+// +union
+type SecretEncryptionKeyStatus struct {
+ // provider identifies the encryption provider.
+ // +required
+ // +unionDiscriminator
+ // +kubebuilder:validation:Enum=Azure;AWS;IBMCloud;AESCBC
+ Provider SecretEncryptionProvider `json:"provider,omitempty"`
+ // azure holds the Azure KMS key identity fields.
+ // +optional
+ // +unionMember
+ Azure AzureKMSKeyStatus `json:"azure,omitzero"`
+ // aws holds the AWS KMS key identity fields.
+ // +optional
+ // +unionMember
+ AWS AWSKMSKeyStatus `json:"aws,omitzero"`
+ // ibmCloud holds the IBM Cloud KMS key identity fields.
+ // +optional
+ // +unionMember
+ IBMCloud IBMCloudKMSKeyStatus `json:"ibmCloud,omitzero"`
+ // aescbc holds a reference to the AESCBC key secret.
+ // +optional
+ // +unionMember
+ AESCBC AESCBCKeyStatus `json:"aescbc,omitzero"`
+}
+
+// AESCBCKeyStatus contains a reference to the AESCBC key secret and a SHA-256 hash
+// of its contents for fingerprinting.
+// +k8s:deepcopy-gen=true
+type AESCBCKeyStatus struct {
+ // secret is a reference to the secret containing the AESCBC key.
+ // +required
+ Secret corev1.LocalObjectReference `json:"secret,omitempty"`
+ // dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ // at the time re-encryption completed.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=64
+ DataHash string `json:"dataHash,omitempty"`
+}
+
+// EncryptionKeyReference identifies an encryption key by its provider and fingerprint.
+// +k8s:deepcopy-gen=true
+type EncryptionKeyReference struct {
+ // provider identifies the encryption provider.
+ // +required
+ // +kubebuilder:validation:Enum=Azure;AWS;IBMCloud;AESCBC
+ Provider SecretEncryptionProvider `json:"provider,omitempty"`
+ // fingerprint is the hex-encoded SHA-256 hash of the key's identity fields.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=64
+ Fingerprint string `json:"fingerprint,omitempty"`
+}
+
+// EncryptionMigrationState tracks the lifecycle of a key rotation.
+// +kubebuilder:validation:Enum=ReadOnlyDeploy;WritePromote;Migrating;Completed;Interrupted
+type EncryptionMigrationState string
+
+const (
+ // EncryptionMigrationStateReadOnlyDeploy means the new key is being deployed as a read-only
+ // provider. The old key remains the write provider.
+ EncryptionMigrationStateReadOnlyDeploy EncryptionMigrationState = "ReadOnlyDeploy"
+ // EncryptionMigrationStateWritePromote means the new key is being promoted to write provider.
+ // The old key becomes read-only.
+ EncryptionMigrationStateWritePromote EncryptionMigrationState = "WritePromote"
+ // EncryptionMigrationStateMigrating means all KAS replicas have converged on the new write
+ // provider and re-encryption (StorageVersionMigration) is in progress.
+ EncryptionMigrationStateMigrating EncryptionMigrationState = "Migrating"
+ // EncryptionMigrationStateCompleted means all data was successfully re-encrypted with the target key.
+ EncryptionMigrationStateCompleted EncryptionMigrationState = "Completed"
+ // EncryptionMigrationStateInterrupted means the rotation was abandoned before data was encrypted
+ // with the target key (e.g., targetKey replaced during ReadOnlyDeploy).
+ EncryptionMigrationStateInterrupted EncryptionMigrationState = "Interrupted"
+)
+
+// EncryptionMigrationHistory records a key rotation, including in-progress rotations.
+// +k8s:deepcopy-gen=true
+type EncryptionMigrationHistory struct {
+ // from is the key that data was migrated from (the previous active key).
+ // +required
+ From EncryptionKeyReference `json:"from,omitzero"`
+ // to is the key that data was migrated to (the target key).
+ // +required
+ To EncryptionKeyReference `json:"to,omitzero"`
+ // state tracks the current phase of this rotation.
+ // +required
+ State EncryptionMigrationState `json:"state,omitempty"`
+ // startedTime is when the rotation was initiated.
+ // +required
+ StartedTime metav1.Time `json:"startedTime,omitempty"`
+ // completionTime is when the rotation finished. Not set while the rotation is in progress.
+ // +optional
+ CompletionTime *metav1.Time `json:"completionTime,omitempty"`
+}
+
type PayloadArchType string
const (
@@ -2190,6 +2331,10 @@ type HostedClusterStatus struct {
// +kubebuilder:validation:MaxLength=2048
// +kubebuilder:validation:XValidation:rule="self.matches('^(https|s3)://.*')",message="lastSuccessfulEtcdBackupURL must be a valid URL with scheme https or s3"
LastSuccessfulEtcdBackupURL string `json:"lastSuccessfulEtcdBackupURL,omitempty"`
+
+ // secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ // +optional
+ SecretEncryption SecretEncryptionStatus `json:"secretEncryption,omitzero"`
}
// AutoNodeStatus contains the observed state of the AutoNode provisioner.
diff --git a/api/hypershift/v1beta1/ibmcloud.go b/api/hypershift/v1beta1/ibmcloud.go
index 0f824883e300..bad0e9c3c1c0 100644
--- a/api/hypershift/v1beta1/ibmcloud.go
+++ b/api/hypershift/v1beta1/ibmcloud.go
@@ -44,6 +44,41 @@ type IBMCloudKMSKeyEntry struct {
KeyVersion int `json:"keyVersion"`
}
+// IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
+// sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
+// +k8s:deepcopy-gen=true
+type IBMCloudKMSKeyStatus struct {
+ // crkID is the Customer Root Key ID.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ CRKID string `json:"crkID,omitempty"`
+ // instanceID is the KMS instance ID.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ InstanceID string `json:"instanceID,omitempty"`
+ // keyVersion is the key version number.
+ // +required
+ // +kubebuilder:validation:Minimum=0
+ KeyVersion int32 `json:"keyVersion,omitempty"`
+ // region is the IBM Cloud region.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ Region string `json:"region,omitempty"`
+ // correlationID is the correlation ID for the key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ CorrelationID string `json:"correlationID,omitempty"`
+ // url is the KMS endpoint URL.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=2048
+ URL string `json:"url,omitempty"`
+}
+
// IBMCloudKMSAuthSpec defines metadata for how authentication is done with IBM Cloud KMS
type IBMCloudKMSAuthSpec struct {
// type defines the IBM Cloud KMS authentication strategy
diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 454f86378499..33601892dd28 100644
--- a/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -29,6 +29,22 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AESCBCKeyStatus) DeepCopyInto(out *AESCBCKeyStatus) {
+ *out = *in
+ out.Secret = in.Secret
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AESCBCKeyStatus.
+func (in *AESCBCKeyStatus) DeepCopy() *AESCBCKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AESCBCKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AESCBCSpec) DeepCopyInto(out *AESCBCSpec) {
*out = *in
@@ -256,6 +272,21 @@ func (in *AWSKMSKeyEntry) DeepCopy() *AWSKMSKeyEntry {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSKMSKeyStatus) DeepCopyInto(out *AWSKMSKeyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSKMSKeyStatus.
+func (in *AWSKMSKeyStatus) DeepCopy() *AWSKMSKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AWSKMSKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSKMSSpec) DeepCopyInto(out *AWSKMSSpec) {
*out = *in
@@ -641,6 +672,21 @@ func (in *AzureKMSKey) DeepCopy() *AzureKMSKey {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureKMSKeyStatus) DeepCopyInto(out *AzureKMSKeyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKMSKeyStatus.
+func (in *AzureKMSKeyStatus) DeepCopy() *AzureKMSKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AzureKMSKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureKMSSpec) DeepCopyInto(out *AzureKMSSpec) {
*out = *in
@@ -1615,6 +1661,43 @@ func (in *Diagnostics) DeepCopy() *Diagnostics {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EncryptionKeyReference) DeepCopyInto(out *EncryptionKeyReference) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EncryptionKeyReference.
+func (in *EncryptionKeyReference) DeepCopy() *EncryptionKeyReference {
+ if in == nil {
+ return nil
+ }
+ out := new(EncryptionKeyReference)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EncryptionMigrationHistory) DeepCopyInto(out *EncryptionMigrationHistory) {
+ *out = *in
+ out.From = in.From
+ out.To = in.To
+ in.StartedTime.DeepCopyInto(&out.StartedTime)
+ if in.CompletionTime != nil {
+ in, out := &in.CompletionTime, &out.CompletionTime
+ *out = (*in).DeepCopy()
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EncryptionMigrationHistory.
+func (in *EncryptionMigrationHistory) DeepCopy() *EncryptionMigrationHistory {
+ if in == nil {
+ return nil
+ }
+ out := new(EncryptionMigrationHistory)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EtcdSpec) DeepCopyInto(out *EtcdSpec) {
*out = *in
@@ -2461,6 +2544,7 @@ func (in *HostedClusterStatus) DeepCopyInto(out *HostedClusterStatus) {
*out = new(ConfigurationStatus)
(*in).DeepCopyInto(*out)
}
+ in.SecretEncryption.DeepCopyInto(&out.SecretEncryption)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedClusterStatus.
@@ -2697,6 +2781,7 @@ func (in *HostedControlPlaneStatus) DeepCopyInto(out *HostedControlPlaneStatus)
*out = new(ConfigurationStatus)
(*in).DeepCopyInto(*out)
}
+ in.SecretEncryption.DeepCopyInto(&out.SecretEncryption)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedControlPlaneStatus.
@@ -2749,6 +2834,21 @@ func (in *IBMCloudKMSKeyEntry) DeepCopy() *IBMCloudKMSKeyEntry {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IBMCloudKMSKeyStatus) DeepCopyInto(out *IBMCloudKMSKeyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMCloudKMSKeyStatus.
+func (in *IBMCloudKMSKeyStatus) DeepCopy() *IBMCloudKMSKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(IBMCloudKMSKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IBMCloudKMSManagedAuthSpec) DeepCopyInto(out *IBMCloudKMSManagedAuthSpec) {
*out = *in
@@ -4423,6 +4523,25 @@ func (in *ScaleDownConfig) DeepCopy() *ScaleDownConfig {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecretEncryptionKeyStatus) DeepCopyInto(out *SecretEncryptionKeyStatus) {
+ *out = *in
+ out.Azure = in.Azure
+ out.AWS = in.AWS
+ out.IBMCloud = in.IBMCloud
+ out.AESCBC = in.AESCBC
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretEncryptionKeyStatus.
+func (in *SecretEncryptionKeyStatus) DeepCopy() *SecretEncryptionKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(SecretEncryptionKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretEncryptionSpec) DeepCopyInto(out *SecretEncryptionSpec) {
*out = *in
@@ -4448,6 +4567,30 @@ func (in *SecretEncryptionSpec) DeepCopy() *SecretEncryptionSpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecretEncryptionStatus) DeepCopyInto(out *SecretEncryptionStatus) {
+ *out = *in
+ out.ActiveKey = in.ActiveKey
+ out.TargetKey = in.TargetKey
+ if in.History != nil {
+ in, out := &in.History, &out.History
+ *out = make([]EncryptionMigrationHistory, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretEncryptionStatus.
+func (in *SecretEncryptionStatus) DeepCopy() *SecretEncryptionStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(SecretEncryptionStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretReference) DeepCopyInto(out *SecretReference) {
*out = *in
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
index 4ed2391e13e2..9550a6992ce2 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
@@ -6022,6 +6022,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6079,6 +6082,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6133,6 +6139,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7004,6 +7013,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 9185fb00d932..fea5196ecf83 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -6005,6 +6005,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6062,6 +6065,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6116,6 +6122,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6987,6 +6996,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 2269797a21d4..16ad0192fc0e 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -6025,6 +6025,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6082,6 +6085,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6136,6 +6142,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7007,6 +7016,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
index 0a1a136fa308..c3b19174d9d0 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
@@ -6337,6 +6337,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6394,6 +6397,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6448,6 +6454,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7484,6 +7493,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index cebc53316acf..cec6736ddbb4 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -6477,6 +6477,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6534,6 +6537,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6588,6 +6594,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7624,6 +7633,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 1270fd8cb1fb..c62dd3d18d83 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -6468,6 +6468,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6525,6 +6528,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6579,6 +6585,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7450,6 +7459,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
index f7170ecada7a..a47c6e4f7458 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
@@ -6451,6 +6451,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6508,6 +6511,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6562,6 +6568,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7433,6 +7442,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
index fd458cb1f13b..3ca56744ebd3 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -6070,6 +6070,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6127,6 +6130,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6181,6 +6187,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7064,6 +7073,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 461ae7dc7982..cfdd95d57a99 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -6027,6 +6027,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6084,6 +6087,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6138,6 +6144,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7009,6 +7018,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
index f741a117e78b..4504461be66a 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -6023,6 +6023,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6080,6 +6083,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6134,6 +6140,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7016,6 +7025,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
index 33c70e1bc312..daf3aac48042 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -6081,6 +6081,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6138,6 +6141,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6192,6 +6198,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7063,6 +7072,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
index bdb6610a9248..ab1ff8ad45c5 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
@@ -6556,6 +6556,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6613,6 +6616,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6667,6 +6673,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7538,6 +7547,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
index 517516cd2f4a..d8b3291b5a15 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
@@ -6045,6 +6045,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6102,6 +6105,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6156,6 +6162,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7027,6 +7036,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
index 7faf853bd178..b5b5eb86392a 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
@@ -5877,6 +5877,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5934,6 +5937,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -5988,6 +5994,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6836,6 +6845,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 927f2b9ffc23..97f443cb0d21 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -5860,6 +5860,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5917,6 +5920,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -5971,6 +5977,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6819,6 +6828,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index ad6e7742c0ec..d1f563f98d7b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -5880,6 +5880,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5937,6 +5940,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -5991,6 +5997,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6839,6 +6848,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
index 1b9da7de5255..5a0a3088891e 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
@@ -6192,6 +6192,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6249,6 +6252,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6303,6 +6309,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7316,6 +7325,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 3cd3503473be..4c1d71b72f76 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -6332,6 +6332,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6389,6 +6392,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6443,6 +6449,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7456,6 +7465,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 9d7a73cb3bf0..7e7a23418f13 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -6323,6 +6323,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6380,6 +6383,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6434,6 +6440,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7282,6 +7291,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
index 1527b355549f..034333cd3535 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
@@ -6306,6 +6306,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6363,6 +6366,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6417,6 +6423,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7265,6 +7274,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
index 36a11500968d..26fe90e75e63 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -5925,6 +5925,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5982,6 +5985,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6036,6 +6042,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6884,6 +6893,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 5ea38844b584..7d5de94eecd4 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -5882,6 +5882,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5939,6 +5942,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -5993,6 +5999,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6841,6 +6850,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
index 9de4ad90ead5..4327a332bc93 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -5878,6 +5878,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5935,6 +5938,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -5989,6 +5995,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6848,6 +6857,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
index db3f3840a8c2..fae5de3d2ce0 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -5936,6 +5936,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5993,6 +5996,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6047,6 +6053,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6895,6 +6904,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
index c3c0b64fcf23..63879512e486 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
@@ -6411,6 +6411,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6468,6 +6471,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6522,6 +6528,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7370,6 +7379,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
index e52cbe485e19..68fe67fe532d 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
@@ -5900,6 +5900,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -5957,6 +5960,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6011,6 +6017,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -6859,6 +6868,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
From 40ac0a0b184ad25d361ef233937863c752f5dc41 Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 13:42:52 +0200
Subject: [PATCH 02/12] chore(api): regenerate CRDs, clients, deepcopy, and
vendor
Auto-generated output from make update after API type changes.
Includes vendored library-go migrators and kube-storage-version-migrator
informer/lister packages required by the HCCO re-encryption controller.
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
.../hypershift/v1beta1/aescbckeystatus.go | 51 +++
.../hypershift/v1beta1/awskmskeystatus.go | 47 +++
.../hypershift/v1beta1/azurekmskeystatus.go | 56 +++
.../v1beta1/encryptionkeyreference.go | 51 +++
.../v1beta1/encryptionmigrationhistory.go | 79 ++++
.../hypershift/v1beta1/hostedclusterstatus.go | 9 +
.../v1beta1/hostedcontrolplanestatus.go | 9 +
.../v1beta1/ibmcloudkmskeystatus.go | 83 ++++
.../v1beta1/secretencryptionkeystatus.go | 78 ++++
.../v1beta1/secretencryptionstatus.go | 61 +++
client/applyconfiguration/utils.go | 16 +
...usters-Hypershift-CustomNoUpgrade.crd.yaml | 387 ++++++++++++++++++
...hostedclusters-Hypershift-Default.crd.yaml | 387 ++++++++++++++++++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 387 ++++++++++++++++++
...planes-Hypershift-CustomNoUpgrade.crd.yaml | 387 ++++++++++++++++++
...dcontrolplanes-Hypershift-Default.crd.yaml | 387 ++++++++++++++++++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 387 ++++++++++++++++++
go.mod | 2 +-
.../hypershift/api/hypershift/v1beta1/aws.go | 19 +
.../api/hypershift/v1beta1/azure.go | 24 ++
20 files changed, 2906 insertions(+), 1 deletion(-)
create mode 100644 client/applyconfiguration/hypershift/v1beta1/aescbckeystatus.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/encryptionkeyreference.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/encryptionmigrationhistory.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go
create mode 100644 client/applyconfiguration/hypershift/v1beta1/secretencryptionstatus.go
diff --git a/client/applyconfiguration/hypershift/v1beta1/aescbckeystatus.go b/client/applyconfiguration/hypershift/v1beta1/aescbckeystatus.go
new file mode 100644
index 000000000000..414a0f19836e
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/aescbckeystatus.go
@@ -0,0 +1,51 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ v1 "k8s.io/api/core/v1"
+)
+
+// AESCBCKeyStatusApplyConfiguration represents a declarative configuration of the AESCBCKeyStatus type for use
+// with apply.
+type AESCBCKeyStatusApplyConfiguration struct {
+ Secret *v1.LocalObjectReference `json:"secret,omitempty"`
+ DataHash *string `json:"dataHash,omitempty"`
+}
+
+// AESCBCKeyStatusApplyConfiguration constructs a declarative configuration of the AESCBCKeyStatus type for use with
+// apply.
+func AESCBCKeyStatus() *AESCBCKeyStatusApplyConfiguration {
+ return &AESCBCKeyStatusApplyConfiguration{}
+}
+
+// WithSecret sets the Secret field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Secret field is set to the value of the last call.
+func (b *AESCBCKeyStatusApplyConfiguration) WithSecret(value v1.LocalObjectReference) *AESCBCKeyStatusApplyConfiguration {
+ b.Secret = &value
+ return b
+}
+
+// WithDataHash sets the DataHash field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the DataHash field is set to the value of the last call.
+func (b *AESCBCKeyStatusApplyConfiguration) WithDataHash(value string) *AESCBCKeyStatusApplyConfiguration {
+ b.DataHash = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go b/client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go
new file mode 100644
index 000000000000..337edbc9ea75
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go
@@ -0,0 +1,47 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// AWSKMSKeyStatusApplyConfiguration represents a declarative configuration of the AWSKMSKeyStatus type for use
+// with apply.
+type AWSKMSKeyStatusApplyConfiguration struct {
+ ARN *string `json:"arn,omitempty"`
+ Region *string `json:"region,omitempty"`
+}
+
+// AWSKMSKeyStatusApplyConfiguration constructs a declarative configuration of the AWSKMSKeyStatus type for use with
+// apply.
+func AWSKMSKeyStatus() *AWSKMSKeyStatusApplyConfiguration {
+ return &AWSKMSKeyStatusApplyConfiguration{}
+}
+
+// WithARN sets the ARN field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the ARN field is set to the value of the last call.
+func (b *AWSKMSKeyStatusApplyConfiguration) WithARN(value string) *AWSKMSKeyStatusApplyConfiguration {
+ b.ARN = &value
+ return b
+}
+
+// WithRegion sets the Region field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Region field is set to the value of the last call.
+func (b *AWSKMSKeyStatusApplyConfiguration) WithRegion(value string) *AWSKMSKeyStatusApplyConfiguration {
+ b.Region = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go b/client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go
new file mode 100644
index 000000000000..29c942b8c66a
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go
@@ -0,0 +1,56 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// AzureKMSKeyStatusApplyConfiguration represents a declarative configuration of the AzureKMSKeyStatus type for use
+// with apply.
+type AzureKMSKeyStatusApplyConfiguration struct {
+ KeyVaultName *string `json:"keyVaultName,omitempty"`
+ KeyName *string `json:"keyName,omitempty"`
+ KeyVersion *string `json:"keyVersion,omitempty"`
+}
+
+// AzureKMSKeyStatusApplyConfiguration constructs a declarative configuration of the AzureKMSKeyStatus type for use with
+// apply.
+func AzureKMSKeyStatus() *AzureKMSKeyStatusApplyConfiguration {
+ return &AzureKMSKeyStatusApplyConfiguration{}
+}
+
+// WithKeyVaultName sets the KeyVaultName field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the KeyVaultName field is set to the value of the last call.
+func (b *AzureKMSKeyStatusApplyConfiguration) WithKeyVaultName(value string) *AzureKMSKeyStatusApplyConfiguration {
+ b.KeyVaultName = &value
+ return b
+}
+
+// WithKeyName sets the KeyName field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the KeyName field is set to the value of the last call.
+func (b *AzureKMSKeyStatusApplyConfiguration) WithKeyName(value string) *AzureKMSKeyStatusApplyConfiguration {
+ b.KeyName = &value
+ return b
+}
+
+// WithKeyVersion sets the KeyVersion field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the KeyVersion field is set to the value of the last call.
+func (b *AzureKMSKeyStatusApplyConfiguration) WithKeyVersion(value string) *AzureKMSKeyStatusApplyConfiguration {
+ b.KeyVersion = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/encryptionkeyreference.go b/client/applyconfiguration/hypershift/v1beta1/encryptionkeyreference.go
new file mode 100644
index 000000000000..4d5cfb3a0803
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/encryptionkeyreference.go
@@ -0,0 +1,51 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ hypershiftv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+)
+
+// EncryptionKeyReferenceApplyConfiguration represents a declarative configuration of the EncryptionKeyReference type for use
+// with apply.
+type EncryptionKeyReferenceApplyConfiguration struct {
+ Provider *hypershiftv1beta1.SecretEncryptionProvider `json:"provider,omitempty"`
+ Fingerprint *string `json:"fingerprint,omitempty"`
+}
+
+// EncryptionKeyReferenceApplyConfiguration constructs a declarative configuration of the EncryptionKeyReference type for use with
+// apply.
+func EncryptionKeyReference() *EncryptionKeyReferenceApplyConfiguration {
+ return &EncryptionKeyReferenceApplyConfiguration{}
+}
+
+// WithProvider sets the Provider field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Provider field is set to the value of the last call.
+func (b *EncryptionKeyReferenceApplyConfiguration) WithProvider(value hypershiftv1beta1.SecretEncryptionProvider) *EncryptionKeyReferenceApplyConfiguration {
+ b.Provider = &value
+ return b
+}
+
+// WithFingerprint sets the Fingerprint field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Fingerprint field is set to the value of the last call.
+func (b *EncryptionKeyReferenceApplyConfiguration) WithFingerprint(value string) *EncryptionKeyReferenceApplyConfiguration {
+ b.Fingerprint = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/encryptionmigrationhistory.go b/client/applyconfiguration/hypershift/v1beta1/encryptionmigrationhistory.go
new file mode 100644
index 000000000000..7399882773f6
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/encryptionmigrationhistory.go
@@ -0,0 +1,79 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ hypershiftv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EncryptionMigrationHistoryApplyConfiguration represents a declarative configuration of the EncryptionMigrationHistory type for use
+// with apply.
+type EncryptionMigrationHistoryApplyConfiguration struct {
+ From *EncryptionKeyReferenceApplyConfiguration `json:"from,omitempty"`
+ To *EncryptionKeyReferenceApplyConfiguration `json:"to,omitempty"`
+ State *hypershiftv1beta1.EncryptionMigrationState `json:"state,omitempty"`
+ StartedTime *v1.Time `json:"startedTime,omitempty"`
+ CompletionTime *v1.Time `json:"completionTime,omitempty"`
+}
+
+// EncryptionMigrationHistoryApplyConfiguration constructs a declarative configuration of the EncryptionMigrationHistory type for use with
+// apply.
+func EncryptionMigrationHistory() *EncryptionMigrationHistoryApplyConfiguration {
+ return &EncryptionMigrationHistoryApplyConfiguration{}
+}
+
+// WithFrom sets the From field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the From field is set to the value of the last call.
+func (b *EncryptionMigrationHistoryApplyConfiguration) WithFrom(value *EncryptionKeyReferenceApplyConfiguration) *EncryptionMigrationHistoryApplyConfiguration {
+ b.From = value
+ return b
+}
+
+// WithTo sets the To field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the To field is set to the value of the last call.
+func (b *EncryptionMigrationHistoryApplyConfiguration) WithTo(value *EncryptionKeyReferenceApplyConfiguration) *EncryptionMigrationHistoryApplyConfiguration {
+ b.To = value
+ return b
+}
+
+// WithState sets the State field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the State field is set to the value of the last call.
+func (b *EncryptionMigrationHistoryApplyConfiguration) WithState(value hypershiftv1beta1.EncryptionMigrationState) *EncryptionMigrationHistoryApplyConfiguration {
+ b.State = &value
+ return b
+}
+
+// WithStartedTime sets the StartedTime field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the StartedTime field is set to the value of the last call.
+func (b *EncryptionMigrationHistoryApplyConfiguration) WithStartedTime(value v1.Time) *EncryptionMigrationHistoryApplyConfiguration {
+ b.StartedTime = &value
+ return b
+}
+
+// WithCompletionTime sets the CompletionTime field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the CompletionTime field is set to the value of the last call.
+func (b *EncryptionMigrationHistoryApplyConfiguration) WithCompletionTime(value v1.Time) *EncryptionMigrationHistoryApplyConfiguration {
+ b.CompletionTime = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/hostedclusterstatus.go b/client/applyconfiguration/hypershift/v1beta1/hostedclusterstatus.go
index 4ca327284e20..3f0658004684 100644
--- a/client/applyconfiguration/hypershift/v1beta1/hostedclusterstatus.go
+++ b/client/applyconfiguration/hypershift/v1beta1/hostedclusterstatus.go
@@ -40,6 +40,7 @@ type HostedClusterStatusApplyConfiguration struct {
AutoNode *AutoNodeStatusApplyConfiguration `json:"autoNode,omitempty"`
Configuration *ConfigurationStatusApplyConfiguration `json:"configuration,omitempty"`
LastSuccessfulEtcdBackupURL *string `json:"lastSuccessfulEtcdBackupURL,omitempty"`
+ SecretEncryption *SecretEncryptionStatusApplyConfiguration `json:"secretEncryption,omitempty"`
}
// HostedClusterStatusApplyConfiguration constructs a declarative configuration of the HostedClusterStatus type for use with
@@ -164,3 +165,11 @@ func (b *HostedClusterStatusApplyConfiguration) WithLastSuccessfulEtcdBackupURL(
b.LastSuccessfulEtcdBackupURL = &value
return b
}
+
+// WithSecretEncryption sets the SecretEncryption field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the SecretEncryption field is set to the value of the last call.
+func (b *HostedClusterStatusApplyConfiguration) WithSecretEncryption(value *SecretEncryptionStatusApplyConfiguration) *HostedClusterStatusApplyConfiguration {
+ b.SecretEncryption = value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go b/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go
index 3921f0dd7d99..eb7967bf4494 100644
--- a/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go
+++ b/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go
@@ -44,6 +44,7 @@ type HostedControlPlaneStatusApplyConfiguration struct {
NodeCount *int `json:"nodeCount,omitempty"`
AutoNode *AutoNodeStatusApplyConfiguration `json:"autoNode,omitempty"`
Configuration *ConfigurationStatusApplyConfiguration `json:"configuration,omitempty"`
+ SecretEncryption *SecretEncryptionStatusApplyConfiguration `json:"secretEncryption,omitempty"`
}
// HostedControlPlaneStatusApplyConfiguration constructs a declarative configuration of the HostedControlPlaneStatus type for use with
@@ -200,3 +201,11 @@ func (b *HostedControlPlaneStatusApplyConfiguration) WithConfiguration(value *Co
b.Configuration = value
return b
}
+
+// WithSecretEncryption sets the SecretEncryption field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the SecretEncryption field is set to the value of the last call.
+func (b *HostedControlPlaneStatusApplyConfiguration) WithSecretEncryption(value *SecretEncryptionStatusApplyConfiguration) *HostedControlPlaneStatusApplyConfiguration {
+ b.SecretEncryption = value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go b/client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go
new file mode 100644
index 000000000000..8c865d62888c
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go
@@ -0,0 +1,83 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// IBMCloudKMSKeyStatusApplyConfiguration represents a declarative configuration of the IBMCloudKMSKeyStatus type for use
+// with apply.
+type IBMCloudKMSKeyStatusApplyConfiguration struct {
+ CRKID *string `json:"crkID,omitempty"`
+ InstanceID *string `json:"instanceID,omitempty"`
+ KeyVersion *int32 `json:"keyVersion,omitempty"`
+ Region *string `json:"region,omitempty"`
+ CorrelationID *string `json:"correlationID,omitempty"`
+ URL *string `json:"url,omitempty"`
+}
+
+// IBMCloudKMSKeyStatusApplyConfiguration constructs a declarative configuration of the IBMCloudKMSKeyStatus type for use with
+// apply.
+func IBMCloudKMSKeyStatus() *IBMCloudKMSKeyStatusApplyConfiguration {
+ return &IBMCloudKMSKeyStatusApplyConfiguration{}
+}
+
+// WithCRKID sets the CRKID field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the CRKID field is set to the value of the last call.
+func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithCRKID(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
+ b.CRKID = &value
+ return b
+}
+
+// WithInstanceID sets the InstanceID field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the InstanceID field is set to the value of the last call.
+func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithInstanceID(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
+ b.InstanceID = &value
+ return b
+}
+
+// WithKeyVersion sets the KeyVersion field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the KeyVersion field is set to the value of the last call.
+func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithKeyVersion(value int32) *IBMCloudKMSKeyStatusApplyConfiguration {
+ b.KeyVersion = &value
+ return b
+}
+
+// WithRegion sets the Region field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Region field is set to the value of the last call.
+func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithRegion(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
+ b.Region = &value
+ return b
+}
+
+// WithCorrelationID sets the CorrelationID field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the CorrelationID field is set to the value of the last call.
+func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithCorrelationID(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
+ b.CorrelationID = &value
+ return b
+}
+
+// WithURL sets the URL field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the URL field is set to the value of the last call.
+func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithURL(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
+ b.URL = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go b/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go
new file mode 100644
index 000000000000..21174a8ce320
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go
@@ -0,0 +1,78 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ hypershiftv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+)
+
+// SecretEncryptionKeyStatusApplyConfiguration represents a declarative configuration of the SecretEncryptionKeyStatus type for use
+// with apply.
+type SecretEncryptionKeyStatusApplyConfiguration struct {
+ Provider *hypershiftv1beta1.SecretEncryptionProvider `json:"provider,omitempty"`
+ Azure *AzureKMSKeyStatusApplyConfiguration `json:"azure,omitempty"`
+ AWS *AWSKMSKeyStatusApplyConfiguration `json:"aws,omitempty"`
+ IBMCloud *IBMCloudKMSKeyStatusApplyConfiguration `json:"ibmCloud,omitempty"`
+ AESCBC *AESCBCKeyStatusApplyConfiguration `json:"aescbc,omitempty"`
+}
+
+// SecretEncryptionKeyStatusApplyConfiguration constructs a declarative configuration of the SecretEncryptionKeyStatus type for use with
+// apply.
+func SecretEncryptionKeyStatus() *SecretEncryptionKeyStatusApplyConfiguration {
+ return &SecretEncryptionKeyStatusApplyConfiguration{}
+}
+
+// WithProvider sets the Provider field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Provider field is set to the value of the last call.
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithProvider(value hypershiftv1beta1.SecretEncryptionProvider) *SecretEncryptionKeyStatusApplyConfiguration {
+ b.Provider = &value
+ return b
+}
+
+// WithAzure sets the Azure field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Azure field is set to the value of the last call.
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAzure(value *AzureKMSKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+ b.Azure = value
+ return b
+}
+
+// WithAWS sets the AWS field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the AWS field is set to the value of the last call.
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAWS(value *AWSKMSKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+ b.AWS = value
+ return b
+}
+
+// WithIBMCloud sets the IBMCloud field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the IBMCloud field is set to the value of the last call.
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithIBMCloud(value *IBMCloudKMSKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+ b.IBMCloud = value
+ return b
+}
+
+// WithAESCBC sets the AESCBC field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the AESCBC field is set to the value of the last call.
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAESCBC(value *AESCBCKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+ b.AESCBC = value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/secretencryptionstatus.go b/client/applyconfiguration/hypershift/v1beta1/secretencryptionstatus.go
new file mode 100644
index 000000000000..1f318e71f7b1
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/secretencryptionstatus.go
@@ -0,0 +1,61 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// SecretEncryptionStatusApplyConfiguration represents a declarative configuration of the SecretEncryptionStatus type for use
+// with apply.
+type SecretEncryptionStatusApplyConfiguration struct {
+ ActiveKey *SecretEncryptionKeyStatusApplyConfiguration `json:"activeKey,omitempty"`
+ TargetKey *SecretEncryptionKeyStatusApplyConfiguration `json:"targetKey,omitempty"`
+ History []EncryptionMigrationHistoryApplyConfiguration `json:"history,omitempty"`
+}
+
+// SecretEncryptionStatusApplyConfiguration constructs a declarative configuration of the SecretEncryptionStatus type for use with
+// apply.
+func SecretEncryptionStatus() *SecretEncryptionStatusApplyConfiguration {
+ return &SecretEncryptionStatusApplyConfiguration{}
+}
+
+// WithActiveKey sets the ActiveKey field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the ActiveKey field is set to the value of the last call.
+func (b *SecretEncryptionStatusApplyConfiguration) WithActiveKey(value *SecretEncryptionKeyStatusApplyConfiguration) *SecretEncryptionStatusApplyConfiguration {
+ b.ActiveKey = value
+ return b
+}
+
+// WithTargetKey sets the TargetKey field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the TargetKey field is set to the value of the last call.
+func (b *SecretEncryptionStatusApplyConfiguration) WithTargetKey(value *SecretEncryptionKeyStatusApplyConfiguration) *SecretEncryptionStatusApplyConfiguration {
+ b.TargetKey = value
+ return b
+}
+
+// WithHistory adds the given value to the History field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the History field.
+func (b *SecretEncryptionStatusApplyConfiguration) WithHistory(values ...*EncryptionMigrationHistoryApplyConfiguration) *SecretEncryptionStatusApplyConfiguration {
+ for i := range values {
+ if values[i] == nil {
+ panic("nil value passed to WithHistory")
+ }
+ b.History = append(b.History, *values[i])
+ }
+ return b
+}
diff --git a/client/applyconfiguration/utils.go b/client/applyconfiguration/utils.go
index 5464e88f8024..e2d56550593a 100644
--- a/client/applyconfiguration/utils.go
+++ b/client/applyconfiguration/utils.go
@@ -65,6 +65,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
// Group=hypershift.openshift.io, Version=v1beta1
case v1beta1.SchemeGroupVersion.WithKind("AddressPair"):
return &hypershiftv1beta1.AddressPairApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("AESCBCKeyStatus"):
+ return &hypershiftv1beta1.AESCBCKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AESCBCSpec"):
return &hypershiftv1beta1.AESCBCSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AgentNodePoolPlatform"):
@@ -87,6 +89,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.AWSKMSAuthSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AWSKMSKeyEntry"):
return &hypershiftv1beta1.AWSKMSKeyEntryApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("AWSKMSKeyStatus"):
+ return &hypershiftv1beta1.AWSKMSKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AWSKMSSpec"):
return &hypershiftv1beta1.AWSKMSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AWSNodePoolPlatform"):
@@ -111,6 +115,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.AzureAuthenticationConfigurationApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureKMSKey"):
return &hypershiftv1beta1.AzureKMSKeyApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("AzureKMSKeyStatus"):
+ return &hypershiftv1beta1.AzureKMSKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureKMSSpec"):
return &hypershiftv1beta1.AzureKMSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureMarketplaceImage"):
@@ -175,6 +181,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.DNSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("DNSZoneStatus"):
return &hypershiftv1beta1.DNSZoneStatusApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("EncryptionKeyReference"):
+ return &hypershiftv1beta1.EncryptionKeyReferenceApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("EncryptionMigrationHistory"):
+ return &hypershiftv1beta1.EncryptionMigrationHistoryApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("EtcdSpec"):
return &hypershiftv1beta1.EtcdSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("EtcdTLSConfig"):
@@ -249,6 +259,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.IBMCloudKMSAuthSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSKeyEntry"):
return &hypershiftv1beta1.IBMCloudKMSKeyEntryApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSKeyStatus"):
+ return &hypershiftv1beta1.IBMCloudKMSKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSSpec"):
return &hypershiftv1beta1.IBMCloudKMSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSUnmanagedAuthSpec"):
@@ -389,8 +401,12 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.RouterParamApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("ScaleDownConfig"):
return &hypershiftv1beta1.ScaleDownConfigApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("SecretEncryptionKeyStatus"):
+ return &hypershiftv1beta1.SecretEncryptionKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("SecretEncryptionSpec"):
return &hypershiftv1beta1.SecretEncryptionSpecApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("SecretEncryptionStatus"):
+ return &hypershiftv1beta1.SecretEncryptionStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("SecretReference"):
return &hypershiftv1beta1.SecretReferenceApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("ServiceNetworkEntry"):
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
index d406b89a759f..43da88bcb60f 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
@@ -7843,6 +7843,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -7900,6 +7903,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -7954,6 +7960,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -9013,6 +9022,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
index bbafc3f882a8..e3e13d9085f6 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
@@ -6514,6 +6514,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6571,6 +6574,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6625,6 +6631,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7661,6 +7670,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 30d17382b0f8..396e8eebb4ac 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -7714,6 +7714,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -7771,6 +7774,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -7825,6 +7831,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -8873,6 +8882,384 @@ spec:
type: string
type: object
type: object
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the status of the release version applied to the
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
index 798d4f0664f8..23dee0c4929a 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
@@ -7698,6 +7698,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -7755,6 +7758,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -7809,6 +7815,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -8833,6 +8842,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
index 5fd583a45ffa..d9f699d90075 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
@@ -6369,6 +6369,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -6426,6 +6429,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -6480,6 +6486,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -7493,6 +7502,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 25068f5cf7f6..8b87154523da 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -7569,6 +7569,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
name:
default: ""
@@ -7626,6 +7629,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
arn:
description: arn is the Amazon Resource Name for the
@@ -7680,6 +7686,9 @@ spec:
description: |-
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+
+ Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ The system automatically manages the previous key via the status field.
properties:
keyName:
description: keyName is the name of the keyvault key
@@ -8693,6 +8702,384 @@ spec:
Deprecated: Use versionStatus.desired.image instead.
maxLength: 255
type: string
+ secretEncryption:
+ description: secretEncryption tracks the state of secret encryption
+ key rotation and re-encryption.
+ minProperties: 1
+ properties:
+ activeKey:
+ description: |-
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ Updated after successful re-encryption.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ history:
+ description: |-
+ history contains a list of key rotations applied to this cluster. The newest
+ entry is first in the list. Entries have state Completed when re-encryption
+ has finished. The current rotation phase is always history[0].state when
+ history[0] is not Completed or Interrupted.
+ items:
+ description: EncryptionMigrationHistory records a key rotation,
+ including in-progress rotations.
+ properties:
+ completionTime:
+ description: completionTime is when the rotation finished.
+ Not set while the rotation is in progress.
+ format: date-time
+ type: string
+ from:
+ description: from is the key that data was migrated from
+ (the previous active key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ startedTime:
+ description: startedTime is when the rotation was initiated.
+ format: date-time
+ type: string
+ state:
+ description: state tracks the current phase of this rotation.
+ enum:
+ - ReadOnlyDeploy
+ - WritePromote
+ - Migrating
+ - Completed
+ - Interrupted
+ type: string
+ to:
+ description: to is the key that data was migrated to (the
+ target key).
+ properties:
+ fingerprint:
+ description: fingerprint is the hex-encoded SHA-256
+ hash of the key's identity fields.
+ maxLength: 64
+ minLength: 1
+ type: string
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - fingerprint
+ - provider
+ type: object
+ required:
+ - from
+ - startedTime
+ - state
+ - to
+ type: object
+ maxItems: 5
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: atomic
+ targetKey:
+ description: |-
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+ spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ (not the current spec) during the rotation, so mid-rotation spec changes are
+ safely queued until the current rotation completes. Cleared when rotation completes.
+ properties:
+ aescbc:
+ description: aescbc holds a reference to the AESCBC key secret.
+ properties:
+ dataHash:
+ description: |-
+ dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ at the time re-encryption completed.
+ maxLength: 64
+ minLength: 1
+ type: string
+ secret:
+ description: secret is a reference to the secret containing
+ the AESCBC key.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - dataHash
+ - secret
+ type: object
+ aws:
+ description: aws holds the AWS KMS key identity fields.
+ properties:
+ arn:
+ description: arn is the Amazon Resource Name of the KMS
+ key.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ region:
+ description: region is the AWS region of the KMS key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - arn
+ - region
+ type: object
+ azure:
+ description: azure holds the Azure KMS key identity fields.
+ properties:
+ keyName:
+ description: keyName is the name of the key in the vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVaultName:
+ description: keyVaultName is the name of the Azure Key
+ Vault.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the version of the key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ required:
+ - keyName
+ - keyVaultName
+ - keyVersion
+ type: object
+ ibmCloud:
+ description: ibmCloud holds the IBM Cloud KMS key identity
+ fields.
+ properties:
+ correlationID:
+ description: correlationID is the correlation ID for the
+ key.
+ maxLength: 255
+ minLength: 1
+ type: string
+ crkID:
+ description: crkID is the Customer Root Key ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ instanceID:
+ description: instanceID is the KMS instance ID.
+ maxLength: 255
+ minLength: 1
+ type: string
+ keyVersion:
+ description: keyVersion is the key version number.
+ format: int32
+ minimum: 0
+ type: integer
+ region:
+ description: region is the IBM Cloud region.
+ maxLength: 255
+ minLength: 1
+ type: string
+ url:
+ description: url is the KMS endpoint URL.
+ maxLength: 2048
+ minLength: 1
+ type: string
+ required:
+ - correlationID
+ - crkID
+ - instanceID
+ - keyVersion
+ - region
+ - url
+ type: object
+ provider:
+ description: provider identifies the encryption provider.
+ enum:
+ - Azure
+ - AWS
+ - IBMCloud
+ - AESCBC
+ type: string
+ required:
+ - provider
+ type: object
+ x-kubernetes-validations:
+ - message: azure is required when provider is Azure, and forbidden
+ otherwise
+ rule: 'self.provider == ''Azure'' ? has(self.azure) : !has(self.azure)'
+ - message: aws is required when provider is AWS, and forbidden
+ otherwise
+ rule: 'self.provider == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ - message: ibmCloud is required when provider is IBMCloud, and
+ forbidden otherwise
+ rule: 'self.provider == ''IBMCloud'' ? has(self.ibmCloud) :
+ !has(self.ibmCloud)'
+ - message: aescbc is required when provider is AESCBC, and forbidden
+ otherwise
+ rule: 'self.provider == ''AESCBC'' ? has(self.aescbc) : !has(self.aescbc)'
+ type: object
version:
description: |-
version is the semantic version of the release applied by
diff --git a/go.mod b/go.mod
index 9f6766e6c333..4842a8107675 100644
--- a/go.mod
+++ b/go.mod
@@ -125,6 +125,7 @@ require (
sigs.k8s.io/cluster-api-provider-openstack v0.13.3
sigs.k8s.io/controller-runtime v0.22.4
sigs.k8s.io/karpenter v1.9.0
+ sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96
sigs.k8s.io/secrets-store-csi-driver v1.4.8
sigs.k8s.io/structured-merge-diff/v6 v6.3.2
sigs.k8s.io/yaml v1.6.0
@@ -305,7 +306,6 @@ require (
kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
- sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96 // indirect
sigs.k8s.io/kustomize/api v0.21.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.21.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/aws.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/aws.go
index 3f8f39ede110..a5b9c824274c 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/aws.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/aws.go
@@ -1018,6 +1018,9 @@ type AWSKMSSpec struct {
ActiveKey AWSKMSKeyEntry `json:"activeKey"`
// backupKey defines the old key during the rotation process so previously created
// secrets can continue to be decrypted until they are all re-encrypted with the active key.
+ //
+ // Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ // The system automatically manages the previous key via the status field.
// +optional
BackupKey *AWSKMSKeyEntry `json:"backupKey,omitempty"`
// auth defines metadata about the management of credentials used to interact with AWS KMS
@@ -1082,6 +1085,22 @@ type AWSKMSKeyEntry struct {
ARN string `json:"arn"`
}
+// AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
+// reconstruct the backup sidecar container arguments.
+// +k8s:deepcopy-gen=true
+type AWSKMSKeyStatus struct {
+ // arn is the Amazon Resource Name of the KMS key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=2048
+ ARN string `json:"arn,omitempty"`
+ // region is the AWS region of the KMS key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ Region string `json:"region,omitempty"`
+}
+
// AWSPlatformStatus contains status specific to the AWS platform
type AWSPlatformStatus struct {
// defaultWorkerSecurityGroupID is the ID of a security group created by
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go
index c95773e13bd7..71f7beea32a4 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go
@@ -856,6 +856,9 @@ type AzureKMSSpec struct {
ActiveKey AzureKMSKey `json:"activeKey"`
// backupKey defines the old key during the rotation process so previously created
// secrets can continue to be decrypted until they are all re-encrypted with the active key.
+ //
+ // Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ // The system automatically manages the previous key via the status field.
// +optional
BackupKey *AzureKMSKey `json:"backupKey,omitempty"`
@@ -902,6 +905,27 @@ type AzureKMSKey struct {
KeyVersion string `json:"keyVersion"`
}
+// AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
+// reconstruct the EncryptionConfiguration read provider.
+// +k8s:deepcopy-gen=true
+type AzureKMSKeyStatus struct {
+ // keyVaultName is the name of the Azure Key Vault.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ KeyVaultName string `json:"keyVaultName,omitempty"`
+ // keyName is the name of the key in the vault.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ KeyName string `json:"keyName,omitempty"`
+ // keyVersion is the version of the key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ KeyVersion string `json:"keyVersion,omitempty"`
+}
+
// AzureAuthenticationType is a discriminated union type that contains the Azure authentication configuration for an
// Azure Hosted Cluster. This type is used to determine which authentication configuration is being used. Valid values
// are "ManagedIdentities" and "WorkloadIdentities".
From c9878b4589bc6a7974b90091329a13ba57584b4a Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 13:43:08 +0200
Subject: [PATCH 03/12] feat(hypershift-operator): add re-encryption utilities,
status bubble-up, and rotation guard VAP
- Add support/secretencryption/ package with fingerprint computation,
key status construction, and EncryptionConfiguration parsing
- Copy EtcdDataEncryptionUpToDate condition from HCP to HostedCluster
using the copy-if-present pattern
- Copy SecretEncryption status from HCP to HostedCluster
- Deploy ValidatingAdmissionPolicy that blocks active key changes while
re-encryption is in progress (EtcdDataEncryptionUpToDate=False)
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
.../hostedcluster/hostedcluster_controller.go | 20 +-
hypershift-operator/main.go | 73 ++++++
support/config/kms.go | 17 ++
support/secretencryption/encryptionconfig.go | 114 +++++++++
.../secretencryption/encryptionconfig_test.go | 232 ++++++++++++++++++
support/secretencryption/fingerprint.go | 82 +++++++
support/secretencryption/fingerprint_test.go | 131 ++++++++++
support/secretencryption/keystatus.go | 106 ++++++++
support/secretencryption/keystatus_test.go | 85 +++++++
9 files changed, 857 insertions(+), 3 deletions(-)
create mode 100644 support/secretencryption/encryptionconfig.go
create mode 100644 support/secretencryption/encryptionconfig_test.go
create mode 100644 support/secretencryption/fingerprint.go
create mode 100644 support/secretencryption/fingerprint_test.go
create mode 100644 support/secretencryption/keystatus.go
create mode 100644 support/secretencryption/keystatus_test.go
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
index f7c2deac532f..1a655d07c5d3 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
@@ -876,6 +876,11 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
hcluster.Status.AutoNode = hcp.Status.AutoNode
}
+ // Copy the secret encryption status from the hostedcontrolplane
+ if hcp != nil {
+ hcp.Status.SecretEncryption.DeepCopyInto(&hcluster.Status.SecretEncryption)
+ }
+
// Copy the control plane version status from the hostedcontrolplane
propagateControlPlaneVersion(hcluster, hcp)
@@ -910,6 +915,15 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
}
}
+ // Copy the EtcdDataEncryptionUpToDate condition from the HostedControlPlane
+ if hcp != nil {
+ encryptionCond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ if encryptionCond != nil {
+ encryptionCond.ObservedGeneration = hcluster.Generation
+ meta.SetStatusCondition(&hcluster.Status.Conditions, *encryptionCond)
+ }
+ }
+
// Reconcile unmanaged etcd client tls secret validation error status. Note only update status on validation error case to
// provide clear status to the user on the resource without having to look at operator logs.
{
@@ -1580,10 +1594,10 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed reconciling aescbc active key: %w", err)
}
- if hcluster.Spec.SecretEncryption.AESCBC.BackupKey != nil && len(hcluster.Spec.SecretEncryption.AESCBC.BackupKey.Name) > 0 {
+ if hcluster.Spec.SecretEncryption.AESCBC.BackupKey != nil && len(hcluster.Spec.SecretEncryption.AESCBC.BackupKey.Name) > 0 { //nolint:staticcheck
var src corev1.Secret
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: hcluster.GetNamespace(), Name: hcluster.Spec.SecretEncryption.AESCBC.BackupKey.Name}, &src); err != nil {
- return ctrl.Result{}, fmt.Errorf("failed to get backup aescbc secret %s: %w", hcluster.Spec.SecretEncryption.AESCBC.BackupKey.Name, err)
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: hcluster.GetNamespace(), Name: hcluster.Spec.SecretEncryption.AESCBC.BackupKey.Name}, &src); err != nil { //nolint:staticcheck
+ return ctrl.Result{}, fmt.Errorf("failed to get backup aescbc secret %s: %w", hcluster.Spec.SecretEncryption.AESCBC.BackupKey.Name, err) //nolint:staticcheck
}
if err := ensureReferencedResourceAnnotation(ctx, r.Client, hcluster.Name, &src); err != nil {
return ctrl.Result{}, fmt.Errorf("failed to set referenced resource annotation: %w", err)
diff --git a/hypershift-operator/main.go b/hypershift-operator/main.go
index a663242bf0f8..07eb365b6ee2 100644
--- a/hypershift-operator/main.go
+++ b/hypershift-operator/main.go
@@ -285,6 +285,11 @@ func run(ctx context.Context, opts *StartOptions, log logr.Logger) error {
return fmt.Errorf("failed to reconcile deprecation ValidatingAdmissionPolicy: %w", err)
}
+ // Reconcile encryption rotation guard ValidatingAdmissionPolicy if supported
+ if err := reconcileEncryptionRotationGuardVAP(ctx, apiReadingClient, mgmtClusterCaps, log); err != nil {
+ return fmt.Errorf("failed to reconcile encryption rotation guard ValidatingAdmissionPolicy: %w", err)
+ }
+
registryProvider, err := globalconfig.NewCommonRegistryProvider(ctx, mgmtClusterCaps, apiReadingClient, opts.RegistryOverrides)
if err != nil {
return fmt.Errorf("failed to create registry provider: %w", err)
@@ -1013,3 +1018,71 @@ func reconcileDeprecationValidatingAdmissionPolicy(ctx context.Context, client c
log.Info("Successfully reconciled deprecation ValidatingAdmissionPolicy")
return nil
}
+
+// reconcileEncryptionRotationGuardVAP reconciles a ValidatingAdmissionPolicy that blocks
+// encryption key rotation while re-encryption is in progress (EtcdDataEncryptionUpToDate=False).
+func reconcileEncryptionRotationGuardVAP(ctx context.Context, client crclient.Client, mgmtClusterCaps *capabilities.ManagementClusterCapabilities, log logr.Logger) error {
+ if !mgmtClusterCaps.Has(capabilities.CapabilityValidatingAdmissionPolicy) {
+ log.Info("ValidatingAdmissionPolicy not supported, skipping encryption rotation guard policy reconciliation")
+ return nil
+ }
+
+ log.Info("Reconciling encryption rotation guard ValidatingAdmissionPolicy")
+
+ policy := &admissionregistrationv1.ValidatingAdmissionPolicy{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "hostedcluster-block-key-rotation-during-reencryption",
+ },
+ }
+ if _, err := controllerutil.CreateOrUpdate(ctx, client, policy, func() error {
+ policy.Spec.FailurePolicy = ptr.To(admissionregistrationv1.Ignore)
+ if policy.Spec.MatchConstraints == nil {
+ policy.Spec.MatchConstraints = &admissionregistrationv1.MatchResources{}
+ }
+ policy.Spec.MatchConstraints.ResourceRules = []admissionregistrationv1.NamedRuleWithOperations{
+ {
+ RuleWithOperations: admissionregistrationv1.RuleWithOperations{
+ Operations: []admissionregistrationv1.OperationType{
+ admissionregistrationv1.Update,
+ },
+ Rule: admissionregistrationv1.Rule{
+ APIGroups: []string{"hypershift.openshift.io"},
+ APIVersions: []string{"v1beta1"},
+ Resources: []string{"hostedclusters"},
+ },
+ },
+ },
+ }
+ // Allow the update if any of:
+ // 1. No conditions exist yet (new cluster)
+ // 2. EtcdDataEncryptionUpToDate is not False (no re-encryption in progress)
+ // 3. secretEncryption spec is unchanged between old and new object
+ policy.Spec.Validations = []admissionregistrationv1.Validation{
+ {
+ Expression: `!has(object.status.conditions) || !object.status.conditions.exists(c, c.type == 'EtcdDataEncryptionUpToDate' && c.status == 'False') || (!has(object.spec.secretEncryption) && !has(oldObject.spec.secretEncryption)) || (has(object.spec.secretEncryption) && has(oldObject.spec.secretEncryption) && object.spec.secretEncryption == oldObject.spec.secretEncryption)`,
+ Message: "Cannot change the active encryption key while re-encryption is in progress (EtcdDataEncryptionUpToDate=False). Wait for re-encryption to complete before rotating again.",
+ },
+ }
+ return nil
+ }); err != nil {
+ return fmt.Errorf("failed to reconcile encryption rotation guard ValidatingAdmissionPolicy: %w", err)
+ }
+
+ binding := &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: policy.Name,
+ },
+ }
+ if _, err := controllerutil.CreateOrUpdate(ctx, client, binding, func() error {
+ binding.Spec.PolicyName = policy.Name
+ binding.Spec.ValidationActions = []admissionregistrationv1.ValidationAction{
+ admissionregistrationv1.Deny,
+ }
+ return nil
+ }); err != nil {
+ return fmt.Errorf("failed to reconcile encryption rotation guard ValidatingAdmissionPolicyBinding: %w", err)
+ }
+
+ log.Info("Successfully reconciled encryption rotation guard ValidatingAdmissionPolicy")
+ return nil
+}
diff --git a/support/config/kms.go b/support/config/kms.go
index 44d51da9f202..50ee2bac676c 100644
--- a/support/config/kms.go
+++ b/support/config/kms.go
@@ -1,5 +1,10 @@
package config
+// KMSEncryptedObjects returns the resources declared in the KAS EncryptionConfiguration.
+// TODO(https://github.com/openshift/enhancements/pull/1969#discussion_r3192690488):
+// routes, oauthaccesstokens, and oauthauthorizetokens are listed here but are
+// not actually encrypted today because the OpenShift API servers lack KMS
+// sidecars.
func KMSEncryptedObjects() []string {
return []string{
"secrets",
@@ -9,3 +14,15 @@ func KMSEncryptedObjects() []string {
"oauthauthorizetokens.oauth.openshift.io",
}
}
+
+// AESCBCEncryptedObjects returns the resources declared in the KAS EncryptionConfiguration
+// for AESCBC encryption.
+// TODO(https://github.com/openshift/enhancements/pull/1969#discussion_r3192690488):
+// AESCBC currently only encrypts secrets; configmaps are not covered. This
+// should be expanded to match the full set of sensitive resources once the
+// encryption scope is broadened.
+func AESCBCEncryptedObjects() []string {
+ return []string{
+ "secrets",
+ }
+}
diff --git a/support/secretencryption/encryptionconfig.go b/support/secretencryption/encryptionconfig.go
new file mode 100644
index 000000000000..b7bd57e45c02
--- /dev/null
+++ b/support/secretencryption/encryptionconfig.go
@@ -0,0 +1,114 @@
+package secretencryption
+
+import (
+ "fmt"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/serializer/json"
+ apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
+)
+
+const (
+ // EncryptionConfigurationKey is the data key used in the Secret that holds the EncryptionConfiguration YAML.
+ EncryptionConfigurationKey = "config.yaml"
+
+ // EncryptionConfigurationKind is the Kind used in EncryptionConfiguration manifests.
+ EncryptionConfigurationKind = "EncryptionConfiguration"
+)
+
+var (
+ encScheme = runtime.NewScheme()
+ yamlDecoder runtime.Decoder
+)
+
+func init() {
+ _ = apiserverv1.AddToScheme(encScheme)
+ yamlDecoder = json.NewSerializerWithOptions(json.DefaultMetaFactory, encScheme, encScheme, json.SerializerOptions{Yaml: true})
+}
+
+// DecodeEncryptionConfiguration parses raw YAML bytes into an EncryptionConfiguration.
+func DecodeEncryptionConfiguration(data []byte) (*apiserverv1.EncryptionConfiguration, error) {
+ cfg := &apiserverv1.EncryptionConfiguration{}
+ gvks, _, err := encScheme.ObjectKinds(cfg)
+ if err != nil || len(gvks) == 0 {
+ return nil, fmt.Errorf("cannot determine gvk: %w", err)
+ }
+ if _, _, err := yamlDecoder.Decode(data, &gvks[0], cfg); err != nil {
+ return nil, fmt.Errorf("cannot decode EncryptionConfiguration: %w", err)
+ }
+ return cfg, nil
+}
+
+// TargetKeyRole represents where the target key appears in the EncryptionConfiguration.
+type TargetKeyRole int
+
+const (
+ TargetKeyAbsent TargetKeyRole = iota // target key not in config
+ TargetKeyReadOnly // target key is a read-only provider (not first)
+ TargetKeyWrite // target key is the write provider (first)
+)
+
+// FindKeyRole locates the target key name in the EncryptionConfiguration and
+// returns its role. For KMS, each key is a separate provider entry; the first
+// KMS provider is the write key. For AESCBC, keys are entries inside a single
+// AESCBC provider; the first key is the write key.
+func FindKeyRole(cfg *apiserverv1.EncryptionConfiguration, targetName string, encType hyperv1.SecretEncryptionType) TargetKeyRole {
+ if cfg == nil || len(cfg.Resources) == 0 {
+ return TargetKeyAbsent
+ }
+ providers := cfg.Resources[0].Providers
+
+ switch encType {
+ case hyperv1.KMS:
+ kmsIndex := -1
+ firstKMSIndex := -1
+ for i, p := range providers {
+ if p.KMS != nil {
+ if firstKMSIndex == -1 {
+ firstKMSIndex = i
+ }
+ if p.KMS.Name == targetName {
+ kmsIndex = i
+ break
+ }
+ }
+ }
+ if kmsIndex == -1 {
+ return TargetKeyAbsent
+ }
+ if kmsIndex == firstKMSIndex {
+ return TargetKeyWrite
+ }
+ return TargetKeyReadOnly
+
+ case hyperv1.AESCBC:
+ for _, p := range providers {
+ if p.AESCBC != nil {
+ for j, key := range p.AESCBC.Keys {
+ if key.Name == targetName {
+ if j == 0 {
+ return TargetKeyWrite
+ }
+ return TargetKeyReadOnly
+ }
+ }
+ }
+ }
+ return TargetKeyAbsent
+ }
+
+ return TargetKeyAbsent
+}
+
+// ShouldPromoteTargetKey determines whether the target key should be promoted
+// to write provider based on the current EncryptionConfiguration and KAS
+// convergence state.
+//
+// Returns true when the target key should be the write key (WritePromote/Migrating stage).
+// Returns false when the old key should remain the write key (ReadOnlyDeploy stage).
+func ShouldPromoteTargetKey(cfg *apiserverv1.EncryptionConfiguration, targetName string, encType hyperv1.SecretEncryptionType, kasConverged bool) bool {
+ role := FindKeyRole(cfg, targetName, encType)
+ return role == TargetKeyWrite || (role == TargetKeyReadOnly && kasConverged)
+}
diff --git a/support/secretencryption/encryptionconfig_test.go b/support/secretencryption/encryptionconfig_test.go
new file mode 100644
index 000000000000..6d631f7f3ef2
--- /dev/null
+++ b/support/secretencryption/encryptionconfig_test.go
@@ -0,0 +1,232 @@
+package secretencryption
+
+import (
+ "testing"
+
+ . "github.com/onsi/gomega"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+
+ apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
+)
+
+func kmsConfig(providers ...apiserverv1.ProviderConfiguration) *apiserverv1.EncryptionConfiguration {
+ return &apiserverv1.EncryptionConfiguration{
+ Resources: []apiserverv1.ResourceConfiguration{
+ {Providers: providers},
+ },
+ }
+}
+
+func kmsProvider(name string) apiserverv1.ProviderConfiguration {
+ return apiserverv1.ProviderConfiguration{
+ KMS: &apiserverv1.KMSConfiguration{Name: name, APIVersion: "v2"},
+ }
+}
+
+func identityProvider() apiserverv1.ProviderConfiguration {
+ return apiserverv1.ProviderConfiguration{
+ Identity: &apiserverv1.IdentityConfiguration{},
+ }
+}
+
+func aescbcProvider(keys ...apiserverv1.Key) apiserverv1.ProviderConfiguration {
+ return apiserverv1.ProviderConfiguration{
+ AESCBC: &apiserverv1.AESConfiguration{Keys: keys},
+ }
+}
+
+func aescbcKey(name string) apiserverv1.Key {
+ return apiserverv1.Key{Name: name, Secret: "dW51c2Vk"}
+}
+
+func TestFindKeyRole(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ cfg *apiserverv1.EncryptionConfiguration
+ targetName string
+ encType hyperv1.SecretEncryptionType
+ expected TargetKeyRole
+ }{
+ {
+ name: "When config is nil it should return TargetKeyAbsent",
+ cfg: nil,
+ targetName: "target",
+ encType: hyperv1.KMS,
+ expected: TargetKeyAbsent,
+ },
+ {
+ name: "When config has no resources it should return TargetKeyAbsent",
+ cfg: &apiserverv1.EncryptionConfiguration{},
+ targetName: "target",
+ encType: hyperv1.KMS,
+ expected: TargetKeyAbsent,
+ },
+ {
+ name: "When KMS target key is the first provider it should return TargetKeyWrite",
+ cfg: kmsConfig(kmsProvider("target-key"), kmsProvider("old-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ expected: TargetKeyWrite,
+ },
+ {
+ name: "When KMS target key is the second provider it should return TargetKeyReadOnly",
+ cfg: kmsConfig(kmsProvider("old-key"), kmsProvider("target-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ expected: TargetKeyReadOnly,
+ },
+ {
+ name: "When KMS target key is not in config it should return TargetKeyAbsent",
+ cfg: kmsConfig(kmsProvider("old-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ expected: TargetKeyAbsent,
+ },
+ {
+ name: "When KMS target key is the only provider it should return TargetKeyWrite",
+ cfg: kmsConfig(kmsProvider("target-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ expected: TargetKeyWrite,
+ },
+ {
+ name: "When KMS has identity before KMS providers it should still find write correctly",
+ cfg: kmsConfig(identityProvider(), kmsProvider("target-key"), kmsProvider("old-key")),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ expected: TargetKeyWrite,
+ },
+ {
+ name: "When AESCBC target key is the first key it should return TargetKeyWrite",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("target-key"), aescbcKey("old-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ expected: TargetKeyWrite,
+ },
+ {
+ name: "When AESCBC target key is the second key it should return TargetKeyReadOnly",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("old-key"), aescbcKey("target-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ expected: TargetKeyReadOnly,
+ },
+ {
+ name: "When AESCBC target key is not present it should return TargetKeyAbsent",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("old-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ expected: TargetKeyAbsent,
+ },
+ {
+ name: "When AESCBC target key is the only key it should return TargetKeyWrite",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("target-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ expected: TargetKeyWrite,
+ },
+ {
+ name: "When encryption type is unrecognized it should return TargetKeyAbsent",
+ cfg: kmsConfig(kmsProvider("target-key")),
+ targetName: "target-key",
+ encType: hyperv1.SecretEncryptionType("unknown"),
+ expected: TargetKeyAbsent,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ g := NewWithT(t)
+ g.Expect(FindKeyRole(tc.cfg, tc.targetName, tc.encType)).To(Equal(tc.expected))
+ })
+ }
+}
+
+func TestShouldPromoteTargetKey(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ cfg *apiserverv1.EncryptionConfiguration
+ targetName string
+ encType hyperv1.SecretEncryptionType
+ kasConverged bool
+ expected bool
+ }{
+ {
+ name: "When target key is absent it should not promote",
+ cfg: kmsConfig(kmsProvider("old-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ kasConverged: true,
+ expected: false,
+ },
+ {
+ name: "When target key is already write it should promote regardless of convergence",
+ cfg: kmsConfig(kmsProvider("target-key"), kmsProvider("old-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ kasConverged: false,
+ expected: true,
+ },
+ {
+ name: "When target key is read-only and KAS is converged it should promote",
+ cfg: kmsConfig(kmsProvider("old-key"), kmsProvider("target-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ kasConverged: true,
+ expected: true,
+ },
+ {
+ name: "When target key is read-only and KAS is not converged it should not promote",
+ cfg: kmsConfig(kmsProvider("old-key"), kmsProvider("target-key"), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ kasConverged: false,
+ expected: false,
+ },
+ {
+ name: "When config is nil it should not promote",
+ cfg: nil,
+ targetName: "target-key",
+ encType: hyperv1.KMS,
+ kasConverged: true,
+ expected: false,
+ },
+ {
+ name: "When AESCBC target key is write it should promote",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("target-key"), aescbcKey("old-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ kasConverged: false,
+ expected: true,
+ },
+ {
+ name: "When AESCBC target key is read-only and KAS converged it should promote",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("old-key"), aescbcKey("target-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ kasConverged: true,
+ expected: true,
+ },
+ {
+ name: "When AESCBC target key is read-only and KAS not converged it should not promote",
+ cfg: kmsConfig(aescbcProvider(aescbcKey("old-key"), aescbcKey("target-key")), identityProvider()),
+ targetName: "target-key",
+ encType: hyperv1.AESCBC,
+ kasConverged: false,
+ expected: false,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ g := NewWithT(t)
+ g.Expect(ShouldPromoteTargetKey(tc.cfg, tc.targetName, tc.encType, tc.kasConverged)).To(Equal(tc.expected))
+ })
+ }
+}
diff --git a/support/secretencryption/fingerprint.go b/support/secretencryption/fingerprint.go
new file mode 100644
index 000000000000..a8fff49955fa
--- /dev/null
+++ b/support/secretencryption/fingerprint.go
@@ -0,0 +1,82 @@
+package secretencryption
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "strings"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+)
+
+// DataHash computes the hex-encoded SHA-256 hash of raw data.
+func DataHash(data []byte) string {
+ h := sha256.Sum256(data)
+ return fmt.Sprintf("%x", h)
+}
+
+// FingerprintAzureKMSKey computes the SHA-256 fingerprint for an Azure KMS key.
+func FingerprintAzureKMSKey(key hyperv1.AzureKMSKey) string {
+ return DataHash([]byte(key.KeyVaultName + "/" + key.KeyName + "/" + key.KeyVersion))
+}
+
+// FingerprintAWSKMSKey computes the SHA-256 fingerprint for an AWS KMS key.
+func FingerprintAWSKMSKey(arn string) string {
+ return DataHash([]byte(arn))
+}
+
+// FingerprintIBMCloudKMSKeyList computes the SHA-256 fingerprint for an IBM Cloud KMS key list.
+// Only identity-relevant fields are included; CorrelationID and URL are excluded.
+func FingerprintIBMCloudKMSKeyList(entries []hyperv1.IBMCloudKMSKeyEntry) string {
+ parts := make([]string, len(entries))
+ for i, e := range entries {
+ parts[i] = e.CRKID + "/" + e.InstanceID + "/" + fmt.Sprintf("%d", e.KeyVersion)
+ }
+ return DataHash([]byte(strings.Join(parts, ";")))
+}
+
+// FingerprintAESCBCKey computes the SHA-256 fingerprint for an AESCBC key.
+// The dataHash parameter should be the hex-encoded SHA-256 of the secret's "key" data field.
+func FingerprintAESCBCKey(secretName string, dataHash string) string {
+ return DataHash([]byte(secretName + "/" + dataHash))
+}
+
+// FingerprintFromKeyStatus computes the fingerprint from a SecretEncryptionKeyStatus.
+func FingerprintFromKeyStatus(status *hyperv1.SecretEncryptionKeyStatus) string {
+ if status == nil {
+ return ""
+ }
+ switch status.Provider {
+ case hyperv1.SecretEncryptionProviderAzure:
+ if status.Azure.KeyVaultName == "" {
+ return ""
+ }
+ return FingerprintAzureKMSKey(hyperv1.AzureKMSKey{
+ KeyVaultName: status.Azure.KeyVaultName,
+ KeyName: status.Azure.KeyName,
+ KeyVersion: status.Azure.KeyVersion,
+ })
+ case hyperv1.SecretEncryptionProviderAWS:
+ if status.AWS.ARN == "" {
+ return ""
+ }
+ return FingerprintAWSKMSKey(status.AWS.ARN)
+ case hyperv1.SecretEncryptionProviderIBMCloud:
+ if status.IBMCloud.CRKID == "" {
+ return ""
+ }
+ return FingerprintIBMCloudKMSKeyList([]hyperv1.IBMCloudKMSKeyEntry{
+ {
+ CRKID: status.IBMCloud.CRKID,
+ InstanceID: status.IBMCloud.InstanceID,
+ KeyVersion: int(status.IBMCloud.KeyVersion),
+ },
+ })
+ case hyperv1.SecretEncryptionProviderAESCBC:
+ if status.AESCBC.DataHash == "" {
+ return ""
+ }
+ return FingerprintAESCBCKey(status.AESCBC.Secret.Name, status.AESCBC.DataHash)
+ default:
+ return ""
+ }
+}
diff --git a/support/secretencryption/fingerprint_test.go b/support/secretencryption/fingerprint_test.go
new file mode 100644
index 000000000000..ae1bbc109439
--- /dev/null
+++ b/support/secretencryption/fingerprint_test.go
@@ -0,0 +1,131 @@
+package secretencryption
+
+import (
+ "testing"
+
+ . "github.com/onsi/gomega"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+)
+
+func TestFingerprintAzureKMSKey(t *testing.T) {
+ t.Parallel()
+ t.Run("When computing Azure KMS fingerprint it should be deterministic", func(t *testing.T) {
+ g := NewWithT(t)
+ key := hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"}
+ fp1 := FingerprintAzureKMSKey(key)
+ fp2 := FingerprintAzureKMSKey(key)
+ g.Expect(fp1).To(Equal(fp2))
+ g.Expect(fp1).ToNot(BeEmpty())
+ })
+
+ t.Run("When Azure KMS key version changes it should produce a different fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ key1 := hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"}
+ key2 := hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v2"}
+ g.Expect(FingerprintAzureKMSKey(key1)).ToNot(Equal(FingerprintAzureKMSKey(key2)))
+ })
+}
+
+func TestFingerprintAWSKMSKey(t *testing.T) {
+ t.Parallel()
+ t.Run("When computing AWS KMS fingerprint it should hash the ARN", func(t *testing.T) {
+ g := NewWithT(t)
+ fp := FingerprintAWSKMSKey("arn:aws:kms:us-east-1:123456789:key/test-key")
+ g.Expect(fp).ToNot(BeEmpty())
+ g.Expect(fp).To(Equal(FingerprintAWSKMSKey("arn:aws:kms:us-east-1:123456789:key/test-key")))
+ })
+
+ t.Run("When AWS KMS ARN changes it should produce a different fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ fp1 := FingerprintAWSKMSKey("arn:aws:kms:us-east-1:123456789:key/key-1")
+ fp2 := FingerprintAWSKMSKey("arn:aws:kms:us-east-1:123456789:key/key-2")
+ g.Expect(fp1).ToNot(Equal(fp2))
+ })
+}
+
+func TestFingerprintIBMCloudKMSKeyList(t *testing.T) {
+ t.Parallel()
+ t.Run("When computing IBM Cloud fingerprint it should use CRK ID, instance ID, and key version", func(t *testing.T) {
+ g := NewWithT(t)
+ entries := []hyperv1.IBMCloudKMSKeyEntry{
+ {CRKID: "crk1", InstanceID: "inst1", KeyVersion: 1, CorrelationID: "corr1", URL: "https://kms.example.com"},
+ }
+ fp := FingerprintIBMCloudKMSKeyList(entries)
+ g.Expect(fp).ToNot(BeEmpty())
+ })
+
+ t.Run("When IBM Cloud metadata changes but identity stays same it should produce same fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ entries1 := []hyperv1.IBMCloudKMSKeyEntry{
+ {CRKID: "crk1", InstanceID: "inst1", KeyVersion: 1, CorrelationID: "corr1", URL: "https://url1.com"},
+ }
+ entries2 := []hyperv1.IBMCloudKMSKeyEntry{
+ {CRKID: "crk1", InstanceID: "inst1", KeyVersion: 1, CorrelationID: "corr2", URL: "https://url2.com"},
+ }
+ g.Expect(FingerprintIBMCloudKMSKeyList(entries1)).To(Equal(FingerprintIBMCloudKMSKeyList(entries2)))
+ })
+
+ t.Run("When IBM Cloud key version changes it should produce a different fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ entries1 := []hyperv1.IBMCloudKMSKeyEntry{
+ {CRKID: "crk1", InstanceID: "inst1", KeyVersion: 1},
+ }
+ entries2 := []hyperv1.IBMCloudKMSKeyEntry{
+ {CRKID: "crk1", InstanceID: "inst1", KeyVersion: 2},
+ }
+ g.Expect(FingerprintIBMCloudKMSKeyList(entries1)).ToNot(Equal(FingerprintIBMCloudKMSKeyList(entries2)))
+ })
+}
+
+func TestFingerprintAESCBCKey(t *testing.T) {
+ t.Parallel()
+ t.Run("When computing AESCBC fingerprint it should combine secret name and data hash", func(t *testing.T) {
+ g := NewWithT(t)
+ fp := FingerprintAESCBCKey("my-secret", "abc123")
+ g.Expect(fp).ToNot(BeEmpty())
+ g.Expect(fp).To(Equal(FingerprintAESCBCKey("my-secret", "abc123")))
+ })
+
+ t.Run("When AESCBC secret name changes it should produce a different fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ fp1 := FingerprintAESCBCKey("secret-1", "abc123")
+ fp2 := FingerprintAESCBCKey("secret-2", "abc123")
+ g.Expect(fp1).ToNot(Equal(fp2))
+ })
+
+ t.Run("When AESCBC data hash changes it should produce a different fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ fp1 := FingerprintAESCBCKey("my-secret", "hash1")
+ fp2 := FingerprintAESCBCKey("my-secret", "hash2")
+ g.Expect(fp1).ToNot(Equal(fp2))
+ })
+}
+
+func TestFingerprintFromKeyStatus(t *testing.T) {
+ t.Parallel()
+ t.Run("When status is nil it should return empty string", func(t *testing.T) {
+ g := NewWithT(t)
+ g.Expect(FingerprintFromKeyStatus(nil)).To(BeEmpty())
+ })
+
+ t.Run("When Azure status is provided it should match spec fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ key := hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"}
+ status := &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAzure,
+ Azure: hyperv1.AzureKMSKeyStatus{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"},
+ }
+ g.Expect(FingerprintFromKeyStatus(status)).To(Equal(FingerprintAzureKMSKey(key)))
+ })
+
+ t.Run("When AWS status is provided it should match spec fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ arn := "arn:aws:kms:us-east-1:123:key/test"
+ status := &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{ARN: arn, Region: "us-east-1"},
+ }
+ g.Expect(FingerprintFromKeyStatus(status)).To(Equal(FingerprintAWSKMSKey(arn)))
+ })
+}
diff --git a/support/secretencryption/keystatus.go b/support/secretencryption/keystatus.go
new file mode 100644
index 000000000000..661fa741ebec
--- /dev/null
+++ b/support/secretencryption/keystatus.go
@@ -0,0 +1,106 @@
+package secretencryption
+
+import (
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+
+ corev1 "k8s.io/api/core/v1"
+)
+
+// KeyStatusFromAzureSpec creates a SecretEncryptionKeyStatus from an Azure KMS key spec.
+func KeyStatusFromAzureSpec(key hyperv1.AzureKMSKey) *hyperv1.SecretEncryptionKeyStatus {
+ return &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAzure,
+ Azure: hyperv1.AzureKMSKeyStatus(key),
+ }
+}
+
+// KeyStatusFromAWSSpec creates a SecretEncryptionKeyStatus from an AWS KMS key spec.
+func KeyStatusFromAWSSpec(key hyperv1.AWSKMSKeyEntry, region string) *hyperv1.SecretEncryptionKeyStatus {
+ return &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{
+ ARN: key.ARN,
+ Region: region,
+ },
+ }
+}
+
+// KeyStatusFromIBMCloudSpec creates a SecretEncryptionKeyStatus from IBM Cloud KMS key entries.
+// Uses the first entry in the key list as the representative key.
+func KeyStatusFromIBMCloudSpec(entries []hyperv1.IBMCloudKMSKeyEntry, region string) *hyperv1.SecretEncryptionKeyStatus {
+ if len(entries) == 0 {
+ return nil
+ }
+ e := entries[0]
+ return &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderIBMCloud,
+ IBMCloud: hyperv1.IBMCloudKMSKeyStatus{
+ CRKID: e.CRKID,
+ InstanceID: e.InstanceID,
+ KeyVersion: int32(e.KeyVersion),
+ Region: region,
+ CorrelationID: e.CorrelationID,
+ URL: e.URL,
+ },
+ }
+}
+
+// KeyStatusFromAESCBCSpec creates a SecretEncryptionKeyStatus from an AESCBC spec.
+func KeyStatusFromAESCBCSpec(secretRef corev1.LocalObjectReference, dataHash string) *hyperv1.SecretEncryptionKeyStatus {
+ return &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAESCBC,
+ AESCBC: hyperv1.AESCBCKeyStatus{
+ Secret: secretRef,
+ DataHash: dataHash,
+ },
+ }
+}
+
+// KeyStatusFromSpec creates a SecretEncryptionKeyStatus from a SecretEncryptionSpec.
+// For AESCBC, the caller must provide the dataHash (SHA-256 of the secret's "key" data field).
+func KeyStatusFromSpec(spec *hyperv1.SecretEncryptionSpec, aescbcDataHash string) *hyperv1.SecretEncryptionKeyStatus {
+ if spec == nil {
+ return nil
+ }
+ switch spec.Type {
+ case hyperv1.KMS:
+ if spec.KMS == nil {
+ return nil
+ }
+ switch spec.KMS.Provider {
+ case hyperv1.AZURE:
+ if spec.KMS.Azure == nil {
+ return nil
+ }
+ return KeyStatusFromAzureSpec(spec.KMS.Azure.ActiveKey)
+ case hyperv1.AWS:
+ if spec.KMS.AWS == nil {
+ return nil
+ }
+ return KeyStatusFromAWSSpec(spec.KMS.AWS.ActiveKey, spec.KMS.AWS.Region)
+ case hyperv1.IBMCloud:
+ if spec.KMS.IBMCloud == nil {
+ return nil
+ }
+ return KeyStatusFromIBMCloudSpec(spec.KMS.IBMCloud.KeyList, spec.KMS.IBMCloud.Region)
+ }
+ case hyperv1.AESCBC:
+ if spec.AESCBC == nil {
+ return nil
+ }
+ return KeyStatusFromAESCBCSpec(spec.AESCBC.ActiveKey, aescbcDataHash)
+ }
+ return nil
+}
+
+// KeyReferenceFromStatus extracts an EncryptionKeyReference from a SecretEncryptionKeyStatus.
+func KeyReferenceFromStatus(status *hyperv1.SecretEncryptionKeyStatus) hyperv1.EncryptionKeyReference {
+ if status == nil {
+ return hyperv1.EncryptionKeyReference{}
+ }
+ fp := FingerprintFromKeyStatus(status)
+ return hyperv1.EncryptionKeyReference{
+ Provider: status.Provider,
+ Fingerprint: fp,
+ }
+}
diff --git a/support/secretencryption/keystatus_test.go b/support/secretencryption/keystatus_test.go
new file mode 100644
index 000000000000..9827f3a14ed7
--- /dev/null
+++ b/support/secretencryption/keystatus_test.go
@@ -0,0 +1,85 @@
+package secretencryption
+
+import (
+ "testing"
+
+ . "github.com/onsi/gomega"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+
+ corev1 "k8s.io/api/core/v1"
+)
+
+func TestKeyStatusFromAzureSpec(t *testing.T) {
+ t.Parallel()
+ t.Run("When creating key status from Azure spec it should populate all fields", func(t *testing.T) {
+ g := NewWithT(t)
+ key := hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"}
+ status := KeyStatusFromAzureSpec(key)
+ g.Expect(status.Provider).To(Equal(hyperv1.SecretEncryptionProviderAzure))
+ g.Expect(status.Azure).ToNot(BeNil())
+ g.Expect(status.Azure.KeyVaultName).To(Equal("vault"))
+ g.Expect(status.Azure.KeyName).To(Equal("key"))
+ g.Expect(status.Azure.KeyVersion).To(Equal("v1"))
+ })
+}
+
+func TestKeyStatusFromSpec(t *testing.T) {
+ t.Parallel()
+ t.Run("When spec is nil it should return nil", func(t *testing.T) {
+ g := NewWithT(t)
+ g.Expect(KeyStatusFromSpec(nil, "")).To(BeNil())
+ })
+
+ t.Run("When spec is Azure KMS it should create Azure key status", func(t *testing.T) {
+ g := NewWithT(t)
+ spec := &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.KMS,
+ KMS: &hyperv1.KMSSpec{
+ Provider: hyperv1.AZURE,
+ Azure: &hyperv1.AzureKMSSpec{
+ ActiveKey: hyperv1.AzureKMSKey{KeyVaultName: "v", KeyName: "k", KeyVersion: "1"},
+ },
+ },
+ }
+ status := KeyStatusFromSpec(spec, "")
+ g.Expect(status).ToNot(BeNil())
+ g.Expect(status.Provider).To(Equal(hyperv1.SecretEncryptionProviderAzure))
+ })
+
+ t.Run("When spec is AESCBC it should create AESCBC key status with data hash", func(t *testing.T) {
+ g := NewWithT(t)
+ spec := &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "my-secret"},
+ },
+ }
+ status := KeyStatusFromSpec(spec, "deadbeef")
+ g.Expect(status).ToNot(BeNil())
+ g.Expect(status.Provider).To(Equal(hyperv1.SecretEncryptionProviderAESCBC))
+ g.Expect(status.AESCBC.Secret.Name).To(Equal("my-secret"))
+ g.Expect(status.AESCBC.DataHash).To(Equal("deadbeef"))
+ })
+}
+
+func TestKeyReferenceFromStatus(t *testing.T) {
+ t.Parallel()
+ t.Run("When status is nil it should return empty reference", func(t *testing.T) {
+ g := NewWithT(t)
+ ref := KeyReferenceFromStatus(nil)
+ g.Expect(ref.Provider).To(BeEmpty())
+ g.Expect(ref.Fingerprint).To(BeEmpty())
+ })
+
+ t.Run("When status is Azure it should return correct provider and fingerprint", func(t *testing.T) {
+ g := NewWithT(t)
+ status := &hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAzure,
+ Azure: hyperv1.AzureKMSKeyStatus{KeyVaultName: "v", KeyName: "k", KeyVersion: "1"},
+ }
+ ref := KeyReferenceFromStatus(status)
+ g.Expect(ref.Provider).To(Equal(hyperv1.SecretEncryptionProviderAzure))
+ g.Expect(ref.Fingerprint).ToNot(BeEmpty())
+ })
+}
From 96c1fc4e65be07900713000e0538afada5218d0f Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 13:52:25 +0200
Subject: [PATCH 04/12] feat(control-plane-operator): implement two-stage
encryption key rollout and deploy migrator
Two-stage KAS encryption key rollout:
- Rewrite adaptSecretEncryptionConfig to derive write/read key assignment
from HCP status and live EncryptionConfiguration
- ReadOnlyDeploy: old key writes, new key read-only
- WritePromote: new key writes once in config and KAS converged
- Extract AWSKMSProviderName, AzureKMSProviderName, AESCBCKeyName as
shared functions for provider name computation
- Add --encryption-provider-config-automatic-reload=false for Azure KMS
Control plane kube-storage-version-migrator:
- New CPOv2 component with platform predicate (skip IBM/PowerVS)
- Add data-plane migrator deployments to CVO resourcesToRemove
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
.../hostedcontrolplane_controller.go | 2 +
...s_cluster_version_operator_deployment.yaml | 18 +
...s_cluster_version_operator_deployment.yaml | 18 +
...s_cluster_version_operator_deployment.yaml | 18 +
...s_cluster_version_operator_deployment.yaml | 18 +
...eComponents_kube_apiserver_deployment.yaml | 1 +
...ersion_migrator_controlplanecomponent.yaml | 20 ++
...e_storage_version_migrator_deployment.yaml | 117 +++++++
...ersion_migrator_controlplanecomponent.yaml | 20 ++
...e_storage_version_migrator_deployment.yaml | 118 +++++++
...ersion_migrator_controlplanecomponent.yaml | 20 ++
...e_storage_version_migrator_deployment.yaml | 117 +++++++
...ersion_migrator_controlplanecomponent.yaml | 20 ++
...e_storage_version_migrator_deployment.yaml | 117 +++++++
...ersion_migrator_controlplanecomponent.yaml | 20 ++
...e_storage_version_migrator_deployment.yaml | 117 +++++++
.../deployment.yaml | 56 +++
.../hostedcontrolplane/v2/cvo/deployment.go | 2 +
.../hostedcontrolplane/v2/kas/aescbc.go | 25 +-
.../hostedcontrolplane/v2/kas/deployment.go | 18 +-
.../hostedcontrolplane/v2/kas/kms.go | 154 ++++++++-
.../hostedcontrolplane/v2/kas/kms/aws.go | 32 +-
.../hostedcontrolplane/v2/kas/kms/aws_test.go | 161 ++++-----
.../hostedcontrolplane/v2/kas/kms/azure.go | 37 +-
.../v2/kas/kms/azure_test.go | 48 +--
.../hostedcontrolplane/v2/kas/kms/ibmcloud.go | 10 +-
.../hostedcontrolplane/v2/kas/kms/kms.go | 4 +-
.../hostedcontrolplane/v2/kas/kms_test.go | 176 ++++++++++
.../v2/kas/secretencryption.go | 198 +++++++----
.../v2/kas/secretencryption_test.go | 320 +++++++++++++++++-
.../component.go | 43 +++
31 files changed, 1837 insertions(+), 208 deletions(-)
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/v2/assets/kube-storage-version-migrator/deployment.yaml
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/v2/kube_storage_version_migrator/component.go
diff --git a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
index 5861a1fda10d..068c4d90c16f 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
@@ -52,6 +52,7 @@ import (
kcmv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kcm"
konnectivityv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/konnectivity_agent"
schedulerv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kube_scheduler"
+ kubestorageversionmigratorv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kube_storage_version_migrator"
machineapproverv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/machine_approver"
metricsproxyv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/metrics_proxy"
ntov2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/nto"
@@ -276,6 +277,7 @@ func (r *HostedControlPlaneReconciler) registerComponents(hcp *hyperv1.HostedCon
ignitionproxyv2.NewComponent(r.DefaultIngressDomain),
endpointresolverv2.NewComponent(),
metricsproxyv2.NewComponent(r.DefaultIngressDomain),
+ kubestorageversionmigratorv2.NewComponent(),
)
r.components = append(r.components,
olmv2.NewComponents(r.ManagementClusterCapabilities.Has(capabilities.CapabilityImageStream))...,
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/AROSwift/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/AROSwift/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
index 2d9b1f3026d5..fbcfa41bcd8f 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/AROSwift/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/AROSwift/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
@@ -284,6 +284,24 @@ spec:
annotations:
include.release.openshift.io/ibm-cloud-managed: "true"
release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: kube-storage-version-migrator-operator
+ namespace: openshift-kube-storage-version-migrator-operator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: migrator
+ namespace: openshift-kube-storage-version-migrator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
EOF
command:
- /bin/bash
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/GCP/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/GCP/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
index 1b3c7f44f78c..6014b1053971 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/GCP/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/GCP/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
@@ -295,6 +295,24 @@ spec:
annotations:
include.release.openshift.io/ibm-cloud-managed: "true"
release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: kube-storage-version-migrator-operator
+ namespace: openshift-kube-storage-version-migrator-operator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: migrator
+ namespace: openshift-kube-storage-version-migrator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
EOF
command:
- /bin/bash
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
index e1230b097c4a..3e1780f62a72 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
@@ -284,6 +284,24 @@ spec:
annotations:
include.release.openshift.io/ibm-cloud-managed: "true"
release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: kube-storage-version-migrator-operator
+ namespace: openshift-kube-storage-version-migrator-operator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: migrator
+ namespace: openshift-kube-storage-version-migrator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
EOF
command:
- /bin/bash
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
index 2d9b1f3026d5..fbcfa41bcd8f 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/cluster-version-operator/zz_fixture_TestControlPlaneComponents_cluster_version_operator_deployment.yaml
@@ -284,6 +284,24 @@ spec:
annotations:
include.release.openshift.io/ibm-cloud-managed: "true"
release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: kube-storage-version-migrator-operator
+ namespace: openshift-kube-storage-version-migrator-operator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
+ ---
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: migrator
+ namespace: openshift-kube-storage-version-migrator
+ annotations:
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ release.openshift.io/delete: "true"
EOF
command:
- /bin/bash
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_deployment.yaml
index 7008c8048b57..1d6ec0b4cf15 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_deployment.yaml
@@ -84,6 +84,7 @@ spec:
- --openshift-config=/etc/kubernetes/config/config.json
- --v=2
- --encryption-provider-config=/etc/kubernetes/secret-encryption/config.yaml
+ - --encryption-provider-config-automatic-reload=false
command:
- hyperkube
env:
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
new file mode 100644
index 000000000000..3bca5b47ade3
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
@@ -0,0 +1,20 @@
+apiVersion: hypershift.openshift.io/v1beta1
+kind: ControlPlaneComponent
+metadata:
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ resourceVersion: "1"
+spec: {}
+status:
+ conditions:
+ - lastTransitionTime: null
+ message: kube-storage-version-migrator Deployment Available condition not found
+ reason: NotFound
+ status: "False"
+ type: Available
+ - lastTransitionTime: null
+ message: 'Waiting for deployment kube-storage-version-migrator rollout to finish:
+ 0 out of 1 new replicas have been updated'
+ reason: WaitingForRolloutComplete
+ status: "False"
+ type: RolloutComplete
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
new file mode 100644
index 000000000000..56e4c5277e49
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/AROSwift/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
@@ -0,0 +1,117 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ hypershift.openshift.io/managed-by: control-plane-operator
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: hcp
+ uid: ""
+ resourceVersion: "1"
+spec:
+ replicas: 1
+ revisionHistoryLimit: 2
+ selector:
+ matchLabels:
+ app: kube-storage-version-migrator
+ strategy: {}
+ template:
+ metadata:
+ annotations:
+ cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: tmp-dir
+ component.hypershift.openshift.io/config-hash: ""
+ hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
+ labels:
+ app: kube-storage-version-migrator
+ hypershift.openshift.io/control-plane-component: kube-storage-version-migrator
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ spec:
+ affinity:
+ nodeAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/control-plane
+ operator: In
+ values:
+ - "true"
+ weight: 50
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/cluster
+ operator: In
+ values:
+ - hcp-namespace
+ weight: 100
+ podAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ topologyKey: kubernetes.io/hostname
+ weight: 100
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --alsologtostderr
+ - --v=2
+ - --kubeconfig=/etc/kubernetes/kubeconfig
+ command:
+ - migrator
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ image: kube-storage-version-migrator
+ imagePullPolicy: IfNotPresent
+ name: migrator
+ resources:
+ requests:
+ cpu: 10m
+ memory: 200Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ terminationMessagePolicy: FallbackToLogsOnError
+ volumeMounts:
+ - mountPath: /etc/kubernetes
+ name: kubeconfig
+ readOnly: true
+ - mountPath: /tmp
+ name: tmp-dir
+ priorityClassName: hypershift-control-plane
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
+ tolerations:
+ - effect: NoSchedule
+ key: hypershift.openshift.io/control-plane
+ operator: Equal
+ value: "true"
+ - effect: NoSchedule
+ key: hypershift.openshift.io/cluster
+ operator: Equal
+ value: hcp-namespace
+ volumes:
+ - name: kubeconfig
+ secret:
+ defaultMode: 416
+ secretName: service-network-admin-kubeconfig
+ - emptyDir: {}
+ name: tmp-dir
+status: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
new file mode 100644
index 000000000000..3bca5b47ade3
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
@@ -0,0 +1,20 @@
+apiVersion: hypershift.openshift.io/v1beta1
+kind: ControlPlaneComponent
+metadata:
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ resourceVersion: "1"
+spec: {}
+status:
+ conditions:
+ - lastTransitionTime: null
+ message: kube-storage-version-migrator Deployment Available condition not found
+ reason: NotFound
+ status: "False"
+ type: Available
+ - lastTransitionTime: null
+ message: 'Waiting for deployment kube-storage-version-migrator rollout to finish:
+ 0 out of 1 new replicas have been updated'
+ reason: WaitingForRolloutComplete
+ status: "False"
+ type: RolloutComplete
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
new file mode 100644
index 000000000000..5c751997562f
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/GCP/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
@@ -0,0 +1,118 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ hypershift.openshift.io/managed-by: control-plane-operator
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: hcp
+ uid: ""
+ resourceVersion: "1"
+spec:
+ replicas: 1
+ revisionHistoryLimit: 2
+ selector:
+ matchLabels:
+ app: kube-storage-version-migrator
+ strategy: {}
+ template:
+ metadata:
+ annotations:
+ cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: tmp-dir
+ component.hypershift.openshift.io/config-hash: ""
+ hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
+ labels:
+ app: kube-storage-version-migrator
+ hypershift.openshift.io/control-plane-component: kube-storage-version-migrator
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ spec:
+ affinity:
+ nodeAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/control-plane
+ operator: In
+ values:
+ - "true"
+ weight: 50
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/cluster
+ operator: In
+ values:
+ - hcp-namespace
+ weight: 100
+ podAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ topologyKey: kubernetes.io/hostname
+ weight: 100
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --alsologtostderr
+ - --v=2
+ - --kubeconfig=/etc/kubernetes/kubeconfig
+ command:
+ - migrator
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ image: kube-storage-version-migrator
+ imagePullPolicy: IfNotPresent
+ name: migrator
+ resources:
+ requests:
+ cpu: 10m
+ memory: 200Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ terminationMessagePolicy: FallbackToLogsOnError
+ volumeMounts:
+ - mountPath: /etc/kubernetes
+ name: kubeconfig
+ readOnly: true
+ - mountPath: /tmp
+ name: tmp-dir
+ priorityClassName: hypershift-control-plane
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
+ tolerations:
+ - effect: NoSchedule
+ key: hypershift.openshift.io/control-plane
+ operator: Equal
+ value: "true"
+ - effect: NoSchedule
+ key: hypershift.openshift.io/cluster
+ operator: Equal
+ value: hcp-namespace
+ volumes:
+ - name: kubeconfig
+ secret:
+ defaultMode: 416
+ secretName: service-network-admin-kubeconfig
+ - emptyDir: {}
+ name: tmp-dir
+status: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
new file mode 100644
index 000000000000..3bca5b47ade3
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
@@ -0,0 +1,20 @@
+apiVersion: hypershift.openshift.io/v1beta1
+kind: ControlPlaneComponent
+metadata:
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ resourceVersion: "1"
+spec: {}
+status:
+ conditions:
+ - lastTransitionTime: null
+ message: kube-storage-version-migrator Deployment Available condition not found
+ reason: NotFound
+ status: "False"
+ type: Available
+ - lastTransitionTime: null
+ message: 'Waiting for deployment kube-storage-version-migrator rollout to finish:
+ 0 out of 1 new replicas have been updated'
+ reason: WaitingForRolloutComplete
+ status: "False"
+ type: RolloutComplete
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
new file mode 100644
index 000000000000..56e4c5277e49
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
@@ -0,0 +1,117 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ hypershift.openshift.io/managed-by: control-plane-operator
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: hcp
+ uid: ""
+ resourceVersion: "1"
+spec:
+ replicas: 1
+ revisionHistoryLimit: 2
+ selector:
+ matchLabels:
+ app: kube-storage-version-migrator
+ strategy: {}
+ template:
+ metadata:
+ annotations:
+ cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: tmp-dir
+ component.hypershift.openshift.io/config-hash: ""
+ hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
+ labels:
+ app: kube-storage-version-migrator
+ hypershift.openshift.io/control-plane-component: kube-storage-version-migrator
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ spec:
+ affinity:
+ nodeAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/control-plane
+ operator: In
+ values:
+ - "true"
+ weight: 50
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/cluster
+ operator: In
+ values:
+ - hcp-namespace
+ weight: 100
+ podAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ topologyKey: kubernetes.io/hostname
+ weight: 100
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --alsologtostderr
+ - --v=2
+ - --kubeconfig=/etc/kubernetes/kubeconfig
+ command:
+ - migrator
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ image: kube-storage-version-migrator
+ imagePullPolicy: IfNotPresent
+ name: migrator
+ resources:
+ requests:
+ cpu: 10m
+ memory: 200Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ terminationMessagePolicy: FallbackToLogsOnError
+ volumeMounts:
+ - mountPath: /etc/kubernetes
+ name: kubeconfig
+ readOnly: true
+ - mountPath: /tmp
+ name: tmp-dir
+ priorityClassName: hypershift-control-plane
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
+ tolerations:
+ - effect: NoSchedule
+ key: hypershift.openshift.io/control-plane
+ operator: Equal
+ value: "true"
+ - effect: NoSchedule
+ key: hypershift.openshift.io/cluster
+ operator: Equal
+ value: hcp-namespace
+ volumes:
+ - name: kubeconfig
+ secret:
+ defaultMode: 416
+ secretName: service-network-admin-kubeconfig
+ - emptyDir: {}
+ name: tmp-dir
+status: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
new file mode 100644
index 000000000000..3bca5b47ade3
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
@@ -0,0 +1,20 @@
+apiVersion: hypershift.openshift.io/v1beta1
+kind: ControlPlaneComponent
+metadata:
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ resourceVersion: "1"
+spec: {}
+status:
+ conditions:
+ - lastTransitionTime: null
+ message: kube-storage-version-migrator Deployment Available condition not found
+ reason: NotFound
+ status: "False"
+ type: Available
+ - lastTransitionTime: null
+ message: 'Waiting for deployment kube-storage-version-migrator rollout to finish:
+ 0 out of 1 new replicas have been updated'
+ reason: WaitingForRolloutComplete
+ status: "False"
+ type: RolloutComplete
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
new file mode 100644
index 000000000000..56e4c5277e49
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
@@ -0,0 +1,117 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ hypershift.openshift.io/managed-by: control-plane-operator
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: hcp
+ uid: ""
+ resourceVersion: "1"
+spec:
+ replicas: 1
+ revisionHistoryLimit: 2
+ selector:
+ matchLabels:
+ app: kube-storage-version-migrator
+ strategy: {}
+ template:
+ metadata:
+ annotations:
+ cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: tmp-dir
+ component.hypershift.openshift.io/config-hash: ""
+ hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
+ labels:
+ app: kube-storage-version-migrator
+ hypershift.openshift.io/control-plane-component: kube-storage-version-migrator
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ spec:
+ affinity:
+ nodeAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/control-plane
+ operator: In
+ values:
+ - "true"
+ weight: 50
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/cluster
+ operator: In
+ values:
+ - hcp-namespace
+ weight: 100
+ podAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ topologyKey: kubernetes.io/hostname
+ weight: 100
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --alsologtostderr
+ - --v=2
+ - --kubeconfig=/etc/kubernetes/kubeconfig
+ command:
+ - migrator
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ image: kube-storage-version-migrator
+ imagePullPolicy: IfNotPresent
+ name: migrator
+ resources:
+ requests:
+ cpu: 10m
+ memory: 200Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ terminationMessagePolicy: FallbackToLogsOnError
+ volumeMounts:
+ - mountPath: /etc/kubernetes
+ name: kubeconfig
+ readOnly: true
+ - mountPath: /tmp
+ name: tmp-dir
+ priorityClassName: hypershift-control-plane
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
+ tolerations:
+ - effect: NoSchedule
+ key: hypershift.openshift.io/control-plane
+ operator: Equal
+ value: "true"
+ - effect: NoSchedule
+ key: hypershift.openshift.io/cluster
+ operator: Equal
+ value: hcp-namespace
+ volumes:
+ - name: kubeconfig
+ secret:
+ defaultMode: 416
+ secretName: service-network-admin-kubeconfig
+ - emptyDir: {}
+ name: tmp-dir
+status: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
new file mode 100644
index 000000000000..3bca5b47ade3
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_controlplanecomponent.yaml
@@ -0,0 +1,20 @@
+apiVersion: hypershift.openshift.io/v1beta1
+kind: ControlPlaneComponent
+metadata:
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ resourceVersion: "1"
+spec: {}
+status:
+ conditions:
+ - lastTransitionTime: null
+ message: kube-storage-version-migrator Deployment Available condition not found
+ reason: NotFound
+ status: "False"
+ type: Available
+ - lastTransitionTime: null
+ message: 'Waiting for deployment kube-storage-version-migrator rollout to finish:
+ 0 out of 1 new replicas have been updated'
+ reason: WaitingForRolloutComplete
+ status: "False"
+ type: RolloutComplete
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
new file mode 100644
index 000000000000..56e4c5277e49
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-storage-version-migrator/zz_fixture_TestControlPlaneComponents_kube_storage_version_migrator_deployment.yaml
@@ -0,0 +1,117 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ hypershift.openshift.io/managed-by: control-plane-operator
+ name: kube-storage-version-migrator
+ namespace: hcp-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: hcp
+ uid: ""
+ resourceVersion: "1"
+spec:
+ replicas: 1
+ revisionHistoryLimit: 2
+ selector:
+ matchLabels:
+ app: kube-storage-version-migrator
+ strategy: {}
+ template:
+ metadata:
+ annotations:
+ cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: tmp-dir
+ component.hypershift.openshift.io/config-hash: ""
+ hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
+ labels:
+ app: kube-storage-version-migrator
+ hypershift.openshift.io/control-plane-component: kube-storage-version-migrator
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ spec:
+ affinity:
+ nodeAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/control-plane
+ operator: In
+ values:
+ - "true"
+ weight: 50
+ - preference:
+ matchExpressions:
+ - key: hypershift.openshift.io/cluster
+ operator: In
+ values:
+ - hcp-namespace
+ weight: 100
+ podAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ hypershift.openshift.io/hosted-control-plane: hcp-namespace
+ topologyKey: kubernetes.io/hostname
+ weight: 100
+ automountServiceAccountToken: false
+ containers:
+ - args:
+ - --alsologtostderr
+ - --v=2
+ - --kubeconfig=/etc/kubernetes/kubeconfig
+ command:
+ - migrator
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ image: kube-storage-version-migrator
+ imagePullPolicy: IfNotPresent
+ name: migrator
+ resources:
+ requests:
+ cpu: 10m
+ memory: 200Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ terminationMessagePolicy: FallbackToLogsOnError
+ volumeMounts:
+ - mountPath: /etc/kubernetes
+ name: kubeconfig
+ readOnly: true
+ - mountPath: /tmp
+ name: tmp-dir
+ priorityClassName: hypershift-control-plane
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
+ tolerations:
+ - effect: NoSchedule
+ key: hypershift.openshift.io/control-plane
+ operator: Equal
+ value: "true"
+ - effect: NoSchedule
+ key: hypershift.openshift.io/cluster
+ operator: Equal
+ value: hcp-namespace
+ volumes:
+ - name: kubeconfig
+ secret:
+ defaultMode: 416
+ secretName: service-network-admin-kubeconfig
+ - emptyDir: {}
+ name: tmp-dir
+status: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/assets/kube-storage-version-migrator/deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/v2/assets/kube-storage-version-migrator/deployment.yaml
new file mode 100644
index 000000000000..53d6c702f3f9
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/assets/kube-storage-version-migrator/deployment.yaml
@@ -0,0 +1,56 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: kube-storage-version-migrator
+spec:
+ replicas: 1
+ revisionHistoryLimit: 2
+ selector:
+ matchLabels:
+ app: kube-storage-version-migrator
+ template:
+ metadata:
+ labels:
+ app: kube-storage-version-migrator
+ spec:
+ automountServiceAccountToken: false
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
+ volumes:
+ - name: kubeconfig
+ secret:
+ secretName: service-network-admin-kubeconfig
+ containers:
+ - name: migrator
+ image: kube-storage-version-migrator
+ command:
+ - migrator
+ args:
+ - '--alsologtostderr'
+ - '--v=2'
+ - '--kubeconfig=/etc/kubernetes/kubeconfig'
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ volumeMounts:
+ - name: kubeconfig
+ mountPath: /etc/kubernetes
+ readOnly: true
+ terminationMessagePolicy: FallbackToLogsOnError
+ resources:
+ requests:
+ cpu: 10m
+ memory: 200Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cvo/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cvo/deployment.go
index 0e337423a6a6..00d4ab524f5a 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/cvo/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cvo/deployment.go
@@ -284,6 +284,8 @@ func resourcesToRemove(platformType hyperv1.PlatformType) []client.Object {
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "aws-ebs-csi-driver-operator", Namespace: "openshift-cluster-csi-drivers"}},
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "aws-ebs-csi-driver-controller", Namespace: "openshift-cluster-csi-drivers"}},
&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "csi-snapshot-controller", Namespace: "openshift-cluster-storage-operator"}},
+ &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "kube-storage-version-migrator-operator", Namespace: "openshift-kube-storage-version-migrator-operator"}},
+ &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "migrator", Namespace: "openshift-kube-storage-version-migrator"}},
}
}
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/aescbc.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/aescbc.go
index 0575f2f5b047..f29f2bee3243 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/aescbc.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/aescbc.go
@@ -7,6 +7,7 @@ import (
"hash/fnv"
"github.com/openshift/hypershift/support/api"
+ "github.com/openshift/hypershift/support/config"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
@@ -14,29 +15,36 @@ import (
const aescbcKeyNamePrefix = "key"
+// AESCBCKeyName computes the EncryptionConfiguration key name for an AESCBC key.
+func AESCBCKeyName(keyData []byte) (string, error) {
+ hasher := fnv.New32()
+ if _, err := hasher.Write(keyData); err != nil {
+ return "", fmt.Errorf("failed to hash AESCBC key: %w", err)
+ }
+ return fmt.Sprintf("%s-%d", aescbcKeyNamePrefix, hasher.Sum32()), nil
+}
+
func generateAESCBCEncryptionConfig(activeKey []byte, backupKey []byte) ([]byte, error) {
var providerConfiguration []v1.ProviderConfiguration
var keyList []v1.Key
if len(activeKey) == 0 {
return nil, fmt.Errorf("active key is empty")
}
- hasher := fnv.New32()
- _, err := hasher.Write(activeKey)
+ activeKeyName, err := AESCBCKeyName(activeKey)
if err != nil {
return nil, err
}
keyList = append(keyList, v1.Key{
- Name: fmt.Sprintf("%s-%d", aescbcKeyNamePrefix, hasher.Sum32()),
+ Name: activeKeyName,
Secret: base64.StdEncoding.EncodeToString(activeKey),
})
if len(backupKey) > 0 {
- hasher = fnv.New32()
- _, err := hasher.Write(backupKey)
+ backupKeyName, err := AESCBCKeyName(backupKey)
if err != nil {
return nil, err
}
keyList = append(keyList, v1.Key{
- Name: fmt.Sprintf("%s-%d", aescbcKeyNamePrefix, hasher.Sum32()),
+ Name: backupKeyName,
Secret: base64.StdEncoding.EncodeToString(backupKey),
})
}
@@ -55,14 +63,13 @@ func generateAESCBCEncryptionConfig(activeKey []byte, backupKey []byte) ([]byte,
},
Resources: []v1.ResourceConfiguration{
{
- Resources: []string{"secrets"},
+ Resources: config.AESCBCEncryptedObjects(),
Providers: providerConfiguration,
},
},
}
bufferInstance := bytes.NewBuffer([]byte{})
- err = api.YamlSerializer.Encode(&encryptionConfig, bufferInstance)
- if err != nil {
+ if err := api.YamlSerializer.Encode(&encryptionConfig, bufferInstance); err != nil {
return nil, err
}
return bufferInstance.Bytes(), nil
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go
index d0ecc5523bcc..ff637fa525e5 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go
@@ -127,7 +127,16 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
applyGenericSecretEncryptionConfig(&deployment.Spec.Template.Spec)
switch secretEncryption.Type {
case hyperv1.KMS:
- if err := applyKMSConfig(&deployment.Spec.Template.Spec, secretEncryption, newKMSImages(hcp), hcp); err != nil {
+ encConfigSecret := manifests.KASSecretEncryptionConfigFile(hcp.Namespace)
+ currentConfig, err := readCurrentEncryptionConfig(cpContext, encConfigSecret)
+ if err != nil {
+ return fmt.Errorf("failed to read current encryption config: %w", err)
+ }
+ kasReady, err := isKASConverged(cpContext)
+ if err != nil {
+ return fmt.Errorf("failed to check KAS convergence: %w", err)
+ }
+ if err := applyKMSConfig(&deployment.Spec.Template.Spec, secretEncryption, &hcp.Status.SecretEncryption, currentConfig, kasReady, newKMSImages(hcp), hcp); err != nil {
return err
}
}
@@ -213,7 +222,7 @@ func updateMainContainer(podSpec *corev1.PodSpec, hcp *hyperv1.HostedControlPlan
if hcp.Spec.SecretEncryption.KMS.AWS != nil {
// Always will have an active key
totalProviderInstances = 1
- if hcp.Spec.SecretEncryption.KMS.AWS.BackupKey != nil && len(hcp.Spec.SecretEncryption.KMS.AWS.BackupKey.ARN) > 0 {
+ if hcp.Spec.SecretEncryption.KMS.AWS.BackupKey != nil && len(hcp.Spec.SecretEncryption.KMS.AWS.BackupKey.ARN) > 0 { //nolint:staticcheck
totalProviderInstances++
}
}
@@ -257,7 +266,10 @@ func applyGenericSecretEncryptionConfig(podSpec *corev1.PodSpec) {
podSpec.Volumes = append(podSpec.Volumes, buildVolumeSecretEncryptionConfigFile())
podspec.UpdateContainer(ComponentName, podSpec.Containers, func(c *corev1.Container) {
- c.Args = append(c.Args, fmt.Sprintf("--encryption-provider-config=%s/%s", genericSecretEncryptionConfigFileVolumeMount.Path(ComponentName, secretEncryptionConfigFileVolumeName), secretEncryptionConfigurationKey))
+ c.Args = append(c.Args,
+ fmt.Sprintf("--encryption-provider-config=%s/%s", genericSecretEncryptionConfigFileVolumeMount.Path(ComponentName, secretEncryptionConfigFileVolumeName), secretEncryptionConfigurationKey),
+ "--encryption-provider-config-automatic-reload=false",
+ )
c.VolumeMounts = append(c.VolumeMounts, genericSecretEncryptionConfigFileVolumeMount.ContainerMounts(ComponentName)...)
})
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms.go
index 993e3976836a..50f073497aa2 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms.go
@@ -9,16 +9,22 @@ import (
"github.com/openshift/hypershift/support/api"
"github.com/openshift/hypershift/support/azureutil"
"github.com/openshift/hypershift/support/podspec"
+ "github.com/openshift/hypershift/support/secretencryption"
corev1 "k8s.io/api/core/v1"
+ apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
)
-func applyKMSConfig(podSpec *corev1.PodSpec, secretEncryptionData *hyperv1.SecretEncryptionSpec, images kmsImages, hcp *hyperv1.HostedControlPlane) error {
+func applyKMSConfig(podSpec *corev1.PodSpec, secretEncryptionData *hyperv1.SecretEncryptionSpec, encStatus *hyperv1.SecretEncryptionStatus, currentConfig *apiserverv1.EncryptionConfiguration, kasConverged bool, images kmsImages, hcp *hyperv1.HostedControlPlane) error {
if secretEncryptionData.KMS == nil {
return fmt.Errorf("kms metadata not specified")
}
- provider, err := getKMSProvider(secretEncryptionData.KMS, images, hcp)
+ keys, err := deriveKMSKeys(secretEncryptionData.KMS, encStatus, currentConfig, kasConverged)
+ if err != nil {
+ return fmt.Errorf("failed to derive KMS keys: %w", err)
+ }
+ provider, err := getKMSProvider(secretEncryptionData.KMS, keys, images, hcp)
if err != nil {
return err
}
@@ -34,8 +40,12 @@ func applyKMSConfig(podSpec *corev1.PodSpec, secretEncryptionData *hyperv1.Secre
return nil
}
-func generateKMSEncryptionConfig(kmsSpec *hyperv1.KMSSpec, apiVersion string) ([]byte, error) {
- provider, err := getKMSProvider(kmsSpec, kmsImages{}, nil)
+func generateKMSEncryptionConfig(kmsSpec *hyperv1.KMSSpec, encStatus *hyperv1.SecretEncryptionStatus, currentConfig *apiserverv1.EncryptionConfiguration, kasConverged bool, apiVersion string) ([]byte, error) {
+ keys, err := deriveKMSKeys(kmsSpec, encStatus, currentConfig, kasConverged)
+ if err != nil {
+ return nil, fmt.Errorf("failed to derive KMS keys: %w", err)
+ }
+ provider, err := getKMSProvider(kmsSpec, keys, kmsImages{}, nil)
if err != nil {
return nil, err
}
@@ -46,34 +56,150 @@ func generateKMSEncryptionConfig(kmsSpec *hyperv1.KMSSpec, apiVersion string) ([
}
bufferInstance := bytes.NewBuffer([]byte{})
- err = api.YamlSerializer.Encode(encryptionConfig, bufferInstance)
- if err != nil {
+ if err := api.YamlSerializer.Encode(encryptionConfig, bufferInstance); err != nil {
return nil, err
}
return bufferInstance.Bytes(), nil
}
+// kmsWriteReadKeys holds the provider-specific write and read key assignments
+// derived from the HCP status and current EncryptionConfiguration.
+type kmsWriteReadKeys struct {
+ awsWrite *hyperv1.AWSKMSKeyEntry
+ awsRead *hyperv1.AWSKMSKeyEntry
+ azureWrite *hyperv1.AzureKMSKey
+ azureRead *hyperv1.AzureKMSKey
+}
+
+// deriveKMSKeys determines the write and read KMS keys using the two-stage
+// rollout pattern. It inspects the current EncryptionConfiguration and KAS
+// convergence to determine the correct stage:
+//
+// - No targetKey: no rotation, spec.activeKey is the sole write key.
+// - targetKey set, not yet in config or present as read-only and KAS not
+// converged: ReadOnlyDeploy stage — old key (status.activeKey) writes,
+// new key (status.targetKey) reads.
+// - targetKey present as read-only and KAS converged, or targetKey is
+// already write provider: WritePromote/Migrating — new key
+// (status.targetKey) writes, old key (status.activeKey) reads.
+// - status has no active key (upgrade transition): fall back to spec.backupKey.
+func deriveKMSKeys(kmsSpec *hyperv1.KMSSpec, encStatus *hyperv1.SecretEncryptionStatus, currentConfig *apiserverv1.EncryptionConfiguration, kasConverged bool) (kmsWriteReadKeys, error) {
+ keys := kmsWriteReadKeys{}
+
+ switch kmsSpec.Provider {
+ case hyperv1.AWS:
+ if kmsSpec.AWS == nil {
+ return keys, nil
+ }
+
+ if encStatus == nil || encStatus.ActiveKey.Provider == "" {
+ // Upgrade transition or initial setup: use spec keys with deprecated backupKey fallback.
+ keys.awsWrite = &kmsSpec.AWS.ActiveKey
+ if kmsSpec.AWS.BackupKey != nil { //nolint:staticcheck
+ keys.awsRead = kmsSpec.AWS.BackupKey //nolint:staticcheck
+ }
+ return keys, nil
+ }
+
+ if encStatus.TargetKey.Provider == "" || encStatus.TargetKey.AWS.ARN == "" || encStatus.ActiveKey.AWS.ARN == "" {
+ keys.awsWrite = &kmsSpec.AWS.ActiveKey
+ return keys, nil
+ }
+
+ // Rotation in progress. Determine the stage from the current config.
+ targetKey := &hyperv1.AWSKMSKeyEntry{ARN: encStatus.TargetKey.AWS.ARN}
+ oldKey := &hyperv1.AWSKMSKeyEntry{ARN: encStatus.ActiveKey.AWS.ARN}
+ targetName, err := kms.AWSKMSProviderName(targetKey.ARN)
+ if err != nil {
+ return keys, err
+ }
+
+ if secretencryption.ShouldPromoteTargetKey(currentConfig, targetName, hyperv1.KMS, kasConverged) {
+ keys.awsWrite = targetKey
+ keys.awsRead = oldKey
+ } else {
+ keys.awsWrite = oldKey
+ keys.awsRead = targetKey
+ }
+
+ case hyperv1.AZURE:
+ if kmsSpec.Azure == nil {
+ return keys, nil
+ }
+
+ if encStatus == nil || encStatus.ActiveKey.Provider == "" {
+ keys.azureWrite = &kmsSpec.Azure.ActiveKey
+ if kmsSpec.Azure.BackupKey != nil { //nolint:staticcheck
+ keys.azureRead = kmsSpec.Azure.BackupKey //nolint:staticcheck
+ }
+ return keys, nil
+ }
+
+ if encStatus.TargetKey.Provider == "" || encStatus.TargetKey.Azure.KeyVaultName == "" || encStatus.ActiveKey.Azure.KeyVaultName == "" {
+ keys.azureWrite = &kmsSpec.Azure.ActiveKey
+ return keys, nil
+ }
+
+ targetKey := &hyperv1.AzureKMSKey{
+ KeyVaultName: encStatus.TargetKey.Azure.KeyVaultName,
+ KeyName: encStatus.TargetKey.Azure.KeyName,
+ KeyVersion: encStatus.TargetKey.Azure.KeyVersion,
+ }
+ oldKey := &hyperv1.AzureKMSKey{
+ KeyVaultName: encStatus.ActiveKey.Azure.KeyVaultName,
+ KeyName: encStatus.ActiveKey.Azure.KeyName,
+ KeyVersion: encStatus.ActiveKey.Azure.KeyVersion,
+ }
+ targetName, err := kms.AzureKMSProviderName(*targetKey)
+ if err != nil {
+ return keys, err
+ }
+
+ if secretencryption.ShouldPromoteTargetKey(currentConfig, targetName, hyperv1.KMS, kasConverged) {
+ keys.azureWrite = targetKey
+ keys.azureRead = oldKey
+ } else {
+ keys.azureWrite = oldKey
+ keys.azureRead = targetKey
+ }
+
+ case hyperv1.IBMCloud:
+ // IBM Cloud uses a single KMS provider with a fixed name; the sidecar
+ // handles key versioning internally via KP_DATA_JSON. No write/read
+ // key derivation is needed.
+ }
+
+ return keys, nil
+}
+
// getKMSProvider returns a KMS provider for the given spec. When hcp is nil (called from
// generateKMSEncryptionConfig), the provider is always created as "managed" because encryption
// config generation only produces the EncryptionConfiguration resource and does not need
// platform-specific pod/volume configuration.
-func getKMSProvider(kmsSpec *hyperv1.KMSSpec, images kmsImages, hcp *hyperv1.HostedControlPlane) (kms.KMSProvider, error) {
+func getKMSProvider(kmsSpec *hyperv1.KMSSpec, keys kmsWriteReadKeys, images kmsImages, hcp *hyperv1.HostedControlPlane) (kms.KMSProvider, error) {
switch kmsSpec.Provider {
case hyperv1.IBMCloud:
return kms.NewIBMCloudKMSProvider(kmsSpec.IBMCloud, images.IBMCloudKMS)
case hyperv1.AWS:
- return kms.NewAWSKMSProvider(kmsSpec.AWS, images.AWSKMS, images.TokenMinterImage)
+ if kmsSpec.AWS == nil {
+ return nil, fmt.Errorf("AWS kms metadata not specified")
+ }
+ return kms.NewAWSKMSProvider(*keys.awsWrite, keys.awsRead, kmsSpec.AWS.Region, images.AWSKMS, images.TokenMinterImage)
case hyperv1.AZURE:
- isSelfManaged := hcp != nil && azureutil.IsSelfManagedAzure(hcp.Spec.Platform.Type)
+ if kmsSpec.Azure == nil {
+ return nil, fmt.Errorf("azure kms metadata not specified")
+ }
opts := kms.AzureKMSProviderOptions{
- IsSelfManaged: isSelfManaged,
TokenMinterImage: images.TokenMinterImage,
}
- if isSelfManaged && kmsSpec.Azure.WorkloadIdentity.ClientID != "" {
- opts.KMSClientID = string(kmsSpec.Azure.WorkloadIdentity.ClientID)
- opts.TenantID = hcp.Spec.Platform.Azure.TenantID
+ if hcp != nil {
+ opts.IsSelfManaged = azureutil.IsSelfManagedAzure(hcp.Spec.Platform.Type)
+ if opts.IsSelfManaged && kmsSpec.Azure.WorkloadIdentity.ClientID != "" {
+ opts.KMSClientID = string(kmsSpec.Azure.WorkloadIdentity.ClientID)
+ opts.TenantID = hcp.Spec.Platform.Azure.TenantID
+ }
}
- return kms.NewAzureKMSProvider(kmsSpec.Azure, images.AzureKMS, opts)
+ return kms.NewAzureKMSProvider(*keys.azureWrite, keys.azureRead, kmsSpec.Azure, images.AzureKMS, opts)
default:
return nil, fmt.Errorf("unrecognized kms provider %s", kmsSpec.Provider)
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws.go
index 40725bc04ea4..546557f757b5 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws.go
@@ -29,6 +29,15 @@ const (
kmsAPIVersionV1 = "v1"
)
+// AWSKMSProviderName computes the EncryptionConfiguration KMS provider name for an AWS KMS key ARN.
+func AWSKMSProviderName(arn string) (string, error) {
+ hasher := fnv.New32()
+ if _, err := hasher.Write([]byte(arn)); err != nil {
+ return "", fmt.Errorf("failed to hash AWS KMS ARN: %w", err)
+ }
+ return fmt.Sprintf("%s-%d", awsKeyNamePrefix, hasher.Sum32()), nil
+}
+
var (
awsKMSVolumeMounts = podspec.VolumeMounts{
KasMainContainerName: {
@@ -64,14 +73,14 @@ type awsKMSProvider struct {
tokenMinterImage string
}
-func NewAWSKMSProvider(kmsSpec *hyperv1.AWSKMSSpec, kmsImage, tokenMinterImage string) (*awsKMSProvider, error) {
- if kmsSpec == nil {
- return nil, fmt.Errorf("AWS kms metadata not specified")
+func NewAWSKMSProvider(writeKey hyperv1.AWSKMSKeyEntry, readKey *hyperv1.AWSKMSKeyEntry, region string, kmsImage, tokenMinterImage string) (*awsKMSProvider, error) {
+ if len(writeKey.ARN) == 0 {
+ return nil, fmt.Errorf("AWS KMS write key ARN is empty")
}
return &awsKMSProvider{
- activeKey: kmsSpec.ActiveKey,
- backupKey: kmsSpec.BackupKey,
- awsRegion: kmsSpec.Region,
+ activeKey: writeKey,
+ backupKey: readKey,
+ awsRegion: region,
kmsImage: kmsImage,
tokenMinterImage: tokenMinterImage,
}, nil
@@ -82,29 +91,27 @@ func (p *awsKMSProvider) GenerateKMSEncryptionConfig(apiVersion string) (*v1.Enc
if len(p.activeKey.ARN) == 0 {
return nil, fmt.Errorf("active key metadata is nil")
}
- hasher := fnv.New32()
- _, err := hasher.Write([]byte(p.activeKey.ARN))
+ activeKeyName, err := AWSKMSProviderName(p.activeKey.ARN)
if err != nil {
return nil, err
}
providerConfiguration = append(providerConfiguration, v1.ProviderConfiguration{
KMS: &v1.KMSConfiguration{
APIVersion: apiVersion,
- Name: fmt.Sprintf("%s-%d", awsKeyNamePrefix, hasher.Sum32()),
+ Name: activeKeyName,
Endpoint: activeAWSKMSUnixSocket,
Timeout: &metav1.Duration{Duration: 35 * time.Second},
},
})
if p.backupKey != nil && len(p.backupKey.ARN) > 0 {
- hasher = fnv.New32()
- _, err := hasher.Write([]byte(p.backupKey.ARN))
+ backupKeyName, err := AWSKMSProviderName(p.backupKey.ARN)
if err != nil {
return nil, err
}
providerConfiguration = append(providerConfiguration, v1.ProviderConfiguration{
KMS: &v1.KMSConfiguration{
APIVersion: apiVersion,
- Name: fmt.Sprintf("%s-%d", awsKeyNamePrefix, hasher.Sum32()),
+ Name: backupKeyName,
Endpoint: backupAWSKMSUnixSocket,
Timeout: &metav1.Duration{Duration: 35 * time.Second},
},
@@ -155,7 +162,6 @@ func (p *awsKMSProvider) GenerateKMSPodConfig() (*KMSPodConfig, error) {
podConfig.KASContainerMutate = func(c *corev1.Container) {
c.VolumeMounts = append(c.VolumeMounts, awsKMSVolumeMounts.ContainerMounts(KasMainContainerName)...)
- c.Args = append(c.Args, "--encryption-provider-config-automatic-reload=false")
}
return podConfig, nil
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws_test.go
index 5a0b4a6ea519..0d415cd57bc2 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/aws_test.go
@@ -19,22 +19,23 @@ func TestNewAWSKMSProvider(t *testing.T) {
tests := []struct {
name string
- kmsSpec *hyperv1.AWSKMSSpec
+ writeKey hyperv1.AWSKMSKeyEntry
+ readKey *hyperv1.AWSKMSKeyEntry
+ region string
kmsImage string
tokenMinterImage string
expectError bool
}{
{
- name: "When kmsSpec is nil, it should return an error",
- kmsSpec: nil,
+ name: "When write key ARN is empty, it should return an error",
+ writeKey: hyperv1.AWSKMSKeyEntry{ARN: ""},
+ region: "us-east-1",
expectError: true,
},
{
- name: "When kmsSpec is valid, it should return a provider with the correct fields",
- kmsSpec: &hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- },
+ name: "When write key is valid, it should return a provider with the correct fields",
+ writeKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ region: "us-east-1",
kmsImage: "quay.io/test/kms:latest",
tokenMinterImage: "quay.io/test/token-minter:latest",
expectError: false,
@@ -46,7 +47,7 @@ func TestNewAWSKMSProvider(t *testing.T) {
t.Parallel()
g := NewWithT(t)
- provider, err := NewAWSKMSProvider(tc.kmsSpec, tc.kmsImage, tc.tokenMinterImage)
+ provider, err := NewAWSKMSProvider(tc.writeKey, tc.readKey, tc.region, tc.kmsImage, tc.tokenMinterImage)
if tc.expectError {
g.Expect(err).To(HaveOccurred())
g.Expect(provider).To(BeNil())
@@ -55,9 +56,9 @@ func TestNewAWSKMSProvider(t *testing.T) {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(provider).ToNot(BeNil())
- g.Expect(provider.activeKey).To(Equal(tc.kmsSpec.ActiveKey))
- g.Expect(provider.backupKey).To(Equal(tc.kmsSpec.BackupKey))
- g.Expect(provider.awsRegion).To(Equal(tc.kmsSpec.Region))
+ g.Expect(provider.activeKey).To(Equal(tc.writeKey))
+ g.Expect(provider.backupKey).To(Equal(tc.readKey))
+ g.Expect(provider.awsRegion).To(Equal(tc.region))
g.Expect(provider.kmsImage).To(Equal(tc.kmsImage))
g.Expect(provider.tokenMinterImage).To(Equal(tc.tokenMinterImage))
})
@@ -76,10 +77,10 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
{
name: "When active key ARN is empty, it should return an error",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: ""},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: ""},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -88,12 +89,12 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
},
},
{
- name: "When only active key is provided, it should generate config with 2 providers (KMS + identity)",
+ name: "When only write key is provided, it should generate config with 2 providers (KMS + identity)",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -105,13 +106,13 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
},
},
{
- name: "When active and backup keys are provided, it should generate config with 3 providers (active KMS + backup KMS + identity)",
+ name: "When write and read keys are provided, it should generate config with 3 providers (write KMS + read KMS + identity)",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/active-key"},
- BackupKey: &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/backup-key"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/active-key"},
+ &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/backup-key"},
+ "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -124,13 +125,13 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
},
},
{
- name: "When backup key ARN is empty, it should only include active KMS provider",
+ name: "When read key ARN is empty, it should only include write KMS provider",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- BackupKey: &hyperv1.AWSKMSKeyEntry{ARN: ""},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ &hyperv1.AWSKMSKeyEntry{ARN: ""},
+ "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -144,10 +145,10 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
{
name: "When called, it should set the correct API version on the encryption config",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -159,11 +160,11 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
{
name: "When called, it should set timeout to 35 seconds on KMS providers",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/active-key"},
- BackupKey: &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/backup-key"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/active-key"},
+ &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/backup-key"},
+ "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -179,10 +180,10 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
{
name: "When called, the KMS provider name should be based on a hash of the ARN",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
apiVersion: "v2",
validate: func(g Gomega, config *v1.EncryptionConfiguration, err error) {
@@ -206,7 +207,11 @@ func TestGenerateKMSEncryptionConfig(t *testing.T) {
g := NewWithT(t)
provider, err := tc.provider()
- g.Expect(err).ToNot(HaveOccurred())
+ if err != nil {
+ // Constructor-level validation error (e.g., empty write key ARN).
+ tc.validate(g, nil, err)
+ return
+ }
config, err := provider.GenerateKMSEncryptionConfig(tc.apiVersion)
tc.validate(g, config, err)
@@ -223,12 +228,12 @@ func TestGenerateKMSPodConfig(t *testing.T) {
validate func(g Gomega, podConfig *KMSPodConfig, err error)
}{
{
- name: "When active key ARN is empty, it should return an error",
+ name: "When write key ARN is empty, it should return an error",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: ""},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: ""},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
validate: func(g Gomega, podConfig *KMSPodConfig, err error) {
g.Expect(err).To(HaveOccurred())
@@ -238,10 +243,10 @@ func TestGenerateKMSPodConfig(t *testing.T) {
{
name: "When kms image is empty, it should return an error",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "", "quay.io/test/token-minter:latest")
},
validate: func(g Gomega, podConfig *KMSPodConfig, err error) {
g.Expect(err).To(HaveOccurred())
@@ -249,12 +254,12 @@ func TestGenerateKMSPodConfig(t *testing.T) {
},
},
{
- name: "When valid config is provided without backup key, it should return 2 containers (token-minter + active)",
+ name: "When valid config is provided without read key, it should return 2 containers (token-minter + active)",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
validate: func(g Gomega, podConfig *KMSPodConfig, err error) {
g.Expect(err).ToNot(HaveOccurred())
@@ -264,13 +269,13 @@ func TestGenerateKMSPodConfig(t *testing.T) {
},
},
{
- name: "When valid config is provided with backup key, it should return 3 containers (token-minter + active + backup)",
+ name: "When valid config is provided with read key, it should return 3 containers (token-minter + active + backup)",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/active-key"},
- BackupKey: &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/backup-key"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/active-key"},
+ &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/backup-key"},
+ "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
validate: func(g Gomega, podConfig *KMSPodConfig, err error) {
g.Expect(err).ToNot(HaveOccurred())
@@ -283,10 +288,10 @@ func TestGenerateKMSPodConfig(t *testing.T) {
{
name: "When valid config is provided, it should return 3 volumes",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
validate: func(g Gomega, podConfig *KMSPodConfig, err error) {
g.Expect(err).ToNot(HaveOccurred())
@@ -299,10 +304,10 @@ func TestGenerateKMSPodConfig(t *testing.T) {
{
name: "When valid config is provided, it should set KASContainerMutate function",
provider: func() (*awsKMSProvider, error) {
- return NewAWSKMSProvider(&hyperv1.AWSKMSSpec{
- ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
- Region: "us-east-1",
- }, "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
+ return NewAWSKMSProvider(
+ hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/test-key-id"},
+ nil, "us-east-1",
+ "quay.io/test/kms:latest", "quay.io/test/token-minter:latest")
},
validate: func(g Gomega, podConfig *KMSPodConfig, err error) {
g.Expect(err).ToNot(HaveOccurred())
@@ -317,7 +322,11 @@ func TestGenerateKMSPodConfig(t *testing.T) {
g := NewWithT(t)
provider, err := tc.provider()
- g.Expect(err).ToNot(HaveOccurred())
+ if err != nil {
+ // Constructor-level validation error (e.g., empty write key ARN).
+ tc.validate(g, nil, err)
+ return
+ }
podConfig, err := provider.GenerateKMSPodConfig()
tc.validate(g, podConfig, err)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure.go
index 8f9cbb83539e..242950545543 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure.go
@@ -37,6 +37,15 @@ const (
azureProviderConfigNamePrefix = "azure"
)
+// AzureKMSProviderName computes the EncryptionConfiguration KMS provider name for an Azure KMS key.
+func AzureKMSProviderName(key hyperv1.AzureKMSKey) (string, error) {
+ h, err := util.HashStruct(key)
+ if err != nil {
+ return "", err
+ }
+ return fmt.Sprintf("%s-%s", azureProviderConfigNamePrefix, h), nil
+}
+
var (
azureKMSVolumeMounts = podspec.VolumeMounts{
KasMainContainerName: {
@@ -59,6 +68,8 @@ var (
var _ KMSProvider = &azureKMSProvider{}
type azureKMSProvider struct {
+ writeKey hyperv1.AzureKMSKey
+ readKey *hyperv1.AzureKMSKey
kmsSpec *hyperv1.AzureKMSSpec
kmsImage string
isSelfManaged bool
@@ -75,7 +86,7 @@ type AzureKMSProviderOptions struct {
TokenMinterImage string
}
-func NewAzureKMSProvider(kmsSpec *hyperv1.AzureKMSSpec, image string, opts AzureKMSProviderOptions) (*azureKMSProvider, error) {
+func NewAzureKMSProvider(writeKey hyperv1.AzureKMSKey, readKey *hyperv1.AzureKMSKey, kmsSpec *hyperv1.AzureKMSSpec, image string, opts AzureKMSProviderOptions) (*azureKMSProvider, error) {
if kmsSpec == nil {
return nil, fmt.Errorf("azure kms metadata not specified")
}
@@ -88,6 +99,8 @@ func NewAzureKMSProvider(kmsSpec *hyperv1.AzureKMSSpec, image string, opts Azure
}
}
return &azureKMSProvider{
+ writeKey: writeKey,
+ readKey: readKey,
kmsSpec: kmsSpec,
kmsImage: image,
isSelfManaged: opts.IsSelfManaged,
@@ -100,26 +113,26 @@ func NewAzureKMSProvider(kmsSpec *hyperv1.AzureKMSSpec, image string, opts Azure
func (p *azureKMSProvider) GenerateKMSEncryptionConfig(apiVersion string) (*v1.EncryptionConfiguration, error) {
var providerConfiguration []v1.ProviderConfiguration
- activeKeyHash, err := util.HashStruct(p.kmsSpec.ActiveKey)
+ writeKeyName, err := AzureKMSProviderName(p.writeKey)
if err != nil {
return nil, err
}
providerConfiguration = append(providerConfiguration, v1.ProviderConfiguration{
KMS: &v1.KMSConfiguration{
- Name: fmt.Sprintf("%s-%s", azureProviderConfigNamePrefix, activeKeyHash),
+ Name: writeKeyName,
APIVersion: apiVersion,
Endpoint: azureActiveKMSUnixSocket,
Timeout: &metav1.Duration{Duration: 35 * time.Second},
},
})
- if p.kmsSpec.BackupKey != nil {
- backupKeyHash, err := util.HashStruct(p.kmsSpec.BackupKey)
+ if p.readKey != nil {
+ readKeyName, err := AzureKMSProviderName(*p.readKey)
if err != nil {
return nil, err
}
providerConfiguration = append(providerConfiguration, v1.ProviderConfiguration{
KMS: &v1.KMSConfiguration{
- Name: fmt.Sprintf("%s-%s", azureProviderConfigNamePrefix, backupKeyHash),
+ Name: readKeyName,
APIVersion: apiVersion,
Endpoint: azureBackupKMSUnixSocket,
Timeout: &metav1.Duration{Duration: 35 * time.Second},
@@ -166,13 +179,19 @@ func (p *azureKMSProvider) GenerateKMSPodConfig() (*KMSPodConfig, error) {
podConfig.Containers = append(podConfig.Containers,
podspec.BuildContainer(
kasContainerAzureKMSActive(),
- p.buildKASContainerAzureKMS(p.kmsSpec.ActiveKey, azureActiveKMSUnixSocket, azureActiveKMSHealthPort, azureActiveKMSMetricsAddr)),
+ p.buildKASContainerAzureKMS(p.writeKey, azureActiveKMSUnixSocket, azureActiveKMSHealthPort, azureActiveKMSMetricsAddr)),
)
- if p.kmsSpec.BackupKey != nil {
+ if p.readKey != nil {
podConfig.Containers = append(podConfig.Containers,
podspec.BuildContainer(
kasContainerAzureKMSBackup(),
- p.buildKASContainerAzureKMS(*p.kmsSpec.BackupKey, azureBackupKMSUnixSocket, azureBackupKMSHealthPort, azureBackupKMSMetricsAddr)),
+ p.buildKASContainerAzureKMS(*p.readKey, azureBackupKMSUnixSocket, azureBackupKMSHealthPort, azureBackupKMSMetricsAddr)),
+ )
+ }
+
+ if p.isSelfManaged {
+ podConfig.Containers = append(podConfig.Containers,
+ podspec.BuildContainer(kasContainerAzureKMSTokenMinter(), p.buildKASContainerAzureKMSTokenMinter()),
)
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure_test.go
index 0b2bc35ec58c..f4f26bd64c20 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/azure_test.go
@@ -33,7 +33,7 @@ func validAzureKMSSpec() *hyperv1.AzureKMSSpec {
func validAzureKMSSpecWithBackup() *hyperv1.AzureKMSSpec {
spec := validAzureKMSSpec()
- spec.BackupKey = &hyperv1.AzureKMSKey{
+ spec.BackupKey = &hyperv1.AzureKMSKey{ //nolint:staticcheck
KeyVaultName: "test-vault",
KeyName: "backup-key",
KeyVersion: "1",
@@ -41,6 +41,16 @@ func validAzureKMSSpecWithBackup() *hyperv1.AzureKMSSpec {
return spec
}
+func newTestAzureKMSProvider(spec *hyperv1.AzureKMSSpec, image string, opts AzureKMSProviderOptions) (*azureKMSProvider, error) {
+ var writeKey hyperv1.AzureKMSKey
+ var readKey *hyperv1.AzureKMSKey
+ if spec != nil {
+ writeKey = spec.ActiveKey
+ readKey = spec.BackupKey //nolint:staticcheck
+ }
+ return NewAzureKMSProvider(writeKey, readKey, spec, image, opts)
+}
+
func TestNewAzureKMSProvider(t *testing.T) {
tests := []struct {
name string
@@ -122,7 +132,7 @@ func TestNewAzureKMSProvider(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(tc.kmsSpec, tc.image, tc.opts)
+ provider, err := newTestAzureKMSProvider(tc.kmsSpec, tc.image, tc.opts)
if tc.expectError {
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(ContainSubstring(tc.errContains))
@@ -240,7 +250,7 @@ func TestGenerateKMSPodConfig_SelfManaged(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: true,
KMSClientID: "test-client-id",
TenantID: "test-tenant-id",
@@ -321,7 +331,7 @@ func TestGenerateKMSPodConfig_Managed(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -339,7 +349,7 @@ func TestGenerateKMSPodConfig_BackupKey(t *testing.T) {
t.Run("When self-managed backup key is specified it should include backup KMS container with env vars", func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: true,
KMSClientID: "test-client-id",
TenantID: "test-tenant-id",
@@ -371,7 +381,7 @@ func TestGenerateKMSPodConfig_BackupKey(t *testing.T) {
t.Run("When managed backup key is specified it should include backup container with secret-store mount", func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -415,7 +425,7 @@ func findContainer(containers []corev1.Container, name string) *corev1.Container
func TestGenerateKMSPodConfig_ActiveContainerArgs(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -479,7 +489,7 @@ func TestGenerateKMSPodConfig_ActiveContainerArgs(t *testing.T) {
func TestGenerateKMSPodConfig_BackupContainerArgs(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -550,7 +560,7 @@ func TestGenerateKMSPodConfig_LivenessProbe(t *testing.T) {
t.Run(fmt.Sprintf("When %s is created it should have a correctly configured liveness probe", tc.name), func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -577,7 +587,7 @@ func TestGenerateKMSPodConfig_LivenessProbe(t *testing.T) {
func TestGenerateKMSPodConfig_ResourceRequests(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: true,
KMSClientID: "test-client-id",
TenantID: "test-tenant-id",
@@ -690,7 +700,7 @@ func TestGenerateKMSPodConfig_VolumeMountPaths(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", tc.opts)
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", tc.opts)
g.Expect(err).NotTo(HaveOccurred())
podConfig, err := provider.GenerateKMSPodConfig()
g.Expect(err).NotTo(HaveOccurred())
@@ -703,7 +713,7 @@ func TestGenerateKMSPodConfig_KASContainerMutation(t *testing.T) {
t.Run("When KAS container mutation is applied it should mount the KMS socket volume at /opt", func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -725,7 +735,7 @@ func TestGenerateKMSPodConfig_KASContainerMutation(t *testing.T) {
func TestGenerateKMSPodConfig_ContainerPorts(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpecWithBackup(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -766,7 +776,7 @@ func TestGenerateKMSPodConfig_ContainerPorts(t *testing.T) {
func TestGenerateKMSPodConfig_ImagePullPolicy(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: true,
KMSClientID: "test-client-id",
TenantID: "test-tenant-id",
@@ -805,7 +815,7 @@ func TestGenerateKMSPodConfig_NoBackupContainerWithoutBackupKey(t *testing.T) {
t.Run("When no backup key is specified it should not create a backup container", func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(validAzureKMSSpec(), "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -838,7 +848,7 @@ func TestGenerateKMSEncryptionConfig_Azure(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
- provider, err := NewAzureKMSProvider(tc.spec, "test-kms-image:latest", AzureKMSProviderOptions{
+ provider, err := newTestAzureKMSProvider(tc.spec, "test-kms-image:latest", AzureKMSProviderOptions{
IsSelfManaged: false,
})
g.Expect(err).NotTo(HaveOccurred())
@@ -852,7 +862,7 @@ func TestGenerateKMSEncryptionConfig_Azure(t *testing.T) {
g.Expect(encConfig.Resources[0].Resources).To(Equal(config.KMSEncryptedObjects()))
providers := encConfig.Resources[0].Providers
- if tc.spec.BackupKey != nil {
+ if tc.spec.BackupKey != nil { //nolint:staticcheck
g.Expect(providers).To(HaveLen(3), "expected active KMS + backup KMS + Identity")
} else {
g.Expect(providers).To(HaveLen(2), "expected active KMS + Identity")
@@ -867,9 +877,9 @@ func TestGenerateKMSEncryptionConfig_Azure(t *testing.T) {
g.Expect(providers[0].KMS.Endpoint).To(Equal(azureActiveKMSUnixSocket))
g.Expect(providers[0].KMS.Timeout).To(Equal(&metav1.Duration{Duration: 35 * time.Second}))
- if tc.spec.BackupKey != nil {
+ if tc.spec.BackupKey != nil { //nolint:staticcheck
g.Expect(providers[1].KMS).NotTo(BeNil())
- backupKeyHash, err := util.HashStruct(tc.spec.BackupKey)
+ backupKeyHash, err := util.HashStruct(tc.spec.BackupKey) //nolint:staticcheck
g.Expect(err).NotTo(HaveOccurred())
g.Expect(providers[1].KMS.Name).To(Equal(fmt.Sprintf("azure-%s", backupKeyHash)))
g.Expect(providers[1].KMS.Endpoint).To(Equal(azureBackupKMSUnixSocket))
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/ibmcloud.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/ibmcloud.go
index 0e3ba9cfc67f..0bbf0df7ad58 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/ibmcloud.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/ibmcloud.go
@@ -42,6 +42,13 @@ const (
ibmCloudKMSHealthPort = 8081
)
+// IBMCloudKMSProviderName returns the fixed EncryptionConfiguration KMS provider
+// name used for IBM Cloud. Unlike AWS/Azure, IBM Cloud always uses a single
+// provider with all key versions bundled into the sidecar.
+func IBMCloudKMSProviderName() string {
+ return fmt.Sprintf("%s%s", ibmKeyNamePrefix, "v2")
+}
+
var _ KMSProvider = &ibmCloudKMSProvider{}
type ibmCloudKMSProvider struct {
@@ -65,7 +72,7 @@ func (p *ibmCloudKMSProvider) GenerateKMSEncryptionConfig(_ string) (*v1.Encrypt
{
KMS: &v1.KMSConfiguration{
APIVersion: "v2",
- Name: fmt.Sprintf("%s%s", ibmKeyNamePrefix, "v2"),
+ Name: IBMCloudKMSProviderName(),
Endpoint: ibmCloudKMSUnixSocket,
Timeout: &metav1.Duration{Duration: 35 * time.Second},
},
@@ -299,7 +306,6 @@ func (p *ibmCloudKMSProvider) GenerateKMSPodConfig() (*KMSPodConfig, error) {
podConfig.KASContainerMutate = func(c *corev1.Container) {
c.VolumeMounts = append(c.VolumeMounts, ibmCloudKMSVolumeMounts.ContainerMounts(KasMainContainerName)...)
- c.Args = append(c.Args, "--encryption-provider-config-automatic-reload=false")
}
return podConfig, nil
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/kms.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/kms.go
index cbd26825658d..66c970a8d17b 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/kms.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms/kms.go
@@ -1,6 +1,8 @@
package kms
import (
+ "github.com/openshift/hypershift/support/secretencryption"
+
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
)
@@ -20,7 +22,7 @@ type KMSProvider interface {
const (
KasMainContainerName = "kube-apiserver"
- encryptionConfigurationKind = "EncryptionConfiguration"
+ encryptionConfigurationKind = secretencryption.EncryptionConfigurationKind
kasVolumeLocalhostKubeconfig = "localhost-kubeconfig"
)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go
new file mode 100644
index 000000000000..569922f01123
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go
@@ -0,0 +1,176 @@
+package kas
+
+import (
+ "testing"
+
+ . "github.com/onsi/gomega"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms"
+
+ apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
+)
+
+func TestDeriveKMSKeys(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ kmsSpec *hyperv1.KMSSpec
+ encStatus *hyperv1.SecretEncryptionStatus
+ currentConfig *apiserverv1.EncryptionConfiguration
+ kasConverged bool
+ validate func(g Gomega, keys kmsWriteReadKeys)
+ }{
+ {
+ name: "When AWS with nil status it should use spec active key as write with spec backup as read",
+ kmsSpec: &hyperv1.KMSSpec{
+ Provider: hyperv1.AWS,
+ AWS: &hyperv1.AWSKMSSpec{
+ ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key"},
+ BackupKey: &hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key"},
+ Region: "us-east-1",
+ },
+ },
+ encStatus: nil,
+ validate: func(g Gomega, keys kmsWriteReadKeys) {
+ g.Expect(keys.awsWrite).ToNot(BeNil())
+ g.Expect(keys.awsWrite.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/new-key"))
+ g.Expect(keys.awsRead).ToNot(BeNil())
+ g.Expect(keys.awsRead.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/old-key"))
+ },
+ },
+ {
+ name: "When AWS with status set but no target key it should use only write key",
+ kmsSpec: &hyperv1.KMSSpec{
+ Provider: hyperv1.AWS,
+ AWS: &hyperv1.AWSKMSSpec{
+ ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/current-key"},
+ Region: "us-east-1",
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/current-key", Region: "us-east-1"},
+ },
+ },
+ validate: func(g Gomega, keys kmsWriteReadKeys) {
+ g.Expect(keys.awsWrite).ToNot(BeNil())
+ g.Expect(keys.awsWrite.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/current-key"))
+ g.Expect(keys.awsRead).To(BeNil())
+ },
+ },
+ {
+ name: "When AWS rotation in progress and target key absent from config it should use old key as write (ReadOnlyDeploy)",
+ kmsSpec: &hyperv1.KMSSpec{
+ Provider: hyperv1.AWS,
+ AWS: &hyperv1.AWSKMSSpec{
+ ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key"},
+ Region: "us-east-1",
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key", Region: "us-east-1"},
+ },
+ TargetKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key", Region: "us-east-1"},
+ },
+ },
+ currentConfig: nil,
+ validate: func(g Gomega, keys kmsWriteReadKeys) {
+ g.Expect(keys.awsWrite.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/old-key"), "old key should be write during ReadOnlyDeploy")
+ g.Expect(keys.awsRead.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/new-key"), "new key should be read-only during ReadOnlyDeploy")
+ },
+ },
+ {
+ name: "When AWS rotation in progress and target key present in config it should promote target to write (WritePromote)",
+ kmsSpec: &hyperv1.KMSSpec{
+ Provider: hyperv1.AWS,
+ AWS: &hyperv1.AWSKMSSpec{
+ ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key"},
+ Region: "us-east-1",
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key", Region: "us-east-1"},
+ },
+ TargetKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAWS,
+ AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key", Region: "us-east-1"},
+ },
+ },
+ currentConfig: kmsEncryptionConfig(
+ mustAWSProviderName("arn:aws:kms:us-east-1:123456789:key/old-key"),
+ mustAWSProviderName("arn:aws:kms:us-east-1:123456789:key/new-key"),
+ ),
+ kasConverged: true,
+ validate: func(g Gomega, keys kmsWriteReadKeys) {
+ g.Expect(keys.awsWrite.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/new-key"), "target key should be write after promotion")
+ g.Expect(keys.awsRead.ARN).To(Equal("arn:aws:kms:us-east-1:123456789:key/old-key"), "old key should be read after promotion")
+ },
+ },
+ {
+ name: "When Azure rotation in progress and target key absent from config it should use old key as write",
+ kmsSpec: &hyperv1.KMSSpec{
+ Provider: hyperv1.AZURE,
+ Azure: &hyperv1.AzureKMSSpec{
+ ActiveKey: hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v2"},
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAzure,
+ Azure: hyperv1.AzureKMSKeyStatus{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"},
+ },
+ TargetKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAzure,
+ Azure: hyperv1.AzureKMSKeyStatus{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v2"},
+ },
+ },
+ currentConfig: nil,
+ validate: func(g Gomega, keys kmsWriteReadKeys) {
+ g.Expect(keys.azureWrite.KeyVersion).To(Equal("v1"), "old key should be write during ReadOnlyDeploy")
+ g.Expect(keys.azureRead.KeyVersion).To(Equal("v2"), "target key should be read-only during ReadOnlyDeploy")
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ g := NewWithT(t)
+
+ keys, err := deriveKMSKeys(tc.kmsSpec, tc.encStatus, tc.currentConfig, tc.kasConverged)
+ g.Expect(err).ToNot(HaveOccurred())
+ tc.validate(g, keys)
+ })
+ }
+}
+
+func mustAWSProviderName(arn string) string {
+ name, _ := kms.AWSKMSProviderName(arn)
+ return name
+}
+
+func kmsEncryptionConfig(writeProviderName, readProviderName string) *apiserverv1.EncryptionConfiguration {
+ providers := []apiserverv1.ProviderConfiguration{
+ {KMS: &apiserverv1.KMSConfiguration{Name: writeProviderName, APIVersion: "v2"}},
+ }
+ if readProviderName != "" {
+ providers = append(providers, apiserverv1.ProviderConfiguration{
+ KMS: &apiserverv1.KMSConfiguration{Name: readProviderName, APIVersion: "v2"},
+ })
+ }
+ providers = append(providers, apiserverv1.ProviderConfiguration{Identity: &apiserverv1.IdentityConfiguration{}})
+ return &apiserverv1.EncryptionConfiguration{
+ Resources: []apiserverv1.ResourceConfiguration{
+ {Providers: providers},
+ },
+ }
+}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption.go
index 5baaf8c1f7f8..d9acda27073e 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption.go
@@ -5,9 +5,11 @@ import (
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests"
- "github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/api"
component "github.com/openshift/hypershift/support/controlplane-component"
+ "github.com/openshift/hypershift/support/podspec"
+ "github.com/openshift/hypershift/support/secretencryption"
+ appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -17,8 +19,8 @@ import (
)
const (
- secretEncryptionConfigurationKey = "config.yaml"
- encryptionConfigurationKind = "EncryptionConfiguration"
+ secretEncryptionConfigurationKey = secretencryption.EncryptionConfigurationKey
+ encryptionConfigurationKind = secretencryption.EncryptionConfigurationKind
secretEncryptionConfigFileVolumeName = "kas-secret-encryption-config"
)
@@ -30,43 +32,23 @@ func secretEncryptionConfigPredicate(cpContext component.WorkloadContext) bool {
func adaptSecretEncryptionConfig(cpContext component.WorkloadContext, secret *corev1.Secret) error {
var data []byte
secretEncryption := cpContext.HCP.Spec.SecretEncryption
+ encStatus := &cpContext.HCP.Status.SecretEncryption
+
+ // Read the live encryption config from the cluster to derive the two-stage rollout state.
+ currentConfig, err := readCurrentEncryptionConfig(cpContext, secret)
+ if err != nil {
+ return fmt.Errorf("failed to read current encryption config: %w", err)
+ }
+
+ // Check KAS convergence — needed to decide whether to promote the target key.
+ kasConverged, err := isKASConverged(cpContext)
+ if err != nil {
+ return fmt.Errorf("failed to check KAS convergence: %w", err)
+ }
+
switch secretEncryption.Type {
case hyperv1.AESCBC:
- if secretEncryption.AESCBC == nil || len(secretEncryption.AESCBC.ActiveKey.Name) == 0 {
- return fmt.Errorf("aescbc metadata not specified")
- }
- activeKeySecret := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: secretEncryption.AESCBC.ActiveKey.Name,
- Namespace: cpContext.HCP.Namespace,
- },
- }
- if err := cpContext.Client.Get(cpContext, client.ObjectKeyFromObject(activeKeySecret), activeKeySecret); err != nil {
- return fmt.Errorf("failed to get aescbc active secret: %w", err)
- }
- if _, ok := activeKeySecret.Data[hyperv1.AESCBCKeySecretKey]; !ok {
- return fmt.Errorf("aescbc key field '%s' in active key secret not specified", hyperv1.AESCBCKeySecretKey)
- }
- aesCBCActiveKey := activeKeySecret.Data[hyperv1.AESCBCKeySecretKey]
- var aesCBCBackupKey []byte
- if secretEncryption.AESCBC.BackupKey != nil && len(secretEncryption.AESCBC.BackupKey.Name) > 0 {
- backupKeySecret := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: secretEncryption.AESCBC.BackupKey.Name,
- Namespace: cpContext.HCP.Namespace,
- },
- }
- if err := cpContext.Client.Get(cpContext, client.ObjectKeyFromObject(backupKeySecret), backupKeySecret); err != nil {
- return fmt.Errorf("failed to get aescbc backup key secret: %w", err)
- }
- if _, ok := backupKeySecret.Data[hyperv1.AESCBCKeySecretKey]; !ok {
- return fmt.Errorf("aescbc key field %s in backup key secret not specified", hyperv1.AESCBCKeySecretKey)
- }
- aesCBCBackupKey = backupKeySecret.Data[hyperv1.AESCBCKeySecretKey]
- }
-
- var err error
- data, err = generateAESCBCEncryptionConfig(aesCBCActiveKey, aesCBCBackupKey)
+ data, err = deriveAESCBCEncryptionConfig(cpContext, secretEncryption, encStatus, currentConfig, kasConverged)
if err != nil {
return err
}
@@ -74,11 +56,8 @@ func adaptSecretEncryptionConfig(cpContext component.WorkloadContext, secret *co
if secretEncryption.KMS == nil {
return fmt.Errorf("kms metadata not specified")
}
- apiVersion, err := getKMSAPIVersion(cpContext, secret)
- if err != nil {
- return err
- }
- data, err = generateKMSEncryptionConfig(secretEncryption.KMS, apiVersion)
+ apiVersion := getKMSAPIVersion(currentConfig)
+ data, err = generateKMSEncryptionConfig(secretEncryption.KMS, encStatus, currentConfig, kasConverged, apiVersion)
if err != nil {
return err
}
@@ -88,36 +67,133 @@ func adaptSecretEncryptionConfig(cpContext component.WorkloadContext, secret *co
return nil
}
-// getKMSAPIVersion returns the KMS API version from the given EncryptionConfig secret.
-// If the current state is using the IdentityProvider, the function returns v2 as the default version to start with.
-func getKMSAPIVersion(cpContext component.WorkloadContext, secret *corev1.Secret) (string, error) {
- apiVersion := "v2"
- if err := cpContext.Client.Get(cpContext, client.ObjectKeyFromObject(secret), secret); err != nil {
+// isKASConverged checks if the KAS Deployment has fully rolled out.
+// Returns false (not error) if the deployment doesn't exist yet.
+func isKASConverged(cpContext component.WorkloadContext) (bool, error) {
+ kasDeployment := &appsv1.Deployment{}
+ kasRef := manifests.KASDeployment(cpContext.HCP.Namespace)
+ if err := cpContext.Client.Get(cpContext, client.ObjectKeyFromObject(kasRef), kasDeployment); err != nil {
if apierrors.IsNotFound(err) {
- return apiVersion, nil
+ return false, nil
}
- return "", fmt.Errorf("failed to get existing secret encryption config: %w", err)
+ return false, fmt.Errorf("failed to get KAS deployment: %w", err)
}
+ return podspec.IsDeploymentReady(cpContext, kasDeployment), nil
+}
- encryptionConfigBytes := secret.Data[secretEncryptionConfigurationKey]
- if len(encryptionConfigBytes) > 0 {
- currentConfig := apiserverv1.EncryptionConfiguration{}
- gvks, _, err := api.Scheme.ObjectKinds(¤tConfig)
- if err != nil || len(gvks) == 0 {
- return "", fmt.Errorf("cannot determine gvk of resource: %w", err)
+// readCurrentEncryptionConfig reads the live encryption config secret from the
+// cluster and parses its EncryptionConfiguration. Returns nil (not an error)
+// if the secret does not exist yet.
+func readCurrentEncryptionConfig(cpContext component.WorkloadContext, templateSecret *corev1.Secret) (*apiserverv1.EncryptionConfiguration, error) {
+ existingSecret := &corev1.Secret{}
+ if err := cpContext.Client.Get(cpContext, client.ObjectKeyFromObject(templateSecret), existingSecret); err != nil {
+ if apierrors.IsNotFound(err) {
+ return nil, nil
}
- if _, _, err = api.YamlSerializer.Decode(encryptionConfigBytes, &gvks[0], ¤tConfig); err != nil {
- return "", fmt.Errorf("cannot decode resource: %w", err)
+ return nil, err
+ }
+
+ configBytes := existingSecret.Data[secretEncryptionConfigurationKey]
+ if len(configBytes) == 0 {
+ return nil, nil
+ }
+
+ return secretencryption.DecodeEncryptionConfiguration(configBytes)
+}
+
+// deriveAESCBCEncryptionConfig determines the AESCBC write and read keys using
+// the two-stage rollout pattern, then generates the EncryptionConfiguration.
+//
+// Two-stage derivation:
+// - No targetKey: spec.activeKey is the sole write key.
+// - targetKey set, target not yet promoted in current config: ReadOnlyDeploy —
+// old key (status.activeKey) writes, new key (status.targetKey) reads.
+// - targetKey set and already promoted in current config: WritePromote/Migrating —
+// new key (status.targetKey) writes, old key (status.activeKey) reads.
+// - status has no active key (upgrade transition): fall back to spec.backupKey.
+func deriveAESCBCEncryptionConfig(cpContext component.WorkloadContext, secretEncryption *hyperv1.SecretEncryptionSpec, encStatus *hyperv1.SecretEncryptionStatus, currentConfig *apiserverv1.EncryptionConfiguration, kasConverged bool) ([]byte, error) {
+ if secretEncryption.AESCBC == nil || len(secretEncryption.AESCBC.ActiveKey.Name) == 0 {
+ return nil, fmt.Errorf("aescbc metadata not specified")
+ }
+
+ if encStatus == nil || encStatus.ActiveKey.Provider == "" {
+ // Upgrade transition or initial setup: use spec keys with deprecated backupKey fallback.
+ writeKeyData, err := fetchAESCBCKeyData(cpContext, secretEncryption.AESCBC.ActiveKey.Name)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get aescbc active key: %w", err)
+ }
+ var readKeyData []byte
+ if secretEncryption.AESCBC.BackupKey != nil && len(secretEncryption.AESCBC.BackupKey.Name) > 0 { //nolint:staticcheck
+ readKeyData, err = fetchAESCBCKeyData(cpContext, secretEncryption.AESCBC.BackupKey.Name) //nolint:staticcheck
+ if err != nil {
+ return nil, fmt.Errorf("failed to get aescbc backup key: %w", err)
+ }
}
+ return generateAESCBCEncryptionConfig(writeKeyData, readKeyData)
+ }
+
+ if encStatus.TargetKey.Provider == "" || encStatus.TargetKey.AESCBC.DataHash == "" || encStatus.ActiveKey.AESCBC.DataHash == "" {
+ // No rotation in progress or provider mismatch: spec.activeKey is the sole write key.
+ writeKeyData, err := fetchAESCBCKeyData(cpContext, secretEncryption.AESCBC.ActiveKey.Name)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get aescbc active key: %w", err)
+ }
+ return generateAESCBCEncryptionConfig(writeKeyData, nil)
+ }
+
+ // Rotation in progress. Fetch both keys.
+ targetSecretName := encStatus.TargetKey.AESCBC.Secret.Name
+ oldSecretName := encStatus.ActiveKey.AESCBC.Secret.Name
+ targetKeyData, err := fetchAESCBCKeyData(cpContext, targetSecretName)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get aescbc target key secret %q: %w", targetSecretName, err)
+ }
+ oldKeyData, err := fetchAESCBCKeyData(cpContext, oldSecretName)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get aescbc old key secret %q: %w", oldSecretName, err)
+ }
+
+ // Determine stage from current EncryptionConfiguration.
+ targetKeyName, err := AESCBCKeyName(targetKeyData)
+ if err != nil {
+ return nil, fmt.Errorf("failed to compute aescbc target key name: %w", err)
+ }
+ if secretencryption.ShouldPromoteTargetKey(currentConfig, targetKeyName, hyperv1.AESCBC, kasConverged) {
+ return generateAESCBCEncryptionConfig(targetKeyData, oldKeyData)
+ }
+ // ReadOnlyDeploy: old key writes, target key reads.
+ return generateAESCBCEncryptionConfig(oldKeyData, targetKeyData)
+}
+
+// fetchAESCBCKeyData retrieves the AESCBC key data from a named secret.
+func fetchAESCBCKeyData(cpContext component.WorkloadContext, secretName string) ([]byte, error) {
+ keySecret := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: secretName,
+ Namespace: cpContext.HCP.Namespace,
+ },
+ }
+ if err := cpContext.Client.Get(cpContext, client.ObjectKeyFromObject(keySecret), keySecret); err != nil {
+ return nil, err
+ }
+ keyData, ok := keySecret.Data[hyperv1.AESCBCKeySecretKey]
+ if !ok {
+ return nil, fmt.Errorf("aescbc key field %q not found in secret %q", hyperv1.AESCBCKeySecretKey, secretName)
+ }
+ return keyData, nil
+}
- // Only look at write keys to return the APIVersion currently used.
+// getKMSAPIVersion extracts the KMS API version from the current EncryptionConfiguration.
+// Returns "v2" as default if no config exists or no KMS provider is configured.
+func getKMSAPIVersion(currentConfig *apiserverv1.EncryptionConfiguration) string {
+ if currentConfig != nil {
for _, r := range currentConfig.Resources {
if len(r.Providers) > 0 && r.Providers[0].KMS != nil {
- return r.Providers[0].KMS.APIVersion, nil
+ return r.Providers[0].KMS.APIVersion
}
}
}
- return apiVersion, nil
+ return "v2"
}
func buildVolumeSecretEncryptionConfigFile() corev1.Volume {
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption_test.go
index 7f9d658ded65..a3037fe631e0 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/secretencryption_test.go
@@ -3,6 +3,7 @@ package kas
import (
"bytes"
"context"
+ "encoding/base64"
"fmt"
"testing"
"time"
@@ -15,6 +16,7 @@ import (
controlplanecomponent "github.com/openshift/hypershift/support/controlplane-component"
"github.com/openshift/hypershift/support/util"
+ appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
@@ -113,7 +115,25 @@ func TestReconcileKMSEncryptionConfigAWS(t *testing.T) {
Data: make(map[string][]byte),
}
- clientBuilder := fake.NewClientBuilder().WithScheme(api.Scheme)
+ kasDeployment := &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "kube-apiserver",
+ Generation: 1,
+ },
+ Spec: appsv1.DeploymentSpec{
+ Replicas: ptr.To[int32](1),
+ },
+ Status: appsv1.DeploymentStatus{
+ ObservedGeneration: 1,
+ Replicas: 1,
+ UpdatedReplicas: 1,
+ ReadyReplicas: 1,
+ AvailableReplicas: 1,
+ UnavailableReplicas: 0,
+ },
+ }
+
+ clientBuilder := fake.NewClientBuilder().WithScheme(api.Scheme).WithObjects(kasDeployment)
if tc.config != nil {
buff := bytes.NewBuffer([]byte{})
err := api.YamlSerializer.Encode(tc.config, buff)
@@ -501,3 +521,301 @@ func generateExpectedEncryptionConfig(apiVersion string) *v1.EncryptionConfigura
return config
}
+
+func TestDeriveAESCBCEncryptionConfig(t *testing.T) {
+ t.Parallel()
+
+ const testNamespace = "test-namespace"
+
+ newAESCBCKeySecret := func(name string, keyData []byte) *corev1.Secret {
+ return &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: testNamespace},
+ Data: map[string][]byte{hyperv1.AESCBCKeySecretKey: keyData},
+ }
+ }
+
+ convergedKASDeployment := func() *appsv1.Deployment {
+ return &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "kube-apiserver",
+ Namespace: testNamespace,
+ Generation: 1,
+ },
+ Spec: appsv1.DeploymentSpec{
+ Replicas: ptr.To[int32](1),
+ },
+ Status: appsv1.DeploymentStatus{
+ ObservedGeneration: 1,
+ Replicas: 1,
+ UpdatedReplicas: 1,
+ ReadyReplicas: 1,
+ AvailableReplicas: 1,
+ UnavailableReplicas: 0,
+ },
+ }
+ }
+
+ decodeEncryptionConfig := func(g Gomega, data []byte) *v1.EncryptionConfiguration {
+ cfg := &v1.EncryptionConfiguration{}
+ gvks, _, err := api.Scheme.ObjectKinds(cfg)
+ g.Expect(err).NotTo(HaveOccurred())
+ g.Expect(gvks).NotTo(BeEmpty())
+ _, _, err = api.YamlSerializer.Decode(data, &gvks[0], cfg)
+ g.Expect(err).NotTo(HaveOccurred())
+ return cfg
+ }
+
+ testCases := []struct {
+ name string
+ secretObjects []*corev1.Secret
+ secretSpec *hyperv1.SecretEncryptionSpec
+ encStatus *hyperv1.SecretEncryptionStatus
+ currentConfig *v1.EncryptionConfiguration
+ kasConverged bool
+ verify func(g Gomega, data []byte)
+ }{
+ {
+ name: "When status has no active key it should use spec active key as write key",
+ secretObjects: []*corev1.Secret{
+ newAESCBCKeySecret("aescbc-key-1", []byte("active-key-data")),
+ },
+ secretSpec: &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "aescbc-key-1"},
+ },
+ },
+ encStatus: nil,
+ verify: func(g Gomega, data []byte) {
+ cfg := decodeEncryptionConfig(g, data)
+ g.Expect(cfg.Resources).To(HaveLen(1))
+ providers := cfg.Resources[0].Providers
+ g.Expect(providers).To(HaveLen(2))
+ g.Expect(providers[0].AESCBC).NotTo(BeNil())
+ g.Expect(providers[0].AESCBC.Keys).To(HaveLen(1))
+
+ expectedName, err := AESCBCKeyName([]byte("active-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+ g.Expect(providers[0].AESCBC.Keys[0].Name).To(Equal(expectedName))
+ g.Expect(providers[0].AESCBC.Keys[0].Secret).To(Equal(base64.StdEncoding.EncodeToString([]byte("active-key-data"))))
+
+ g.Expect(providers[1].Identity).NotTo(BeNil())
+ },
+ },
+ {
+ name: "When status has no active key and backup key is set it should use both keys",
+ secretObjects: []*corev1.Secret{
+ newAESCBCKeySecret("aescbc-key-1", []byte("active-key-data")),
+ newAESCBCKeySecret("aescbc-backup", []byte("backup-key-data")),
+ },
+ secretSpec: &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "aescbc-key-1"},
+ BackupKey: &corev1.LocalObjectReference{Name: "aescbc-backup"},
+ },
+ },
+ encStatus: nil,
+ verify: func(g Gomega, data []byte) {
+ cfg := decodeEncryptionConfig(g, data)
+ g.Expect(cfg.Resources).To(HaveLen(1))
+ providers := cfg.Resources[0].Providers
+ g.Expect(providers).To(HaveLen(2))
+ g.Expect(providers[0].AESCBC).NotTo(BeNil())
+ g.Expect(providers[0].AESCBC.Keys).To(HaveLen(2))
+
+ activeKeyName, err := AESCBCKeyName([]byte("active-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+ backupKeyName, err := AESCBCKeyName([]byte("backup-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+
+ g.Expect(providers[0].AESCBC.Keys[0].Name).To(Equal(activeKeyName))
+ g.Expect(providers[0].AESCBC.Keys[1].Name).To(Equal(backupKeyName))
+ },
+ },
+ {
+ name: "When no rotation in progress it should use spec active key only",
+ secretObjects: []*corev1.Secret{
+ newAESCBCKeySecret("aescbc-key-1", []byte("active-key-data")),
+ },
+ secretSpec: &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "aescbc-key-1"},
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAESCBC,
+ AESCBC: hyperv1.AESCBCKeyStatus{
+ Secret: corev1.LocalObjectReference{Name: "aescbc-key-1"},
+ DataHash: "activehash",
+ },
+ },
+ },
+ verify: func(g Gomega, data []byte) {
+ cfg := decodeEncryptionConfig(g, data)
+ g.Expect(cfg.Resources).To(HaveLen(1))
+ providers := cfg.Resources[0].Providers
+ g.Expect(providers).To(HaveLen(2))
+ g.Expect(providers[0].AESCBC).NotTo(BeNil())
+ g.Expect(providers[0].AESCBC.Keys).To(HaveLen(1))
+
+ expectedName, err := AESCBCKeyName([]byte("active-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+ g.Expect(providers[0].AESCBC.Keys[0].Name).To(Equal(expectedName))
+ },
+ },
+ {
+ name: "When rotation in progress and target key is read-only it should keep old key as write",
+ secretObjects: []*corev1.Secret{
+ newAESCBCKeySecret("old-key-secret", []byte("old-key-data")),
+ newAESCBCKeySecret("new-key-secret", []byte("new-key-data")),
+ },
+ secretSpec: &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "new-key-secret"},
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAESCBC,
+ AESCBC: hyperv1.AESCBCKeyStatus{
+ Secret: corev1.LocalObjectReference{Name: "old-key-secret"},
+ DataHash: "oldhash",
+ },
+ },
+ TargetKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAESCBC,
+ AESCBC: hyperv1.AESCBCKeyStatus{
+ Secret: corev1.LocalObjectReference{Name: "new-key-secret"},
+ DataHash: "newhash",
+ },
+ },
+ },
+ currentConfig: func() *v1.EncryptionConfiguration {
+ oldKeyName, _ := AESCBCKeyName([]byte("old-key-data"))
+ targetKeyName, _ := AESCBCKeyName([]byte("new-key-data"))
+ return &v1.EncryptionConfiguration{
+ Resources: []v1.ResourceConfiguration{{
+ Providers: []v1.ProviderConfiguration{
+ {AESCBC: &v1.AESConfiguration{Keys: []v1.Key{
+ {Name: oldKeyName, Secret: base64.StdEncoding.EncodeToString([]byte("old-key-data"))},
+ {Name: targetKeyName, Secret: base64.StdEncoding.EncodeToString([]byte("new-key-data"))},
+ }}},
+ {Identity: &v1.IdentityConfiguration{}},
+ },
+ }},
+ }
+ }(),
+ kasConverged: false,
+ verify: func(g Gomega, data []byte) {
+ cfg := decodeEncryptionConfig(g, data)
+ g.Expect(cfg.Resources).To(HaveLen(1))
+ providers := cfg.Resources[0].Providers
+ g.Expect(providers[0].AESCBC).NotTo(BeNil())
+ g.Expect(providers[0].AESCBC.Keys).To(HaveLen(2))
+
+ oldKeyName, err := AESCBCKeyName([]byte("old-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+ targetKeyName, err := AESCBCKeyName([]byte("new-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+
+ g.Expect(providers[0].AESCBC.Keys[0].Name).To(Equal(oldKeyName), "old key should remain the write key")
+ g.Expect(providers[0].AESCBC.Keys[1].Name).To(Equal(targetKeyName), "target key should be read-only")
+ },
+ },
+ {
+ name: "When rotation in progress and target key should be promoted it should swap keys",
+ secretObjects: []*corev1.Secret{
+ newAESCBCKeySecret("old-key-secret", []byte("old-key-data")),
+ newAESCBCKeySecret("new-key-secret", []byte("new-key-data")),
+ },
+ secretSpec: &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "new-key-secret"},
+ },
+ },
+ encStatus: &hyperv1.SecretEncryptionStatus{
+ ActiveKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAESCBC,
+ AESCBC: hyperv1.AESCBCKeyStatus{
+ Secret: corev1.LocalObjectReference{Name: "old-key-secret"},
+ DataHash: "oldhash",
+ },
+ },
+ TargetKey: hyperv1.SecretEncryptionKeyStatus{
+ Provider: hyperv1.SecretEncryptionProviderAESCBC,
+ AESCBC: hyperv1.AESCBCKeyStatus{
+ Secret: corev1.LocalObjectReference{Name: "new-key-secret"},
+ DataHash: "newhash",
+ },
+ },
+ },
+ currentConfig: func() *v1.EncryptionConfiguration {
+ oldKeyName, _ := AESCBCKeyName([]byte("old-key-data"))
+ targetKeyName, _ := AESCBCKeyName([]byte("new-key-data"))
+ return &v1.EncryptionConfiguration{
+ Resources: []v1.ResourceConfiguration{{
+ Providers: []v1.ProviderConfiguration{
+ {AESCBC: &v1.AESConfiguration{Keys: []v1.Key{
+ {Name: oldKeyName, Secret: base64.StdEncoding.EncodeToString([]byte("old-key-data"))},
+ {Name: targetKeyName, Secret: base64.StdEncoding.EncodeToString([]byte("new-key-data"))},
+ }}},
+ {Identity: &v1.IdentityConfiguration{}},
+ },
+ }},
+ }
+ }(),
+ kasConverged: true,
+ verify: func(g Gomega, data []byte) {
+ cfg := decodeEncryptionConfig(g, data)
+ g.Expect(cfg.Resources).To(HaveLen(1))
+ providers := cfg.Resources[0].Providers
+ g.Expect(providers[0].AESCBC).NotTo(BeNil())
+ g.Expect(providers[0].AESCBC.Keys).To(HaveLen(2))
+
+ oldKeyName, err := AESCBCKeyName([]byte("old-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+ targetKeyName, err := AESCBCKeyName([]byte("new-key-data"))
+ g.Expect(err).NotTo(HaveOccurred())
+
+ g.Expect(providers[0].AESCBC.Keys[0].Name).To(Equal(targetKeyName), "target key should be promoted to write key")
+ g.Expect(providers[0].AESCBC.Keys[1].Name).To(Equal(oldKeyName), "old key should become read-only")
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ g := NewWithT(t)
+
+ kasDeployment := convergedKASDeployment()
+ clientBuilder := fake.NewClientBuilder().WithScheme(api.Scheme).WithObjects(kasDeployment)
+ for _, s := range tc.secretObjects {
+ clientBuilder.WithObjects(s)
+ }
+
+ cpContext := controlplanecomponent.WorkloadContext{
+ HCP: &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: testNamespace,
+ },
+ Spec: hyperv1.HostedControlPlaneSpec{
+ SecretEncryption: tc.secretSpec,
+ },
+ },
+ Client: clientBuilder.Build(),
+ }
+
+ data, err := deriveAESCBCEncryptionConfig(cpContext, tc.secretSpec, tc.encStatus, tc.currentConfig, tc.kasConverged)
+ g.Expect(err).NotTo(HaveOccurred())
+ g.Expect(data).NotTo(BeEmpty())
+
+ tc.verify(g, data)
+ })
+ }
+}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kube_storage_version_migrator/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kube_storage_version_migrator/component.go
new file mode 100644
index 000000000000..4357e2b4aca2
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kube_storage_version_migrator/component.go
@@ -0,0 +1,43 @@
+package kubestorageversionmigrator
+
+import (
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ component "github.com/openshift/hypershift/support/controlplane-component"
+)
+
+const (
+ ComponentName = "kube-storage-version-migrator"
+)
+
+var _ component.ComponentOptions = &migratorOptions{}
+
+type migratorOptions struct{}
+
+// IsRequestServing implements controlplanecomponent.ComponentOptions.
+func (o *migratorOptions) IsRequestServing() bool {
+ return false
+}
+
+// MultiZoneSpread implements controlplanecomponent.ComponentOptions.
+func (o *migratorOptions) MultiZoneSpread() bool {
+ return false
+}
+
+// NeedsManagementKASAccess implements controlplanecomponent.ComponentOptions.
+func (o *migratorOptions) NeedsManagementKASAccess() bool {
+ return false
+}
+
+func NewComponent() component.ControlPlaneComponent {
+ return component.NewDeploymentComponent(ComponentName, &migratorOptions{}).
+ WithPredicate(predicate).
+ Build()
+}
+
+func predicate(cpContext component.WorkloadContext) (bool, error) {
+ p := cpContext.HCP.Spec.Platform.Type
+ if p == hyperv1.IBMCloudPlatform || p == hyperv1.PowerVSPlatform {
+ return false, nil
+ }
+ return cpContext.HCP.Spec.SecretEncryption != nil, nil
+}
From a9e3944ff9bca6bd2a1782a4d7652fb4e586de89 Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 13:52:35 +0200
Subject: [PATCH 05/12] feat(control-plane-operator): add HCCO re-encryption
controller
Add re-encryption controller to the HCCO that drives the key rotation
lifecycle by deriving the current phase from observable state:
- Detect key changes by comparing spec vs status fingerprints
- Derive phase from EncryptionConfiguration contents and KAS convergence
- Create StorageVersionMigration CRs via KubeStorageVersionMigrator
- Manage targetKey, activeKey, and history in HCP status
- Set EtcdDataEncryptionUpToDate condition with phase-specific reasons
- Expose Prometheus metrics for rotation state, duration, and failures
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
.../hostedclusterconfigoperator/cmd.go | 2 +
.../controllers/reencryption/metrics.go | 72 ++
.../controllers/reencryption/reencryption.go | 532 ++++++++++
.../reencryption/reencryption_test.go | 957 ++++++++++++++++++
.../controllers/reencryption/setup.go | 104 ++
5 files changed, 1667 insertions(+)
create mode 100644 control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/metrics.go
create mode 100644 control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption.go
create mode 100644 control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go
create mode 100644 control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/setup.go
diff --git a/control-plane-operator/hostedclusterconfigoperator/cmd.go b/control-plane-operator/hostedclusterconfigoperator/cmd.go
index 797f8973fcfe..29d8189ffd1b 100644
--- a/control-plane-operator/hostedclusterconfigoperator/cmd.go
+++ b/control-plane-operator/hostedclusterconfigoperator/cmd.go
@@ -29,6 +29,7 @@ import (
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/machine"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/node"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/nodecount"
+ "github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation"
"github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/operator"
@@ -72,6 +73,7 @@ var controllerFuncs = map[string]operator.ControllerSetupFunc{
"drainer": drainer.Setup,
hcpstatus.ControllerName: hcpstatus.Setup,
spotremediation.ControllerName: spotremediation.Setup,
+ reencryption.ControllerName: reencryption.Setup,
}
type HostedClusterConfigOperator struct {
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/metrics.go b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/metrics.go
new file mode 100644
index 000000000000..0a51602ba639
--- /dev/null
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/metrics.go
@@ -0,0 +1,72 @@
+package reencryption
+
+import (
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+
+ "sigs.k8s.io/controller-runtime/pkg/metrics"
+
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+var (
+ migrationStateGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{
+ Name: "hypershift_encryption_migration_state",
+ Help: "Current rotation state per hosted cluster. Label 'state' maps to history[0].state or 'idle' when no rotation is in progress.",
+ }, []string{"namespace", "name", "state"})
+
+ migrationDurationHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{
+ Name: "hypershift_encryption_migration_duration_seconds",
+ Help: "Duration of completed rotations from startedTime to completionTime.",
+ Buckets: prometheus.ExponentialBuckets(30, 2, 10),
+ }, []string{"namespace", "name"})
+
+ migrationFailuresCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
+ Name: "hypershift_encryption_migration_failures_total",
+ Help: "Total StorageVersionMigration CR failures per hosted cluster.",
+ }, []string{"namespace", "name"})
+)
+
+func init() {
+ metrics.Registry.MustRegister(migrationStateGauge, migrationDurationHistogram, migrationFailuresCounter)
+}
+
+var allStates = []string{
+ string(hyperv1.EncryptionMigrationStateReadOnlyDeploy),
+ string(hyperv1.EncryptionMigrationStateWritePromote),
+ string(hyperv1.EncryptionMigrationStateMigrating),
+ string(hyperv1.EncryptionMigrationStateCompleted),
+ string(hyperv1.EncryptionMigrationStateInterrupted),
+ "idle",
+}
+
+func recordMigrationState(namespace, name string, status hyperv1.SecretEncryptionStatus) {
+ state := "idle"
+ if len(status.History) > 0 {
+ h := status.History[0]
+ if h.State != hyperv1.EncryptionMigrationStateCompleted && h.State != hyperv1.EncryptionMigrationStateInterrupted {
+ state = string(h.State)
+ }
+ }
+ for _, s := range allStates {
+ val := float64(0)
+ if s == state {
+ val = 1
+ }
+ migrationStateGauge.WithLabelValues(namespace, name, s).Set(val)
+ }
+}
+
+func recordMigrationDuration(namespace, name string, status hyperv1.SecretEncryptionStatus) {
+ if len(status.History) == 0 {
+ return
+ }
+ h := status.History[0]
+ if h.State == hyperv1.EncryptionMigrationStateCompleted && h.CompletionTime != nil {
+ duration := h.CompletionTime.Sub(h.StartedTime.Time).Seconds()
+ migrationDurationHistogram.WithLabelValues(namespace, name).Observe(duration)
+ }
+}
+
+func recordMigrationFailure(namespace, name string) {
+ migrationFailuresCounter.WithLabelValues(namespace, name).Inc()
+}
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption.go b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption.go
new file mode 100644
index 000000000000..f1cdfbb3c2cf
--- /dev/null
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption.go
@@ -0,0 +1,532 @@
+// Package reencryption implements the HCCO re-encryption controller that
+// manages etcd data re-encryption after encryption key rotation.
+package reencryption
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests"
+ kasaescbc "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kas"
+ "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms"
+ "github.com/openshift/hypershift/support/config"
+ "github.com/openshift/hypershift/support/podspec"
+ "github.com/openshift/hypershift/support/secretencryption"
+
+ "github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators"
+
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/equality"
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/types"
+
+ ctrl "sigs.k8s.io/controller-runtime"
+ crclient "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+
+ "github.com/go-logr/logr"
+)
+
+const (
+ // maxHistoryEntries is the maximum number of entries kept in the rotation history.
+ maxHistoryEntries = 5
+)
+
+// Reconciler watches for encryption key changes on the HCP spec and drives the
+// multi-phase key rotation lifecycle: ReadOnlyDeploy -> WritePromote -> Migrating -> Completed.
+type Reconciler struct {
+ cpClient crclient.Client
+ guestClient crclient.Client
+ hcpName string
+ hcpNamespace string
+ migrator migrators.Migrator
+ now func() time.Time
+}
+
+func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
+ log := ctrl.LoggerFrom(ctx)
+
+ hcp := &hyperv1.HostedControlPlane{}
+ if err := r.cpClient.Get(ctx, types.NamespacedName{Namespace: r.hcpNamespace, Name: r.hcpName}, hcp); err != nil {
+ return reconcile.Result{}, fmt.Errorf("failed to get HCP: %w", err)
+ }
+
+ originalHCP := hcp.DeepCopy()
+ result, err := r.reconcile(ctx, log, hcp)
+ if err != nil {
+ return result, err
+ }
+
+ if !equality.Semantic.DeepEqual(hcp.Status, originalHCP.Status) {
+ log.Info("Patching HCP status with secret encryption changes")
+ patch := crclient.MergeFrom(originalHCP)
+ if err := r.cpClient.Status().Patch(ctx, hcp, patch); err != nil {
+ return reconcile.Result{}, fmt.Errorf("failed to patch HCP status: %w", err)
+ }
+ log.Info("Successfully patched HCP status")
+ recordMigrationState(r.hcpNamespace, r.hcpName, hcp.Status.SecretEncryption)
+ recordMigrationDuration(r.hcpNamespace, r.hcpName, hcp.Status.SecretEncryption)
+ }
+
+ return result, nil
+}
+
+func (r *Reconciler) reconcile(ctx context.Context, log logr.Logger, hcp *hyperv1.HostedControlPlane) (reconcile.Result, error) {
+ // If encryption is not configured, ensure status is clean.
+ if hcp.Spec.SecretEncryption == nil {
+ return r.handleEncryptionNotConfigured(hcp)
+ }
+
+ // Compute the spec fingerprint from the current spec.
+ specKeyStatus, err := r.keyStatusFromSpec(ctx, hcp)
+ if err != nil {
+ return reconcile.Result{}, fmt.Errorf("failed to compute key status from spec: %w", err)
+ }
+ if specKeyStatus == nil {
+ log.Info("Secret encryption configured but key status could not be derived, skipping")
+ return reconcile.Result{}, nil
+ }
+
+ specFingerprint := secretencryption.FingerprintFromKeyStatus(specKeyStatus)
+
+ statusActiveFingerprint := secretencryption.FingerprintFromKeyStatus(&hcp.Status.SecretEncryption.ActiveKey)
+
+ // Case 1: Status has no active key (first-time setup or upgrade bootstrap).
+ if hcp.Status.SecretEncryption.ActiveKey.Provider == "" {
+ return r.handleInitialBootstrap(log, hcp, specKeyStatus)
+ }
+
+ // Case 2: A rotation is already in progress (targetKey is set).
+ if hcp.Status.SecretEncryption.TargetKey.Provider != "" {
+ return r.handleInProgressRotation(ctx, log, hcp, specKeyStatus, specFingerprint)
+ }
+
+ // Case 3: No rotation in progress and spec matches status -> steady state.
+ if specFingerprint == statusActiveFingerprint {
+ log.V(2).Info("Encryption key is up to date, no rotation needed")
+ return reconcile.Result{}, nil
+ }
+
+ // Case 4: Spec key differs from status active key -> start new rotation.
+ return r.startNewRotation(log, hcp, specKeyStatus, specFingerprint, statusActiveFingerprint)
+}
+
+// handleEncryptionNotConfigured clears the targetKey and removes the EtcdDataEncryptionUpToDate condition.
+func (r *Reconciler) handleEncryptionNotConfigured(hcp *hyperv1.HostedControlPlane) (reconcile.Result, error) {
+ hcp.Status.SecretEncryption.TargetKey = hyperv1.SecretEncryptionKeyStatus{}
+ meta.RemoveStatusCondition(&hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ return reconcile.Result{}, nil
+}
+
+// handleInitialBootstrap sets the initial active key from the spec without starting a rotation.
+func (r *Reconciler) handleInitialBootstrap(log logr.Logger, hcp *hyperv1.HostedControlPlane, specKeyStatus *hyperv1.SecretEncryptionKeyStatus) (reconcile.Result, error) {
+ log.Info("Initializing secret encryption status with active key from spec")
+ hcp.Status.SecretEncryption.ActiveKey = *specKeyStatus.DeepCopy()
+
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionTrue,
+ Reason: hyperv1.ReEncryptionCompletedReason,
+ Message: "Encryption key initialized",
+ ObservedGeneration: hcp.Generation,
+ })
+ return reconcile.Result{}, nil
+}
+
+// startNewRotation sets the targetKey and creates a history entry for a new rotation.
+func (r *Reconciler) startNewRotation(log logr.Logger, hcp *hyperv1.HostedControlPlane, specKeyStatus *hyperv1.SecretEncryptionKeyStatus, specFingerprint, statusActiveFingerprint string) (reconcile.Result, error) {
+ log.Info("Encryption key changed, starting new rotation",
+ "specFingerprint", specFingerprint,
+ "statusActiveFingerprint", statusActiveFingerprint)
+
+ hcp.Status.SecretEncryption.TargetKey = *specKeyStatus.DeepCopy()
+
+ fromRef := secretencryption.KeyReferenceFromStatus(&hcp.Status.SecretEncryption.ActiveKey)
+ toRef := secretencryption.KeyReferenceFromStatus(specKeyStatus)
+
+ entry := hyperv1.EncryptionMigrationHistory{
+ From: fromRef,
+ To: toRef,
+ State: hyperv1.EncryptionMigrationStateReadOnlyDeploy,
+ StartedTime: metav1.Time{Time: r.now()},
+ }
+
+ // Prepend new entry and trim history.
+ hcp.Status.SecretEncryption.History = prependHistory(hcp.Status.SecretEncryption.History, entry)
+
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.ReadOnlyRolloutInProgressReason,
+ Message: "Encryption key rotation started: deploying new key as read-only",
+ ObservedGeneration: hcp.Generation,
+ })
+
+ return reconcile.Result{}, nil
+}
+
+// handleInProgressRotation derives the current phase from observable state and acts accordingly.
+// It inspects the EncryptionConfiguration and KAS Deployment convergence rather than
+// reading history[0].state. The history state is updated for observability only.
+func (r *Reconciler) handleInProgressRotation(ctx context.Context, log logr.Logger, hcp *hyperv1.HostedControlPlane, _ *hyperv1.SecretEncryptionKeyStatus, specFingerprint string) (reconcile.Result, error) {
+ targetFingerprint := secretencryption.FingerprintFromKeyStatus(&hcp.Status.SecretEncryption.TargetKey)
+
+ if specFingerprint != targetFingerprint {
+ log.Info("Spec key differs from target key during rotation, current rotation will complete first",
+ "specFingerprint", specFingerprint,
+ "targetFingerprint", targetFingerprint)
+ }
+
+ if len(hcp.Status.SecretEncryption.History) == 0 {
+ log.Info("Target key set but no history entry found, creating one")
+ fromRef := secretencryption.KeyReferenceFromStatus(&hcp.Status.SecretEncryption.ActiveKey)
+ toRef := secretencryption.KeyReferenceFromStatus(&hcp.Status.SecretEncryption.TargetKey)
+ entry := hyperv1.EncryptionMigrationHistory{
+ From: fromRef,
+ To: toRef,
+ State: hyperv1.EncryptionMigrationStateReadOnlyDeploy,
+ StartedTime: metav1.Time{Time: r.now()},
+ }
+ hcp.Status.SecretEncryption.History = prependHistory(hcp.Status.SecretEncryption.History, entry)
+ }
+
+ // Derive the current phase from observable state.
+ role, err := r.deriveTargetKeyRole(ctx, hcp)
+ if err != nil {
+ return reconcile.Result{}, fmt.Errorf("failed to derive target key role from EncryptionConfiguration: %w", err)
+ }
+
+ converged, err := r.isKASConverged(ctx, log, hcp)
+ if err != nil {
+ return reconcile.Result{}, fmt.Errorf("failed to check KAS convergence: %w", err)
+ }
+
+ switch {
+ case role == secretencryption.TargetKeyAbsent:
+ // Target key not yet in EncryptionConfiguration — CPO hasn't generated the new config yet.
+ log.Info("Target key not yet in EncryptionConfiguration, waiting for CPO")
+ r.setHistoryState(hcp, hyperv1.EncryptionMigrationStateReadOnlyDeploy)
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.ReadOnlyRolloutInProgressReason,
+ Message: "Waiting for new encryption key to be added to EncryptionConfiguration",
+ ObservedGeneration: hcp.Generation,
+ })
+ return reconcile.Result{RequeueAfter: 30 * time.Second}, nil
+
+ case role == secretencryption.TargetKeyReadOnly && !converged:
+ // Target key is read-only but KAS hasn't fully rolled out with it.
+ log.Info("Target key is read-only in config, waiting for KAS convergence")
+ r.setHistoryState(hcp, hyperv1.EncryptionMigrationStateReadOnlyDeploy)
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.ReEncryptionWaitingForKASReason,
+ Message: "Waiting for KAS to converge with new encryption key in read-only mode",
+ ObservedGeneration: hcp.Generation,
+ })
+ return reconcile.Result{RequeueAfter: 30 * time.Second}, nil
+
+ case role == secretencryption.TargetKeyReadOnly && converged:
+ // KAS converged with target key as read-only — ready for write promotion.
+ log.Info("KAS converged with read-only key, ready for write promotion")
+ r.setHistoryState(hcp, hyperv1.EncryptionMigrationStateWritePromote)
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.WritePromotionInProgressReason,
+ Message: "Promoting new encryption key to write provider",
+ ObservedGeneration: hcp.Generation,
+ })
+ return reconcile.Result{}, nil
+
+ case role == secretencryption.TargetKeyWrite && !converged:
+ // Target key is the write provider but KAS hasn't converged with it.
+ log.Info("Target key is write provider, waiting for KAS convergence")
+ r.setHistoryState(hcp, hyperv1.EncryptionMigrationStateWritePromote)
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.ReEncryptionWaitingForKASReason,
+ Message: "Waiting for KAS to converge with new encryption key as write provider",
+ ObservedGeneration: hcp.Generation,
+ })
+ return reconcile.Result{RequeueAfter: 30 * time.Second}, nil
+
+ case role == secretencryption.TargetKeyWrite && converged:
+ // Target key is write provider and KAS converged — run migrations.
+ log.Info("KAS converged with target key as write provider, running migrations")
+ r.setHistoryState(hcp, hyperv1.EncryptionMigrationStateMigrating)
+ return r.handleMigratingPhase(ctx, log, hcp)
+
+ default:
+ return reconcile.Result{}, nil
+ }
+}
+
+// deriveTargetKeyRole reads the kas-secret-encryption-config Secret, parses the
+// EncryptionConfiguration, and determines where the target key appears.
+func (r *Reconciler) deriveTargetKeyRole(ctx context.Context, hcp *hyperv1.HostedControlPlane) (secretencryption.TargetKeyRole, error) {
+ secret := &corev1.Secret{}
+ secretKey := crclient.ObjectKey{
+ Namespace: hcp.Namespace,
+ Name: manifests.KASSecretEncryptionConfigFile("").Name,
+ }
+ if err := r.cpClient.Get(ctx, secretKey, secret); err != nil {
+ return secretencryption.TargetKeyAbsent, fmt.Errorf("failed to get encryption config secret: %w", err)
+ }
+
+ configBytes := secret.Data[secretencryption.EncryptionConfigurationKey]
+ if len(configBytes) == 0 {
+ return secretencryption.TargetKeyAbsent, nil
+ }
+
+ currentConfig, err := secretencryption.DecodeEncryptionConfiguration(configBytes)
+ if err != nil {
+ return secretencryption.TargetKeyAbsent, err
+ }
+
+ targetName, err := r.computeTargetKeyProviderName(ctx, hcp)
+ if err != nil {
+ return secretencryption.TargetKeyAbsent, fmt.Errorf("failed to compute target key provider name: %w", err)
+ }
+
+ return secretencryption.FindKeyRole(currentConfig, targetName, hcp.Spec.SecretEncryption.Type), nil
+}
+
+// computeTargetKeyProviderName computes the provider name that the CPO would
+// generate for the target key in the EncryptionConfiguration. It reuses the
+// same functions the CPO uses to ensure the names always match.
+func (r *Reconciler) computeTargetKeyProviderName(ctx context.Context, hcp *hyperv1.HostedControlPlane) (string, error) {
+ tk := hcp.Status.SecretEncryption.TargetKey
+ if tk.Provider == "" {
+ return "", fmt.Errorf("no target key set")
+ }
+
+ switch tk.Provider {
+ case hyperv1.SecretEncryptionProviderAzure:
+ if tk.Azure.KeyVaultName == "" {
+ return "", fmt.Errorf("azure target key status is nil")
+ }
+ return kms.AzureKMSProviderName(hyperv1.AzureKMSKey{
+ KeyVaultName: tk.Azure.KeyVaultName,
+ KeyName: tk.Azure.KeyName,
+ KeyVersion: tk.Azure.KeyVersion,
+ })
+
+ case hyperv1.SecretEncryptionProviderAWS:
+ if tk.AWS.ARN == "" {
+ return "", fmt.Errorf("aws target key status is nil")
+ }
+ return kms.AWSKMSProviderName(tk.AWS.ARN)
+
+ case hyperv1.SecretEncryptionProviderIBMCloud:
+ // IBM Cloud uses a single KMS provider with a fixed name; the sidecar
+ // handles key versioning internally via KP_DATA_JSON.
+ return kms.IBMCloudKMSProviderName(), nil
+
+ case hyperv1.SecretEncryptionProviderAESCBC:
+ if tk.AESCBC.DataHash == "" {
+ return "", fmt.Errorf("aescbc target key status is nil")
+ }
+ secret := &corev1.Secret{}
+ if err := r.cpClient.Get(ctx, types.NamespacedName{
+ Namespace: hcp.Namespace,
+ Name: tk.AESCBC.Secret.Name,
+ }, secret); err != nil {
+ return "", fmt.Errorf("failed to get AESCBC target key secret: %w", err)
+ }
+ return kasaescbc.AESCBCKeyName(secret.Data[hyperv1.AESCBCKeySecretKey])
+
+ default:
+ return "", fmt.Errorf("unsupported provider: %s", tk.Provider)
+ }
+}
+
+// setHistoryState updates history[0].state for observability. This value is
+// never used as input for phase derivation.
+func (r *Reconciler) setHistoryState(hcp *hyperv1.HostedControlPlane, state hyperv1.EncryptionMigrationState) {
+ if len(hcp.Status.SecretEncryption.History) > 0 {
+ hcp.Status.SecretEncryption.History[0].State = state
+ }
+}
+
+// handleMigratingPhase creates/monitors StorageVersionMigration CRs for each encrypted resource.
+func (r *Reconciler) handleMigratingPhase(_ context.Context, log logr.Logger, hcp *hyperv1.HostedControlPlane) (reconcile.Result, error) {
+ if !r.migrator.HasSynced() {
+ log.Info("Migrator cache not yet synced, requeuing")
+ return reconcile.Result{RequeueAfter: 10 * time.Second}, nil
+ }
+
+ resources := r.encryptedResources(hcp)
+ targetFingerprint := secretencryption.FingerprintFromKeyStatus(&hcp.Status.SecretEncryption.TargetKey)
+ writeKey := fmt.Sprintf("encryption-key-%s", targetFingerprint)
+
+ allFinished := true
+ var migrationErrors []string
+
+ for _, gr := range resources {
+ finished, result, _, err := r.migrator.EnsureMigration(gr, writeKey)
+ if err != nil {
+ return reconcile.Result{}, fmt.Errorf("failed to ensure migration for %s: %w", gr, err)
+ }
+ if !finished {
+ allFinished = false
+ continue
+ }
+ if result != nil {
+ migrationErrors = append(migrationErrors, fmt.Sprintf("%s: %v", gr, result))
+ }
+ }
+
+ if len(migrationErrors) > 0 {
+ errMsg := strings.Join(migrationErrors, "; ")
+ log.Info("StorageVersionMigration encountered errors", "errors", errMsg)
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.ReEncryptionFailedReason,
+ Message: fmt.Sprintf("Re-encryption failed for some resources: %s", errMsg),
+ ObservedGeneration: hcp.Generation,
+ })
+ recordMigrationFailure(r.hcpNamespace, r.hcpName)
+ return reconcile.Result{RequeueAfter: 60 * time.Second}, nil
+ }
+
+ if !allFinished {
+ log.Info("StorageVersionMigrations still in progress")
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.ReEncryptionInProgressReason,
+ Message: "Re-encrypting etcd data with new encryption key",
+ ObservedGeneration: hcp.Generation,
+ })
+ return reconcile.Result{RequeueAfter: 30 * time.Second}, nil
+ }
+
+ // All migrations completed successfully.
+ log.Info("All StorageVersionMigrations completed successfully")
+ r.setHistoryState(hcp, hyperv1.EncryptionMigrationStateCompleted)
+ if len(hcp.Status.SecretEncryption.History) > 0 {
+ now := metav1.Time{Time: r.now()}
+ hcp.Status.SecretEncryption.History[0].CompletionTime = &now
+ }
+
+ return r.completeRotation(log, hcp)
+}
+
+// completeRotation promotes the target key to active and clears the target key.
+func (r *Reconciler) completeRotation(log logr.Logger, hcp *hyperv1.HostedControlPlane) (reconcile.Result, error) {
+ if hcp.Status.SecretEncryption.TargetKey.Provider != "" {
+ log.Info("Completing rotation: promoting target key to active")
+ hcp.Status.SecretEncryption.ActiveKey = *hcp.Status.SecretEncryption.TargetKey.DeepCopy()
+ hcp.Status.SecretEncryption.TargetKey = hyperv1.SecretEncryptionKeyStatus{}
+ }
+
+ meta.SetStatusCondition(&hcp.Status.Conditions, metav1.Condition{
+ Type: string(hyperv1.EtcdDataEncryptionUpToDate),
+ Status: metav1.ConditionTrue,
+ Reason: hyperv1.ReEncryptionCompletedReason,
+ Message: "All etcd data is encrypted with the current active key",
+ ObservedGeneration: hcp.Generation,
+ })
+
+ return reconcile.Result{}, nil
+}
+
+// isKASConverged checks if the KAS Deployment has fully rolled out.
+func (r *Reconciler) isKASConverged(ctx context.Context, log logr.Logger, hcp *hyperv1.HostedControlPlane) (bool, error) {
+ deployment := &appsv1.Deployment{}
+ kasRef := manifests.KASDeployment(hcp.Namespace)
+ if err := r.cpClient.Get(ctx, crclient.ObjectKeyFromObject(kasRef), deployment); err != nil {
+ return false, fmt.Errorf("failed to get KAS deployment: %w", err)
+ }
+
+ ready := podspec.IsDeploymentReady(ctx, deployment)
+ if !ready {
+ log.V(2).Info("KAS not converged")
+ }
+ return ready, nil
+}
+
+// keyStatusFromSpec computes a SecretEncryptionKeyStatus from the HCP spec.
+// For AESCBC, this reads the key secret to compute the data hash.
+func (r *Reconciler) keyStatusFromSpec(ctx context.Context, hcp *hyperv1.HostedControlPlane) (*hyperv1.SecretEncryptionKeyStatus, error) {
+ spec := hcp.Spec.SecretEncryption
+ if spec == nil {
+ return nil, nil
+ }
+
+ var dataHash string
+ if spec.Type == hyperv1.AESCBC && spec.AESCBC != nil {
+ secret := &corev1.Secret{}
+ secretKey := types.NamespacedName{
+ Namespace: hcp.Namespace,
+ Name: spec.AESCBC.ActiveKey.Name,
+ }
+ if err := r.cpClient.Get(ctx, secretKey, secret); err != nil {
+ return nil, fmt.Errorf("failed to get AESCBC key secret %s: %w", secretKey, err)
+ }
+ keyData, ok := secret.Data[hyperv1.AESCBCKeySecretKey]
+ if !ok {
+ return nil, fmt.Errorf("AESCBC key secret %s missing %q key", secretKey, hyperv1.AESCBCKeySecretKey)
+ }
+ dataHash = secretencryption.DataHash(keyData)
+ }
+
+ return secretencryption.KeyStatusFromSpec(spec, dataHash), nil
+}
+
+// encryptedResources returns the list of GroupResources that need re-encryption.
+func (r *Reconciler) encryptedResources(hcp *hyperv1.HostedControlPlane) []schema.GroupResource {
+ spec := hcp.Spec.SecretEncryption
+ if spec == nil {
+ return nil
+ }
+
+ var resourceStrings []string
+ switch spec.Type {
+ case hyperv1.KMS:
+ resourceStrings = config.KMSEncryptedObjects()
+ case hyperv1.AESCBC:
+ resourceStrings = config.AESCBCEncryptedObjects()
+ default:
+ return nil
+ }
+
+ resources := make([]schema.GroupResource, 0, len(resourceStrings))
+ for _, rs := range resourceStrings {
+ resources = append(resources, parseGroupResource(rs))
+ }
+ return resources
+}
+
+// parseGroupResource converts a resource string like "routes.route.openshift.io" to a GroupResource.
+func parseGroupResource(rs string) schema.GroupResource {
+ parts := strings.SplitN(rs, ".", 2)
+ if len(parts) == 1 {
+ return schema.GroupResource{Resource: parts[0]}
+ }
+ return schema.GroupResource{Resource: parts[0], Group: parts[1]}
+}
+
+// prependHistory prepends a new entry to the history and trims it to maxHistoryEntries.
+func prependHistory(history []hyperv1.EncryptionMigrationHistory, entry hyperv1.EncryptionMigrationHistory) []hyperv1.EncryptionMigrationHistory {
+ result := make([]hyperv1.EncryptionMigrationHistory, 0, maxHistoryEntries)
+ result = append(result, entry)
+ for i, h := range history {
+ if i >= maxHistoryEntries-1 {
+ break
+ }
+ result = append(result, h)
+ }
+ return result
+}
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go
new file mode 100644
index 000000000000..538b94652141
--- /dev/null
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go
@@ -0,0 +1,957 @@
+package reencryption
+
+import (
+ "bytes"
+ "context"
+ "encoding/base64"
+ "fmt"
+ "strings"
+ "testing"
+ "time"
+
+ . "github.com/onsi/gomega"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ kasaescbc "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kas"
+ "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms"
+ hccoapi "github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/api"
+ "github.com/openshift/hypershift/support/config"
+ "github.com/openshift/hypershift/support/secretencryption"
+
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/types"
+ apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
+ clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+ "k8s.io/client-go/tools/cache"
+
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+)
+
+const (
+ testNamespace = "test-hcp-namespace"
+ testHCPName = "test-hcp"
+)
+
+var (
+ testScheme = func() *runtime.Scheme {
+ s := runtime.NewScheme()
+ _ = clientgoscheme.AddToScheme(s)
+ _ = hyperv1.AddToScheme(s)
+ return s
+ }()
+
+ fixedTime = time.Date(2025, 6, 15, 12, 0, 0, 0, time.UTC)
+)
+
+// fakeMigrator implements the Migrator interface for testing.
+type fakeMigrator struct {
+ migrations map[string]*fakeMigrationState
+}
+
+type fakeMigrationState struct {
+ finished bool
+ result error
+ ts time.Time
+}
+
+func newFakeMigrator() *fakeMigrator {
+ return &fakeMigrator{
+ migrations: make(map[string]*fakeMigrationState),
+ }
+}
+
+func (f *fakeMigrator) EnsureMigration(gr schema.GroupResource, writeKey string) (finished bool, result error, ts time.Time, err error) {
+ key := fmt.Sprintf("%s/%s", gr.String(), writeKey)
+ state, exists := f.migrations[key]
+ if !exists {
+ f.migrations[key] = &fakeMigrationState{finished: false}
+ return false, nil, time.Time{}, nil
+ }
+ return state.finished, state.result, state.ts, nil
+}
+
+func (f *fakeMigrator) PruneMigration(gr schema.GroupResource) error {
+ for k := range f.migrations {
+ if strings.HasPrefix(k, gr.String()) {
+ delete(f.migrations, k)
+ }
+ }
+ return nil
+}
+
+func (f *fakeMigrator) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
+ return nil, nil
+}
+
+func (f *fakeMigrator) HasSynced() bool {
+ return true
+}
+
+func (f *fakeMigrator) completeMigration(gr schema.GroupResource, writeKey string) {
+ key := fmt.Sprintf("%s/%s", gr.String(), writeKey)
+ f.migrations[key] = &fakeMigrationState{
+ finished: true,
+ result: nil,
+ ts: fixedTime,
+ }
+}
+
+func (f *fakeMigrator) failMigration(gr schema.GroupResource, writeKey string, err error) {
+ key := fmt.Sprintf("%s/%s", gr.String(), writeKey)
+ f.migrations[key] = &fakeMigrationState{
+ finished: true,
+ result: err,
+ ts: fixedTime,
+ }
+}
+
+func (f *fakeMigrator) completeAll(resources []schema.GroupResource, writeKey string) {
+ for _, gr := range resources {
+ f.completeMigration(gr, writeKey)
+ }
+}
+
+// Test helpers.
+
+func newHCP(opts ...func(*hyperv1.HostedControlPlane)) *hyperv1.HostedControlPlane {
+ hcp := &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: testHCPName,
+ Namespace: testNamespace,
+ Generation: 1,
+ },
+ }
+ for _, opt := range opts {
+ opt(hcp)
+ }
+ return hcp
+}
+
+func withAESCBCEncryption(secretName string) func(*hyperv1.HostedControlPlane) {
+ return func(hcp *hyperv1.HostedControlPlane) {
+ hcp.Spec.SecretEncryption = &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: secretName},
+ },
+ }
+ }
+}
+
+func withKMSEncryption() func(*hyperv1.HostedControlPlane) {
+ return func(hcp *hyperv1.HostedControlPlane) {
+ hcp.Spec.SecretEncryption = &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.KMS,
+ KMS: &hyperv1.KMSSpec{
+ Provider: hyperv1.AWS,
+ AWS: &hyperv1.AWSKMSSpec{
+ ActiveKey: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789012:key/test-key-1"},
+ Region: "us-east-1",
+ },
+ },
+ }
+ }
+}
+
+func withActiveKey(ks *hyperv1.SecretEncryptionKeyStatus) func(*hyperv1.HostedControlPlane) {
+ return func(hcp *hyperv1.HostedControlPlane) {
+ hcp.Status.SecretEncryption.ActiveKey = *ks.DeepCopy()
+ }
+}
+
+func withTargetKey(ks *hyperv1.SecretEncryptionKeyStatus) func(*hyperv1.HostedControlPlane) {
+ return func(hcp *hyperv1.HostedControlPlane) {
+ hcp.Status.SecretEncryption.TargetKey = *ks.DeepCopy()
+ }
+}
+
+func withHistory(entries ...hyperv1.EncryptionMigrationHistory) func(*hyperv1.HostedControlPlane) {
+ return func(hcp *hyperv1.HostedControlPlane) {
+ hcp.Status.SecretEncryption.History = entries
+ }
+}
+
+func aescbcKeyStatus(secretName, dataHash string) *hyperv1.SecretEncryptionKeyStatus {
+ return secretencryption.KeyStatusFromAESCBCSpec(corev1.LocalObjectReference{Name: secretName}, dataHash)
+}
+
+func awsKeyStatus(arn, region string) *hyperv1.SecretEncryptionKeyStatus {
+ return secretencryption.KeyStatusFromAWSSpec(hyperv1.AWSKMSKeyEntry{ARN: arn}, region)
+}
+
+func aescbcKeySecret(name, namespace, keyData string) *corev1.Secret {
+ return &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Data: map[string][]byte{
+ hyperv1.AESCBCKeySecretKey: []byte(keyData),
+ },
+ }
+}
+
+// aescbcProviderKeyName computes the provider key name that the CPO generates
+// for an AESCBC key. This must match the naming in kas/aescbc.go.
+func aescbcProviderKeyName(keyData string) string {
+ name, _ := kasaescbc.AESCBCKeyName([]byte(keyData))
+ return name
+}
+
+func awsProviderKeyName(arn string) string {
+ name, _ := kms.AWSKMSProviderName(arn)
+ return name
+}
+
+// encryptionConfigSecret builds the kas-secret-encryption-config Secret with
+// a config.yaml field containing a YAML-encoded EncryptionConfiguration.
+// writeKeyName is the first (write) provider key; readKeyName (if non-empty) is
+// the second (read-only) provider key.
+func encryptionConfigSecret(namespace string, encType hyperv1.SecretEncryptionType, writeKeyName, readKeyName string) *corev1.Secret {
+ var cfg apiserverv1.EncryptionConfiguration
+ cfg.TypeMeta = metav1.TypeMeta{
+ APIVersion: apiserverv1.SchemeGroupVersion.String(),
+ Kind: "EncryptionConfiguration",
+ }
+
+ var providers []apiserverv1.ProviderConfiguration
+
+ switch encType {
+ case hyperv1.AESCBC:
+ keys := []apiserverv1.Key{
+ {Name: writeKeyName, Secret: base64.StdEncoding.EncodeToString([]byte("dummy"))},
+ }
+ if readKeyName != "" {
+ keys = append(keys, apiserverv1.Key{Name: readKeyName, Secret: base64.StdEncoding.EncodeToString([]byte("dummy"))})
+ }
+ providers = append(providers,
+ apiserverv1.ProviderConfiguration{AESCBC: &apiserverv1.AESConfiguration{Keys: keys}},
+ apiserverv1.ProviderConfiguration{Identity: &apiserverv1.IdentityConfiguration{}},
+ )
+ cfg.Resources = []apiserverv1.ResourceConfiguration{
+ {Resources: []string{"secrets"}, Providers: providers},
+ }
+
+ case hyperv1.KMS:
+ providers = append(providers, apiserverv1.ProviderConfiguration{
+ KMS: &apiserverv1.KMSConfiguration{
+ Name: writeKeyName,
+ APIVersion: "v2",
+ Endpoint: "unix:///var/run/awskmsactive.sock",
+ Timeout: &metav1.Duration{Duration: 35 * time.Second},
+ },
+ })
+ if readKeyName != "" {
+ providers = append(providers, apiserverv1.ProviderConfiguration{
+ KMS: &apiserverv1.KMSConfiguration{
+ Name: readKeyName,
+ APIVersion: "v2",
+ Endpoint: "unix:///var/run/awskmsbackup.sock",
+ Timeout: &metav1.Duration{Duration: 35 * time.Second},
+ },
+ })
+ }
+ providers = append(providers, apiserverv1.ProviderConfiguration{Identity: &apiserverv1.IdentityConfiguration{}})
+ cfg.Resources = []apiserverv1.ResourceConfiguration{
+ {Resources: config.KMSEncryptedObjects(), Providers: providers},
+ }
+ }
+
+ buf := bytes.NewBuffer(nil)
+ if err := hccoapi.YamlSerializer.Encode(&cfg, buf); err != nil {
+ panic(fmt.Sprintf("failed to encode EncryptionConfiguration: %v", err))
+ }
+
+ return &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "kas-secret-encryption-config",
+ Namespace: namespace,
+ },
+ Data: map[string][]byte{
+ "config.yaml": buf.Bytes(),
+ },
+ }
+}
+
+func convergedKASDeployment(namespace string) *appsv1.Deployment {
+ replicas := int32(3)
+ return &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "kube-apiserver",
+ Namespace: namespace,
+ Generation: 1,
+ },
+ Spec: appsv1.DeploymentSpec{
+ Replicas: &replicas,
+ },
+ Status: appsv1.DeploymentStatus{
+ ObservedGeneration: 1,
+ Replicas: 3,
+ UpdatedReplicas: 3,
+ ReadyReplicas: 3,
+ AvailableReplicas: 3,
+ UnavailableReplicas: 0,
+ },
+ }
+}
+
+func rollingKASDeployment(namespace string) *appsv1.Deployment {
+ replicas := int32(3)
+ return &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "kube-apiserver",
+ Namespace: namespace,
+ Generation: 2,
+ },
+ Spec: appsv1.DeploymentSpec{
+ Replicas: &replicas,
+ },
+ Status: appsv1.DeploymentStatus{
+ ObservedGeneration: 1,
+ Replicas: 3,
+ UpdatedReplicas: 1,
+ ReadyReplicas: 2,
+ AvailableReplicas: 2,
+ UnavailableReplicas: 1,
+ },
+ }
+}
+
+func newReconciler(cpClient, guestClient client.Client, migrator *fakeMigrator) *Reconciler {
+ return &Reconciler{
+ cpClient: cpClient,
+ guestClient: guestClient,
+ hcpName: testHCPName,
+ hcpNamespace: testNamespace,
+ migrator: migrator,
+ now: func() time.Time { return fixedTime },
+ }
+}
+
+func buildCPClient(objs ...client.Object) client.Client {
+ return fake.NewClientBuilder().
+ WithScheme(testScheme).
+ WithObjects(objs...).
+ WithStatusSubresource(&hyperv1.HostedControlPlane{}).
+ Build()
+}
+
+func getHCP(ctx context.Context, g Gomega, cl client.Client) *hyperv1.HostedControlPlane {
+ hcp := &hyperv1.HostedControlPlane{}
+ g.Expect(cl.Get(ctx, types.NamespacedName{Name: testHCPName, Namespace: testNamespace}, hcp)).To(Succeed())
+ return hcp
+}
+
+func TestReconcile(t *testing.T) {
+ tests := []struct {
+ name string
+ cpObjects []client.Object
+ migrator func() *fakeMigrator
+ expectResult reconcile.Result
+ expectError bool
+ validate func(*testing.T, Gomega, client.Client, *fakeMigrator)
+ }{
+ {
+ name: "When encryption is not configured it should remove the condition and clear targetKey",
+ cpObjects: []client.Object{
+ newHCP(), // no encryption spec
+ convergedKASDeployment(testNamespace),
+ },
+ migrator: newFakeMigrator,
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).To(BeNil(), "condition should be removed when encryption is not configured")
+ },
+ },
+ {
+ name: "When encryption is configured with AESCBC and no active key in status it should initialize active key",
+ cpObjects: []client.Object{
+ newHCP(withAESCBCEncryption("aescbc-key-1")),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "test-key-data-1"),
+ convergedKASDeployment(testNamespace),
+ },
+ migrator: newFakeMigrator,
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.Provider).ToNot(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.Provider).To(Equal(hyperv1.SecretEncryptionProviderAESCBC))
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.AESCBC.DataHash).ToNot(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.AESCBC.Secret.Name).To(Equal("aescbc-key-1"))
+ dh := secretencryption.DataHash([]byte("test-key-data-1"))
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.AESCBC.DataHash).To(Equal(dh))
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).To(BeEmpty())
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+ g.Expect(cond.Reason).To(Equal(hyperv1.ReEncryptionCompletedReason))
+ },
+ },
+ {
+ name: "When encryption key is already up to date it should remain in steady state",
+ cpObjects: func() []client.Object {
+ dataHash := secretencryption.DataHash([]byte("test-key-data-1"))
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(aescbcKeyStatus("aescbc-key-1", dataHash)),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "test-key-data-1"),
+ convergedKASDeployment(testNamespace),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).To(BeEmpty())
+ },
+ },
+ {
+ name: "When AESCBC key data changes it should start a new rotation",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(aescbcKeyStatus("aescbc-key-1", oldHash)),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ convergedKASDeployment(testNamespace),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).ToNot(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).To(Equal(hyperv1.SecretEncryptionProviderAESCBC))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.AESCBC.DataHash).To(Equal(newHash))
+
+ g.Expect(hcp.Status.SecretEncryption.History).To(HaveLen(1))
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateReadOnlyDeploy))
+ g.Expect(hcp.Status.SecretEncryption.History[0].CompletionTime).To(BeNil())
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionFalse))
+ g.Expect(cond.Reason).To(Equal(hyperv1.ReadOnlyRolloutInProgressReason))
+ },
+ },
+ {
+ name: "When in ReadOnlyDeploy phase and KAS is not converged it should wait",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ newKS := aescbcKeyStatus("aescbc-key-1", newHash)
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateReadOnlyDeploy,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ rollingKASDeployment(testNamespace),
+ // Target key is read-only (second), old key is write (first).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("old-key-data"),
+ aescbcProviderKeyName("new-key-data")),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ expectResult: reconcile.Result{RequeueAfter: 30 * time.Second},
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateReadOnlyDeploy))
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionFalse))
+ g.Expect(cond.Reason).To(Equal(hyperv1.ReEncryptionWaitingForKASReason))
+ },
+ },
+ {
+ name: "When in ReadOnlyDeploy phase and KAS is converged it should advance to WritePromote",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ newKS := aescbcKeyStatus("aescbc-key-1", newHash)
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateReadOnlyDeploy,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ convergedKASDeployment(testNamespace),
+ // Target key is read-only (second), old key is write (first).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("old-key-data"),
+ aescbcProviderKeyName("new-key-data")),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateWritePromote))
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionFalse))
+ g.Expect(cond.Reason).To(Equal(hyperv1.WritePromotionInProgressReason))
+ },
+ },
+ {
+ name: "When in WritePromote phase and KAS is converged it should advance to Migrating",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ newKS := aescbcKeyStatus("aescbc-key-1", newHash)
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateWritePromote,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ convergedKASDeployment(testNamespace),
+ // Target key promoted to write (first), old key demoted to read-only (second).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("new-key-data"),
+ aescbcProviderKeyName("old-key-data")),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ // The controller derives Migrating from observable state (target key is write + KAS converged)
+ // and immediately starts migrations which are not yet finished, so it requeues.
+ expectResult: reconcile.Result{RequeueAfter: 30 * time.Second},
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateMigrating))
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionFalse))
+ g.Expect(cond.Reason).To(Equal(hyperv1.ReEncryptionInProgressReason))
+ },
+ },
+ {
+ name: "When in Migrating phase and migrations are in progress it should wait",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ newKS := aescbcKeyStatus("aescbc-key-1", newHash)
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateMigrating,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ convergedKASDeployment(testNamespace),
+ // Target key is write (first), old key is read-only (second).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("new-key-data"),
+ aescbcProviderKeyName("old-key-data")),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ expectResult: reconcile.Result{RequeueAfter: 30 * time.Second},
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateMigrating))
+ },
+ },
+ {
+ name: "When in Migrating phase and all AESCBC migrations complete it should complete rotation",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ newKS := aescbcKeyStatus("aescbc-key-1", newHash)
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateMigrating,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ convergedKASDeployment(testNamespace),
+ // Target key is write (first), old key is read-only (second).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("new-key-data"),
+ aescbcProviderKeyName("old-key-data")),
+ }
+ }(),
+ migrator: func() *fakeMigrator {
+ m := newFakeMigrator()
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ fp := secretencryption.FingerprintAESCBCKey("aescbc-key-1", newHash)
+ writeKey := fmt.Sprintf("encryption-key-%s", fp)
+ // AESCBC only encrypts secrets.
+ m.completeMigration(schema.GroupResource{Resource: "secrets"}, writeKey)
+ return m
+ },
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).To(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.Provider).ToNot(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.Provider).To(Equal(hyperv1.SecretEncryptionProviderAESCBC))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.AESCBC.DataHash).To(Equal(newHash))
+
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateCompleted))
+ g.Expect(hcp.Status.SecretEncryption.History[0].CompletionTime).ToNot(BeNil())
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+ g.Expect(cond.Reason).To(Equal(hyperv1.ReEncryptionCompletedReason))
+ },
+ },
+ {
+ name: "When in Migrating phase and a migration fails it should set failed condition",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ newKS := aescbcKeyStatus("aescbc-key-1", newHash)
+ return []client.Object{
+ newHCP(
+ withAESCBCEncryption("aescbc-key-1"),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateMigrating,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ aescbcKeySecret("aescbc-key-1", testNamespace, "new-key-data"),
+ convergedKASDeployment(testNamespace),
+ // Target key is write (first), old key is read-only (second).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("new-key-data"),
+ aescbcProviderKeyName("old-key-data")),
+ }
+ }(),
+ migrator: func() *fakeMigrator {
+ m := newFakeMigrator()
+ newHash := secretencryption.DataHash([]byte("new-key-data"))
+ fp := secretencryption.FingerprintAESCBCKey("aescbc-key-1", newHash)
+ writeKey := fmt.Sprintf("encryption-key-%s", fp)
+ m.failMigration(schema.GroupResource{Resource: "secrets"}, writeKey, fmt.Errorf("migration failed: timeout"))
+ return m
+ },
+ expectResult: reconcile.Result{RequeueAfter: 60 * time.Second},
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateMigrating))
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionFalse))
+ g.Expect(cond.Reason).To(Equal(hyperv1.ReEncryptionFailedReason))
+ },
+ },
+ {
+ name: "When using AWS KMS and key ARN changes it should start rotation with 5 encrypted resources",
+ cpObjects: func() []client.Object {
+ oldKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/old-key", "us-east-1")
+ return []client.Object{
+ newHCP(
+ withKMSEncryption(),
+ withActiveKey(oldKS),
+ ),
+ convergedKASDeployment(testNamespace),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).ToNot(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).To(Equal(hyperv1.SecretEncryptionProviderAWS))
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.AWS.ARN).To(Equal("arn:aws:kms:us-east-1:123456789012:key/test-key-1"))
+
+ g.Expect(hcp.Status.SecretEncryption.History).To(HaveLen(1))
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateReadOnlyDeploy))
+ },
+ },
+ {
+ name: "When in Migrating phase with KMS and all 5 migrations complete it should complete rotation",
+ cpObjects: func() []client.Object {
+ oldKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/old-key", "us-east-1")
+ newKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/test-key-1", "us-east-1")
+ return []client.Object{
+ newHCP(
+ withKMSEncryption(),
+ withActiveKey(oldKS),
+ withTargetKey(newKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(newKS),
+ State: hyperv1.EncryptionMigrationStateMigrating,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ ),
+ convergedKASDeployment(testNamespace),
+ // Target key is write (first KMS provider), old key is read-only (second).
+ encryptionConfigSecret(testNamespace, hyperv1.KMS,
+ awsProviderKeyName("arn:aws:kms:us-east-1:123456789012:key/test-key-1"),
+ awsProviderKeyName("arn:aws:kms:us-east-1:123456789012:key/old-key")),
+ }
+ }(),
+ migrator: func() *fakeMigrator {
+ m := newFakeMigrator()
+ fp := secretencryption.FingerprintAWSKMSKey("arn:aws:kms:us-east-1:123456789012:key/test-key-1")
+ writeKey := fmt.Sprintf("encryption-key-%s", fp)
+ resources := []schema.GroupResource{
+ {Resource: "secrets"},
+ {Resource: "configmaps"},
+ {Resource: "routes", Group: "route.openshift.io"},
+ {Resource: "oauthaccesstokens", Group: "oauth.openshift.io"},
+ {Resource: "oauthauthorizetokens", Group: "oauth.openshift.io"},
+ }
+ m.completeAll(resources, writeKey)
+ return m
+ },
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).To(BeEmpty())
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.Provider).To(Equal(hyperv1.SecretEncryptionProviderAWS))
+ g.Expect(hcp.Status.SecretEncryption.ActiveKey.AWS.ARN).To(Equal("arn:aws:kms:us-east-1:123456789012:key/test-key-1"))
+
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateCompleted))
+
+ cond := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate))
+ g.Expect(cond).ToNot(BeNil())
+ g.Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+ },
+ },
+ {
+ name: "When spec key changes mid-rotation it should let current rotation complete first",
+ cpObjects: func() []client.Object {
+ oldHash := secretencryption.DataHash([]byte("old-key-data"))
+ midHash := secretencryption.DataHash([]byte("mid-key-data"))
+ oldKS := aescbcKeyStatus("aescbc-key-1", oldHash)
+ midKS := aescbcKeyStatus("aescbc-key-2", midHash)
+
+ hcp := newHCP(
+ withActiveKey(oldKS),
+ withTargetKey(midKS),
+ withHistory(hyperv1.EncryptionMigrationHistory{
+ From: secretencryption.KeyReferenceFromStatus(oldKS),
+ To: secretencryption.KeyReferenceFromStatus(midKS),
+ State: hyperv1.EncryptionMigrationStateWritePromote,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }),
+ )
+ // Spec now points to a third key (simulates user changing spec again).
+ hcp.Spec.SecretEncryption = &hyperv1.SecretEncryptionSpec{
+ Type: hyperv1.AESCBC,
+ AESCBC: &hyperv1.AESCBCSpec{
+ ActiveKey: corev1.LocalObjectReference{Name: "aescbc-key-3"},
+ },
+ }
+ return []client.Object{
+ hcp,
+ aescbcKeySecret("aescbc-key-2", testNamespace, "mid-key-data"),
+ aescbcKeySecret("aescbc-key-3", testNamespace, "third-key-data"),
+ convergedKASDeployment(testNamespace),
+ // Target (mid) key is write (first), old key is read-only (second).
+ encryptionConfigSecret(testNamespace, hyperv1.AESCBC,
+ aescbcProviderKeyName("mid-key-data"),
+ aescbcProviderKeyName("old-key-data")),
+ }
+ }(),
+ migrator: newFakeMigrator,
+ // The controller derives Migrating from observable state (target key is write + KAS converged)
+ // and immediately starts migrations which are not yet finished, so it requeues.
+ expectResult: reconcile.Result{RequeueAfter: 30 * time.Second},
+ validate: func(t *testing.T, g Gomega, cl client.Client, _ *fakeMigrator) {
+ hcp := getHCP(context.Background(), g, cl)
+ // The current rotation should continue: WritePromote -> Migrating.
+ g.Expect(hcp.Status.SecretEncryption.History[0].State).To(Equal(hyperv1.EncryptionMigrationStateMigrating))
+ // TargetKey should remain the mid-rotation key, not the new spec key.
+ g.Expect(hcp.Status.SecretEncryption.TargetKey.Provider).ToNot(BeEmpty())
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ ctx := context.Background()
+
+ cpClient := buildCPClient(tt.cpObjects...)
+ migrator := tt.migrator()
+ r := newReconciler(cpClient, nil, migrator)
+
+ result, err := r.Reconcile(ctx, reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Namespace: testNamespace,
+ Name: testHCPName,
+ },
+ })
+
+ if tt.expectError {
+ g.Expect(err).To(HaveOccurred())
+ } else {
+ g.Expect(err).ToNot(HaveOccurred())
+ }
+
+ g.Expect(result).To(Equal(tt.expectResult))
+
+ if tt.validate != nil {
+ tt.validate(t, g, cpClient, migrator)
+ }
+ })
+ }
+}
+
+func TestParseGroupResource(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ expected schema.GroupResource
+ }{
+ {
+ name: "When parsing a core resource it should return empty group",
+ input: "secrets",
+ expected: schema.GroupResource{Group: "", Resource: "secrets"},
+ },
+ {
+ name: "When parsing a core resource configmaps it should return empty group",
+ input: "configmaps",
+ expected: schema.GroupResource{Group: "", Resource: "configmaps"},
+ },
+ {
+ name: "When parsing a route resource it should split group correctly",
+ input: "routes.route.openshift.io",
+ expected: schema.GroupResource{Group: "route.openshift.io", Resource: "routes"},
+ },
+ {
+ name: "When parsing an oauth resource it should split group correctly",
+ input: "oauthaccesstokens.oauth.openshift.io",
+ expected: schema.GroupResource{Group: "oauth.openshift.io", Resource: "oauthaccesstokens"},
+ },
+ {
+ name: "When parsing oauthauthorizetokens resource it should split group correctly",
+ input: "oauthauthorizetokens.oauth.openshift.io",
+ expected: schema.GroupResource{Group: "oauth.openshift.io", Resource: "oauthauthorizetokens"},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ g.Expect(parseGroupResource(tt.input)).To(Equal(tt.expected))
+ })
+ }
+}
+
+func TestPrependHistory(t *testing.T) {
+ t.Run("When prepending to empty history it should contain only the new entry", func(t *testing.T) {
+ g := NewWithT(t)
+ entry := hyperv1.EncryptionMigrationHistory{
+ State: hyperv1.EncryptionMigrationStateReadOnlyDeploy,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }
+ result := prependHistory(nil, entry)
+ g.Expect(result).To(HaveLen(1))
+ g.Expect(result[0].State).To(Equal(hyperv1.EncryptionMigrationStateReadOnlyDeploy))
+ })
+
+ t.Run("When prepending to full history it should trim to max entries", func(t *testing.T) {
+ g := NewWithT(t)
+ existing := make([]hyperv1.EncryptionMigrationHistory, maxHistoryEntries)
+ for i := range existing {
+ existing[i] = hyperv1.EncryptionMigrationHistory{
+ State: hyperv1.EncryptionMigrationStateCompleted,
+ StartedTime: metav1.Time{Time: fixedTime.Add(-time.Duration(i) * time.Hour)},
+ }
+ }
+ entry := hyperv1.EncryptionMigrationHistory{
+ State: hyperv1.EncryptionMigrationStateReadOnlyDeploy,
+ StartedTime: metav1.Time{Time: fixedTime},
+ }
+ result := prependHistory(existing, entry)
+ g.Expect(result).To(HaveLen(maxHistoryEntries))
+ g.Expect(result[0].State).To(Equal(hyperv1.EncryptionMigrationStateReadOnlyDeploy))
+ g.Expect(result[maxHistoryEntries-1].State).To(Equal(hyperv1.EncryptionMigrationStateCompleted))
+ })
+}
+
+func TestEncryptedResources(t *testing.T) {
+ t.Run("When encryption type is AESCBC it should return only secrets", func(t *testing.T) {
+ g := NewWithT(t)
+ r := &Reconciler{}
+ hcp := newHCP(withAESCBCEncryption("key"))
+ resources := r.encryptedResources(hcp)
+ g.Expect(resources).To(HaveLen(1))
+ g.Expect(resources[0]).To(Equal(schema.GroupResource{Resource: "secrets"}))
+ })
+
+ t.Run("When encryption type is KMS it should return 5 resources", func(t *testing.T) {
+ g := NewWithT(t)
+ r := &Reconciler{}
+ hcp := newHCP(withKMSEncryption())
+ resources := r.encryptedResources(hcp)
+ g.Expect(resources).To(HaveLen(5))
+ g.Expect(resources).To(ContainElement(schema.GroupResource{Resource: "secrets"}))
+ g.Expect(resources).To(ContainElement(schema.GroupResource{Resource: "configmaps"}))
+ g.Expect(resources).To(ContainElement(schema.GroupResource{Group: "route.openshift.io", Resource: "routes"}))
+ g.Expect(resources).To(ContainElement(schema.GroupResource{Group: "oauth.openshift.io", Resource: "oauthaccesstokens"}))
+ g.Expect(resources).To(ContainElement(schema.GroupResource{Group: "oauth.openshift.io", Resource: "oauthauthorizetokens"}))
+ })
+
+ t.Run("When encryption is not configured it should return nil", func(t *testing.T) {
+ g := NewWithT(t)
+ r := &Reconciler{}
+ hcp := newHCP()
+ resources := r.encryptedResources(hcp)
+ g.Expect(resources).To(BeNil())
+ })
+}
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/setup.go b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/setup.go
new file mode 100644
index 000000000000..b7d4dd5fc5ed
--- /dev/null
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/setup.go
@@ -0,0 +1,104 @@
+package reencryption
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ "github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/operator"
+
+ "github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators"
+
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/types"
+ kubeclient "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/tools/cache"
+
+ crclient "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/controller-runtime/pkg/source"
+ kubemigratorclient "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset"
+ migrationv1alpha1informer "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer"
+)
+
+const ControllerName = "reencryption"
+
+func Setup(ctx context.Context, opts *operator.HostedClusterConfigOperatorConfig) error {
+ // Create the kube-storage-version-migrator client for the guest cluster.
+ svmClient, err := kubemigratorclient.NewForConfig(opts.TargetConfig)
+ if err != nil {
+ return fmt.Errorf("failed to create storage-version-migrator client: %w", err)
+ }
+
+ // Create a discovery client for the guest cluster to resolve preferred versions.
+ guestKubeClient, err := kubeclient.NewForConfig(opts.TargetConfig)
+ if err != nil {
+ return fmt.Errorf("failed to create guest kube client: %w", err)
+ }
+
+ svmInformerFactory := migrationv1alpha1informer.NewSharedInformerFactory(svmClient, 10*time.Minute)
+ svmInformer := svmInformerFactory.Migration().V1alpha1()
+
+ migrator := migrators.NewKubeStorageVersionMigrator(
+ svmClient,
+ svmInformer,
+ guestKubeClient.Discovery(),
+ )
+
+ r := &Reconciler{
+ cpClient: opts.CPCluster.GetClient(),
+ guestClient: opts.Manager.GetClient(),
+ hcpName: opts.HCPName,
+ hcpNamespace: opts.Namespace,
+ migrator: migrator,
+ now: time.Now,
+ }
+
+ c, err := controller.New(ControllerName, opts.Manager, controller.Options{Reconciler: r})
+ if err != nil {
+ return fmt.Errorf("failed to construct controller: %w", err)
+ }
+
+ // Watch the HostedControlPlane in the CP cluster.
+ if err := c.Watch(source.Kind(opts.CPCluster.GetCache(), &hyperv1.HostedControlPlane{},
+ &handler.TypedEnqueueRequestForObject[*hyperv1.HostedControlPlane]{})); err != nil {
+ return fmt.Errorf("failed to watch HostedControlPlane: %w", err)
+ }
+
+ // Watch KAS Deployment in the CP cluster for convergence detection.
+ hcpMapper := func(_ context.Context, obj crclient.Object) []reconcile.Request {
+ if obj.GetNamespace() == opts.Namespace {
+ return []reconcile.Request{{NamespacedName: types.NamespacedName{
+ Namespace: opts.Namespace,
+ Name: opts.HCPName,
+ }}}
+ }
+ return nil
+ }
+ if err := c.Watch(source.Kind[crclient.Object](opts.CPCluster.GetCache(), &appsv1.Deployment{},
+ handler.EnqueueRequestsFromMapFunc(hcpMapper))); err != nil {
+ return fmt.Errorf("failed to watch KAS Deployment: %w", err)
+ }
+
+ // Watch Secrets in the CP cluster namespace (for AESCBC key changes).
+ if err := c.Watch(source.Kind[crclient.Object](opts.CPCluster.GetCache(), &corev1.Secret{},
+ handler.EnqueueRequestsFromMapFunc(hcpMapper))); err != nil {
+ return fmt.Errorf("failed to watch Secrets: %w", err)
+ }
+
+ // Register an event handler on the SVM informer. This call is required
+ // because AddEventHandler initializes the migrator's internal cacheSynced
+ // function; without it, HasSynced() will panic. The handler itself is a
+ // no-op because the controller reconciles on a requeue interval while
+ // migrations are in progress.
+ if _, err := migrator.AddEventHandler(cache.ResourceEventHandlerFuncs{}); err != nil {
+ return fmt.Errorf("failed to add SVM event handler: %w", err)
+ }
+ svmInformerFactory.Start(ctx.Done())
+
+ return nil
+}
From 36d576448a0caff654b1462b12cf5b96047816d4 Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 13:52:40 +0200
Subject: [PATCH 06/12] docs: regenerate API reference and aggregated docs
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
docs/content/reference/aggregated-docs.md | 608 ++++++++++++++++++++++
docs/content/reference/api.md | 608 ++++++++++++++++++++++
2 files changed, 1216 insertions(+)
diff --git a/docs/content/reference/aggregated-docs.md b/docs/content/reference/aggregated-docs.md
index d70c1b359e8d..6a4e3d70a299 100644
--- a/docs/content/reference/aggregated-docs.md
+++ b/docs/content/reference/aggregated-docs.md
@@ -37047,6 +37047,50 @@ NodePoolStatus
+###AESCBCKeyStatus { #hypershift.openshift.io/v1beta1.AESCBCKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
AESCBCKeyStatus contains a reference to the AESCBC key secret and a SHA-256 hash
+of its contents for fingerprinting.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+secret
+
+
+Kubernetes core/v1.LocalObjectReference
+
+
+ |
+
+ secret is a reference to the secret containing the AESCBC key.
+ |
+
+
+
+dataHash
+
+string
+
+ |
+
+ dataHash is the hex-encoded SHA-256 hash of the secret’s “key” data field
+at the time re-encryption completed.
+ |
+
+
+
###AESCBCSpec { #hypershift.openshift.io/v1beta1.AESCBCSpec }
(Appears on:
@@ -37089,6 +37133,8 @@ Kubernetes core/v1.LocalObjectReference
(Optional)
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+The system automatically manages the previous key via the status field.
@@ -37345,6 +37391,47 @@ string
+###AWSKMSKeyStatus { #hypershift.openshift.io/v1beta1.AWSKMSKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
+reconstruct the backup sidecar container arguments.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+arn
+
+string
+
+ |
+
+ arn is the Amazon Resource Name of the KMS key.
+ |
+
+
+
+region
+
+string
+
+ |
+
+ region is the AWS region of the KMS key.
+ |
+
+
+
###AWSKMSSpec { #hypershift.openshift.io/v1beta1.AWSKMSSpec }
(Appears on:
@@ -37398,6 +37485,8 @@ AWSKMSKeyEntry
(Optional)
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+The system automatically manages the previous key via the status field.
@@ -39084,6 +39173,58 @@ string
+###AzureKMSKeyStatus { #hypershift.openshift.io/v1beta1.AzureKMSKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
+reconstruct the EncryptionConfiguration read provider.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+keyVaultName
+
+string
+
+ |
+
+ keyVaultName is the name of the Azure Key Vault.
+ |
+
+
+
+keyName
+
+string
+
+ |
+
+ keyName is the name of the key in the vault.
+ |
+
+
+
+keyVersion
+
+string
+
+ |
+
+ keyVersion is the version of the key.
+ |
+
+
+
###AzureKMSSpec { #hypershift.openshift.io/v1beta1.AzureKMSSpec }
(Appears on:
@@ -39126,6 +39267,8 @@ AzureKMSKey
(Optional)
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+The system automatically manages the previous key via the status field.
@@ -41644,6 +41787,13 @@ A failure here often means a software bug or a non-stable cluster.
most recent etcd backup. True means the last backup completed successfully;
False means a backup is in progress or the last backup failed.
+
"EtcdDataEncryptionUpToDate" |
+EtcdDataEncryptionUpToDate indicates whether all etcd data is encrypted with the
+currently active encryption key.
+True: all data confirmed encrypted with the active key.
+False: re-encryption is in progress or has failed.
+Absent: encryption is not configured.
+ |
"EtcdRecoveryActive" |
EtcdRecoveryActive indicates that the Etcd cluster is failing and the
recovery job was triggered.
@@ -42529,6 +42679,168 @@ UserManagedDiagnostics
|
+###EncryptionKeyReference { #hypershift.openshift.io/v1beta1.EncryptionKeyReference }
+
+(Appears on:
+EncryptionMigrationHistory)
+
+
+
EncryptionKeyReference identifies an encryption key by its provider and fingerprint.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+provider
+
+
+SecretEncryptionProvider
+
+
+ |
+
+ provider identifies the encryption provider.
+ |
+
+
+
+fingerprint
+
+string
+
+ |
+
+ fingerprint is the hex-encoded SHA-256 hash of the key’s identity fields.
+ |
+
+
+
+###EncryptionMigrationHistory { #hypershift.openshift.io/v1beta1.EncryptionMigrationHistory }
+
+(Appears on:
+SecretEncryptionStatus)
+
+
+
EncryptionMigrationHistory records a key rotation, including in-progress rotations.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+from,omitzero
+
+
+EncryptionKeyReference
+
+
+ |
+
+ from is the key that data was migrated from (the previous active key).
+ |
+
+
+
+to,omitzero
+
+
+EncryptionKeyReference
+
+
+ |
+
+ to is the key that data was migrated to (the target key).
+ |
+
+
+
+state
+
+
+EncryptionMigrationState
+
+
+ |
+
+ state tracks the current phase of this rotation.
+ |
+
+
+
+startedTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ startedTime is when the rotation was initiated.
+ |
+
+
+
+completionTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ completionTime is when the rotation finished. Not set while the rotation is in progress.
+ |
+
+
+
+###EncryptionMigrationState { #hypershift.openshift.io/v1beta1.EncryptionMigrationState }
+
+(Appears on:
+EncryptionMigrationHistory)
+
+
+
EncryptionMigrationState tracks the lifecycle of a key rotation.
+
+
+
+
+| Value |
+Description |
+
+
+"Completed" |
+EncryptionMigrationStateCompleted means all data was successfully re-encrypted with the target key.
+ |
+
"Interrupted" |
+EncryptionMigrationStateInterrupted means the rotation was abandoned before data was encrypted
+with the target key (e.g., targetKey replaced during ReadOnlyDeploy).
+ |
+
"Migrating" |
+EncryptionMigrationStateMigrating means all KAS replicas have converged on the new write
+provider and re-encryption (StorageVersionMigration) is in progress.
+ |
+
"ReadOnlyDeploy" |
+EncryptionMigrationStateReadOnlyDeploy means the new key is being deployed as a read-only
+provider. The old key remains the write provider.
+ |
+
"WritePromote" |
+EncryptionMigrationStateWritePromote means the new key is being promoted to write provider.
+The old key becomes read-only.
+ |
+
+
###EtcdManagementType { #hypershift.openshift.io/v1beta1.EtcdManagementType }
(Appears on:
@@ -45313,6 +45625,20 @@ successful etcd backup snapshot. Persisted here because HCPEtcdBackup CRs
are ephemeral and may be deleted by retention policies.
+
+
+secretEncryption,omitzero
+
+
+SecretEncryptionStatus
+
+
+ |
+
+(Optional)
+ secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ |
+
###HostedControlPlaneSpec { #hypershift.openshift.io/v1beta1.HostedControlPlaneSpec }
@@ -46101,6 +46427,20 @@ ConfigurationStatus
configuration contains the cluster configuration status of the HostedCluster
+
+
+secretEncryption,omitzero
+
+
+SecretEncryptionStatus
+
+
+ |
+
+(Optional)
+ secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ |
+
###IBMCloudKMSAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSAuthSpec }
@@ -46262,6 +46602,91 @@ key is enabled for data encryption.
+###IBMCloudKMSKeyStatus { #hypershift.openshift.io/v1beta1.IBMCloudKMSKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
+sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+crkID
+
+string
+
+ |
+
+ crkID is the Customer Root Key ID.
+ |
+
+
+
+instanceID
+
+string
+
+ |
+
+ instanceID is the KMS instance ID.
+ |
+
+
+
+keyVersion
+
+int32
+
+ |
+
+ keyVersion is the key version number.
+ |
+
+
+
+region
+
+string
+
+ |
+
+ region is the IBM Cloud region.
+ |
+
+
+
+correlationID
+
+string
+
+ |
+
+ correlationID is the correlation ID for the key.
+ |
+
+
+
+url
+
+string
+
+ |
+
+ url is the KMS endpoint URL.
+ |
+
+
+
###IBMCloudKMSManagedAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSManagedAuthSpec }
(Appears on:
@@ -51663,6 +52088,121 @@ When omitted, the autoscaler defaults to 50%.
+###SecretEncryptionKeyStatus { #hypershift.openshift.io/v1beta1.SecretEncryptionKeyStatus }
+
+(Appears on:
+SecretEncryptionStatus)
+
+
+
SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
+instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+provider
+
+
+SecretEncryptionProvider
+
+
+ |
+
+ provider identifies the encryption provider.
+ |
+
+
+
+azure,omitzero
+
+
+AzureKMSKeyStatus
+
+
+ |
+
+(Optional)
+ azure holds the Azure KMS key identity fields.
+ |
+
+
+
+aws,omitzero
+
+
+AWSKMSKeyStatus
+
+
+ |
+
+(Optional)
+ aws holds the AWS KMS key identity fields.
+ |
+
+
+
+ibmCloud,omitzero
+
+
+IBMCloudKMSKeyStatus
+
+
+ |
+
+(Optional)
+ ibmCloud holds the IBM Cloud KMS key identity fields.
+ |
+
+
+
+aescbc,omitzero
+
+
+AESCBCKeyStatus
+
+
+ |
+
+(Optional)
+ aescbc holds a reference to the AESCBC key secret.
+ |
+
+
+
+###SecretEncryptionProvider { #hypershift.openshift.io/v1beta1.SecretEncryptionProvider }
+
+(Appears on:
+EncryptionKeyReference,
+SecretEncryptionKeyStatus)
+
+
+
SecretEncryptionProvider identifies the encryption provider recorded in status.
+This is a separate type from KMSProvider because the KMSProvider enum does not include AESCBC.
+
+
+
+
+| Value |
+Description |
+
+
+"AESCBC" |
+ |
+
"AWS" |
+ |
+
"Azure" |
+ |
+
"IBMCloud" |
+ |
+
+
###SecretEncryptionSpec { #hypershift.openshift.io/v1beta1.SecretEncryptionSpec }
(Appears on:
@@ -51724,6 +52264,74 @@ AESCBCSpec
+###SecretEncryptionStatus { #hypershift.openshift.io/v1beta1.SecretEncryptionStatus }
+
+(Appears on:
+HostedClusterStatus,
+HostedControlPlaneStatus)
+
+
+
SecretEncryptionStatus tracks the state of secret encryption key rotation and re-encryption.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+activeKey,omitzero
+
+
+SecretEncryptionKeyStatus
+
+
+ |
+
+(Optional)
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+Updated after successful re-encryption.
+ |
+
+
+
+targetKey,omitzero
+
+
+SecretEncryptionKeyStatus
+
+
+ |
+
+(Optional)
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+spec.secretEncryption’s active key when the rotation starts. The CPO uses this
+(not the current spec) during the rotation, so mid-rotation spec changes are
+safely queued until the current rotation completes. Cleared when rotation completes.
+ |
+
+
+
+history
+
+
+[]EncryptionMigrationHistory
+
+
+ |
+
+(Optional)
+ history contains a list of key rotations applied to this cluster. The newest
+entry is first in the list. Entries have state Completed when re-encryption
+has finished. The current rotation phase is always history[0].state when
+history[0] is not Completed or Interrupted.
+ |
+
+
+
###SecretEncryptionType { #hypershift.openshift.io/v1beta1.SecretEncryptionType }
(Appears on:
diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md
index fb4fb96c1b20..a25c11791714 100644
--- a/docs/content/reference/api.md
+++ b/docs/content/reference/api.md
@@ -1362,6 +1362,50 @@ NodePoolStatus
+###AESCBCKeyStatus { #hypershift.openshift.io/v1beta1.AESCBCKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
AESCBCKeyStatus contains a reference to the AESCBC key secret and a SHA-256 hash
+of its contents for fingerprinting.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+secret
+
+
+Kubernetes core/v1.LocalObjectReference
+
+
+ |
+
+ secret is a reference to the secret containing the AESCBC key.
+ |
+
+
+
+dataHash
+
+string
+
+ |
+
+ dataHash is the hex-encoded SHA-256 hash of the secret’s “key” data field
+at the time re-encryption completed.
+ |
+
+
+
###AESCBCSpec { #hypershift.openshift.io/v1beta1.AESCBCSpec }
(Appears on:
@@ -1404,6 +1448,8 @@ Kubernetes core/v1.LocalObjectReference
(Optional)
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+The system automatically manages the previous key via the status field.
@@ -1660,6 +1706,47 @@ string
+###AWSKMSKeyStatus { #hypershift.openshift.io/v1beta1.AWSKMSKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
+reconstruct the backup sidecar container arguments.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+arn
+
+string
+
+ |
+
+ arn is the Amazon Resource Name of the KMS key.
+ |
+
+
+
+region
+
+string
+
+ |
+
+ region is the AWS region of the KMS key.
+ |
+
+
+
###AWSKMSSpec { #hypershift.openshift.io/v1beta1.AWSKMSSpec }
(Appears on:
@@ -1713,6 +1800,8 @@ AWSKMSKeyEntry
(Optional)
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+The system automatically manages the previous key via the status field.
@@ -3399,6 +3488,58 @@ string
+###AzureKMSKeyStatus { #hypershift.openshift.io/v1beta1.AzureKMSKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
+reconstruct the EncryptionConfiguration read provider.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+keyVaultName
+
+string
+
+ |
+
+ keyVaultName is the name of the Azure Key Vault.
+ |
+
+
+
+keyName
+
+string
+
+ |
+
+ keyName is the name of the key in the vault.
+ |
+
+
+
+keyVersion
+
+string
+
+ |
+
+ keyVersion is the version of the key.
+ |
+
+
+
###AzureKMSSpec { #hypershift.openshift.io/v1beta1.AzureKMSSpec }
(Appears on:
@@ -3441,6 +3582,8 @@ AzureKMSKey
(Optional)
backupKey defines the old key during the rotation process so previously created
secrets can continue to be decrypted until they are all re-encrypted with the active key.
+Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+The system automatically manages the previous key via the status field.
@@ -5959,6 +6102,13 @@ A failure here often means a software bug or a non-stable cluster.
most recent etcd backup. True means the last backup completed successfully;
False means a backup is in progress or the last backup failed.
+
"EtcdDataEncryptionUpToDate" |
+EtcdDataEncryptionUpToDate indicates whether all etcd data is encrypted with the
+currently active encryption key.
+True: all data confirmed encrypted with the active key.
+False: re-encryption is in progress or has failed.
+Absent: encryption is not configured.
+ |
"EtcdRecoveryActive" |
EtcdRecoveryActive indicates that the Etcd cluster is failing and the
recovery job was triggered.
@@ -6844,6 +6994,168 @@ UserManagedDiagnostics
|
+###EncryptionKeyReference { #hypershift.openshift.io/v1beta1.EncryptionKeyReference }
+
+(Appears on:
+EncryptionMigrationHistory)
+
+
+
EncryptionKeyReference identifies an encryption key by its provider and fingerprint.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+provider
+
+
+SecretEncryptionProvider
+
+
+ |
+
+ provider identifies the encryption provider.
+ |
+
+
+
+fingerprint
+
+string
+
+ |
+
+ fingerprint is the hex-encoded SHA-256 hash of the key’s identity fields.
+ |
+
+
+
+###EncryptionMigrationHistory { #hypershift.openshift.io/v1beta1.EncryptionMigrationHistory }
+
+(Appears on:
+SecretEncryptionStatus)
+
+
+
EncryptionMigrationHistory records a key rotation, including in-progress rotations.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+from,omitzero
+
+
+EncryptionKeyReference
+
+
+ |
+
+ from is the key that data was migrated from (the previous active key).
+ |
+
+
+
+to,omitzero
+
+
+EncryptionKeyReference
+
+
+ |
+
+ to is the key that data was migrated to (the target key).
+ |
+
+
+
+state
+
+
+EncryptionMigrationState
+
+
+ |
+
+ state tracks the current phase of this rotation.
+ |
+
+
+
+startedTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ startedTime is when the rotation was initiated.
+ |
+
+
+
+completionTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ completionTime is when the rotation finished. Not set while the rotation is in progress.
+ |
+
+
+
+###EncryptionMigrationState { #hypershift.openshift.io/v1beta1.EncryptionMigrationState }
+
+(Appears on:
+EncryptionMigrationHistory)
+
+
+
EncryptionMigrationState tracks the lifecycle of a key rotation.
+
+
+
+
+| Value |
+Description |
+
+
+"Completed" |
+EncryptionMigrationStateCompleted means all data was successfully re-encrypted with the target key.
+ |
+
"Interrupted" |
+EncryptionMigrationStateInterrupted means the rotation was abandoned before data was encrypted
+with the target key (e.g., targetKey replaced during ReadOnlyDeploy).
+ |
+
"Migrating" |
+EncryptionMigrationStateMigrating means all KAS replicas have converged on the new write
+provider and re-encryption (StorageVersionMigration) is in progress.
+ |
+
"ReadOnlyDeploy" |
+EncryptionMigrationStateReadOnlyDeploy means the new key is being deployed as a read-only
+provider. The old key remains the write provider.
+ |
+
"WritePromote" |
+EncryptionMigrationStateWritePromote means the new key is being promoted to write provider.
+The old key becomes read-only.
+ |
+
+
###EtcdManagementType { #hypershift.openshift.io/v1beta1.EtcdManagementType }
(Appears on:
@@ -9628,6 +9940,20 @@ successful etcd backup snapshot. Persisted here because HCPEtcdBackup CRs
are ephemeral and may be deleted by retention policies.
+
+
+secretEncryption,omitzero
+
+
+SecretEncryptionStatus
+
+
+ |
+
+(Optional)
+ secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ |
+
###HostedControlPlaneSpec { #hypershift.openshift.io/v1beta1.HostedControlPlaneSpec }
@@ -10416,6 +10742,20 @@ ConfigurationStatus
configuration contains the cluster configuration status of the HostedCluster
+
+
+secretEncryption,omitzero
+
+
+SecretEncryptionStatus
+
+
+ |
+
+(Optional)
+ secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ |
+
###IBMCloudKMSAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSAuthSpec }
@@ -10577,6 +10917,91 @@ key is enabled for data encryption.
+###IBMCloudKMSKeyStatus { #hypershift.openshift.io/v1beta1.IBMCloudKMSKeyStatus }
+
+(Appears on:
+SecretEncryptionKeyStatus)
+
+
+
IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
+sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+crkID
+
+string
+
+ |
+
+ crkID is the Customer Root Key ID.
+ |
+
+
+
+instanceID
+
+string
+
+ |
+
+ instanceID is the KMS instance ID.
+ |
+
+
+
+keyVersion
+
+int32
+
+ |
+
+ keyVersion is the key version number.
+ |
+
+
+
+region
+
+string
+
+ |
+
+ region is the IBM Cloud region.
+ |
+
+
+
+correlationID
+
+string
+
+ |
+
+ correlationID is the correlation ID for the key.
+ |
+
+
+
+url
+
+string
+
+ |
+
+ url is the KMS endpoint URL.
+ |
+
+
+
###IBMCloudKMSManagedAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSManagedAuthSpec }
(Appears on:
@@ -15978,6 +16403,121 @@ When omitted, the autoscaler defaults to 50%.
+###SecretEncryptionKeyStatus { #hypershift.openshift.io/v1beta1.SecretEncryptionKeyStatus }
+
+(Appears on:
+SecretEncryptionStatus)
+
+
+
SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
+instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+provider
+
+
+SecretEncryptionProvider
+
+
+ |
+
+ provider identifies the encryption provider.
+ |
+
+
+
+azure,omitzero
+
+
+AzureKMSKeyStatus
+
+
+ |
+
+(Optional)
+ azure holds the Azure KMS key identity fields.
+ |
+
+
+
+aws,omitzero
+
+
+AWSKMSKeyStatus
+
+
+ |
+
+(Optional)
+ aws holds the AWS KMS key identity fields.
+ |
+
+
+
+ibmCloud,omitzero
+
+
+IBMCloudKMSKeyStatus
+
+
+ |
+
+(Optional)
+ ibmCloud holds the IBM Cloud KMS key identity fields.
+ |
+
+
+
+aescbc,omitzero
+
+
+AESCBCKeyStatus
+
+
+ |
+
+(Optional)
+ aescbc holds a reference to the AESCBC key secret.
+ |
+
+
+
+###SecretEncryptionProvider { #hypershift.openshift.io/v1beta1.SecretEncryptionProvider }
+
+(Appears on:
+EncryptionKeyReference,
+SecretEncryptionKeyStatus)
+
+
+
SecretEncryptionProvider identifies the encryption provider recorded in status.
+This is a separate type from KMSProvider because the KMSProvider enum does not include AESCBC.
+
+
+
+
+| Value |
+Description |
+
+
+"AESCBC" |
+ |
+
"AWS" |
+ |
+
"Azure" |
+ |
+
"IBMCloud" |
+ |
+
+
###SecretEncryptionSpec { #hypershift.openshift.io/v1beta1.SecretEncryptionSpec }
(Appears on:
@@ -16039,6 +16579,74 @@ AESCBCSpec
+###SecretEncryptionStatus { #hypershift.openshift.io/v1beta1.SecretEncryptionStatus }
+
+(Appears on:
+HostedClusterStatus,
+HostedControlPlaneStatus)
+
+
+
SecretEncryptionStatus tracks the state of secret encryption key rotation and re-encryption.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+activeKey,omitzero
+
+
+SecretEncryptionKeyStatus
+
+
+ |
+
+(Optional)
+ activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+Updated after successful re-encryption.
+ |
+
+
+
+targetKey,omitzero
+
+
+SecretEncryptionKeyStatus
+
+
+ |
+
+(Optional)
+ targetKey is the key being rolled out during an active rotation. Snapshot from
+spec.secretEncryption’s active key when the rotation starts. The CPO uses this
+(not the current spec) during the rotation, so mid-rotation spec changes are
+safely queued until the current rotation completes. Cleared when rotation completes.
+ |
+
+
+
+history
+
+
+[]EncryptionMigrationHistory
+
+
+ |
+
+(Optional)
+ history contains a list of key rotations applied to this cluster. The newest
+entry is first in the list. Entries have state Completed when re-encryption
+has finished. The current rotation phase is always history[0].state when
+history[0] is not Completed or Interrupted.
+ |
+
+
+
###SecretEncryptionType { #hypershift.openshift.io/v1beta1.SecretEncryptionType }
(Appears on:
From 5f0a579df235d9c34fa771d24c7a4b5c1011f8fb Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Thu, 21 May 2026 14:24:04 +0200
Subject: [PATCH 07/12] chore(api): sync vendored API types after rebase
Signed-off-by: Mulham Raee
Commit-Message-Assisted-by: Claude (via Claude Code)
---
.../hypershift/v1beta1/hosted_controlplane.go | 4 +
.../v1beta1/hostedcluster_conditions.go | 14 +
.../hypershift/v1beta1/hostedcluster_types.go | 145 ++++++++++
.../api/hypershift/v1beta1/ibmcloud.go | 35 +++
.../v1beta1/zz_generated.deepcopy.go | 143 ++++++++++
.../controllers/migrators/errors.go | 47 ++++
.../controllers/migrators/inprocess.go | 198 ++++++++++++++
.../migrators/inprocess_processor.go | 185 +++++++++++++
.../migrators/kubestorageversionmigrator.go | 120 +++++++++
.../controllers/migrators/metrics.go | 93 +++++++
.../encryption/controllers/migrators/types.go | 26 ++
vendor/modules.txt | 6 +
.../pkg/clients/informer/factory.go | 251 ++++++++++++++++++
.../pkg/clients/informer/generic.go | 64 +++++
.../internalinterfaces/factory_interfaces.go | 40 +++
.../clients/informer/migration/interface.go | 46 ++++
.../informer/migration/v1alpha1/interface.go | 52 ++++
.../migration/v1alpha1/storagestate.go | 89 +++++++
.../v1alpha1/storageversionmigration.go | 89 +++++++
.../migration/v1alpha1/expansion_generated.go | 27 ++
.../lister/migration/v1alpha1/storagestate.go | 68 +++++
.../v1alpha1/storageversionmigration.go | 68 +++++
22 files changed, 1810 insertions(+)
create mode 100644 vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/errors.go
create mode 100644 vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess.go
create mode 100644 vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess_processor.go
create mode 100644 vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/kubestorageversionmigrator.go
create mode 100644 vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/metrics.go
create mode 100644 vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/types.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/factory.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/generic.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces/factory_interfaces.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/interface.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/interface.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storagestate.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storageversionmigration.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/expansion_generated.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storagestate.go
create mode 100644 vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storageversionmigration.go
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
index 8486514f0a18..05a2fa60d220 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
@@ -419,6 +419,10 @@ type HostedControlPlaneStatus struct {
// configuration contains the cluster configuration status of the HostedCluster
// +optional
Configuration *ConfigurationStatus `json:"configuration,omitempty"`
+
+ // secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ // +optional
+ SecretEncryption SecretEncryptionStatus `json:"secretEncryption,omitzero"`
}
// APIEndpoint represents a reachable Kubernetes API endpoint.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go
index 9fda11a60a2c..374e52a4fefc 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go
@@ -265,6 +265,12 @@ const (
PublicEndpointSharedIngressConfiguredReason = "SharedIngressConfigured"
PublicEndpointTopologyPrivateReason = "TopologyPrivate"
PublicEndpointConvergenceInProgressReason = "ConvergenceInProgress"
+ // EtcdDataEncryptionUpToDate indicates whether all etcd data is encrypted with the
+ // currently active encryption key.
+ // True: all data confirmed encrypted with the active key.
+ // False: re-encryption is in progress or has failed.
+ // Absent: encryption is not configured.
+ EtcdDataEncryptionUpToDate ConditionType = "EtcdDataEncryptionUpToDate"
)
// Reasons.
@@ -349,6 +355,14 @@ const (
AutoNodeNotConfiguredReason = "AutoNodeNotConfigured"
AutoNodeProgressingReason = "AutoNodeProgressing"
AutoNodeEvaluationFailedReason = "AutoNodeEvaluationFailed"
+
+ ReadOnlyRolloutInProgressReason = "ReadOnlyRolloutInProgress"
+ WritePromotionInProgressReason = "WritePromotionInProgress"
+ ReEncryptionInProgressReason = "ReEncryptionInProgress"
+ ReEncryptionCompletedReason = "ReEncryptionCompleted"
+ ReEncryptionFailedReason = "ReEncryptionFailed"
+ ReEncryptionWaitingForKASReason = "ReEncryptionWaitingForKASConvergence"
+ ReEncryptionPersistentFailureReason = "ReEncryptionPersistentFailure"
)
// Messages.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_types.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_types.go
index 74b50f24ad38..98b7c1e9ba9d 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_types.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_types.go
@@ -2073,10 +2073,151 @@ type AESCBCSpec struct {
ActiveKey corev1.LocalObjectReference `json:"activeKey"`
// backupKey defines the old key during the rotation process so previously created
// secrets can continue to be decrypted until they are all re-encrypted with the active key.
+ //
+ // Deprecated: This field will be ignored when status.secretEncryption.activeKey is set.
+ // The system automatically manages the previous key via the status field.
// +optional
BackupKey *corev1.LocalObjectReference `json:"backupKey,omitempty"`
}
+// SecretEncryptionProvider identifies the encryption provider recorded in status.
+// This is a separate type from KMSProvider because the KMSProvider enum does not include AESCBC.
+type SecretEncryptionProvider string
+
+const (
+ SecretEncryptionProviderAzure SecretEncryptionProvider = "Azure"
+ SecretEncryptionProviderAWS SecretEncryptionProvider = "AWS"
+ SecretEncryptionProviderIBMCloud SecretEncryptionProvider = "IBMCloud"
+ SecretEncryptionProviderAESCBC SecretEncryptionProvider = "AESCBC"
+)
+
+// SecretEncryptionStatus tracks the state of secret encryption key rotation and re-encryption.
+// +k8s:deepcopy-gen=true
+// +kubebuilder:validation:MinProperties=1
+type SecretEncryptionStatus struct {
+ // activeKey is the encryption key specification that all etcd data is confirmed encrypted with.
+ // Updated after successful re-encryption.
+ // +optional
+ ActiveKey SecretEncryptionKeyStatus `json:"activeKey,omitzero"`
+ // targetKey is the key being rolled out during an active rotation. Snapshot from
+ // spec.secretEncryption's active key when the rotation starts. The CPO uses this
+ // (not the current spec) during the rotation, so mid-rotation spec changes are
+ // safely queued until the current rotation completes. Cleared when rotation completes.
+ // +optional
+ TargetKey SecretEncryptionKeyStatus `json:"targetKey,omitzero"`
+ // history contains a list of key rotations applied to this cluster. The newest
+ // entry is first in the list. Entries have state Completed when re-encryption
+ // has finished. The current rotation phase is always history[0].state when
+ // history[0] is not Completed or Interrupted.
+ // +optional
+ // +listType=atomic
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=5
+ History []EncryptionMigrationHistory `json:"history,omitempty"`
+}
+
+// SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
+// instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+// +k8s:deepcopy-gen=true
+// +kubebuilder:validation:XValidation:rule="self.provider == 'Azure' ? has(self.azure) : !has(self.azure)",message="azure is required when provider is Azure, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.provider == 'AWS' ? has(self.aws) : !has(self.aws)",message="aws is required when provider is AWS, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.provider == 'IBMCloud' ? has(self.ibmCloud) : !has(self.ibmCloud)",message="ibmCloud is required when provider is IBMCloud, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.provider == 'AESCBC' ? has(self.aescbc) : !has(self.aescbc)",message="aescbc is required when provider is AESCBC, and forbidden otherwise"
+// +union
+type SecretEncryptionKeyStatus struct {
+ // provider identifies the encryption provider.
+ // +required
+ // +unionDiscriminator
+ // +kubebuilder:validation:Enum=Azure;AWS;IBMCloud;AESCBC
+ Provider SecretEncryptionProvider `json:"provider,omitempty"`
+ // azure holds the Azure KMS key identity fields.
+ // +optional
+ // +unionMember
+ Azure AzureKMSKeyStatus `json:"azure,omitzero"`
+ // aws holds the AWS KMS key identity fields.
+ // +optional
+ // +unionMember
+ AWS AWSKMSKeyStatus `json:"aws,omitzero"`
+ // ibmCloud holds the IBM Cloud KMS key identity fields.
+ // +optional
+ // +unionMember
+ IBMCloud IBMCloudKMSKeyStatus `json:"ibmCloud,omitzero"`
+ // aescbc holds a reference to the AESCBC key secret.
+ // +optional
+ // +unionMember
+ AESCBC AESCBCKeyStatus `json:"aescbc,omitzero"`
+}
+
+// AESCBCKeyStatus contains a reference to the AESCBC key secret and a SHA-256 hash
+// of its contents for fingerprinting.
+// +k8s:deepcopy-gen=true
+type AESCBCKeyStatus struct {
+ // secret is a reference to the secret containing the AESCBC key.
+ // +required
+ Secret corev1.LocalObjectReference `json:"secret,omitempty"`
+ // dataHash is the hex-encoded SHA-256 hash of the secret's "key" data field
+ // at the time re-encryption completed.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=64
+ DataHash string `json:"dataHash,omitempty"`
+}
+
+// EncryptionKeyReference identifies an encryption key by its provider and fingerprint.
+// +k8s:deepcopy-gen=true
+type EncryptionKeyReference struct {
+ // provider identifies the encryption provider.
+ // +required
+ // +kubebuilder:validation:Enum=Azure;AWS;IBMCloud;AESCBC
+ Provider SecretEncryptionProvider `json:"provider,omitempty"`
+ // fingerprint is the hex-encoded SHA-256 hash of the key's identity fields.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=64
+ Fingerprint string `json:"fingerprint,omitempty"`
+}
+
+// EncryptionMigrationState tracks the lifecycle of a key rotation.
+// +kubebuilder:validation:Enum=ReadOnlyDeploy;WritePromote;Migrating;Completed;Interrupted
+type EncryptionMigrationState string
+
+const (
+ // EncryptionMigrationStateReadOnlyDeploy means the new key is being deployed as a read-only
+ // provider. The old key remains the write provider.
+ EncryptionMigrationStateReadOnlyDeploy EncryptionMigrationState = "ReadOnlyDeploy"
+ // EncryptionMigrationStateWritePromote means the new key is being promoted to write provider.
+ // The old key becomes read-only.
+ EncryptionMigrationStateWritePromote EncryptionMigrationState = "WritePromote"
+ // EncryptionMigrationStateMigrating means all KAS replicas have converged on the new write
+ // provider and re-encryption (StorageVersionMigration) is in progress.
+ EncryptionMigrationStateMigrating EncryptionMigrationState = "Migrating"
+ // EncryptionMigrationStateCompleted means all data was successfully re-encrypted with the target key.
+ EncryptionMigrationStateCompleted EncryptionMigrationState = "Completed"
+ // EncryptionMigrationStateInterrupted means the rotation was abandoned before data was encrypted
+ // with the target key (e.g., targetKey replaced during ReadOnlyDeploy).
+ EncryptionMigrationStateInterrupted EncryptionMigrationState = "Interrupted"
+)
+
+// EncryptionMigrationHistory records a key rotation, including in-progress rotations.
+// +k8s:deepcopy-gen=true
+type EncryptionMigrationHistory struct {
+ // from is the key that data was migrated from (the previous active key).
+ // +required
+ From EncryptionKeyReference `json:"from,omitzero"`
+ // to is the key that data was migrated to (the target key).
+ // +required
+ To EncryptionKeyReference `json:"to,omitzero"`
+ // state tracks the current phase of this rotation.
+ // +required
+ State EncryptionMigrationState `json:"state,omitempty"`
+ // startedTime is when the rotation was initiated.
+ // +required
+ StartedTime metav1.Time `json:"startedTime,omitempty"`
+ // completionTime is when the rotation finished. Not set while the rotation is in progress.
+ // +optional
+ CompletionTime *metav1.Time `json:"completionTime,omitempty"`
+}
+
type PayloadArchType string
const (
@@ -2190,6 +2331,10 @@ type HostedClusterStatus struct {
// +kubebuilder:validation:MaxLength=2048
// +kubebuilder:validation:XValidation:rule="self.matches('^(https|s3)://.*')",message="lastSuccessfulEtcdBackupURL must be a valid URL with scheme https or s3"
LastSuccessfulEtcdBackupURL string `json:"lastSuccessfulEtcdBackupURL,omitempty"`
+
+ // secretEncryption tracks the state of secret encryption key rotation and re-encryption.
+ // +optional
+ SecretEncryption SecretEncryptionStatus `json:"secretEncryption,omitzero"`
}
// AutoNodeStatus contains the observed state of the AutoNode provisioner.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/ibmcloud.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/ibmcloud.go
index 0f824883e300..bad0e9c3c1c0 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/ibmcloud.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/ibmcloud.go
@@ -44,6 +44,41 @@ type IBMCloudKMSKeyEntry struct {
KeyVersion int `json:"keyVersion"`
}
+// IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
+// sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
+// +k8s:deepcopy-gen=true
+type IBMCloudKMSKeyStatus struct {
+ // crkID is the Customer Root Key ID.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ CRKID string `json:"crkID,omitempty"`
+ // instanceID is the KMS instance ID.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ InstanceID string `json:"instanceID,omitempty"`
+ // keyVersion is the key version number.
+ // +required
+ // +kubebuilder:validation:Minimum=0
+ KeyVersion int32 `json:"keyVersion,omitempty"`
+ // region is the IBM Cloud region.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ Region string `json:"region,omitempty"`
+ // correlationID is the correlation ID for the key.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=255
+ CorrelationID string `json:"correlationID,omitempty"`
+ // url is the KMS endpoint URL.
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=2048
+ URL string `json:"url,omitempty"`
+}
+
// IBMCloudKMSAuthSpec defines metadata for how authentication is done with IBM Cloud KMS
type IBMCloudKMSAuthSpec struct {
// type defines the IBM Cloud KMS authentication strategy
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 454f86378499..33601892dd28 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -29,6 +29,22 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AESCBCKeyStatus) DeepCopyInto(out *AESCBCKeyStatus) {
+ *out = *in
+ out.Secret = in.Secret
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AESCBCKeyStatus.
+func (in *AESCBCKeyStatus) DeepCopy() *AESCBCKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AESCBCKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AESCBCSpec) DeepCopyInto(out *AESCBCSpec) {
*out = *in
@@ -256,6 +272,21 @@ func (in *AWSKMSKeyEntry) DeepCopy() *AWSKMSKeyEntry {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSKMSKeyStatus) DeepCopyInto(out *AWSKMSKeyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSKMSKeyStatus.
+func (in *AWSKMSKeyStatus) DeepCopy() *AWSKMSKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AWSKMSKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSKMSSpec) DeepCopyInto(out *AWSKMSSpec) {
*out = *in
@@ -641,6 +672,21 @@ func (in *AzureKMSKey) DeepCopy() *AzureKMSKey {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureKMSKeyStatus) DeepCopyInto(out *AzureKMSKeyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKMSKeyStatus.
+func (in *AzureKMSKeyStatus) DeepCopy() *AzureKMSKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(AzureKMSKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureKMSSpec) DeepCopyInto(out *AzureKMSSpec) {
*out = *in
@@ -1615,6 +1661,43 @@ func (in *Diagnostics) DeepCopy() *Diagnostics {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EncryptionKeyReference) DeepCopyInto(out *EncryptionKeyReference) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EncryptionKeyReference.
+func (in *EncryptionKeyReference) DeepCopy() *EncryptionKeyReference {
+ if in == nil {
+ return nil
+ }
+ out := new(EncryptionKeyReference)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EncryptionMigrationHistory) DeepCopyInto(out *EncryptionMigrationHistory) {
+ *out = *in
+ out.From = in.From
+ out.To = in.To
+ in.StartedTime.DeepCopyInto(&out.StartedTime)
+ if in.CompletionTime != nil {
+ in, out := &in.CompletionTime, &out.CompletionTime
+ *out = (*in).DeepCopy()
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EncryptionMigrationHistory.
+func (in *EncryptionMigrationHistory) DeepCopy() *EncryptionMigrationHistory {
+ if in == nil {
+ return nil
+ }
+ out := new(EncryptionMigrationHistory)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EtcdSpec) DeepCopyInto(out *EtcdSpec) {
*out = *in
@@ -2461,6 +2544,7 @@ func (in *HostedClusterStatus) DeepCopyInto(out *HostedClusterStatus) {
*out = new(ConfigurationStatus)
(*in).DeepCopyInto(*out)
}
+ in.SecretEncryption.DeepCopyInto(&out.SecretEncryption)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedClusterStatus.
@@ -2697,6 +2781,7 @@ func (in *HostedControlPlaneStatus) DeepCopyInto(out *HostedControlPlaneStatus)
*out = new(ConfigurationStatus)
(*in).DeepCopyInto(*out)
}
+ in.SecretEncryption.DeepCopyInto(&out.SecretEncryption)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedControlPlaneStatus.
@@ -2749,6 +2834,21 @@ func (in *IBMCloudKMSKeyEntry) DeepCopy() *IBMCloudKMSKeyEntry {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IBMCloudKMSKeyStatus) DeepCopyInto(out *IBMCloudKMSKeyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMCloudKMSKeyStatus.
+func (in *IBMCloudKMSKeyStatus) DeepCopy() *IBMCloudKMSKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(IBMCloudKMSKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IBMCloudKMSManagedAuthSpec) DeepCopyInto(out *IBMCloudKMSManagedAuthSpec) {
*out = *in
@@ -4423,6 +4523,25 @@ func (in *ScaleDownConfig) DeepCopy() *ScaleDownConfig {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecretEncryptionKeyStatus) DeepCopyInto(out *SecretEncryptionKeyStatus) {
+ *out = *in
+ out.Azure = in.Azure
+ out.AWS = in.AWS
+ out.IBMCloud = in.IBMCloud
+ out.AESCBC = in.AESCBC
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretEncryptionKeyStatus.
+func (in *SecretEncryptionKeyStatus) DeepCopy() *SecretEncryptionKeyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(SecretEncryptionKeyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretEncryptionSpec) DeepCopyInto(out *SecretEncryptionSpec) {
*out = *in
@@ -4448,6 +4567,30 @@ func (in *SecretEncryptionSpec) DeepCopy() *SecretEncryptionSpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecretEncryptionStatus) DeepCopyInto(out *SecretEncryptionStatus) {
+ *out = *in
+ out.ActiveKey = in.ActiveKey
+ out.TargetKey = in.TargetKey
+ if in.History != nil {
+ in, out := &in.History, &out.History
+ *out = make([]EncryptionMigrationHistory, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretEncryptionStatus.
+func (in *SecretEncryptionStatus) DeepCopy() *SecretEncryptionStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(SecretEncryptionStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretReference) DeepCopyInto(out *SecretReference) {
*out = *in
diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/errors.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/errors.go
new file mode 100644
index 000000000000..6b153a91bf7d
--- /dev/null
+++ b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/errors.go
@@ -0,0 +1,47 @@
+/*
+Copyright 2018 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrators
+
+import (
+ "strings"
+
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/util/net"
+ "k8s.io/utils/ptr"
+)
+
+// isConnectionRefusedError checks if the error string include "connection refused"
+// TODO: find a "go-way" to detect this error, probably using *os.SyscallError
+func isConnectionRefusedError(err error) bool {
+ return strings.Contains(err.Error(), "connection refused")
+}
+
+// canRetry returns false if the provided error indicates a retry is
+// impossible. It returns true if the error is possibly temporary. It returns
+// nil for all other error where it is unclear.
+func canRetry(err error) *bool {
+ switch {
+ case err == nil:
+ return nil
+ case errors.IsNotFound(err), errors.IsMethodNotSupported(err):
+ return ptr.To(false)
+ case errors.IsConflict(err), errors.IsServerTimeout(err), errors.IsTooManyRequests(err), net.IsProbableEOF(err), net.IsConnectionReset(err), net.IsNoRoutesError(err), isConnectionRefusedError(err):
+ return ptr.To(true)
+ default:
+ return nil
+ }
+}
diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess.go
new file mode 100644
index 000000000000..2a9c1e6022dc
--- /dev/null
+++ b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess.go
@@ -0,0 +1,198 @@
+package migrators
+
+import (
+ "context"
+ "fmt"
+ "sync"
+ "time"
+
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/client-go/discovery"
+ "k8s.io/client-go/dynamic"
+ "k8s.io/client-go/tools/cache"
+ "k8s.io/klog/v2"
+)
+
+func NewInProcessMigrator(dynamicClient dynamic.Interface, discoveryClient discovery.ServerResourcesInterface) *InProcessMigrator {
+ return &InProcessMigrator{
+ dynamicClient: dynamicClient,
+ discoveryClient: discoveryClient,
+ running: map[schema.GroupResource]*inProcessMigration{},
+ }
+}
+
+// InProcessMigrator runs migration in-process using paging.
+type InProcessMigrator struct {
+ dynamicClient dynamic.Interface
+ discoveryClient discovery.ServerResourcesInterface
+
+ lock sync.Mutex
+ running map[schema.GroupResource]*inProcessMigration
+
+ handler cache.ResourceEventHandler
+}
+
+func (m *InProcessMigrator) HasSynced() bool {
+ return true
+}
+
+type inProcessMigration struct {
+ stopCh chan<- struct{}
+ doneCh <-chan struct{}
+ writeKey string
+
+ // non-nil when finished. *result==nil means "no error"
+ result *error
+ // when did it finish
+ timestamp time.Time
+}
+
+var _ Migrator = &InProcessMigrator{}
+
+func (m *InProcessMigrator) EnsureMigration(gr schema.GroupResource, writeKey string) (finished bool, result error, ts time.Time, err error) {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+
+ // finished?
+ migration := m.running[gr]
+ if migration != nil && migration.writeKey == writeKey {
+ if migration.result == nil {
+ return false, nil, time.Time{}, nil
+ }
+ return true, *migration.result, migration.timestamp, nil
+ }
+
+ // different key?
+ if migration != nil && migration.result == nil {
+ klog.V(2).Infof("Interrupting running migration for resource %v and write key %q", gr, migration.writeKey)
+ close(migration.stopCh)
+
+ // give go routine time to update the result
+ m.lock.Unlock()
+ <-migration.doneCh
+ m.lock.Lock()
+ }
+
+ v, err := preferredResourceVersion(m.discoveryClient, gr)
+ if err != nil {
+ return false, nil, time.Time{}, err
+ }
+
+ stopCh := make(chan struct{})
+ doneCh := make(chan struct{})
+ m.running[gr] = &inProcessMigration{
+ stopCh: stopCh,
+ doneCh: doneCh,
+ writeKey: writeKey,
+ }
+
+ go m.runMigration(gr.WithVersion(v), writeKey, stopCh, doneCh)
+
+ return false, nil, time.Time{}, nil
+}
+
+func (m *InProcessMigrator) runMigration(gvr schema.GroupVersionResource, writeKey string, stopCh <-chan struct{}, doneCh chan<- struct{}) {
+ var result error
+
+ defer close(doneCh)
+ defer func() {
+ if r := recover(); r != nil {
+ if err, ok := r.(error); ok {
+ result = err
+ } else {
+ result = fmt.Errorf("panic: %v", r)
+ }
+ }
+
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ migration := m.running[gvr.GroupResource()]
+ if migration == nil || migration.writeKey != writeKey {
+ // ok, this is not us. Should never happen.
+ return
+ }
+
+ migration.result = &result
+ migration.timestamp = time.Now()
+
+ m.handler.OnAdd(&corev1.Secret{}, false) // fake secret to trigger event loop of controller
+ }()
+
+ ctx, cancelFn := context.WithCancel(context.Background())
+ defer cancelFn()
+ go func() {
+ <-stopCh
+ cancelFn()
+ }()
+
+ d := m.dynamicClient.Resource(gvr)
+
+ listProcessor := newListProcessor(ctx, m.dynamicClient, func(obj *unstructured.Unstructured) error {
+ for {
+ _, updateErr := d.Namespace(obj.GetNamespace()).Update(ctx, obj, metav1.UpdateOptions{})
+ if updateErr == nil || errors.IsNotFound(updateErr) || errors.IsConflict(updateErr) {
+ return nil
+ }
+ if retryable := canRetry(updateErr); retryable == nil || *retryable == false {
+ klog.Warningf("Update of %s/%s failed: %v", obj.GetNamespace(), obj.GetName(), updateErr)
+ return updateErr // not retryable or we don't know. Return error and controller will restart migration.
+ }
+ if seconds, delay := errors.SuggestsClientDelay(updateErr); delay && seconds > 0 {
+ klog.V(2).Infof("Sleeping %ds while updating %s/%s of type %v after retryable error: %v", seconds, obj.GetNamespace(), obj.GetName(), gvr, updateErr)
+ time.Sleep(time.Duration(seconds) * time.Second)
+ }
+ }
+ })
+ result = listProcessor.run(ctx, gvr)
+}
+
+func (m *InProcessMigrator) PruneMigration(gr schema.GroupResource) error {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+
+ migration := m.running[gr]
+ delete(m.running, gr)
+
+ // finished?
+ if migration != nil && migration.result == nil {
+ close(migration.stopCh)
+
+ // give go routine time to update the result
+ m.lock.Unlock()
+ <-migration.doneCh
+ m.lock.Lock()
+ }
+
+ return nil
+}
+
+func (m *InProcessMigrator) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
+ m.handler = handler
+ return nil, nil
+}
+
+func preferredResourceVersion(c discovery.ServerResourcesInterface, gr schema.GroupResource) (string, error) {
+ resourceLists, discoveryErr := c.ServerPreferredResources() // safe to ignore error
+ for _, resourceList := range resourceLists {
+ groupVersion, err := schema.ParseGroupVersion(resourceList.GroupVersion)
+ if err != nil {
+ return "", err
+ }
+ if groupVersion.Group != gr.Group {
+ continue
+ }
+ for _, resource := range resourceList.APIResources {
+ if (len(resource.Group) == 0 || resource.Group == gr.Group) && resource.Name == gr.Resource {
+ if len(resource.Version) > 0 {
+ return resource.Version, nil
+ }
+ return groupVersion.Version, nil
+ }
+ }
+ }
+ return "", fmt.Errorf("failed to find version for %s, discoveryErr=%v", gr, discoveryErr)
+}
diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess_processor.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess_processor.go
new file mode 100644
index 000000000000..8cff939bbc2a
--- /dev/null
+++ b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/inprocess_processor.go
@@ -0,0 +1,185 @@
+package migrators
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+ "sync"
+ "time"
+
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ utilerrors "k8s.io/apimachinery/pkg/util/errors"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ "k8s.io/client-go/dynamic"
+ "k8s.io/client-go/tools/pager"
+ "k8s.io/klog/v2"
+)
+
+const (
+ defaultConcurrency = 10
+)
+
+// workerFunc function that is executed by workers to process a single item
+type workerFunc func(*unstructured.Unstructured) error
+
+// listProcessor represents a type that processes resources in parallel.
+// It retrieves resources from the server in batches and distributes among set of workers.
+type listProcessor struct {
+ concurrency int
+ workerFn workerFunc
+ dynamicClient dynamic.Interface
+ ctx context.Context
+}
+
+// newListProcessor creates a new instance of listProcessor
+func newListProcessor(ctx context.Context, dynamicClient dynamic.Interface, workerFn workerFunc) *listProcessor {
+ return &listProcessor{
+ concurrency: defaultConcurrency,
+ workerFn: workerFn,
+ dynamicClient: dynamicClient,
+ ctx: ctx,
+ }
+}
+
+// run starts processing all the instance of the given GVR in batches.
+// Note that this operation block until all resources have been process, we can't get the next page or the context has been cancelled
+func (p *listProcessor) run(ctx context.Context, gvr schema.GroupVersionResource) error {
+ listPager := pager.New(pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.Object, error) {
+ for {
+ allResource, err := p.dynamicClient.Resource(gvr).List(ctx, opts)
+ if err != nil {
+ klog.Warningf("List of %v failed: %v", gvr, err)
+ if errors.IsResourceExpired(err) {
+ token, err := inconsistentContinueToken(err)
+ if err != nil {
+ return nil, err
+ }
+ opts.Continue = token
+ klog.V(2).Infof("Relisting %v after handling expired token", gvr)
+ continue
+ } else if retryable := canRetry(err); retryable == nil || *retryable == false {
+ return nil, err // not retryable or we don't know. Return error and controller will restart migration.
+ } else {
+ if seconds, delay := errors.SuggestsClientDelay(err); delay {
+ time.Sleep(time.Duration(seconds) * time.Second)
+ }
+ klog.V(2).Infof("Relisting %v after retryable error: %v", gvr, err)
+ continue
+ }
+ }
+
+ migrationStarted := time.Now()
+ klog.V(2).Infof("Migrating %d objects of %v", len(allResource.Items), gvr)
+ if err = p.processList(allResource, gvr); err != nil {
+ klog.Warningf("Migration of %v failed after %v: %v", gvr, time.Now().Sub(migrationStarted), err)
+ return nil, err
+ }
+ klog.V(2).Infof("Migration of %d objects of %v finished in %v", len(allResource.Items), gvr, time.Now().Sub(migrationStarted))
+
+ allResource.Items = nil // do not accumulate items, this fakes the visitor pattern
+ return allResource, nil // leave the rest of the list intact to preserve continue token
+ }
+ }))
+ listPager.FullListIfExpired = false // prevent memory explosion from full list
+
+ migrationStarted := time.Now()
+ if _, _, err := listPager.List(p.ctx, metav1.ListOptions{}); err != nil {
+ metrics.ObserveFailedMigration(gvr.String())
+ return err
+ }
+ migrationDuration := time.Now().Sub(migrationStarted)
+ klog.V(2).Infof("Migration for %v finished in %v", gvr, migrationDuration)
+ metrics.ObserveSucceededMigration(gvr.String())
+ metrics.ObserveSucceededMigrationDuration(migrationDuration.Seconds(), gvr.String())
+ return nil
+}
+
+func (p *listProcessor) processList(l *unstructured.UnstructuredList, gvr schema.GroupVersionResource) error {
+ workCh := make(chan *unstructured.Unstructured, p.concurrency)
+ ctx, cancel := context.WithCancel(p.ctx)
+ defer cancel()
+
+ processed := 0
+ go func() {
+ defer utilruntime.HandleCrash()
+ defer close(workCh)
+ for i := range l.Items {
+ select {
+ case workCh <- &l.Items[i]:
+ processed++
+ case <-ctx.Done():
+ return
+ }
+ }
+ }()
+
+ var wg sync.WaitGroup
+ errCh := make(chan error, p.concurrency)
+ for i := 0; i < p.concurrency; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ if err := p.worker(workCh, gvr); err != nil {
+ errCh <- err
+ cancel() // stop everything when the first worker errors
+ }
+ }()
+ }
+ wg.Wait()
+ close(errCh)
+
+ var errs []error
+ for err := range errCh {
+ errs = append(errs, err)
+ }
+ if len(errs) > 0 {
+ return utilerrors.NewAggregate(errs)
+ }
+ if processed < len(l.Items) {
+ return fmt.Errorf("context cancelled")
+ }
+ return nil
+}
+
+func (p *listProcessor) worker(workCh <-chan *unstructured.Unstructured, gvr schema.GroupVersionResource) (result error) {
+ defer func() {
+ if r := recover(); r != nil {
+ if err, ok := r.(error); ok {
+ result = err
+ } else {
+ result = fmt.Errorf("panic: %v", r)
+ }
+ }
+ }()
+
+ for item := range workCh {
+ err := p.workerFn(item)
+ metrics.ObserveObjectsMigrated(1, gvr.String())
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// inconsistentContinueToken extracts the continue token from the response which might be used to retrieve the remainder of the results
+//
+// Note:
+// continuing with the provided token might result in an inconsistent list. Objects that were created,
+// modified, or deleted between the time the first chunk was returned and now may show up in the list.
+func inconsistentContinueToken(err error) (string, error) {
+ status, ok := err.(errors.APIStatus)
+ if !ok {
+ return "", fmt.Errorf("expected error to implement the APIStatus interface, got %v", reflect.TypeOf(err))
+ }
+ token := status.Status().ListMeta.Continue
+ if len(token) == 0 {
+ return "", fmt.Errorf("expected non empty continue token")
+ }
+ return token, nil
+}
diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/kubestorageversionmigrator.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/kubestorageversionmigrator.go
new file mode 100644
index 000000000000..e270eef7446a
--- /dev/null
+++ b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/kubestorageversionmigrator.go
@@ -0,0 +1,120 @@
+package migrators
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/client-go/discovery"
+ "k8s.io/client-go/tools/cache"
+ migrationv1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1"
+ kubemigratorclient "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset"
+ migrationv1alpha1informer "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1"
+)
+
+const writeKeyAnnotationKey = "encryption.apiserver.operator.openshift.io/write-key"
+
+func NewKubeStorageVersionMigrator(client kubemigratorclient.Interface, informer migrationv1alpha1informer.Interface, discoveryClient discovery.ServerResourcesInterface) *KubeStorageVersionMigrator {
+ return &KubeStorageVersionMigrator{
+ discoveryClient: discoveryClient,
+ client: client,
+ informer: informer,
+ }
+}
+
+// KubeStorageVersionMigrator runs migration through the kube-storage-version-migrator components,
+// driven by CustomResources.
+type KubeStorageVersionMigrator struct {
+ discoveryClient discovery.ServerResourcesInterface
+ client kubemigratorclient.Interface
+ informer migrationv1alpha1informer.Interface
+ cacheSynced func() bool
+}
+
+func (m *KubeStorageVersionMigrator) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
+ informer := m.informer.StorageVersionMigrations().Informer()
+ registration, err := informer.AddEventHandler(handler)
+ if err != nil {
+ return nil, err
+ }
+ m.cacheSynced = informer.HasSynced
+ return registration, nil
+}
+
+func (m *KubeStorageVersionMigrator) HasSynced() bool {
+ return m.cacheSynced()
+}
+
+func (m *KubeStorageVersionMigrator) EnsureMigration(gr schema.GroupResource, writeKey string) (finished bool, result error, ts time.Time, err error) {
+ name := migrationResourceName(gr)
+ if migration, err := m.informer.StorageVersionMigrations().Lister().Get(name); err != nil && !errors.IsNotFound(err) {
+ return false, nil, time.Time{}, err
+ } else if err == nil && migration.Annotations[writeKeyAnnotationKey] == writeKey {
+ for _, c := range migration.Status.Conditions {
+ switch c.Type {
+ case migrationv1alpha1.MigrationSucceeded:
+ if c.Status == corev1.ConditionTrue {
+ return true, nil, c.LastUpdateTime.Time, nil
+ }
+ case migrationv1alpha1.MigrationFailed:
+ if c.Status == corev1.ConditionTrue {
+ return true, fmt.Errorf("migration of %s for key %q failed: %s", gr, writeKey, c.Message), c.LastUpdateTime.Time, nil
+ }
+ }
+ }
+ return false, nil, time.Time{}, nil
+ } else if err == nil {
+ if err := m.client.MigrationV1alpha1().StorageVersionMigrations().Delete(context.TODO(), name, metav1.DeleteOptions{
+ Preconditions: &metav1.Preconditions{ResourceVersion: &migration.ResourceVersion},
+ }); err != nil && !errors.IsNotFound(err) {
+ return false, nil, time.Time{}, err
+ }
+ }
+
+ v, err := preferredResourceVersion(m.discoveryClient, gr)
+ if err != nil {
+ return false, nil, time.Time{}, err
+ }
+
+ _, err = m.client.MigrationV1alpha1().StorageVersionMigrations().Create(context.TODO(), &migrationv1alpha1.StorageVersionMigration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Annotations: map[string]string{
+ writeKeyAnnotationKey: writeKey,
+ },
+ },
+ Spec: migrationv1alpha1.StorageVersionMigrationSpec{
+ Resource: migrationv1alpha1.GroupVersionResource{
+ Group: gr.Group,
+ Version: v,
+ Resource: gr.Resource,
+ },
+ },
+ }, metav1.CreateOptions{})
+
+ return false, nil, time.Time{}, err
+}
+
+func (m *KubeStorageVersionMigrator) PruneMigration(gr schema.GroupResource) error {
+ name := migrationResourceName(gr)
+ if err := m.client.MigrationV1alpha1().StorageVersionMigrations().Delete(context.TODO(), name, metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) {
+ return err
+ }
+ return nil
+}
+
+func migrationResourceName(gr schema.GroupResource) string {
+ return fmt.Sprintf("encryption-migration-%s-%s", groupToHumanReadable(gr), gr.Resource)
+}
+
+func groupToHumanReadable(gr schema.GroupResource) string {
+ group := gr.Group
+ if len(group) == 0 {
+ group = "core"
+ }
+ return group
+}
diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/metrics.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/metrics.go
new file mode 100644
index 000000000000..54a2e8d1c1bb
--- /dev/null
+++ b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/metrics.go
@@ -0,0 +1,93 @@
+package migrators
+
+import (
+ "github.com/prometheus/client_golang/prometheus"
+
+ k8smetrics "k8s.io/component-base/metrics"
+ "k8s.io/component-base/metrics/legacyregistry"
+)
+
+const (
+ namespace = "storage_migrator"
+ subsystem = "core_migrator"
+)
+
+// metrics provides access to all core migrator metrics.
+var metrics *migratorMetrics
+
+func init() {
+ metrics = newMigratorMetrics(legacyregistry.Register)
+}
+
+// migratorMetrics instruments core migrator with prometheus metrics.
+type migratorMetrics struct {
+ objectsMigrated *k8smetrics.CounterVec
+ migration *k8smetrics.CounterVec
+ migrationDuration *k8smetrics.HistogramVec
+}
+
+// newMigratorMetrics create a new MigratorMetrics, configured with default metric names.
+func newMigratorMetrics(registerFunc func(k8smetrics.Registerable) error) *migratorMetrics {
+ // objectMigrates is defined in kube-storave-version-migrator
+ objectsMigrated := k8smetrics.NewCounterVec(
+ &k8smetrics.CounterOpts{
+ Namespace: namespace,
+ Subsystem: subsystem,
+ Name: "migrated_objects",
+ Help: "The total number of objects that have been migrated, labeled with the full resource name",
+ }, []string{"resource"})
+ registerFunc(objectsMigrated)
+
+ // migration is defined in kube-storave-version-migrator
+ migration := k8smetrics.NewCounterVec(
+ &k8smetrics.CounterOpts{
+ Namespace: namespace,
+ Subsystem: subsystem,
+ Name: "migrations",
+ Help: "The total number of completed migration, labeled with the full resource name, and the status of the migration (failed or succeeded)",
+ }, []string{"resource", "status"})
+ registerFunc(migration)
+
+ // migrationDuration is not defined upstream but uses the same Namespace and Subsystem
+ // as the other metrics that are defined in kube-storave-version-migrator
+ migrationDuration := k8smetrics.NewHistogramVec(
+ &k8smetrics.HistogramOpts{
+ Namespace: namespace,
+ Subsystem: subsystem,
+ Name: "migration_duration_seconds",
+ Help: "How long a successful migration takes in seconds, labeled with the full resource name",
+ Buckets: prometheus.ExponentialBuckets(120, 2, 7),
+ }, []string{"resource"})
+ registerFunc(migrationDuration)
+
+ return &migratorMetrics{
+ objectsMigrated: objectsMigrated,
+ migration: migration,
+ migrationDuration: migrationDuration,
+ }
+}
+
+func (m *migratorMetrics) Reset() {
+ m.objectsMigrated.Reset()
+ m.migration.Reset()
+}
+
+// ObserveObjectsMigrated adds the number of migrated objects for a resource type
+func (m *migratorMetrics) ObserveObjectsMigrated(added int, resource string) {
+ m.objectsMigrated.WithLabelValues(resource).Add(float64(added))
+}
+
+// ObserveSucceededMigration increments the number of successful migrations for a resource type
+func (m *migratorMetrics) ObserveSucceededMigration(resource string) {
+ m.migration.WithLabelValues(resource, "Succeeded").Add(float64(1))
+}
+
+// ObserveFailedMigration increments the number of failed migrations for a resource type
+func (m *migratorMetrics) ObserveFailedMigration(resource string) {
+ m.migration.WithLabelValues(resource, "Failed").Add(float64(1))
+}
+
+// ObserveMigrationDuration records migration duration in seconds for a resource type
+func (m *migratorMetrics) ObserveSucceededMigrationDuration(seconds float64, resource string) {
+ m.migrationDuration.WithLabelValues(resource).Observe(seconds)
+}
diff --git a/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/types.go b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/types.go
new file mode 100644
index 000000000000..3b6623ff0e63
--- /dev/null
+++ b/vendor/github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators/types.go
@@ -0,0 +1,26 @@
+package migrators
+
+import (
+ "time"
+
+ "k8s.io/apimachinery/pkg/runtime/schema"
+
+ "github.com/openshift/library-go/pkg/controller/factory"
+)
+
+// Migrator is a resource migration mechanism.
+type Migrator interface {
+ // EnsureMigration starts a migration if it does not exist. If a migration of
+ // the same write-key exists and is finished (with or without error), nothing happens.
+ // If a migration of another key exists, that migration is deleted first before
+ // starting a new one. This function is idem-potent as long as a running or finished
+ // migration is not pruned.
+ // If finished is true, result is the result of the migration, with nil meaning that it
+ // finished successfully. The timestamp shows when it has been finished.
+ EnsureMigration(gr schema.GroupResource, writeKey string) (finished bool, result error, ts time.Time, err error)
+ // PruneMigration removes a migration, independently whether it is running or finished,
+ // with error or not. If there is no migration, this must not return an error.
+ PruneMigration(gr schema.GroupResource) error
+
+ factory.Informer
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 5c8b8c880d96..73730f9bbe30 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1161,6 +1161,7 @@ github.com/openshift/library-go/pkg/network
github.com/openshift/library-go/pkg/operator/apiserver/audit
github.com/openshift/library-go/pkg/operator/certrotation
github.com/openshift/library-go/pkg/operator/condition
+github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators
github.com/openshift/library-go/pkg/operator/events
github.com/openshift/library-go/pkg/operator/management
github.com/openshift/library-go/pkg/operator/resource/resourceapply
@@ -2703,6 +2704,11 @@ sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1
sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset
sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset/scheme
sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset/typed/migration/v1alpha1
+sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer
+sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces
+sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration
+sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1
+sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1
# sigs.k8s.io/kustomize/api v0.21.0
## explicit; go 1.24.0
sigs.k8s.io/kustomize/api/filters/annotations
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/factory.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/factory.go
new file mode 100644
index 000000000000..6c8c2d69b283
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/factory.go
@@ -0,0 +1,251 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package informer
+
+import (
+ reflect "reflect"
+ sync "sync"
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ cache "k8s.io/client-go/tools/cache"
+ clientset "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset"
+ internalinterfaces "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces"
+ migration "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration"
+)
+
+// SharedInformerOption defines the functional option type for SharedInformerFactory.
+type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
+
+type sharedInformerFactory struct {
+ client clientset.Interface
+ namespace string
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+ lock sync.Mutex
+ defaultResync time.Duration
+ customResync map[reflect.Type]time.Duration
+
+ informers map[reflect.Type]cache.SharedIndexInformer
+ // startedInformers is used for tracking which informers have been started.
+ // This allows Start() to be called multiple times safely.
+ startedInformers map[reflect.Type]bool
+ // wg tracks how many goroutines were started.
+ wg sync.WaitGroup
+ // shuttingDown is true when Shutdown has been called. It may still be running
+ // because it needs to wait for goroutines.
+ shuttingDown bool
+}
+
+// WithCustomResyncConfig sets a custom resync period for the specified informer types.
+func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
+ return func(factory *sharedInformerFactory) *sharedInformerFactory {
+ for k, v := range resyncConfig {
+ factory.customResync[reflect.TypeOf(k)] = v
+ }
+ return factory
+ }
+}
+
+// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
+func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
+ return func(factory *sharedInformerFactory) *sharedInformerFactory {
+ factory.tweakListOptions = tweakListOptions
+ return factory
+ }
+}
+
+// WithNamespace limits the SharedInformerFactory to the specified namespace.
+func WithNamespace(namespace string) SharedInformerOption {
+ return func(factory *sharedInformerFactory) *sharedInformerFactory {
+ factory.namespace = namespace
+ return factory
+ }
+}
+
+// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
+func NewSharedInformerFactory(client clientset.Interface, defaultResync time.Duration) SharedInformerFactory {
+ return NewSharedInformerFactoryWithOptions(client, defaultResync)
+}
+
+// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
+// Listers obtained via this SharedInformerFactory will be subject to the same filters
+// as specified here.
+// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
+func NewFilteredSharedInformerFactory(client clientset.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
+ return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
+}
+
+// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
+func NewSharedInformerFactoryWithOptions(client clientset.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
+ factory := &sharedInformerFactory{
+ client: client,
+ namespace: v1.NamespaceAll,
+ defaultResync: defaultResync,
+ informers: make(map[reflect.Type]cache.SharedIndexInformer),
+ startedInformers: make(map[reflect.Type]bool),
+ customResync: make(map[reflect.Type]time.Duration),
+ }
+
+ // Apply all options
+ for _, opt := range options {
+ factory = opt(factory)
+ }
+
+ return factory
+}
+
+func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ if f.shuttingDown {
+ return
+ }
+
+ for informerType, informer := range f.informers {
+ if !f.startedInformers[informerType] {
+ f.wg.Add(1)
+ // We need a new variable in each loop iteration,
+ // otherwise the goroutine would use the loop variable
+ // and that keeps changing.
+ informer := informer
+ go func() {
+ defer f.wg.Done()
+ informer.Run(stopCh)
+ }()
+ f.startedInformers[informerType] = true
+ }
+ }
+}
+
+func (f *sharedInformerFactory) Shutdown() {
+ f.lock.Lock()
+ f.shuttingDown = true
+ f.lock.Unlock()
+
+ // Will return immediately if there is nothing to wait for.
+ f.wg.Wait()
+}
+
+func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
+ informers := func() map[reflect.Type]cache.SharedIndexInformer {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ informers := map[reflect.Type]cache.SharedIndexInformer{}
+ for informerType, informer := range f.informers {
+ if f.startedInformers[informerType] {
+ informers[informerType] = informer
+ }
+ }
+ return informers
+ }()
+
+ res := map[reflect.Type]bool{}
+ for informType, informer := range informers {
+ res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
+ }
+ return res
+}
+
+// InternalInformerFor returns the SharedIndexInformer for obj using an internal
+// client.
+func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ informerType := reflect.TypeOf(obj)
+ informer, exists := f.informers[informerType]
+ if exists {
+ return informer
+ }
+
+ resyncPeriod, exists := f.customResync[informerType]
+ if !exists {
+ resyncPeriod = f.defaultResync
+ }
+
+ informer = newFunc(f.client, resyncPeriod)
+ f.informers[informerType] = informer
+
+ return informer
+}
+
+// SharedInformerFactory provides shared informers for resources in all known
+// API group versions.
+//
+// It is typically used like this:
+//
+// ctx, cancel := context.Background()
+// defer cancel()
+// factory := NewSharedInformerFactory(client, resyncPeriod)
+// defer factory.WaitForStop() // Returns immediately if nothing was started.
+// genericInformer := factory.ForResource(resource)
+// typedInformer := factory.SomeAPIGroup().V1().SomeType()
+// factory.Start(ctx.Done()) // Start processing these informers.
+// synced := factory.WaitForCacheSync(ctx.Done())
+// for v, ok := range synced {
+// if !ok {
+// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v)
+// return
+// }
+// }
+//
+// // Creating informers can also be created after Start, but then
+// // Start must be called again:
+// anotherGenericInformer := factory.ForResource(resource)
+// factory.Start(ctx.Done())
+type SharedInformerFactory interface {
+ internalinterfaces.SharedInformerFactory
+
+ // Start initializes all requested informers. They are handled in goroutines
+ // which run until the stop channel gets closed.
+ Start(stopCh <-chan struct{})
+
+ // Shutdown marks a factory as shutting down. At that point no new
+ // informers can be started anymore and Start will return without
+ // doing anything.
+ //
+ // In addition, Shutdown blocks until all goroutines have terminated. For that
+ // to happen, the close channel(s) that they were started with must be closed,
+ // either before Shutdown gets called or while it is waiting.
+ //
+ // Shutdown may be called multiple times, even concurrently. All such calls will
+ // block until all goroutines have terminated.
+ Shutdown()
+
+ // WaitForCacheSync blocks until all started informers' caches were synced
+ // or the stop channel gets closed.
+ WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
+
+ // ForResource gives generic access to a shared informer of the matching type.
+ ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
+
+ // InternalInformerFor returns the SharedIndexInformer for obj using an internal
+ // client.
+ InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer
+
+ Migration() migration.Interface
+}
+
+func (f *sharedInformerFactory) Migration() migration.Interface {
+ return migration.New(f, f.namespace, f.tweakListOptions)
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/generic.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/generic.go
new file mode 100644
index 000000000000..6d572e6df198
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/generic.go
@@ -0,0 +1,64 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package informer
+
+import (
+ "fmt"
+
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ cache "k8s.io/client-go/tools/cache"
+ v1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1"
+)
+
+// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
+// sharedInformers based on type
+type GenericInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() cache.GenericLister
+}
+
+type genericInformer struct {
+ informer cache.SharedIndexInformer
+ resource schema.GroupResource
+}
+
+// Informer returns the SharedIndexInformer.
+func (f *genericInformer) Informer() cache.SharedIndexInformer {
+ return f.informer
+}
+
+// Lister returns the GenericLister.
+func (f *genericInformer) Lister() cache.GenericLister {
+ return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
+}
+
+// ForResource gives generic access to a shared informer of the matching type
+// TODO extend this to unknown resources with a client pool
+func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
+ switch resource {
+ // Group=migration.k8s.io, Version=v1alpha1
+ case v1alpha1.SchemeGroupVersion.WithResource("storagestates"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.Migration().V1alpha1().StorageStates().Informer()}, nil
+ case v1alpha1.SchemeGroupVersion.WithResource("storageversionmigrations"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.Migration().V1alpha1().StorageVersionMigrations().Informer()}, nil
+
+ }
+
+ return nil, fmt.Errorf("no informer found for %v", resource)
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces/factory_interfaces.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces/factory_interfaces.go
new file mode 100644
index 000000000000..3279b434c00d
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces/factory_interfaces.go
@@ -0,0 +1,40 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package internalinterfaces
+
+import (
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ cache "k8s.io/client-go/tools/cache"
+ clientset "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset"
+)
+
+// NewInformerFunc takes clientset.Interface and time.Duration to return a SharedIndexInformer.
+type NewInformerFunc func(clientset.Interface, time.Duration) cache.SharedIndexInformer
+
+// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
+type SharedInformerFactory interface {
+ Start(stopCh <-chan struct{})
+ InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
+}
+
+// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
+type TweakListOptionsFunc func(*v1.ListOptions)
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/interface.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/interface.go
new file mode 100644
index 000000000000..a7afeb46025f
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/interface.go
@@ -0,0 +1,46 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package migration
+
+import (
+ internalinterfaces "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces"
+ v1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1"
+)
+
+// Interface provides access to each of this group's versions.
+type Interface interface {
+ // V1alpha1 provides access to shared informers for resources in V1alpha1.
+ V1alpha1() v1alpha1.Interface
+}
+
+type group struct {
+ factory internalinterfaces.SharedInformerFactory
+ namespace string
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
+ return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
+}
+
+// V1alpha1 returns a new v1alpha1.Interface.
+func (g *group) V1alpha1() v1alpha1.Interface {
+ return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/interface.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/interface.go
new file mode 100644
index 000000000000..22d5acc8106c
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/interface.go
@@ -0,0 +1,52 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ internalinterfaces "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces"
+)
+
+// Interface provides access to all the informers in this group version.
+type Interface interface {
+ // StorageStates returns a StorageStateInformer.
+ StorageStates() StorageStateInformer
+ // StorageVersionMigrations returns a StorageVersionMigrationInformer.
+ StorageVersionMigrations() StorageVersionMigrationInformer
+}
+
+type version struct {
+ factory internalinterfaces.SharedInformerFactory
+ namespace string
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
+ return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
+}
+
+// StorageStates returns a StorageStateInformer.
+func (v *version) StorageStates() StorageStateInformer {
+ return &storageStateInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
+}
+
+// StorageVersionMigrations returns a StorageVersionMigrationInformer.
+func (v *version) StorageVersionMigrations() StorageVersionMigrationInformer {
+ return &storageVersionMigrationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storagestate.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storagestate.go
new file mode 100644
index 000000000000..483b60f1ad8c
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storagestate.go
@@ -0,0 +1,89 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ "context"
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ watch "k8s.io/apimachinery/pkg/watch"
+ cache "k8s.io/client-go/tools/cache"
+ migrationv1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1"
+ clientset "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset"
+ internalinterfaces "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces"
+ v1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1"
+)
+
+// StorageStateInformer provides access to a shared informer and lister for
+// StorageStates.
+type StorageStateInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() v1alpha1.StorageStateLister
+}
+
+type storageStateInformer struct {
+ factory internalinterfaces.SharedInformerFactory
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// NewStorageStateInformer constructs a new informer for StorageState type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewStorageStateInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return NewFilteredStorageStateInformer(client, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredStorageStateInformer constructs a new informer for StorageState type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredStorageStateInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(
+ &cache.ListWatch{
+ ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.MigrationV1alpha1().StorageStates().List(context.TODO(), options)
+ },
+ WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.MigrationV1alpha1().StorageStates().Watch(context.TODO(), options)
+ },
+ },
+ &migrationv1alpha1.StorageState{},
+ resyncPeriod,
+ indexers,
+ )
+}
+
+func (f *storageStateInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFilteredStorageStateInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *storageStateInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&migrationv1alpha1.StorageState{}, f.defaultInformer)
+}
+
+func (f *storageStateInformer) Lister() v1alpha1.StorageStateLister {
+ return v1alpha1.NewStorageStateLister(f.Informer().GetIndexer())
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storageversionmigration.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storageversionmigration.go
new file mode 100644
index 000000000000..4bc90ea5e108
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/migration/v1alpha1/storageversionmigration.go
@@ -0,0 +1,89 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ "context"
+ time "time"
+
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ watch "k8s.io/apimachinery/pkg/watch"
+ cache "k8s.io/client-go/tools/cache"
+ migrationv1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1"
+ clientset "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset"
+ internalinterfaces "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/informer/internalinterfaces"
+ v1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1"
+)
+
+// StorageVersionMigrationInformer provides access to a shared informer and lister for
+// StorageVersionMigrations.
+type StorageVersionMigrationInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() v1alpha1.StorageVersionMigrationLister
+}
+
+type storageVersionMigrationInformer struct {
+ factory internalinterfaces.SharedInformerFactory
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// NewStorageVersionMigrationInformer constructs a new informer for StorageVersionMigration type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewStorageVersionMigrationInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return NewFilteredStorageVersionMigrationInformer(client, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredStorageVersionMigrationInformer constructs a new informer for StorageVersionMigration type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredStorageVersionMigrationInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(
+ &cache.ListWatch{
+ ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.MigrationV1alpha1().StorageVersionMigrations().List(context.TODO(), options)
+ },
+ WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.MigrationV1alpha1().StorageVersionMigrations().Watch(context.TODO(), options)
+ },
+ },
+ &migrationv1alpha1.StorageVersionMigration{},
+ resyncPeriod,
+ indexers,
+ )
+}
+
+func (f *storageVersionMigrationInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFilteredStorageVersionMigrationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *storageVersionMigrationInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&migrationv1alpha1.StorageVersionMigration{}, f.defaultInformer)
+}
+
+func (f *storageVersionMigrationInformer) Lister() v1alpha1.StorageVersionMigrationLister {
+ return v1alpha1.NewStorageVersionMigrationLister(f.Informer().GetIndexer())
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/expansion_generated.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/expansion_generated.go
new file mode 100644
index 000000000000..daa75a09cf14
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/expansion_generated.go
@@ -0,0 +1,27 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+// StorageStateListerExpansion allows custom methods to be added to
+// StorageStateLister.
+type StorageStateListerExpansion interface{}
+
+// StorageVersionMigrationListerExpansion allows custom methods to be added to
+// StorageVersionMigrationLister.
+type StorageVersionMigrationListerExpansion interface{}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storagestate.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storagestate.go
new file mode 100644
index 000000000000..a555aa2f152a
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storagestate.go
@@ -0,0 +1,68 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+ v1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1"
+)
+
+// StorageStateLister helps list StorageStates.
+// All objects returned here must be treated as read-only.
+type StorageStateLister interface {
+ // List lists all StorageStates in the indexer.
+ // Objects returned here must be treated as read-only.
+ List(selector labels.Selector) (ret []*v1alpha1.StorageState, err error)
+ // Get retrieves the StorageState from the index for a given name.
+ // Objects returned here must be treated as read-only.
+ Get(name string) (*v1alpha1.StorageState, error)
+ StorageStateListerExpansion
+}
+
+// storageStateLister implements the StorageStateLister interface.
+type storageStateLister struct {
+ indexer cache.Indexer
+}
+
+// NewStorageStateLister returns a new StorageStateLister.
+func NewStorageStateLister(indexer cache.Indexer) StorageStateLister {
+ return &storageStateLister{indexer: indexer}
+}
+
+// List lists all StorageStates in the indexer.
+func (s *storageStateLister) List(selector labels.Selector) (ret []*v1alpha1.StorageState, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.StorageState))
+ })
+ return ret, err
+}
+
+// Get retrieves the StorageState from the index for a given name.
+func (s *storageStateLister) Get(name string) (*v1alpha1.StorageState, error) {
+ obj, exists, err := s.indexer.GetByKey(name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1alpha1.Resource("storagestate"), name)
+ }
+ return obj.(*v1alpha1.StorageState), nil
+}
diff --git a/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storageversionmigration.go b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storageversionmigration.go
new file mode 100644
index 000000000000..8858bd2dde47
--- /dev/null
+++ b/vendor/sigs.k8s.io/kube-storage-version-migrator/pkg/clients/lister/migration/v1alpha1/storageversionmigration.go
@@ -0,0 +1,68 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+ v1alpha1 "sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1"
+)
+
+// StorageVersionMigrationLister helps list StorageVersionMigrations.
+// All objects returned here must be treated as read-only.
+type StorageVersionMigrationLister interface {
+ // List lists all StorageVersionMigrations in the indexer.
+ // Objects returned here must be treated as read-only.
+ List(selector labels.Selector) (ret []*v1alpha1.StorageVersionMigration, err error)
+ // Get retrieves the StorageVersionMigration from the index for a given name.
+ // Objects returned here must be treated as read-only.
+ Get(name string) (*v1alpha1.StorageVersionMigration, error)
+ StorageVersionMigrationListerExpansion
+}
+
+// storageVersionMigrationLister implements the StorageVersionMigrationLister interface.
+type storageVersionMigrationLister struct {
+ indexer cache.Indexer
+}
+
+// NewStorageVersionMigrationLister returns a new StorageVersionMigrationLister.
+func NewStorageVersionMigrationLister(indexer cache.Indexer) StorageVersionMigrationLister {
+ return &storageVersionMigrationLister{indexer: indexer}
+}
+
+// List lists all StorageVersionMigrations in the indexer.
+func (s *storageVersionMigrationLister) List(selector labels.Selector) (ret []*v1alpha1.StorageVersionMigration, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.StorageVersionMigration))
+ })
+ return ret, err
+}
+
+// Get retrieves the StorageVersionMigration from the index for a given name.
+func (s *storageVersionMigrationLister) Get(name string) (*v1alpha1.StorageVersionMigration, error) {
+ obj, exists, err := s.indexer.GetByKey(name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1alpha1.Resource("storageversionmigration"), name)
+ }
+ return obj.(*v1alpha1.StorageVersionMigration), nil
+}
From 65eb05eb3657150f157dbdde0d1d769c39210b3a Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Tue, 26 May 2026 13:01:48 +0200
Subject: [PATCH 08/12] refactor(api): reuse spec key types in
SecretEncryptionKeyStatus
Replace the duplicated *KeyStatus types (AWSKMSKeyStatus,
AzureKMSKeyStatus, IBMCloudKMSKeyStatus) with the existing spec types
(AWSKMSKeyEntry, AzureKMSKey, IBMCloudKMSKeyEntry) in
SecretEncryptionKeyStatus. This follows the Kubernetes convention of
reusing spec types in status when the data shape is the same.
Also adds omitempty to the inner fields of the three spec types,
fixing a pre-existing API convention violation.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
api/hypershift/v1beta1/aws.go | 16 --
api/hypershift/v1beta1/azure.go | 25 +--
api/hypershift/v1beta1/hostedcluster_types.go | 9 +-
api/hypershift/v1beta1/ibmcloud.go | 45 +---
.../v1beta1/zz_generated.deepcopy.go | 45 ----
.../AAA_ungated.yaml | 110 ++++------
.../ClusterUpdateAcceptRisks.yaml | 110 ++++------
.../ClusterVersionOperatorConfiguration.yaml | 110 ++++------
.../ExternalOIDC.yaml | 110 ++++------
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 110 ++++------
.../ExternalOIDCWithUpstreamParity.yaml | 110 ++++------
.../GCPPlatform.yaml | 110 ++++------
.../HCPEtcdBackup.yaml | 110 ++++------
...perShiftOnlyDynamicResourceAllocation.yaml | 110 ++++------
.../ImageStreamImportMode.yaml | 110 ++++------
.../KMSEncryptionProvider.yaml | 110 ++++------
.../OpenStack.yaml | 110 ++++------
.../TLSAdherence.yaml | 110 ++++------
.../AAA_ungated.yaml | 110 ++++------
.../ClusterUpdateAcceptRisks.yaml | 110 ++++------
.../ClusterVersionOperatorConfiguration.yaml | 110 ++++------
.../ExternalOIDC.yaml | 110 ++++------
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 110 ++++------
.../ExternalOIDCWithUpstreamParity.yaml | 110 ++++------
.../GCPPlatform.yaml | 110 ++++------
.../HCPEtcdBackup.yaml | 110 ++++------
...perShiftOnlyDynamicResourceAllocation.yaml | 110 ++++------
.../ImageStreamImportMode.yaml | 110 ++++------
.../KMSEncryptionProvider.yaml | 110 ++++------
.../OpenStack.yaml | 110 ++++------
.../TLSAdherence.yaml | 110 ++++------
.../hypershift/v1beta1/awskmskeystatus.go | 47 ----
.../hypershift/v1beta1/azurekmskeystatus.go | 56 -----
.../v1beta1/ibmcloudkmskeystatus.go | 83 -------
.../v1beta1/secretencryptionkeystatus.go | 12 +-
client/applyconfiguration/utils.go | 6 -
...usters-Hypershift-CustomNoUpgrade.crd.yaml | 110 ++++------
...hostedclusters-Hypershift-Default.crd.yaml | 110 ++++------
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 110 ++++------
...planes-Hypershift-CustomNoUpgrade.crd.yaml | 110 ++++------
...dcontrolplanes-Hypershift-Default.crd.yaml | 110 ++++------
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 110 ++++------
.../hostedcontrolplane/v2/kas/kms_test.go | 14 +-
.../reencryption/reencryption_test.go | 10 +-
docs/content/reference/aggregated-docs.md | 202 ++----------------
docs/content/reference/api.md | 202 ++----------------
support/secretencryption/fingerprint.go | 14 +-
support/secretencryption/fingerprint_test.go | 4 +-
support/secretencryption/keystatus.go | 25 +--
support/secretencryption/keystatus_test.go | 2 +-
.../hypershift/api/hypershift/v1beta1/aws.go | 16 --
.../api/hypershift/v1beta1/azure.go | 25 +--
.../hypershift/v1beta1/hostedcluster_types.go | 9 +-
.../api/hypershift/v1beta1/ibmcloud.go | 45 +---
.../v1beta1/zz_generated.deepcopy.go | 45 ----
55 files changed, 1486 insertions(+), 2991 deletions(-)
delete mode 100644 client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go
delete mode 100644 client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go
delete mode 100644 client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go
diff --git a/api/hypershift/v1beta1/aws.go b/api/hypershift/v1beta1/aws.go
index a5b9c824274c..5521f6f7d688 100644
--- a/api/hypershift/v1beta1/aws.go
+++ b/api/hypershift/v1beta1/aws.go
@@ -1082,23 +1082,7 @@ type AWSKMSKeyEntry struct {
// +required
// +kubebuilder:validation:Pattern=`^arn:`
// +kubebuilder:validation:MaxLength=2048
- ARN string `json:"arn"`
-}
-
-// AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
-// reconstruct the backup sidecar container arguments.
-// +k8s:deepcopy-gen=true
-type AWSKMSKeyStatus struct {
- // arn is the Amazon Resource Name of the KMS key.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=2048
ARN string `json:"arn,omitempty"`
- // region is the AWS region of the KMS key.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- Region string `json:"region,omitempty"`
}
// AWSPlatformStatus contains status specific to the AWS platform
diff --git a/api/hypershift/v1beta1/azure.go b/api/hypershift/v1beta1/azure.go
index 71f7beea32a4..d9809f7627f0 100644
--- a/api/hypershift/v1beta1/azure.go
+++ b/api/hypershift/v1beta1/azure.go
@@ -892,37 +892,16 @@ type AzureKMSKey struct {
// `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
// +kubebuilder:validation:MaxLength=255
// +required
- KeyVaultName string `json:"keyVaultName"`
+ KeyVaultName string `json:"keyVaultName,omitempty"`
// keyName is the name of the keyvault key used for encrypt/decrypt
// +kubebuilder:validation:MaxLength=255
// +required
- KeyName string `json:"keyName"`
+ KeyName string `json:"keyName,omitempty"`
// keyVersion contains the version of the key to use
// +kubebuilder:validation:MaxLength=255
// +required
- KeyVersion string `json:"keyVersion"`
-}
-
-// AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
-// reconstruct the EncryptionConfiguration read provider.
-// +k8s:deepcopy-gen=true
-type AzureKMSKeyStatus struct {
- // keyVaultName is the name of the Azure Key Vault.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- KeyVaultName string `json:"keyVaultName,omitempty"`
- // keyName is the name of the key in the vault.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- KeyName string `json:"keyName,omitempty"`
- // keyVersion is the version of the key.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
KeyVersion string `json:"keyVersion,omitempty"`
}
diff --git a/api/hypershift/v1beta1/hostedcluster_types.go b/api/hypershift/v1beta1/hostedcluster_types.go
index 98b7c1e9ba9d..fedd090b1504 100644
--- a/api/hypershift/v1beta1/hostedcluster_types.go
+++ b/api/hypershift/v1beta1/hostedcluster_types.go
@@ -2116,8 +2116,7 @@ type SecretEncryptionStatus struct {
History []EncryptionMigrationHistory `json:"history,omitempty"`
}
-// SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
-// instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+// SecretEncryptionKeyStatus records the active key identity using the same types as the spec.
// +k8s:deepcopy-gen=true
// +kubebuilder:validation:XValidation:rule="self.provider == 'Azure' ? has(self.azure) : !has(self.azure)",message="azure is required when provider is Azure, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="self.provider == 'AWS' ? has(self.aws) : !has(self.aws)",message="aws is required when provider is AWS, and forbidden otherwise"
@@ -2133,15 +2132,15 @@ type SecretEncryptionKeyStatus struct {
// azure holds the Azure KMS key identity fields.
// +optional
// +unionMember
- Azure AzureKMSKeyStatus `json:"azure,omitzero"`
+ Azure AzureKMSKey `json:"azure,omitzero"`
// aws holds the AWS KMS key identity fields.
// +optional
// +unionMember
- AWS AWSKMSKeyStatus `json:"aws,omitzero"`
+ AWS AWSKMSKeyEntry `json:"aws,omitzero"`
// ibmCloud holds the IBM Cloud KMS key identity fields.
// +optional
// +unionMember
- IBMCloud IBMCloudKMSKeyStatus `json:"ibmCloud,omitzero"`
+ IBMCloud IBMCloudKMSKeyEntry `json:"ibmCloud,omitzero"`
// aescbc holds a reference to the AESCBC key secret.
// +optional
// +unionMember
diff --git a/api/hypershift/v1beta1/ibmcloud.go b/api/hypershift/v1beta1/ibmcloud.go
index bad0e9c3c1c0..490256c3ab65 100644
--- a/api/hypershift/v1beta1/ibmcloud.go
+++ b/api/hypershift/v1beta1/ibmcloud.go
@@ -22,61 +22,26 @@ type IBMCloudKMSKeyEntry struct {
// crkID is the customer rook key id
// +kubebuilder:validation:MaxLength=255
// +required
- CRKID string `json:"crkID"`
+ CRKID string `json:"crkID,omitempty"`
// instanceID is the id for the key protect instance
// +kubebuilder:validation:MaxLength=255
// +required
- InstanceID string `json:"instanceID"`
+ InstanceID string `json:"instanceID,omitempty"`
// correlationID is an identifier used to track all api call usage from hypershift
// +kubebuilder:validation:MaxLength=255
// +required
- CorrelationID string `json:"correlationID"`
+ CorrelationID string `json:"correlationID,omitempty"`
// url is the url to call key protect apis over
// +kubebuilder:validation:Pattern=`^https://`
// +kubebuilder:validation:MaxLength=2048
// +required
- URL string `json:"url"`
+ URL string `json:"url,omitempty"`
// keyVersion is a unique number associated with the key. The number increments whenever a new
// key is enabled for data encryption.
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=2147483647
// +required
- KeyVersion int `json:"keyVersion"`
-}
-
-// IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
-// sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
-// +k8s:deepcopy-gen=true
-type IBMCloudKMSKeyStatus struct {
- // crkID is the Customer Root Key ID.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- CRKID string `json:"crkID,omitempty"`
- // instanceID is the KMS instance ID.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- InstanceID string `json:"instanceID,omitempty"`
- // keyVersion is the key version number.
- // +required
- // +kubebuilder:validation:Minimum=0
- KeyVersion int32 `json:"keyVersion,omitempty"`
- // region is the IBM Cloud region.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- Region string `json:"region,omitempty"`
- // correlationID is the correlation ID for the key.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=255
- CorrelationID string `json:"correlationID,omitempty"`
- // url is the KMS endpoint URL.
- // +required
- // +kubebuilder:validation:MinLength=1
- // +kubebuilder:validation:MaxLength=2048
- URL string `json:"url,omitempty"`
+ KeyVersion int `json:"keyVersion,omitempty"`
}
// IBMCloudKMSAuthSpec defines metadata for how authentication is done with IBM Cloud KMS
diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 33601892dd28..9dbd2eea6dc4 100644
--- a/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -272,21 +272,6 @@ func (in *AWSKMSKeyEntry) DeepCopy() *AWSKMSKeyEntry {
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AWSKMSKeyStatus) DeepCopyInto(out *AWSKMSKeyStatus) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSKMSKeyStatus.
-func (in *AWSKMSKeyStatus) DeepCopy() *AWSKMSKeyStatus {
- if in == nil {
- return nil
- }
- out := new(AWSKMSKeyStatus)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSKMSSpec) DeepCopyInto(out *AWSKMSSpec) {
*out = *in
@@ -672,21 +657,6 @@ func (in *AzureKMSKey) DeepCopy() *AzureKMSKey {
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AzureKMSKeyStatus) DeepCopyInto(out *AzureKMSKeyStatus) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKMSKeyStatus.
-func (in *AzureKMSKeyStatus) DeepCopy() *AzureKMSKeyStatus {
- if in == nil {
- return nil
- }
- out := new(AzureKMSKeyStatus)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureKMSSpec) DeepCopyInto(out *AzureKMSSpec) {
*out = *in
@@ -2834,21 +2804,6 @@ func (in *IBMCloudKMSKeyEntry) DeepCopy() *IBMCloudKMSKeyEntry {
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *IBMCloudKMSKeyStatus) DeepCopyInto(out *IBMCloudKMSKeyStatus) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMCloudKMSKeyStatus.
-func (in *IBMCloudKMSKeyStatus) DeepCopy() *IBMCloudKMSKeyStatus {
- if in == nil {
- return nil
- }
- out := new(IBMCloudKMSKeyStatus)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IBMCloudKMSManagedAuthSpec) DeepCopyInto(out *IBMCloudKMSManagedAuthSpec) {
*out = *in
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
index 9550a6992ce2..a1357f81d054 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
@@ -7056,38 +7056,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7099,42 +7094,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7284,38 +7273,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7327,42 +7311,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index fea5196ecf83..970be8af6bc4 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -7039,38 +7039,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7082,42 +7077,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7267,38 +7256,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7310,42 +7294,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 16ad0192fc0e..4bac83e16b4d 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -7059,38 +7059,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7102,42 +7097,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7287,38 +7276,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7330,42 +7314,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
index c3b19174d9d0..255b9ff1c6b8 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
@@ -7536,38 +7536,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7579,42 +7574,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7764,38 +7753,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7807,42 +7791,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index cec6736ddbb4..6bce82c2d9ca 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -7676,38 +7676,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7719,42 +7714,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7904,38 +7893,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7947,42 +7931,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index c62dd3d18d83..5552ee23d8cf 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -7502,38 +7502,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7545,42 +7540,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7730,38 +7719,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7773,42 +7757,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
index a47c6e4f7458..18fb61f574dc 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
@@ -7485,38 +7485,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7528,42 +7523,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7713,38 +7702,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7756,42 +7740,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
index 3ca56744ebd3..f7622f5f81ef 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -7116,38 +7116,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7159,42 +7154,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7344,38 +7333,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7387,42 +7371,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index cfdd95d57a99..2b187f273b8b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -7061,38 +7061,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7104,42 +7099,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7289,38 +7278,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7332,42 +7316,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
index 4504461be66a..234525904e2b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -7068,38 +7068,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7111,42 +7106,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7296,38 +7285,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7339,42 +7323,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
index daf3aac48042..fff71701f7b1 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -7115,38 +7115,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7158,42 +7153,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7343,38 +7332,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7386,42 +7370,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
index ab1ff8ad45c5..4fac3acebacc 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
@@ -7590,38 +7590,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7633,42 +7628,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7818,38 +7807,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7861,42 +7845,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
index d8b3291b5a15..eb01515671a7 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
@@ -7079,38 +7079,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7122,42 +7117,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7307,38 +7296,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7350,42 +7334,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
index b5b5eb86392a..9f427b02af63 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
@@ -6888,38 +6888,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6931,42 +6926,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7116,38 +7105,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7159,42 +7143,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 97f443cb0d21..e51e7253608d 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -6871,38 +6871,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6914,42 +6909,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7099,38 +7088,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7142,42 +7126,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index d1f563f98d7b..7c7c8cfa0949 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -6891,38 +6891,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6934,42 +6929,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7119,38 +7108,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7162,42 +7146,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
index 5a0a3088891e..c878d7be7d9b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
@@ -7368,38 +7368,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7411,42 +7406,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7596,38 +7585,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7639,42 +7623,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 4c1d71b72f76..be8899cfa47b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -7508,38 +7508,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7551,42 +7546,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7736,38 +7725,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7779,42 +7763,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 7e7a23418f13..a6e47cd7c4dd 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -7334,38 +7334,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7377,42 +7372,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7562,38 +7551,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7605,42 +7589,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
index 034333cd3535..ce4fbf2fc9e9 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
@@ -7317,38 +7317,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7360,42 +7355,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7545,38 +7534,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7588,42 +7572,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
index 26fe90e75e63..e5756d1e7331 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -6936,38 +6936,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6979,42 +6974,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7164,38 +7153,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7207,42 +7191,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 7d5de94eecd4..7b247b0ae73f 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -6893,38 +6893,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6936,42 +6931,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7121,38 +7110,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7164,42 +7148,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
index 4327a332bc93..37c290db44ca 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -6900,38 +6900,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6943,42 +6938,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7128,38 +7117,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7171,42 +7155,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
index fae5de3d2ce0..fc2cc1cf6932 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -6947,38 +6947,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6990,42 +6985,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7175,38 +7164,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7218,42 +7202,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
index 63879512e486..47d266500749 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
@@ -7422,38 +7422,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7465,42 +7460,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7650,38 +7639,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7693,42 +7677,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
index 68fe67fe532d..97bc9afc60b2 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
@@ -6911,38 +6911,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -6954,42 +6949,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7139,38 +7128,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7182,42 +7166,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go b/client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go
deleted file mode 100644
index 337edbc9ea75..000000000000
--- a/client/applyconfiguration/hypershift/v1beta1/awskmskeystatus.go
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-// Code generated by applyconfiguration-gen. DO NOT EDIT.
-
-package v1beta1
-
-// AWSKMSKeyStatusApplyConfiguration represents a declarative configuration of the AWSKMSKeyStatus type for use
-// with apply.
-type AWSKMSKeyStatusApplyConfiguration struct {
- ARN *string `json:"arn,omitempty"`
- Region *string `json:"region,omitempty"`
-}
-
-// AWSKMSKeyStatusApplyConfiguration constructs a declarative configuration of the AWSKMSKeyStatus type for use with
-// apply.
-func AWSKMSKeyStatus() *AWSKMSKeyStatusApplyConfiguration {
- return &AWSKMSKeyStatusApplyConfiguration{}
-}
-
-// WithARN sets the ARN field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the ARN field is set to the value of the last call.
-func (b *AWSKMSKeyStatusApplyConfiguration) WithARN(value string) *AWSKMSKeyStatusApplyConfiguration {
- b.ARN = &value
- return b
-}
-
-// WithRegion sets the Region field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the Region field is set to the value of the last call.
-func (b *AWSKMSKeyStatusApplyConfiguration) WithRegion(value string) *AWSKMSKeyStatusApplyConfiguration {
- b.Region = &value
- return b
-}
diff --git a/client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go b/client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go
deleted file mode 100644
index 29c942b8c66a..000000000000
--- a/client/applyconfiguration/hypershift/v1beta1/azurekmskeystatus.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-// Code generated by applyconfiguration-gen. DO NOT EDIT.
-
-package v1beta1
-
-// AzureKMSKeyStatusApplyConfiguration represents a declarative configuration of the AzureKMSKeyStatus type for use
-// with apply.
-type AzureKMSKeyStatusApplyConfiguration struct {
- KeyVaultName *string `json:"keyVaultName,omitempty"`
- KeyName *string `json:"keyName,omitempty"`
- KeyVersion *string `json:"keyVersion,omitempty"`
-}
-
-// AzureKMSKeyStatusApplyConfiguration constructs a declarative configuration of the AzureKMSKeyStatus type for use with
-// apply.
-func AzureKMSKeyStatus() *AzureKMSKeyStatusApplyConfiguration {
- return &AzureKMSKeyStatusApplyConfiguration{}
-}
-
-// WithKeyVaultName sets the KeyVaultName field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the KeyVaultName field is set to the value of the last call.
-func (b *AzureKMSKeyStatusApplyConfiguration) WithKeyVaultName(value string) *AzureKMSKeyStatusApplyConfiguration {
- b.KeyVaultName = &value
- return b
-}
-
-// WithKeyName sets the KeyName field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the KeyName field is set to the value of the last call.
-func (b *AzureKMSKeyStatusApplyConfiguration) WithKeyName(value string) *AzureKMSKeyStatusApplyConfiguration {
- b.KeyName = &value
- return b
-}
-
-// WithKeyVersion sets the KeyVersion field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the KeyVersion field is set to the value of the last call.
-func (b *AzureKMSKeyStatusApplyConfiguration) WithKeyVersion(value string) *AzureKMSKeyStatusApplyConfiguration {
- b.KeyVersion = &value
- return b
-}
diff --git a/client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go b/client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go
deleted file mode 100644
index 8c865d62888c..000000000000
--- a/client/applyconfiguration/hypershift/v1beta1/ibmcloudkmskeystatus.go
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-// Code generated by applyconfiguration-gen. DO NOT EDIT.
-
-package v1beta1
-
-// IBMCloudKMSKeyStatusApplyConfiguration represents a declarative configuration of the IBMCloudKMSKeyStatus type for use
-// with apply.
-type IBMCloudKMSKeyStatusApplyConfiguration struct {
- CRKID *string `json:"crkID,omitempty"`
- InstanceID *string `json:"instanceID,omitempty"`
- KeyVersion *int32 `json:"keyVersion,omitempty"`
- Region *string `json:"region,omitempty"`
- CorrelationID *string `json:"correlationID,omitempty"`
- URL *string `json:"url,omitempty"`
-}
-
-// IBMCloudKMSKeyStatusApplyConfiguration constructs a declarative configuration of the IBMCloudKMSKeyStatus type for use with
-// apply.
-func IBMCloudKMSKeyStatus() *IBMCloudKMSKeyStatusApplyConfiguration {
- return &IBMCloudKMSKeyStatusApplyConfiguration{}
-}
-
-// WithCRKID sets the CRKID field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the CRKID field is set to the value of the last call.
-func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithCRKID(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
- b.CRKID = &value
- return b
-}
-
-// WithInstanceID sets the InstanceID field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the InstanceID field is set to the value of the last call.
-func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithInstanceID(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
- b.InstanceID = &value
- return b
-}
-
-// WithKeyVersion sets the KeyVersion field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the KeyVersion field is set to the value of the last call.
-func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithKeyVersion(value int32) *IBMCloudKMSKeyStatusApplyConfiguration {
- b.KeyVersion = &value
- return b
-}
-
-// WithRegion sets the Region field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the Region field is set to the value of the last call.
-func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithRegion(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
- b.Region = &value
- return b
-}
-
-// WithCorrelationID sets the CorrelationID field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the CorrelationID field is set to the value of the last call.
-func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithCorrelationID(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
- b.CorrelationID = &value
- return b
-}
-
-// WithURL sets the URL field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the URL field is set to the value of the last call.
-func (b *IBMCloudKMSKeyStatusApplyConfiguration) WithURL(value string) *IBMCloudKMSKeyStatusApplyConfiguration {
- b.URL = &value
- return b
-}
diff --git a/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go b/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go
index 21174a8ce320..313fc03721ac 100644
--- a/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go
+++ b/client/applyconfiguration/hypershift/v1beta1/secretencryptionkeystatus.go
@@ -25,9 +25,9 @@ import (
// with apply.
type SecretEncryptionKeyStatusApplyConfiguration struct {
Provider *hypershiftv1beta1.SecretEncryptionProvider `json:"provider,omitempty"`
- Azure *AzureKMSKeyStatusApplyConfiguration `json:"azure,omitempty"`
- AWS *AWSKMSKeyStatusApplyConfiguration `json:"aws,omitempty"`
- IBMCloud *IBMCloudKMSKeyStatusApplyConfiguration `json:"ibmCloud,omitempty"`
+ Azure *AzureKMSKeyApplyConfiguration `json:"azure,omitempty"`
+ AWS *AWSKMSKeyEntryApplyConfiguration `json:"aws,omitempty"`
+ IBMCloud *IBMCloudKMSKeyEntryApplyConfiguration `json:"ibmCloud,omitempty"`
AESCBC *AESCBCKeyStatusApplyConfiguration `json:"aescbc,omitempty"`
}
@@ -48,7 +48,7 @@ func (b *SecretEncryptionKeyStatusApplyConfiguration) WithProvider(value hypersh
// WithAzure sets the Azure field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Azure field is set to the value of the last call.
-func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAzure(value *AzureKMSKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAzure(value *AzureKMSKeyApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
b.Azure = value
return b
}
@@ -56,7 +56,7 @@ func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAzure(value *AzureKMSK
// WithAWS sets the AWS field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the AWS field is set to the value of the last call.
-func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAWS(value *AWSKMSKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAWS(value *AWSKMSKeyEntryApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
b.AWS = value
return b
}
@@ -64,7 +64,7 @@ func (b *SecretEncryptionKeyStatusApplyConfiguration) WithAWS(value *AWSKMSKeySt
// WithIBMCloud sets the IBMCloud field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the IBMCloud field is set to the value of the last call.
-func (b *SecretEncryptionKeyStatusApplyConfiguration) WithIBMCloud(value *IBMCloudKMSKeyStatusApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
+func (b *SecretEncryptionKeyStatusApplyConfiguration) WithIBMCloud(value *IBMCloudKMSKeyEntryApplyConfiguration) *SecretEncryptionKeyStatusApplyConfiguration {
b.IBMCloud = value
return b
}
diff --git a/client/applyconfiguration/utils.go b/client/applyconfiguration/utils.go
index e2d56550593a..509c0d1b8811 100644
--- a/client/applyconfiguration/utils.go
+++ b/client/applyconfiguration/utils.go
@@ -89,8 +89,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.AWSKMSAuthSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AWSKMSKeyEntry"):
return &hypershiftv1beta1.AWSKMSKeyEntryApplyConfiguration{}
- case v1beta1.SchemeGroupVersion.WithKind("AWSKMSKeyStatus"):
- return &hypershiftv1beta1.AWSKMSKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AWSKMSSpec"):
return &hypershiftv1beta1.AWSKMSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AWSNodePoolPlatform"):
@@ -115,8 +113,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.AzureAuthenticationConfigurationApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureKMSKey"):
return &hypershiftv1beta1.AzureKMSKeyApplyConfiguration{}
- case v1beta1.SchemeGroupVersion.WithKind("AzureKMSKeyStatus"):
- return &hypershiftv1beta1.AzureKMSKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureKMSSpec"):
return &hypershiftv1beta1.AzureKMSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureMarketplaceImage"):
@@ -259,8 +255,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.IBMCloudKMSAuthSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSKeyEntry"):
return &hypershiftv1beta1.IBMCloudKMSKeyEntryApplyConfiguration{}
- case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSKeyStatus"):
- return &hypershiftv1beta1.IBMCloudKMSKeyStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSSpec"):
return &hypershiftv1beta1.IBMCloudKMSSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("IBMCloudKMSUnmanagedAuthSpec"):
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
index 43da88bcb60f..54afe28d93a7 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
@@ -9065,38 +9065,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -9108,42 +9103,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -9293,38 +9282,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -9336,42 +9320,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
index e3e13d9085f6..4d4b1ef858e0 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
@@ -7713,38 +7713,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7756,42 +7751,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7941,38 +7930,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7984,42 +7968,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 396e8eebb4ac..35f5512b2e8b 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -8925,38 +8925,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -8968,42 +8963,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -9153,38 +9142,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -9196,42 +9180,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
index 23dee0c4929a..3e95916bbd3f 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
@@ -8885,38 +8885,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -8928,42 +8923,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -9113,38 +9102,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -9156,42 +9140,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
index d9f699d90075..cde0ea13824a 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
@@ -7545,38 +7545,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7588,42 +7583,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -7773,38 +7762,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -7816,42 +7800,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 8b87154523da..8b364ec148af 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -8745,38 +8745,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -8788,42 +8783,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
@@ -8973,38 +8962,33 @@ spec:
description: aws holds the AWS KMS key identity fields.
properties:
arn:
- description: arn is the Amazon Resource Name of the KMS
- key.
+ description: arn is the Amazon Resource Name for the encryption
+ key
maxLength: 2048
- minLength: 1
- type: string
- region:
- description: region is the AWS region of the KMS key.
- maxLength: 255
- minLength: 1
+ pattern: '^arn:'
type: string
required:
- arn
- - region
type: object
azure:
description: azure holds the Azure KMS key identity fields.
properties:
keyName:
- description: keyName is the name of the key in the vault.
+ description: keyName is the name of the keyvault key used
+ for encrypt/decrypt
maxLength: 255
- minLength: 1
type: string
keyVaultName:
- description: keyVaultName is the name of the Azure Key
- Vault.
+ description: |-
+ keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
+ Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
+ `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn `
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the version of the key.
+ description: keyVersion contains the version of the key
+ to use
maxLength: 255
- minLength: 1
type: string
required:
- keyName
@@ -9016,42 +9000,36 @@ spec:
fields.
properties:
correlationID:
- description: correlationID is the correlation ID for the
- key.
+ description: correlationID is an identifier used to track
+ all api call usage from hypershift
maxLength: 255
- minLength: 1
type: string
crkID:
- description: crkID is the Customer Root Key ID.
+ description: crkID is the customer rook key id
maxLength: 255
- minLength: 1
type: string
instanceID:
- description: instanceID is the KMS instance ID.
+ description: instanceID is the id for the key protect
+ instance
maxLength: 255
- minLength: 1
type: string
keyVersion:
- description: keyVersion is the key version number.
- format: int32
+ description: |-
+ keyVersion is a unique number associated with the key. The number increments whenever a new
+ key is enabled for data encryption.
+ maximum: 2147483647
minimum: 0
type: integer
- region:
- description: region is the IBM Cloud region.
- maxLength: 255
- minLength: 1
- type: string
url:
- description: url is the KMS endpoint URL.
+ description: url is the url to call key protect apis over
maxLength: 2048
- minLength: 1
+ pattern: ^https://
type: string
required:
- correlationID
- crkID
- instanceID
- keyVersion
- - region
- url
type: object
provider:
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go
index 569922f01123..b15d1f75b370 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms_test.go
@@ -52,7 +52,7 @@ func TestDeriveKMSKeys(t *testing.T) {
encStatus: &hyperv1.SecretEncryptionStatus{
ActiveKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAWS,
- AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/current-key", Region: "us-east-1"},
+ AWS: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/current-key"},
},
},
validate: func(g Gomega, keys kmsWriteReadKeys) {
@@ -73,11 +73,11 @@ func TestDeriveKMSKeys(t *testing.T) {
encStatus: &hyperv1.SecretEncryptionStatus{
ActiveKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAWS,
- AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key", Region: "us-east-1"},
+ AWS: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key"},
},
TargetKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAWS,
- AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key", Region: "us-east-1"},
+ AWS: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key"},
},
},
currentConfig: nil,
@@ -98,11 +98,11 @@ func TestDeriveKMSKeys(t *testing.T) {
encStatus: &hyperv1.SecretEncryptionStatus{
ActiveKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAWS,
- AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key", Region: "us-east-1"},
+ AWS: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/old-key"},
},
TargetKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAWS,
- AWS: hyperv1.AWSKMSKeyStatus{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key", Region: "us-east-1"},
+ AWS: hyperv1.AWSKMSKeyEntry{ARN: "arn:aws:kms:us-east-1:123456789:key/new-key"},
},
},
currentConfig: kmsEncryptionConfig(
@@ -126,11 +126,11 @@ func TestDeriveKMSKeys(t *testing.T) {
encStatus: &hyperv1.SecretEncryptionStatus{
ActiveKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAzure,
- Azure: hyperv1.AzureKMSKeyStatus{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"},
+ Azure: hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v1"},
},
TargetKey: hyperv1.SecretEncryptionKeyStatus{
Provider: hyperv1.SecretEncryptionProviderAzure,
- Azure: hyperv1.AzureKMSKeyStatus{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v2"},
+ Azure: hyperv1.AzureKMSKey{KeyVaultName: "vault", KeyName: "key", KeyVersion: "v2"},
},
},
currentConfig: nil,
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go
index 538b94652141..3f9d525fd3b1 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/reencryption/reencryption_test.go
@@ -182,8 +182,8 @@ func aescbcKeyStatus(secretName, dataHash string) *hyperv1.SecretEncryptionKeySt
return secretencryption.KeyStatusFromAESCBCSpec(corev1.LocalObjectReference{Name: secretName}, dataHash)
}
-func awsKeyStatus(arn, region string) *hyperv1.SecretEncryptionKeyStatus {
- return secretencryption.KeyStatusFromAWSSpec(hyperv1.AWSKMSKeyEntry{ARN: arn}, region)
+func awsKeyStatus(arn string) *hyperv1.SecretEncryptionKeyStatus {
+ return secretencryption.KeyStatusFromAWSSpec(hyperv1.AWSKMSKeyEntry{ARN: arn})
}
func aescbcKeySecret(name, namespace, keyData string) *corev1.Secret {
@@ -699,7 +699,7 @@ func TestReconcile(t *testing.T) {
{
name: "When using AWS KMS and key ARN changes it should start rotation with 5 encrypted resources",
cpObjects: func() []client.Object {
- oldKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/old-key", "us-east-1")
+ oldKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/old-key")
return []client.Object{
newHCP(
withKMSEncryption(),
@@ -722,8 +722,8 @@ func TestReconcile(t *testing.T) {
{
name: "When in Migrating phase with KMS and all 5 migrations complete it should complete rotation",
cpObjects: func() []client.Object {
- oldKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/old-key", "us-east-1")
- newKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/test-key-1", "us-east-1")
+ oldKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/old-key")
+ newKS := awsKeyStatus("arn:aws:kms:us-east-1:123456789012:key/test-key-1")
return []client.Object{
newHCP(
withKMSEncryption(),
diff --git a/docs/content/reference/aggregated-docs.md b/docs/content/reference/aggregated-docs.md
index 6a4e3d70a299..e725f608b88d 100644
--- a/docs/content/reference/aggregated-docs.md
+++ b/docs/content/reference/aggregated-docs.md
@@ -37365,7 +37365,8 @@ string
###AWSKMSKeyEntry { #hypershift.openshift.io/v1beta1.AWSKMSKeyEntry }
(Appears on:
-AWSKMSSpec)
+AWSKMSSpec,
+SecretEncryptionKeyStatus)
AWSKMSKeyEntry defines metadata to locate the encryption key in AWS
@@ -37391,47 +37392,6 @@ string
-###AWSKMSKeyStatus { #hypershift.openshift.io/v1beta1.AWSKMSKeyStatus }
-
-(Appears on:
-SecretEncryptionKeyStatus)
-
-
-
AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
-reconstruct the backup sidecar container arguments.
-
-
-
-
-| Field |
-Description |
-
-
-
-
-
-arn
-
-string
-
- |
-
- arn is the Amazon Resource Name of the KMS key.
- |
-
-
-
-region
-
-string
-
- |
-
- region is the AWS region of the KMS key.
- |
-
-
-
###AWSKMSSpec { #hypershift.openshift.io/v1beta1.AWSKMSSpec }
(Appears on:
@@ -39124,7 +39084,8 @@ applications and dev/test.
###AzureKMSKey { #hypershift.openshift.io/v1beta1.AzureKMSKey }
(Appears on:
-AzureKMSSpec)
+AzureKMSSpec,
+SecretEncryptionKeyStatus)
@@ -39173,58 +39134,6 @@ string
-###AzureKMSKeyStatus { #hypershift.openshift.io/v1beta1.AzureKMSKeyStatus }
-
-(Appears on:
-SecretEncryptionKeyStatus)
-
-
-
AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
-reconstruct the EncryptionConfiguration read provider.
-
-
-
-
-| Field |
-Description |
-
-
-
-
-
-keyVaultName
-
-string
-
- |
-
- keyVaultName is the name of the Azure Key Vault.
- |
-
-
-
-keyName
-
-string
-
- |
-
- keyName is the name of the key in the vault.
- |
-
-
-
-keyVersion
-
-string
-
- |
-
- keyVersion is the version of the key.
- |
-
-
-
###AzureKMSSpec { #hypershift.openshift.io/v1beta1.AzureKMSSpec }
(Appears on:
@@ -46531,7 +46440,8 @@ authentication to interact with IBM Cloud KMS APIs
###IBMCloudKMSKeyEntry { #hypershift.openshift.io/v1beta1.IBMCloudKMSKeyEntry }
(Appears on:
-IBMCloudKMSSpec)
+IBMCloudKMSSpec,
+SecretEncryptionKeyStatus)
IBMCloudKMSKeyEntry defines metadata for an IBM Cloud KMS encryption key
@@ -46602,91 +46512,6 @@ key is enabled for data encryption.
-###IBMCloudKMSKeyStatus { #hypershift.openshift.io/v1beta1.IBMCloudKMSKeyStatus }
-
-(Appears on:
-SecretEncryptionKeyStatus)
-
-
-
IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
-sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
-
-
-
-
-| Field |
-Description |
-
-
-
-
-
-crkID
-
-string
-
- |
-
- crkID is the Customer Root Key ID.
- |
-
-
-
-instanceID
-
-string
-
- |
-
- instanceID is the KMS instance ID.
- |
-
-
-
-keyVersion
-
-int32
-
- |
-
- keyVersion is the key version number.
- |
-
-
-
-region
-
-string
-
- |
-
- region is the IBM Cloud region.
- |
-
-
-
-correlationID
-
-string
-
- |
-
- correlationID is the correlation ID for the key.
- |
-
-
-
-url
-
-string
-
- |
-
- url is the KMS endpoint URL.
- |
-
-
-
###IBMCloudKMSManagedAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSManagedAuthSpec }
(Appears on:
@@ -52094,8 +51919,7 @@ When omitted, the autoscaler defaults to 50%.
SecretEncryptionStatus)
-
SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
-instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+SecretEncryptionKeyStatus records the active key identity using the same types as the spec.
@@ -52122,8 +51946,8 @@ SecretEncryptionProvider
azure,omitzero
-
-AzureKMSKeyStatus
+
+AzureKMSKey
|
@@ -52136,8 +51960,8 @@ AzureKMSKeyStatus
aws,omitzero
-
-AWSKMSKeyStatus
+
+AWSKMSKeyEntry
|
@@ -52150,8 +51974,8 @@ AWSKMSKeyStatus
ibmCloud,omitzero
-
-IBMCloudKMSKeyStatus
+
+IBMCloudKMSKeyEntry
|
diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md
index a25c11791714..a4ecd9a36d0a 100644
--- a/docs/content/reference/api.md
+++ b/docs/content/reference/api.md
@@ -1680,7 +1680,8 @@ string
###AWSKMSKeyEntry { #hypershift.openshift.io/v1beta1.AWSKMSKeyEntry }
(Appears on:
-AWSKMSSpec)
+AWSKMSSpec,
+SecretEncryptionKeyStatus)
AWSKMSKeyEntry defines metadata to locate the encryption key in AWS
@@ -1706,47 +1707,6 @@ string
-###AWSKMSKeyStatus { #hypershift.openshift.io/v1beta1.AWSKMSKeyStatus }
-
-(Appears on:
-SecretEncryptionKeyStatus)
-
-
-
AWSKMSKeyStatus contains identity fields for an AWS KMS key, sufficient to
-reconstruct the backup sidecar container arguments.
-
-
-
-
-| Field |
-Description |
-
-
-
-
-
-arn
-
-string
-
- |
-
- arn is the Amazon Resource Name of the KMS key.
- |
-
-
-
-region
-
-string
-
- |
-
- region is the AWS region of the KMS key.
- |
-
-
-
###AWSKMSSpec { #hypershift.openshift.io/v1beta1.AWSKMSSpec }
(Appears on:
@@ -3439,7 +3399,8 @@ applications and dev/test.
###AzureKMSKey { #hypershift.openshift.io/v1beta1.AzureKMSKey }
(Appears on:
-AzureKMSSpec)
+AzureKMSSpec,
+SecretEncryptionKeyStatus)
@@ -3488,58 +3449,6 @@ string
-###AzureKMSKeyStatus { #hypershift.openshift.io/v1beta1.AzureKMSKeyStatus }
-
-(Appears on:
-SecretEncryptionKeyStatus)
-
-
-
AzureKMSKeyStatus contains identity fields for an Azure KMS key, sufficient to
-reconstruct the EncryptionConfiguration read provider.
-
-
-
-
-| Field |
-Description |
-
-
-
-
-
-keyVaultName
-
-string
-
- |
-
- keyVaultName is the name of the Azure Key Vault.
- |
-
-
-
-keyName
-
-string
-
- |
-
- keyName is the name of the key in the vault.
- |
-
-
-
-keyVersion
-
-string
-
- |
-
- keyVersion is the version of the key.
- |
-
-
-
###AzureKMSSpec { #hypershift.openshift.io/v1beta1.AzureKMSSpec }
(Appears on:
@@ -10846,7 +10755,8 @@ authentication to interact with IBM Cloud KMS APIs
###IBMCloudKMSKeyEntry { #hypershift.openshift.io/v1beta1.IBMCloudKMSKeyEntry }
(Appears on:
-IBMCloudKMSSpec)
+IBMCloudKMSSpec,
+SecretEncryptionKeyStatus)
IBMCloudKMSKeyEntry defines metadata for an IBM Cloud KMS encryption key
@@ -10917,91 +10827,6 @@ key is enabled for data encryption.
-###IBMCloudKMSKeyStatus { #hypershift.openshift.io/v1beta1.IBMCloudKMSKeyStatus }
-
-(Appears on:
-SecretEncryptionKeyStatus)
-
-
-
IBMCloudKMSKeyStatus contains identity fields for an IBM Cloud KMS key list entry,
-sufficient to reconstruct the KP_DATA_JSON entry for the backup key.
-
-
-
-
-| Field |
-Description |
-
-
-
-
-
-crkID
-
-string
-
- |
-
- crkID is the Customer Root Key ID.
- |
-
-
-
-instanceID
-
-string
-
- |
-
- instanceID is the KMS instance ID.
- |
-
-
-
-keyVersion
-
-int32
-
- |
-
- keyVersion is the key version number.
- |
-
-
-
-region
-
-string
-
- |
-
- region is the IBM Cloud region.
- |
-
-
-
-correlationID
-
-string
-
- |
-
- correlationID is the correlation ID for the key.
- |
-
-
-
-url
-
-string
-
- |
-
- url is the KMS endpoint URL.
- |
-
-
-
###IBMCloudKMSManagedAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSManagedAuthSpec }
(Appears on:
@@ -16409,8 +16234,7 @@ When omitted, the autoscaler defaults to 50%.
SecretEncryptionStatus)
-
SecretEncryptionKeyStatus records the active key identity. Status-specific types are used
-instead of reusing the spec types directly, to decouple status serialization from spec type evolution.
+SecretEncryptionKeyStatus records the active key identity using the same types as the spec.