diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 6f65ddbfdf0..41a52f07b5f 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -1067,6 +1067,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/operator/v1.ConsoleSpec": schema_openshift_api_operator_v1_ConsoleSpec(ref), "github.com/openshift/api/operator/v1.ConsoleStatus": schema_openshift_api_operator_v1_ConsoleStatus(ref), "github.com/openshift/api/operator/v1.ContainerLoggingDestinationParameters": schema_openshift_api_operator_v1_ContainerLoggingDestinationParameters(ref), + "github.com/openshift/api/operator/v1.CustomSecretRotation": schema_openshift_api_operator_v1_CustomSecretRotation(ref), "github.com/openshift/api/operator/v1.DNS": schema_openshift_api_operator_v1_DNS(ref), "github.com/openshift/api/operator/v1.DNSCache": schema_openshift_api_operator_v1_DNSCache(ref), "github.com/openshift/api/operator/v1.DNSList": schema_openshift_api_operator_v1_DNSList(ref), @@ -1162,6 +1163,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/operator/v1.MachineManager": schema_openshift_api_operator_v1_MachineManager(ref), "github.com/openshift/api/operator/v1.MachineManagerSelector": schema_openshift_api_operator_v1_MachineManagerSelector(ref), "github.com/openshift/api/operator/v1.ManagedBootImages": schema_openshift_api_operator_v1_ManagedBootImages(ref), + "github.com/openshift/api/operator/v1.ManagedTokenRequests": schema_openshift_api_operator_v1_ManagedTokenRequests(ref), "github.com/openshift/api/operator/v1.MyOperatorResource": schema_openshift_api_operator_v1_MyOperatorResource(ref), "github.com/openshift/api/operator/v1.MyOperatorResourceSpec": schema_openshift_api_operator_v1_MyOperatorResourceSpec(ref), "github.com/openshift/api/operator/v1.MyOperatorResourceStatus": schema_openshift_api_operator_v1_MyOperatorResourceStatus(ref), @@ -1220,6 +1222,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/operator/v1.RestartService": schema_openshift_api_operator_v1_RestartService(ref), "github.com/openshift/api/operator/v1.RouteAdmissionPolicy": schema_openshift_api_operator_v1_RouteAdmissionPolicy(ref), "github.com/openshift/api/operator/v1.SFlowConfig": schema_openshift_api_operator_v1_SFlowConfig(ref), + "github.com/openshift/api/operator/v1.SecretsStoreCSIDriverConfigSpec": schema_openshift_api_operator_v1_SecretsStoreCSIDriverConfigSpec(ref), + "github.com/openshift/api/operator/v1.SecretsStoreSecretRotation": schema_openshift_api_operator_v1_SecretsStoreSecretRotation(ref), + "github.com/openshift/api/operator/v1.SecretsStoreTokenRequest": schema_openshift_api_operator_v1_SecretsStoreTokenRequest(ref), + "github.com/openshift/api/operator/v1.SecretsStoreTokenRequests": schema_openshift_api_operator_v1_SecretsStoreTokenRequests(ref), "github.com/openshift/api/operator/v1.Server": schema_openshift_api_operator_v1_Server(ref), "github.com/openshift/api/operator/v1.ServiceAccountIssuerStatus": schema_openshift_api_operator_v1_ServiceAccountIssuerStatus(ref), "github.com/openshift/api/operator/v1.ServiceCA": schema_openshift_api_operator_v1_ServiceCA(ref), @@ -52657,7 +52663,7 @@ func schema_openshift_api_operator_v1_CSIDriverConfigSpec(ref common.ReferenceCa Properties: map[string]spec.Schema{ "driverType": { SchemaProps: spec.SchemaProps{ - Description: "driverType indicates type of CSI driver for which the driverConfig is being applied to. Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. Consumers should treat unknown values as a NO-OP.", + Description: "driverType indicates type of CSI driver for which the driverConfig is being applied to. Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP.", Default: "", Type: []string{"string"}, Format: "", @@ -52693,6 +52699,12 @@ func schema_openshift_api_operator_v1_CSIDriverConfigSpec(ref common.ReferenceCa Ref: ref("github.com/openshift/api/operator/v1.VSphereCSIDriverConfigSpec"), }, }, + "secretsStore": { + SchemaProps: spec.SchemaProps{ + Description: "secretsStore is used to configure the Secrets Store CSI driver.", + Ref: ref("github.com/openshift/api/operator/v1.SecretsStoreCSIDriverConfigSpec"), + }, + }, }, Required: []string{"driverType"}, }, @@ -52702,11 +52714,12 @@ func schema_openshift_api_operator_v1_CSIDriverConfigSpec(ref common.ReferenceCa map[string]interface{}{ "discriminator": "driverType", "fields-to-discriminateBy": map[string]interface{}{ - "aws": "AWS", - "azure": "Azure", - "gcp": "GCP", - "ibmcloud": "IBMCloud", - "vSphere": "VSphere", + "aws": "AWS", + "azure": "Azure", + "gcp": "GCP", + "ibmcloud": "IBMCloud", + "secretsStore": "SecretsStore", + "vSphere": "VSphere", }, }, }, @@ -52714,7 +52727,7 @@ func schema_openshift_api_operator_v1_CSIDriverConfigSpec(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/openshift/api/operator/v1.AWSCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.AzureCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.GCPCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.IBMCloudCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.VSphereCSIDriverConfigSpec"}, + "github.com/openshift/api/operator/v1.AWSCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.AzureCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.GCPCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.IBMCloudCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.SecretsStoreCSIDriverConfigSpec", "github.com/openshift/api/operator/v1.VSphereCSIDriverConfigSpec"}, } } @@ -54442,6 +54455,27 @@ func schema_openshift_api_operator_v1_ContainerLoggingDestinationParameters(ref } } +func schema_openshift_api_operator_v1_CustomSecretRotation(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "CustomSecretRotation holds configuration for custom secret rotation behavior.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "rotationPollIntervalSeconds": { + SchemaProps: spec.SchemaProps{ + Description: "rotationPollIntervalSeconds is the minimum time in seconds between secret rotation attempts. The driver skips provider calls if less than this interval has elapsed since the last successful rotation. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is 120 (2 minutes).", + Default: 120, + Type: []string{"integer"}, + Format: "int32", + }, + }, + }, + }, + }, + } +} + func schema_openshift_api_operator_v1_DNS(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -59301,6 +59335,40 @@ func schema_openshift_api_operator_v1_ManagedBootImages(ref common.ReferenceCall } } +func schema_openshift_api_operator_v1_ManagedTokenRequests(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ManagedTokenRequests holds the configuration for operator-managed service account token requests.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "audiences": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "audiences specifies service account token audiences that kubelet will provide to the CSI driver during NodePublishVolume calls. These tokens enable workload identity federation (WIF) with cloud providers such as AWS, Azure, and GCP.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/operator/v1.SecretsStoreTokenRequest"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/operator/v1.SecretsStoreTokenRequest"}, + } +} + func schema_openshift_api_operator_v1_MyOperatorResource(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -62237,6 +62305,143 @@ func schema_openshift_api_operator_v1_SFlowConfig(ref common.ReferenceCallback) } } +func schema_openshift_api_operator_v1_SecretsStoreCSIDriverConfigSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SecretsStoreCSIDriverConfigSpec defines properties that can be configured for the Secrets Store CSI driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "secretRotation": { + SchemaProps: spec.SchemaProps{ + Description: "secretRotation controls automatic secret rotation behavior. When omitted, secret rotation is enabled with a default poll interval of 2 minutes.", + Ref: ref("github.com/openshift/api/operator/v1.SecretsStoreSecretRotation"), + }, + }, + "tokenRequests": { + SchemaProps: spec.SchemaProps{ + Description: "tokenRequests controls service account token configuration for workload identity federation (WIF) with cloud providers.", + Ref: ref("github.com/openshift/api/operator/v1.SecretsStoreTokenRequests"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/operator/v1.SecretsStoreSecretRotation", "github.com/openshift/api/operator/v1.SecretsStoreTokenRequests"}, + } +} + +func schema_openshift_api_operator_v1_SecretsStoreSecretRotation(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SecretsStoreSecretRotation configures the automatic secret rotation behavior for the Secrets Store CSI driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "type determines the secret rotation behavior. When \"None\", secret rotation is disabled and secrets are only fetched at initial pod mount time. When \"Custom\", secret rotation is enabled with the configuration specified in the custom field.", + Type: []string{"string"}, + Format: "", + }, + }, + "custom": { + SchemaProps: spec.SchemaProps{ + Description: "custom holds the custom rotation configuration. Only valid when type is \"Custom\".", + Ref: ref("github.com/openshift/api/operator/v1.CustomSecretRotation"), + }, + }, + }, + Required: []string{"type"}, + }, + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-unions": []interface{}{ + map[string]interface{}{ + "discriminator": "type", + "fields-to-discriminateBy": map[string]interface{}{ + "custom": "Custom", + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/operator/v1.CustomSecretRotation"}, + } +} + +func schema_openshift_api_operator_v1_SecretsStoreTokenRequest(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SecretsStoreTokenRequest specifies a service account token audience configuration for workload identity federation (WIF) with the Secrets Store CSI driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "audience": { + SchemaProps: spec.SchemaProps{ + Description: "audience is the intended audience of the service account token. An empty string means the issued token will use the kube-apiserver's default APIAudiences.", + Type: []string{"string"}, + Format: "", + }, + }, + "expirationSeconds": { + SchemaProps: spec.SchemaProps{ + Description: "expirationSeconds is the requested duration of validity of the service account token. The token issuer may return a token with a different validity duration. When omitted, the token expiration is determined by the kube-apiserver. Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds.", + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + Required: []string{"audience"}, + }, + }, + } +} + +func schema_openshift_api_operator_v1_SecretsStoreTokenRequests(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SecretsStoreTokenRequests configures how service account tokens are provided to the Secrets Store CSI driver for workload identity federation.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "type determines how the operator manages tokenRequests on the CSIDriver object. When \"Unmanaged\", existing tokenRequests on the CSIDriver are preserved and the managed field is not used. When \"Managed\", the operator sets tokenRequests from the audiences specified in the managed field, replacing any previously configured values. Once set to \"Managed\", type cannot be reverted back to \"Unmanaged\".", + Type: []string{"string"}, + Format: "", + }, + }, + "managed": { + SchemaProps: spec.SchemaProps{ + Description: "managed holds configuration for operator-managed tokenRequests. Only valid when type is \"Managed\".", + Ref: ref("github.com/openshift/api/operator/v1.ManagedTokenRequests"), + }, + }, + }, + Required: []string{"type"}, + }, + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-unions": []interface{}{ + map[string]interface{}{ + "discriminator": "type", + "fields-to-discriminateBy": map[string]interface{}{ + "managed": "Managed", + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/operator/v1.ManagedTokenRequests"}, + } +} + func schema_openshift_api_operator_v1_Server(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/operator/v1/tests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml b/operator/v1/tests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml index f9370ef9c9a..a600700268e 100644 --- a/operator/v1/tests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml +++ b/operator/v1/tests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml @@ -39,3 +39,617 @@ tests: driverType: IBMCloud ibmcloud: {} expectedError: "spec.driverConfig.ibmcloud.encryptionKeyCRN: Required value, : Invalid value: \"null\": some validation rules were not checked because the object was invalid; correct the existing errors to complete validation" + - name: SecretsStore driverType must have secretsStore spec + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + expectedError: "Invalid value: \"object\": secretsStore must be set if driverType is 'SecretsStore', but remain unset otherwise" + - name: SecretsStore spec must not be set without SecretsStore driverType + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: AWS + secretsStore: + secretRotation: + type: Custom + custom: + rotationPollIntervalSeconds: 300 + expectedError: "Invalid value: \"object\": secretsStore must be set if driverType is 'SecretsStore', but remain unset otherwise" + - name: Should reject secrets-store name with non-SecretsStore driverType + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: AWS + expectedError: "metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io'" + - name: Should reject SecretsStore driverType with non-secrets-store name + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: ebs.csi.aws.com + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + custom: + rotationPollIntervalSeconds: 300 + expectedError: "metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io'" + - name: Should allow secrets-store name without driverType for backward compatibility + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + managementState: Managed + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + managementState: Managed + - name: Should create SecretsStore with Custom rotation and default interval + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + custom: {} + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + custom: + rotationPollIntervalSeconds: 120 + - name: Should create SecretsStore with Managed tokenRequests + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + - name: Should allow Unmanaged tokenRequests + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Unmanaged + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Unmanaged + - name: Should create SecretsStore with rotation None + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: None + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: None + - name: Should create SecretsStore with full configuration + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + custom: + rotationPollIntervalSeconds: 300 + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 3600 + - audience: "api://AzureADTokenExchange" + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + custom: + rotationPollIntervalSeconds: 300 + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 3600 + - audience: "api://AzureADTokenExchange" + - name: Should reject empty secretsStore struct + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: {} + expectedError: "spec.driverConfig.secretsStore: Invalid value" + - name: Should reject secretRotation without type (discriminator required) + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: {} + expectedError: "spec.driverConfig.secretsStore.secretRotation.type" + - name: Should reject tokenRequests without type (discriminator required) + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: {} + expectedError: "spec.driverConfig.secretsStore.tokenRequests.type" + - name: Should allow empty audience string for kube-apiserver default + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "" + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "" + - name: Should allow Managed type with empty audiences to clear tokenRequests + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: {} + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: {} + - name: Should allow audience with expirationSeconds + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 7200 + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 7200 + - name: Should reject expirationSeconds below 600 + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 300 + expectedError: "spec.driverConfig.secretsStore.tokenRequests.managed.audiences[0].expirationSeconds: Invalid value" + - name: Should reject expirationSeconds above 4294967296 + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 4294967297 + expectedError: "spec.driverConfig.secretsStore.tokenRequests.managed.audiences[0].expirationSeconds: Invalid value" + - name: Should allow multiple audiences for multi-cloud WIF + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 3600 + - audience: "api://AzureADTokenExchange" + - audience: "https://accounts.google.com" + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expirationSeconds: 3600 + - audience: "api://AzureADTokenExchange" + - audience: "https://accounts.google.com" + - name: Should reject invalid secretRotation type enum + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Invalid + expectedError: "spec.driverConfig.secretsStore.secretRotation.type" + - name: Should reject invalid tokenRequests type enum + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Invalid + expectedError: "spec.driverConfig.secretsStore.tokenRequests.type" + - name: Should reject Custom secretRotation without custom field + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + expectedError: "custom must be set when type is 'Custom', and must not be set otherwise" + - name: Should reject Managed tokenRequests without managed field + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + expectedError: "managed must be set when type is 'Managed', and must not be set otherwise" + onUpdate: + - name: Should not allow reverting tokenRequests type from Managed to Unmanaged + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + updated: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Unmanaged + expectedError: "type cannot be changed from Managed back to Unmanaged" + - name: Should not allow removing tokenRequests when type was Managed + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + updated: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + secretRotation: + type: Custom + custom: + rotationPollIntervalSeconds: 300 + expectedError: "tokenRequests cannot be removed when type is Managed" + - name: Should allow changing tokenRequests type from Unmanaged to Managed + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Unmanaged + updated: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + - name: Should allow updating audiences when type is Managed + initial: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + updated: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + - audience: "api://AzureADTokenExchange" + expected: | + apiVersion: operator.openshift.io/v1 + kind: ClusterCSIDriver + metadata: + name: secrets-store.csi.k8s.io + spec: + logLevel: Normal + operatorLogLevel: Normal + driverConfig: + driverType: SecretsStore + secretsStore: + tokenRequests: + type: Managed + managed: + audiences: + - audience: "sts.amazonaws.com" + - audience: "api://AzureADTokenExchange" diff --git a/operator/v1/types_csi_cluster_driver.go b/operator/v1/types_csi_cluster_driver.go index 52f5db78d51..f7b6df9804c 100644 --- a/operator/v1/types_csi_cluster_driver.go +++ b/operator/v1/types_csi_cluster_driver.go @@ -21,6 +21,7 @@ import ( // +kubebuilder:subresource:status // +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/701 // +openshift:file-pattern=cvoRunLevel=0000_50,operatorName=csi-driver,operatorOrdering=01 +// +kubebuilder:validation:XValidation:rule="!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType == 'SecretsStore' ? self.metadata.name == 'secrets-store.csi.k8s.io' : (self.metadata.name != 'secrets-store.csi.k8s.io' || self.spec.driverConfig.driverType == ''))",message="metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io'" // ClusterCSIDriver object allows management and configuration of a CSI driver operator // installed by default in OpenShift. Name of the object must be name of the CSI driver @@ -113,25 +114,27 @@ type ClusterCSIDriverSpec struct { } // CSIDriverType indicates type of CSI driver being configured. -// +kubebuilder:validation:Enum="";AWS;Azure;GCP;IBMCloud;vSphere +// +kubebuilder:validation:Enum="";AWS;Azure;GCP;IBMCloud;vSphere;SecretsStore type CSIDriverType string const ( - AWSDriverType CSIDriverType = "AWS" - AzureDriverType CSIDriverType = "Azure" - GCPDriverType CSIDriverType = "GCP" - IBMCloudDriverType CSIDriverType = "IBMCloud" - VSphereDriverType CSIDriverType = "vSphere" + AWSDriverType CSIDriverType = "AWS" + AzureDriverType CSIDriverType = "Azure" + GCPDriverType CSIDriverType = "GCP" + IBMCloudDriverType CSIDriverType = "IBMCloud" + VSphereDriverType CSIDriverType = "vSphere" + SecretsStoreDriverType CSIDriverType = "SecretsStore" ) // CSIDriverConfigSpec defines configuration spec that can be // used to optionally configure a specific CSI Driver. // +kubebuilder:validation:XValidation:rule="has(self.driverType) && self.driverType == 'IBMCloud' ? has(self.ibmcloud) : !has(self.ibmcloud)",message="ibmcloud must be set if driverType is 'IBMCloud', but remain unset otherwise" +// +kubebuilder:validation:XValidation:rule="has(self.driverType) && self.driverType == 'SecretsStore' ? has(self.secretsStore) : !has(self.secretsStore)",message="secretsStore must be set if driverType is 'SecretsStore', but remain unset otherwise" // +union type CSIDriverConfigSpec struct { // driverType indicates type of CSI driver for which the // driverConfig is being applied to. - // Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + // Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. // Consumers should treat unknown values as a NO-OP. // +required // +unionDiscriminator @@ -156,6 +159,10 @@ type CSIDriverConfigSpec struct { // vSphere is used to configure the vsphere CSI driver. // +optional VSphere *VSphereCSIDriverConfigSpec `json:"vSphere,omitempty"` + + // secretsStore is used to configure the Secrets Store CSI driver. + // +optional + SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"` } // AWSCSIDriverConfigSpec defines properties that can be configured for the AWS CSI driver. @@ -389,6 +396,140 @@ type VSphereCSIDriverConfigSpec struct { MaxAllowedBlockVolumesPerNode int32 `json:"maxAllowedBlockVolumesPerNode,omitempty"` } +// SecretsStoreCSIDriverConfigSpec defines properties that can be configured for the Secrets Store CSI driver. +// +kubebuilder:validation:MinProperties=1 +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type != 'Managed' || (has(self.tokenRequests) && self.tokenRequests.type == 'Managed')",message="tokenRequests cannot be removed when type is Managed" +type SecretsStoreCSIDriverConfigSpec struct { + // secretRotation controls automatic secret rotation behavior. + // When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + // +optional + SecretRotation *SecretsStoreSecretRotation `json:"secretRotation,omitempty"` + + // tokenRequests controls service account token configuration for + // workload identity federation (WIF) with cloud providers. + // +optional + TokenRequests *SecretsStoreTokenRequests `json:"tokenRequests,omitempty"` +} + +// TokenRequestsType determines how the operator manages the tokenRequests +// field on the storage.k8s.io CSIDriver object. +// +kubebuilder:validation:Enum=Managed;Unmanaged +type TokenRequestsType string + +const ( + // TokenRequestsManaged means the operator uses the audiences list + // as the sole source of truth for the CSIDriver.spec.tokenRequests field. + TokenRequestsManaged TokenRequestsType = "Managed" + + // TokenRequestsUnmanaged means the operator preserves any existing + // tokenRequests already configured on the CSIDriver object and does not + // overwrite them. + TokenRequestsUnmanaged TokenRequestsType = "Unmanaged" +) + +// SecretsStoreTokenRequests configures how service account tokens are +// provided to the Secrets Store CSI driver for workload identity federation. +// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Managed' ? has(self.managed) : !has(self.managed)",message="managed must be set when type is 'Managed', and must not be set otherwise" +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.type) || oldSelf.type != 'Managed' || self.type == 'Managed'",message="type cannot be changed from Managed back to Unmanaged" +// +union +type SecretsStoreTokenRequests struct { + // type determines how the operator manages tokenRequests on the CSIDriver object. + // When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + // and the managed field is not used. + // When "Managed", the operator sets tokenRequests from the audiences + // specified in the managed field, replacing any previously configured values. + // Once set to "Managed", type cannot be reverted back to "Unmanaged". + // +unionDiscriminator + // +required + Type TokenRequestsType `json:"type,omitempty"` + + // managed holds configuration for operator-managed tokenRequests. + // Only valid when type is "Managed". + // +optional + Managed *ManagedTokenRequests `json:"managed,omitempty"` +} + +// ManagedTokenRequests holds the configuration for operator-managed +// service account token requests. +type ManagedTokenRequests struct { + // audiences specifies service account token audiences that kubelet will + // provide to the CSI driver during NodePublishVolume calls. These tokens + // enable workload identity federation (WIF) with cloud providers such as + // AWS, Azure, and GCP. + // +optional + // +listType=atomic + // +kubebuilder:validation:MaxItems=10 + Audiences []SecretsStoreTokenRequest `json:"audiences,omitempty"` +} + +// SecretRotationType determines the secret rotation behavior for the +// Secrets Store CSI driver. +// +kubebuilder:validation:Enum=None;Custom +type SecretRotationType string + +const ( + // SecretRotationNone disables automatic secret rotation. Secrets are only + // fetched at initial pod mount time. + SecretRotationNone SecretRotationType = "None" + + // SecretRotationCustom enables automatic secret rotation with the + // configuration specified in the custom field. + SecretRotationCustom SecretRotationType = "Custom" +) + +// SecretsStoreSecretRotation configures the automatic secret rotation behavior +// for the Secrets Store CSI driver. +// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Custom' ? has(self.custom) : !has(self.custom)",message="custom must be set when type is 'Custom', and must not be set otherwise" +// +union +type SecretsStoreSecretRotation struct { + // type determines the secret rotation behavior. + // When "None", secret rotation is disabled and secrets are only fetched at + // initial pod mount time. + // When "Custom", secret rotation is enabled with the configuration specified + // in the custom field. + // +unionDiscriminator + // +required + Type SecretRotationType `json:"type,omitempty"` + + // custom holds the custom rotation configuration. + // Only valid when type is "Custom". + // +optional + Custom *CustomSecretRotation `json:"custom,omitempty"` +} + +// CustomSecretRotation holds configuration for custom secret rotation behavior. +type CustomSecretRotation struct { + // rotationPollIntervalSeconds is the minimum time in seconds between secret + // rotation attempts. The driver skips provider calls if less than this interval + // has elapsed since the last successful rotation. + // When omitted, this means no opinion and the platform is left to choose a + // reasonable default, which is subject to change over time. + // The current default is 120 (2 minutes). + // +default=120 + // +optional + RotationPollIntervalSeconds *int32 `json:"rotationPollIntervalSeconds,omitempty"` +} + +// SecretsStoreTokenRequest specifies a service account token audience configuration +// for workload identity federation (WIF) with the Secrets Store CSI driver. +type SecretsStoreTokenRequest struct { + // audience is the intended audience of the service account token. + // An empty string means the issued token will use the kube-apiserver's default APIAudiences. + // +kubebuilder:validation:MinLength=0 + // +kubebuilder:validation:MaxLength=253 + // +required + Audience *string `json:"audience,omitempty"` + + // expirationSeconds is the requested duration of validity of the service account token. + // The token issuer may return a token with a different validity duration. + // When omitted, the token expiration is determined by the kube-apiserver. + // Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + // +kubebuilder:validation:Minimum=600 + // +kubebuilder:validation:Maximum=4294967296 + // +optional + ExpirationSeconds int64 `json:"expirationSeconds,omitempty"` +} + // ClusterCSIDriverStatus is the observed status of CSI driver operator type ClusterCSIDriverStatus struct { OperatorStatus `json:",inline"` diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml index 19b319fcb8d..a92ae264b7c 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -328,6 +449,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -506,6 +631,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml index 5bb6bdddcfb..4e5b52ab63a 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -313,6 +434,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -491,6 +616,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml index a03dd7d88db..7ec0c192a34 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -328,6 +449,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -506,6 +631,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml index 0e925a75110..83915c1b386 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -313,6 +434,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -491,6 +616,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml index 3dc68028e00..4cea5c8c369 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -328,6 +449,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -506,6 +631,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.deepcopy.go b/operator/v1/zz_generated.deepcopy.go index 3d3c8f4f825..08e3e3b9536 100644 --- a/operator/v1/zz_generated.deepcopy.go +++ b/operator/v1/zz_generated.deepcopy.go @@ -469,6 +469,11 @@ func (in *CSIDriverConfigSpec) DeepCopyInto(out *CSIDriverConfigSpec) { *out = new(VSphereCSIDriverConfigSpec) (*in).DeepCopyInto(*out) } + if in.SecretsStore != nil { + in, out := &in.SecretsStore, &out.SecretsStore + *out = new(SecretsStoreCSIDriverConfigSpec) + (*in).DeepCopyInto(*out) + } return } @@ -1180,6 +1185,27 @@ func (in *ContainerLoggingDestinationParameters) DeepCopy() *ContainerLoggingDes return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomSecretRotation) DeepCopyInto(out *CustomSecretRotation) { + *out = *in + if in.RotationPollIntervalSeconds != nil { + in, out := &in.RotationPollIntervalSeconds, &out.RotationPollIntervalSeconds + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomSecretRotation. +func (in *CustomSecretRotation) DeepCopy() *CustomSecretRotation { + if in == nil { + return nil + } + out := new(CustomSecretRotation) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DNS) DeepCopyInto(out *DNS) { *out = *in @@ -3432,6 +3458,29 @@ func (in *ManagedBootImages) DeepCopy() *ManagedBootImages { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedTokenRequests) DeepCopyInto(out *ManagedTokenRequests) { + *out = *in + if in.Audiences != nil { + in, out := &in.Audiences, &out.Audiences + *out = make([]SecretsStoreTokenRequest, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedTokenRequests. +func (in *ManagedTokenRequests) DeepCopy() *ManagedTokenRequests { + if in == nil { + return nil + } + out := new(ManagedTokenRequests) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MyOperatorResource) DeepCopyInto(out *MyOperatorResource) { *out = *in @@ -4869,6 +4918,95 @@ func (in *SFlowConfig) DeepCopy() *SFlowConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretsStoreCSIDriverConfigSpec) DeepCopyInto(out *SecretsStoreCSIDriverConfigSpec) { + *out = *in + if in.SecretRotation != nil { + in, out := &in.SecretRotation, &out.SecretRotation + *out = new(SecretsStoreSecretRotation) + (*in).DeepCopyInto(*out) + } + if in.TokenRequests != nil { + in, out := &in.TokenRequests, &out.TokenRequests + *out = new(SecretsStoreTokenRequests) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretsStoreCSIDriverConfigSpec. +func (in *SecretsStoreCSIDriverConfigSpec) DeepCopy() *SecretsStoreCSIDriverConfigSpec { + if in == nil { + return nil + } + out := new(SecretsStoreCSIDriverConfigSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretsStoreSecretRotation) DeepCopyInto(out *SecretsStoreSecretRotation) { + *out = *in + if in.Custom != nil { + in, out := &in.Custom, &out.Custom + *out = new(CustomSecretRotation) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretsStoreSecretRotation. +func (in *SecretsStoreSecretRotation) DeepCopy() *SecretsStoreSecretRotation { + if in == nil { + return nil + } + out := new(SecretsStoreSecretRotation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretsStoreTokenRequest) DeepCopyInto(out *SecretsStoreTokenRequest) { + *out = *in + if in.Audience != nil { + in, out := &in.Audience, &out.Audience + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretsStoreTokenRequest. +func (in *SecretsStoreTokenRequest) DeepCopy() *SecretsStoreTokenRequest { + if in == nil { + return nil + } + out := new(SecretsStoreTokenRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretsStoreTokenRequests) DeepCopyInto(out *SecretsStoreTokenRequests) { + *out = *in + if in.Managed != nil { + in, out := &in.Managed, &out.Managed + *out = new(ManagedTokenRequests) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretsStoreTokenRequests. +func (in *SecretsStoreTokenRequests) DeepCopy() *SecretsStoreTokenRequests { + if in == nil { + return nil + } + out := new(SecretsStoreTokenRequests) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Server) DeepCopyInto(out *Server) { *out = *in diff --git a/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml b/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml index 12aeaee8795..4ec6bfdf765 100644 --- a/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml +++ b/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml @@ -167,7 +167,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -176,6 +176,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -241,6 +242,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -293,6 +414,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -471,6 +596,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml b/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml index 1aeaf6ae0f2..688a28bd268 100644 --- a/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml +++ b/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml @@ -167,7 +167,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -176,6 +176,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -241,6 +242,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -293,6 +414,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -471,6 +596,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml b/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml index f7696f5e1b9..fa598facd78 100644 --- a/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml +++ b/operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml @@ -163,7 +163,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -172,6 +172,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -237,6 +238,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -304,6 +425,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -482,6 +607,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/operator/v1/zz_generated.swagger_doc_generated.go b/operator/v1/zz_generated.swagger_doc_generated.go index c3ed726028d..77b0fbc42c4 100644 --- a/operator/v1/zz_generated.swagger_doc_generated.go +++ b/operator/v1/zz_generated.swagger_doc_generated.go @@ -515,13 +515,14 @@ func (AzureDiskEncryptionSet) SwaggerDoc() map[string]string { } var map_CSIDriverConfigSpec = map[string]string{ - "": "CSIDriverConfigSpec defines configuration spec that can be used to optionally configure a specific CSI Driver.", - "driverType": "driverType indicates type of CSI driver for which the driverConfig is being applied to. Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. Consumers should treat unknown values as a NO-OP.", - "aws": "aws is used to configure the AWS CSI driver.", - "azure": "azure is used to configure the Azure CSI driver.", - "gcp": "gcp is used to configure the GCP CSI driver.", - "ibmcloud": "ibmcloud is used to configure the IBM Cloud CSI driver.", - "vSphere": "vSphere is used to configure the vsphere CSI driver.", + "": "CSIDriverConfigSpec defines configuration spec that can be used to optionally configure a specific CSI Driver.", + "driverType": "driverType indicates type of CSI driver for which the driverConfig is being applied to. Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP.", + "aws": "aws is used to configure the AWS CSI driver.", + "azure": "azure is used to configure the Azure CSI driver.", + "gcp": "gcp is used to configure the GCP CSI driver.", + "ibmcloud": "ibmcloud is used to configure the IBM Cloud CSI driver.", + "vSphere": "vSphere is used to configure the vsphere CSI driver.", + "secretsStore": "secretsStore is used to configure the Secrets Store CSI driver.", } func (CSIDriverConfigSpec) SwaggerDoc() map[string]string { @@ -566,6 +567,15 @@ func (ClusterCSIDriverStatus) SwaggerDoc() map[string]string { return map_ClusterCSIDriverStatus } +var map_CustomSecretRotation = map[string]string{ + "": "CustomSecretRotation holds configuration for custom secret rotation behavior.", + "rotationPollIntervalSeconds": "rotationPollIntervalSeconds is the minimum time in seconds between secret rotation attempts. The driver skips provider calls if less than this interval has elapsed since the last successful rotation. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is 120 (2 minutes).", +} + +func (CustomSecretRotation) SwaggerDoc() map[string]string { + return map_CustomSecretRotation +} + var map_GCPCSIDriverConfigSpec = map[string]string{ "": "GCPCSIDriverConfigSpec defines properties that can be configured for the GCP CSI driver.", "kmsKey": "kmsKey sets the cluster default storage class to encrypt volumes with customer-supplied encryption keys, rather than the default keys managed by GCP.", @@ -596,6 +606,55 @@ func (IBMCloudCSIDriverConfigSpec) SwaggerDoc() map[string]string { return map_IBMCloudCSIDriverConfigSpec } +var map_ManagedTokenRequests = map[string]string{ + "": "ManagedTokenRequests holds the configuration for operator-managed service account token requests.", + "audiences": "audiences specifies service account token audiences that kubelet will provide to the CSI driver during NodePublishVolume calls. These tokens enable workload identity federation (WIF) with cloud providers such as AWS, Azure, and GCP.", +} + +func (ManagedTokenRequests) SwaggerDoc() map[string]string { + return map_ManagedTokenRequests +} + +var map_SecretsStoreCSIDriverConfigSpec = map[string]string{ + "": "SecretsStoreCSIDriverConfigSpec defines properties that can be configured for the Secrets Store CSI driver.", + "secretRotation": "secretRotation controls automatic secret rotation behavior. When omitted, secret rotation is enabled with a default poll interval of 2 minutes.", + "tokenRequests": "tokenRequests controls service account token configuration for workload identity federation (WIF) with cloud providers.", +} + +func (SecretsStoreCSIDriverConfigSpec) SwaggerDoc() map[string]string { + return map_SecretsStoreCSIDriverConfigSpec +} + +var map_SecretsStoreSecretRotation = map[string]string{ + "": "SecretsStoreSecretRotation configures the automatic secret rotation behavior for the Secrets Store CSI driver.", + "type": "type determines the secret rotation behavior. When \"None\", secret rotation is disabled and secrets are only fetched at initial pod mount time. When \"Custom\", secret rotation is enabled with the configuration specified in the custom field.", + "custom": "custom holds the custom rotation configuration. Only valid when type is \"Custom\".", +} + +func (SecretsStoreSecretRotation) SwaggerDoc() map[string]string { + return map_SecretsStoreSecretRotation +} + +var map_SecretsStoreTokenRequest = map[string]string{ + "": "SecretsStoreTokenRequest specifies a service account token audience configuration for workload identity federation (WIF) with the Secrets Store CSI driver.", + "audience": "audience is the intended audience of the service account token. An empty string means the issued token will use the kube-apiserver's default APIAudiences.", + "expirationSeconds": "expirationSeconds is the requested duration of validity of the service account token. The token issuer may return a token with a different validity duration. When omitted, the token expiration is determined by the kube-apiserver. Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds.", +} + +func (SecretsStoreTokenRequest) SwaggerDoc() map[string]string { + return map_SecretsStoreTokenRequest +} + +var map_SecretsStoreTokenRequests = map[string]string{ + "": "SecretsStoreTokenRequests configures how service account tokens are provided to the Secrets Store CSI driver for workload identity federation.", + "type": "type determines how the operator manages tokenRequests on the CSIDriver object. When \"Unmanaged\", existing tokenRequests on the CSIDriver are preserved and the managed field is not used. When \"Managed\", the operator sets tokenRequests from the audiences specified in the managed field, replacing any previously configured values. Once set to \"Managed\", type cannot be reverted back to \"Unmanaged\".", + "managed": "managed holds configuration for operator-managed tokenRequests. Only valid when type is \"Managed\".", +} + +func (SecretsStoreTokenRequests) SwaggerDoc() map[string]string { + return map_SecretsStoreTokenRequests +} + var map_VSphereCSIDriverConfigSpec = map[string]string{ "": "VSphereCSIDriverConfigSpec defines properties that can be configured for vsphere CSI driver.", "topologyCategories": "topologyCategories indicates tag categories with which vcenter resources such as hostcluster or datacenter were tagged with. If cluster Infrastructure object has a topology, values specified in Infrastructure object will be used and modifications to topologyCategories will be rejected.", diff --git a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml index 19b319fcb8d..a92ae264b7c 100644 --- a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -328,6 +449,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -506,6 +631,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml index 5bb6bdddcfb..4e5b52ab63a 100644 --- a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml +++ b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -313,6 +434,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -491,6 +616,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml index a03dd7d88db..7ec0c192a34 100644 --- a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -328,6 +449,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -506,6 +631,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml index 0e925a75110..83915c1b386 100644 --- a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml +++ b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -313,6 +434,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -491,6 +616,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml index 3dc68028e00..4cea5c8c369 100644 --- a/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml @@ -187,7 +187,7 @@ spec: description: |- driverType indicates type of CSI driver for which the driverConfig is being applied to. - Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. + Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP. enum: - "" @@ -196,6 +196,7 @@ spec: - GCP - IBMCloud - vSphere + - SecretsStore type: string gcp: description: gcp is used to configure the GCP CSI driver. @@ -261,6 +262,126 @@ spec: required: - encryptionKeyCRN type: object + secretsStore: + description: secretsStore is used to configure the Secrets Store + CSI driver. + minProperties: 1 + properties: + secretRotation: + description: |- + secretRotation controls automatic secret rotation behavior. + When omitted, secret rotation is enabled with a default poll interval of 2 minutes. + properties: + custom: + description: |- + custom holds the custom rotation configuration. + Only valid when type is "Custom". + properties: + rotationPollIntervalSeconds: + default: 120 + description: |- + rotationPollIntervalSeconds is the minimum time in seconds between secret + rotation attempts. The driver skips provider calls if less than this interval + has elapsed since the last successful rotation. + When omitted, this means no opinion and the platform is left to choose a + reasonable default, which is subject to change over time. + The current default is 120 (2 minutes). + format: int32 + type: integer + type: object + type: + description: |- + type determines the secret rotation behavior. + When "None", secret rotation is disabled and secrets are only fetched at + initial pod mount time. + When "Custom", secret rotation is enabled with the configuration specified + in the custom field. + enum: + - None + - Custom + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: custom must be set when type is 'Custom', and must + not be set otherwise + rule: 'has(self.type) && self.type == ''Custom'' ? has(self.custom) + : !has(self.custom)' + tokenRequests: + description: |- + tokenRequests controls service account token configuration for + workload identity federation (WIF) with cloud providers. + properties: + managed: + description: |- + managed holds configuration for operator-managed tokenRequests. + Only valid when type is "Managed". + properties: + audiences: + description: |- + audiences specifies service account token audiences that kubelet will + provide to the CSI driver during NodePublishVolume calls. These tokens + enable workload identity federation (WIF) with cloud providers such as + AWS, Azure, and GCP. + items: + description: |- + SecretsStoreTokenRequest specifies a service account token audience configuration + for workload identity federation (WIF) with the Secrets Store CSI driver. + properties: + audience: + description: |- + audience is the intended audience of the service account token. + An empty string means the issued token will use the kube-apiserver's default APIAudiences. + maxLength: 253 + minLength: 0 + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service account token. + The token issuer may return a token with a different validity duration. + When omitted, the token expiration is determined by the kube-apiserver. + Must be at least 600 seconds (10 minutes) and no more than 4294967296 (1 << 32) seconds. + format: int64 + maximum: 4294967296 + minimum: 600 + type: integer + required: + - audience + type: object + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + type: object + type: + description: |- + type determines how the operator manages tokenRequests on the CSIDriver object. + When "Unmanaged", existing tokenRequests on the CSIDriver are preserved + and the managed field is not used. + When "Managed", the operator sets tokenRequests from the audiences + specified in the managed field, replacing any previously configured values. + Once set to "Managed", type cannot be reverted back to "Unmanaged". + enum: + - Managed + - Unmanaged + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: managed must be set when type is 'Managed', and + must not be set otherwise + rule: 'has(self.type) && self.type == ''Managed'' ? has(self.managed) + : !has(self.managed)' + - message: type cannot be changed from Managed back to Unmanaged + rule: '!has(oldSelf.type) || oldSelf.type != ''Managed'' + || self.type == ''Managed''' + type: object + x-kubernetes-validations: + - message: tokenRequests cannot be removed when type is Managed + rule: '!has(oldSelf.tokenRequests) || oldSelf.tokenRequests.type + != ''Managed'' || (has(self.tokenRequests) && self.tokenRequests.type + == ''Managed'')' vSphere: description: vSphere is used to configure the vsphere CSI driver. properties: @@ -328,6 +449,10 @@ spec: unset otherwise rule: 'has(self.driverType) && self.driverType == ''IBMCloud'' ? has(self.ibmcloud) : !has(self.ibmcloud)' + - message: secretsStore must be set if driverType is 'SecretsStore', + but remain unset otherwise + rule: 'has(self.driverType) && self.driverType == ''SecretsStore'' + ? has(self.secretsStore) : !has(self.secretsStore)' logLevel: default: Normal description: |- @@ -506,6 +631,13 @@ spec: required: - spec type: object + x-kubernetes-validations: + - message: metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', + and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io' + rule: '!has(self.spec.driverConfig) || (self.spec.driverConfig.driverType + == ''SecretsStore'' ? self.metadata.name == ''secrets-store.csi.k8s.io'' + : (self.metadata.name != ''secrets-store.csi.k8s.io'' || self.spec.driverConfig.driverType + == ''''))' served: true storage: true subresources: