Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 114 additions & 7 deletions openapi/generated_openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 66 additions & 7 deletions operator/v1/types_csi_cluster_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,25 +113,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
Expand All @@ -156,6 +158,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"`
}
Comment on lines +162 to 165
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Gate the new stable v1 field behind a feature gate.

Line 162 introduces a new stable API field without a +openshift:enable:FeatureGate=... marker. That violates the stable API rollout requirement and can expose partially-supported config in GA surface.

Suggested direction
 	// secretsStore is used to configure the Secrets Store CSI driver.
+	// +openshift:enable:FeatureGate=SecretsStoreCSIDriver
 	// +optional
 	SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`

As per coding guidelines, **/types*.go: New fields on stable APIs should be introduced behind a feature gate using +openshift:enable:FeatureGate=MyFeatureGate.

📝 Committable suggestion

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

Suggested change
// secretsStore is used to configure the Secrets Store CSI driver.
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
}
// secretsStore is used to configure the Secrets Store CSI driver.
// +openshift:enable:FeatureGate=SecretsStoreCSIDriver
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@operator/v1/types_csi_cluster_driver.go` around lines 162 - 165, The new
stable API field SecretsStore (*SecretsStoreCSIDriverConfigSpec) must be gated
with an OpenShift feature gate; add the kubebuilder marker comment
+openshift:enable:FeatureGate=YourFeatureGateName immediately above the
`SecretsStore` field declaration (the SecretsStore
*SecretsStoreCSIDriverConfigSpec line) so the field is only enabled when the
feature gate is on, and update any related docs/tests to use that feature gate
name.


// AWSCSIDriverConfigSpec defines properties that can be configured for the AWS CSI driver.
Expand Down Expand Up @@ -389,6 +395,59 @@ type VSphereCSIDriverConfigSpec struct {
MaxAllowedBlockVolumesPerNode int32 `json:"maxAllowedBlockVolumesPerNode,omitempty"`
}

// SecretsStoreCSIDriverConfigSpec defines properties that can be configured for the Secrets Store CSI driver.
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 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.
// An empty audience string means the token uses the kube-apiserver's default APIAudiences.
// +optional
// +listType=atomic
TokenRequests []SecretsStoreTokenRequest `json:"tokenRequests,omitempty"`
Comment on lines +405 to +411
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document omitted behavior for new optional fields.

tokenRequests and expirationSeconds are marked +optional, but their comments don’t describe behavior when omitted.

As per coding guidelines, Documentation for +optional fields must explain the behavior when the field is omitted.

Also applies to: 445-448

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@operator/v1/types_csi_cluster_driver.go` around lines 405 - 411, Update the
field comments for TokenRequests (type SecretsStoreTokenRequest) and the
expirationSeconds field to document the default behavior when omitted: state
that if TokenRequests is nil/empty, no service account tokens will be requested
and the CSI driver will use the kube-apiserver's default APIAudiences (or no
tokens provided), and if expirationSeconds is omitted the token lifetime
defaults to the kubelet/cluster provider default (or a specific default value
used by the implementation). Modify the comment blocks adjacent to the
TokenRequests declaration and the expirationSeconds declaration to include these
omission semantics and expected default values/behavior so the optional nature
is clear.

}

// SecretsStoreSecretRotation configures the automatic secret rotation behavior
// for the Secrets Store CSI driver.
type SecretsStoreSecretRotation struct {
// enabled controls whether automatic secret rotation is active.
// When true, the CSIDriver object sets requiresRepublish and the driver
// re-fetches secrets from providers.
// When false, secrets are only fetched at initial pod mount time.
// Default is true.
// +kubebuilder:default=true
// +optional
Enabled *bool `json:"enabled,omitempty"`

// rotationPollInterval is the minimum duration between secret rotation attempts.
// The driver skips provider calls if less than this interval has elapsed since
// the last successful rotation. Format is a Go duration string (e.g. "2m", "1h30m").
// Default is "2m".
// +kubebuilder:default="2m"
// +kubebuilder:validation:Pattern=`^([0-9]+(\.[0-9]+)?(s|m|h))+$`
// +kubebuilder:validation:Type:=string
// +optional
RotationPollInterval *metav1.Duration `json:"rotationPollInterval,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.
// +required
Audience string `json:"audience"`

// expirationSeconds is the requested duration of validity of the service account token.
// The token issuer may return a token with a different validity duration.
// +optional
ExpirationSeconds *int64 `json:"expirationSeconds,omitempty"`
}

// ClusterCSIDriverStatus is the observed status of CSI driver operator
type ClusterCSIDriverStatus struct {
OperatorStatus `json:",inline"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
- ""
Expand All @@ -196,6 +196,7 @@ spec:
- GCP
- IBMCloud
- vSphere
- SecretsStore
type: string
gcp:
description: gcp is used to configure the GCP CSI driver.
Expand Down Expand Up @@ -261,6 +262,62 @@ spec:
required:
- encryptionKeyCRN
type: object
secretsStore:
description: secretsStore is used to configure the Secrets Store
CSI driver.
properties:
secretRotation:
description: |-
secretRotation controls automatic secret rotation behavior.
When omitted, secret rotation is enabled with a default poll interval of 2 minutes.
properties:
enabled:
default: true
description: |-
enabled controls whether automatic secret rotation is active.
When true, the CSIDriver object sets requiresRepublish and the driver
re-fetches secrets from providers.
When false, secrets are only fetched at initial pod mount time.
Default is true.
type: boolean
rotationPollInterval:
default: 2m
description: |-
rotationPollInterval is the minimum duration between secret rotation attempts.
The driver skips provider calls if less than this interval has elapsed since
the last successful rotation. Format is a Go duration string (e.g. "2m", "1h30m").
Default is "2m".
pattern: ^([0-9]+(\.[0-9]+)?(s|m|h))+$
type: string
type: object
tokenRequests:
description: |-
tokenRequests 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.
An empty audience string means the token uses the kube-apiserver's default APIAudiences.
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.
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.
format: int64
type: integer
required:
- audience
type: object
type: array
x-kubernetes-list-type: atomic
type: object
vSphere:
description: vSphere is used to configure the vsphere CSI driver.
properties:
Expand Down Expand Up @@ -328,6 +385,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: |-
Expand Down
Loading