Skip to content

Commit d39731f

Browse files
committed
add bucketaccess(class) types, and tidy all CEL rules
Add Kubernetes API (client) types for BucketAccess and BucketAccessClass. Since these are the last API types, also standardize CEL rule invocations for existing types. Signed-off-by: Blaine Gardner <[email protected]>
1 parent f53f9d6 commit d39731f

17 files changed

+1361
-353
lines changed

client/apis/objectstorage/v1alpha2/bucket_types.go

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ const (
3737
)
3838

3939
// BucketSpec defines the desired state of Bucket
40+
// +kubebuilder:validation:XValidation:message="parameters map is immutable",rule="has(oldSelf.parameters) == has(self.parameters)"
41+
// +kubebuilder:validation:XValidation:message="protocols list is immutable",rule="has(oldSelf.protocols) == has(self.protocols)"
42+
// +kubebuilder:validation:XValidation:message="existingBucketID is immutable",rule="has(oldSelf.existingBucketID) == has(self.existingBucketID)"
4043
type BucketSpec struct {
4144
// driverName is the name of the driver that fulfills requests for this Bucket.
4245
// +required
@@ -70,38 +73,70 @@ type BucketSpec struct {
7073
// allowed to bind to this Bucket.
7174
// +required
7275
BucketClaimRef BucketClaimReference `json:"bucketClaim"`
76+
77+
// existingBucketID is the unique identifier for an existing backend bucket known to the driver.
78+
// Use driver documentation to determine how to set this value.
79+
// This field is used only for Bucket static provisioning.
80+
// This field will be empty when the Bucket is dynamically provisioned from a BucketClaim.
81+
// +optional
82+
// +kubebuilder:validation:XValidation:message="existingBucketID is immutable",rule="self == oldSelf"
83+
ExistingBucketID string `json:"existingBucketID,omitempty"`
7384
}
7485

7586
// BucketClaimReference is a reference to a BucketClaim object.
87+
// +kubebuilder:validation:XValidation:message="namespace is immutable once set",rule="!has(oldSelf.namespace) || has(self.namespace)"
88+
// +kubebuilder:validation:XValidation:message="uid is immutable once set",rule="!has(oldSelf.uid) || has(self.uid)"
7689
type BucketClaimReference struct {
7790
// name is the name of the BucketClaim being referenced.
7891
// +required
7992
// +kubebuilder:validation:MinLength=1
80-
// +kubebuilder:validation:XValidation:message="driverName is immutable",rule="self == oldSelf"
93+
// +kubebuilder:validation:MaxLength=253
94+
// +kubebuilder:validation:XValidation:message="name is immutable",rule="self == oldSelf"
8195
Name string `json:"name"`
8296

8397
// namespace is the namespace of the BucketClaim being referenced.
8498
// If empty, the Kubernetes 'default' namespace is assumed.
8599
// namespace is immutable except to update '' to 'default'.
86100
// +optional
87101
// +kubebuilder:validation:MinLength=0
88-
// +kubebuilder:validation:XValidation:message="driverName is immutable",rule="(oldSelf == '' && self == 'default') || self == oldSelf"
102+
// +kubebuilder:validation:MaxLength=253
103+
// +kubebuilder:validation:XValidation:message="namespace is immutable",rule="(oldSelf == '' && self == 'default') || self == oldSelf"
89104
Namespace string `json:"namespace"`
90105

91106
// uid is the UID of the BucketClaim being referenced.
92-
// Once set, the UID is immutable.
93107
// +optional
94-
// +kubebuilder:validation:XValidation:message="driverName is immutable",rule="oldSelf == '' || self == oldSelf"
108+
// +kubebuilder:validation:XValidation:message="uid is immutable once set",rule="oldSelf == '' || self == oldSelf"
95109
UID types.UID `json:"uid"`
96110
}
97111

98112
// BucketStatus defines the observed state of Bucket.
113+
// +kubebuilder:validation:XValidation:message="bucketID is immutable once set",rule="!has(oldSelf.bucketID) || has(self.bucketID)"
114+
// +kubebuilder:validation:XValidation:message="protocols is immutable once set",rule="!has(oldSelf.protocols) || has(self.protocols)"
99115
type BucketStatus struct {
100-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
101-
// Important: Run "make" to regenerate code after modifying this file
116+
// readyToUse indicates that the bucket is ready for consumption by workloads.
117+
ReadyToUse bool `json:"readyToUse"`
102118

103-
// For Kubernetes API conventions, see:
104-
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
119+
// bucketID is the unique identifier for the backend bucket known to the driver.
120+
// +optional
121+
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable once set",rule="oldSelf == '' || self == oldSelf"
122+
BucketID string `json:"bucketID"`
123+
124+
// protocols is the set of protocols the Bucket reports to support. BucketAccesses can request
125+
// access to this BucketClaim using any of the protocols reported here.
126+
// +optional
127+
// +listType=set
128+
Protocols []ObjectProtocol `json:"protocols"`
129+
130+
// BucketInfo reported by the driver, rendered in the COSI_<PROTOCOL>_<KEY> format used for the
131+
// BucketAccess Secret. e.g., COSI_S3_ENDPOINT, COSI_AZURE_STORAGE_ACCOUNT.
132+
// This should not contain any sensitive information.
133+
// +optional
134+
BucketInfo map[string]string `json:"bucketInfo,omitempty"`
135+
136+
// Error holds the most recent error message, with a timestamp.
137+
// This is cleared when provisioning is successful.
138+
// +optional
139+
Error *TimestampedError `json:"error,omitempty"`
105140
}
106141

107142
// +kubebuilder:object:root=true

client/apis/objectstorage/v1alpha2/bucketaccess_types.go

Lines changed: 148 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,39 +20,164 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
)
2222

23+
// BucketAccessAuthenticationType specifies what authentication mechanism is used for provisioning
24+
// bucket access.
25+
// +enum
26+
// +kubebuilder:validation:Enum:="";Key;ServiceAccount
27+
type BucketAccessAuthenticationType string
28+
29+
const (
30+
// The driver should generate a protocol-appropriate access key that clients can use to
31+
// authenticate to the backend object store.
32+
BucketAccessAuthenticationTypeKey = "Key"
33+
34+
// The driver should configure the system such that Pods using the given ServiceAccount
35+
// authenticate to the backend object store automatically.
36+
BucketAccessAuthenticationTypeServiceAccount = "ServiceAccount"
37+
)
38+
39+
// BucketAccessMode describes the Read/Write mode an access should have for a bucket.
40+
// +enum
41+
// +kubebuilder:validation:Enum:=ReadWrite;ReadOnly;WriteOnly
42+
type BucketAccessMode string
43+
44+
const (
45+
// BucketAccessModeReadWrite represents read-write access mode.
46+
BucketAccessModeReadWrite BucketAccessMode = "ReadWrite"
47+
48+
// BucketAccessModeReadOnly represents read-only access mode.
49+
BucketAccessModeReadOnly BucketAccessMode = "ReadOnly"
50+
51+
// BucketAccessModeWriteOnly represents write-only access mode.
52+
BucketAccessModeWriteOnly BucketAccessMode = "WriteOnly"
53+
)
54+
2355
// BucketAccessSpec defines the desired state of BucketAccess
56+
// +kubebuilder:validation:XValidation:message="serviceAccountName is immutable",rule="has(oldSelf.serviceAccountName) == has(self.serviceAccountName)"
2457
type BucketAccessSpec struct {
25-
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
26-
// Important: Run "make" to regenerate code after modifying this file
27-
// The following markers will use OpenAPI v3 schema to validate the value
28-
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html
58+
// bucketClaims is a list of BucketClaims the provisioned access must have permissions for,
59+
// along with per-BucketClaim access parameters and system output definitions.
60+
// At least one BucketClaim must be referenced.
61+
// Multiple references to the same BucketClaim are not permitted.
62+
// +required
63+
// +listType=map
64+
// +listMapKey=bucketClaimName
65+
// +kubebuilder:validation:MinItems=1
66+
// +kubebuilder:validation:XValidation:message="bucketClaims list is immutable",rule="self == oldSelf"
67+
BucketClaims []BucketClaimAccess `json:"bucketClaims"`
2968

30-
// foo is an example field of BucketAccess. Edit bucketaccess_types.go to remove/update
69+
// bucketAccessClassName selects the BucketAccessClass for provisioning the access.
70+
// +required
71+
// +kubebuilder:validation:MinLength=1
72+
// +kubebuilder:validation:MaxLength=253
73+
// +kubebuilder:validation:XValidation:message="bucketAccessClassName is immutable",rule="self == oldSelf"
74+
BucketAccessClassName string `json:"bucketAccessClassName"`
75+
76+
// protocol is the object storage protocol that the provisioned access must use.
77+
// +required
78+
// +kubebuilder:validation:XValidation:message="protocol is immutable",rule="self == oldSelf"
79+
Protocol ObjectProtocol `json:"protocol"`
80+
81+
// serviceAccountName is the name of the Kubernetes ServiceAccount that user application Pods
82+
// intend to use for access to referenced BucketClaims.
83+
// This has different behavior based on the BucketAccessClass's defined AuthenticationType:
84+
// - Key: This field is ignored.
85+
// - ServiceAccount: This field is required. The driver should configure the system so that Pods
86+
// using the ServiceAccount authenticate to the object storage backend automatically.
3187
// +optional
32-
Foo *string `json:"foo,omitempty"`
88+
// +kubebuilder:validation:MaxLength=253
89+
// +kubebuilder:validation:XValidation:message="serviceAccountName is immutable",rule="self == oldSelf"
90+
ServiceAccountName string `json:"serviceAccountName,omitempty"`
3391
}
3492

3593
// BucketAccessStatus defines the observed state of BucketAccess.
94+
// +kubebuilder:validation:XValidation:message="accountID is immutable once set",rule="!has(oldSelf.accountID) || has(self.accountID)"
95+
// +kubebuilder:validation:XValidation:message="accessedBuckets is immutable once set",rule="!has(oldSelf.accessedBuckets) || has(self.accessedBuckets)"
96+
// +kubebuilder:validation:XValidation:message="driverName is immutable once set",rule="!has(oldSelf.driverName) || has(self.driverName)"
97+
// +kubebuilder:validation:XValidation:message="authenticationType is immutable once set",rule="!has(oldSelf.authenticationType) || has(self.authenticationType)"
98+
// +kubebuilder:validation:XValidation:message="parameters is immutable once set",rule="!has(oldSelf.parameters) || has(self.parameters)"
3699
type BucketAccessStatus struct {
37-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
38-
// Important: Run "make" to regenerate code after modifying this file
39-
40-
// For Kubernetes API conventions, see:
41-
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
42-
43-
// conditions represent the current state of the BucketAccess resource.
44-
// Each condition has a unique type and reflects the status of a specific aspect of the resource.
45-
//
46-
// Standard condition types include:
47-
// - "Available": the resource is fully functional
48-
// - "Progressing": the resource is being created or updated
49-
// - "Degraded": the resource failed to reach or maintain its desired state
50-
//
51-
// The status of each condition is one of True, False, or Unknown.
100+
// readyToUse indicates that the BucketAccess is ready for consumption by workloads.
101+
ReadyToUse bool `json:"readyToUse"`
102+
103+
// accountID is the unique identifier for the backend access known to the driver.
104+
// This field is populated by the COSI Sidecar once access has been successfully granted.
105+
// +optional
106+
// +kubebuilder:validation:XValidation:message="accountId is immutable once set",rule="oldSelf == '' || self == oldSelf"
107+
AccountID string `json:"accountID"`
108+
109+
// accessedBuckets is a list of Buckets the provisioned access must have permissions for, along
110+
// with per-Bucket access options. This field is populated by the COSI Controller based on the
111+
// referenced BucketClaims in the spec.
112+
// +optional
52113
// +listType=map
53-
// +listMapKey=type
114+
// +listMapKey=bucketName
115+
// +kubebuilder:validation:XValidation:message="accessedBuckets is immutable once set",rule="oldSelf.size() == 0 || self == oldSelf"
116+
AccessedBuckets []AccessedBucket `json:"accessedBuckets"`
117+
118+
// driverName holds a copy of the BucketAccessClass driver name from the time of BucketAccess
119+
// provisioning. This field is populated by the COSI Controller.
54120
// +optional
55-
Conditions []metav1.Condition `json:"conditions,omitempty"`
121+
// +kubebuilder:validation:XValidation:message="driverName is immutable once set",rule="oldSelf == '' || self == oldSelf"
122+
DriverName string `json:"driverName"`
123+
124+
// authenticationType holds a copy of the BucketAccessClass authentication type from the time of
125+
// BucketAccess provisioning. This field is populated by the COSI Controller.
126+
// +optional
127+
// +kubebuilder:validation:XValidation:message="authenticationType is immutable once set",rule="oldSelf == '' || self == oldSelf"
128+
AuthenticationType BucketAccessAuthenticationType `json:"authenticationType"`
129+
130+
// parameters holds a copy of the BucketAccessClass parameters from the time of BucketAccess
131+
// provisioning. This field is populated by the COSI Controller.
132+
// +optional
133+
// +kubebuilder:validation:XValidation:message="accessedBuckets is immutable once set",rule="oldSelf.size() == 0 || self == oldSelf"
134+
Parameters map[string]string `json:"parameters,omitempty"`
135+
136+
// error holds the most recent error message, with a timestamp.
137+
// This is cleared when provisioning is successful.
138+
// +optional
139+
Error *TimestampedError `json:"error,omitempty"`
140+
}
141+
142+
// BucketClaimAccess selects a BucketClaim for access, defines access parameters for the
143+
// corresponding bucket, and specifies where user-consumable bucket information and access
144+
// credentials for the accessed bucket will be stored.
145+
type BucketClaimAccess struct {
146+
// bucketClaimName is the name of a BucketClaim the access should have permissions for.
147+
// The BucketClaim must be in the same Namespace as the BucketAccess.
148+
// +required
149+
// +kubebuilder:validation:MinLength=1
150+
// +kubebuilder:validation:MaxLength=253
151+
BucketClaimName string `json:"bucketClaimName"`
152+
153+
// accessMode is the Read/Write access mode that the access should have for the bucket.
154+
// Possible values: ReadWrite, ReadOnly, WriteOnly.
155+
// +required
156+
AccessMode BucketAccessMode `json:"accessMode"`
157+
158+
// accessSecretName is the name of a Kubernetes Secret that COSI should create and populate with
159+
// bucket info and access credentials for the bucket.
160+
// The Secret is created in the same Namespace as the BucketAccess and is deleted when the
161+
// BucketAccess is deleted and deprovisioned.
162+
// The Secret name must be unique across all bucketClaimRefs for all BucketAccesses in the same
163+
// Namespace.
164+
// +required
165+
// +kubebuilder:validation:MinLength=1
166+
// +kubebuilder:validation:MaxLength=253
167+
AccessSecretName string `json:"accessSecretName"`
168+
}
169+
170+
// AccessedBucket identifies a Bucket and corresponding access parameters.
171+
type AccessedBucket struct {
172+
// bucketName is the name of a Bucket the access should have permissions for.
173+
// +required
174+
// +kubebuilder:validation:MinLength=1
175+
// +kubebuilder:validation:MaxLength=253
176+
BucketName string `json:"bucketName"`
177+
178+
// accessMode is the Read/Write access mode that the access should have for the bucket.
179+
// +required
180+
AccessMode BucketAccessMode `json:"accessMode"`
56181
}
57182

58183
// +kubebuilder:object:root=true

client/apis/objectstorage/v1alpha2/bucketaccessclass_types.go

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,46 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
)
2222

23-
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
24-
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
25-
2623
// BucketAccessClassSpec defines the desired state of BucketAccessClass
2724
type BucketAccessClassSpec struct {
28-
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
29-
// Important: Run "make" to regenerate code after modifying this file
30-
// The following markers will use OpenAPI v3 schema to validate the value
31-
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html
25+
// driverName is the name of the driver that fulfills requests for this BucketAccessClass.
26+
// +required
27+
// +kubebuilder:validation:MinLength=1
28+
DriverName string `json:"driverName"`
29+
30+
// authenticationType specifies which authentication mechanism is used bucket access.
31+
// Possible values:
32+
// - Key: The driver should generate a protocol-appropriate access key that clients can use to
33+
// authenticate to the backend object store.
34+
// - ServiceAccount: The driver should configure the system such that Pods using the given
35+
// ServiceAccount authenticate to the backend object store automatically.
36+
// +required
37+
// +kubebuilder:validation:Enum:=Key;ServiceAccount
38+
AuthenticationType BucketAccessAuthenticationType `json:"authenticationType"`
39+
40+
// parameters is an opaque map of driver-specific configuration items passed to the driver that
41+
// fulfills requests for this BucketAccessClass.
42+
// +optional
43+
Parameters map[string]string `json:"parameters,omitempty"`
3244

33-
// foo is an example field of BucketAccessClass. Edit bucketaccessclass_types.go to remove/update
45+
// featureOptions can be used to adjust various COSI access provisioning behaviors.
3446
// +optional
35-
Foo *string `json:"foo,omitempty"`
47+
FeatureOptions BucketAccessFeatureOptions `json:"featureOptions,omitempty"`
3648
}
3749

38-
// BucketAccessClassStatus defines the observed state of BucketAccessClass.
39-
type BucketAccessClassStatus struct {
40-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
41-
// Important: Run "make" to regenerate code after modifying this file
42-
43-
// For Kubernetes API conventions, see:
44-
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
45-
46-
// conditions represent the current state of the BucketAccessClass resource.
47-
// Each condition has a unique type and reflects the status of a specific aspect of the resource.
48-
//
49-
// Standard condition types include:
50-
// - "Available": the resource is fully functional
51-
// - "Progressing": the resource is being created or updated
52-
// - "Degraded": the resource failed to reach or maintain its desired state
53-
//
54-
// The status of each condition is one of True, False, or Unknown.
55-
// +listType=map
56-
// +listMapKey=type
50+
// BucketAccessFeatureOptions defines various COSI access provisioning behaviors.
51+
type BucketAccessFeatureOptions struct {
52+
// disallowedBucketAccessModes is a list of disallowed Read/Write access modes. A BucketAccess
53+
// using this class will not be allowed to request access to a BucketClaim with any access mode
54+
// listed here.
5755
// +optional
58-
Conditions []metav1.Condition `json:"conditions,omitempty"`
56+
// +listType=set
57+
DisallowedBucketAccessModes []BucketAccessMode `json:"disallowedBucketAccessModes,omitempty"`
58+
59+
// disallowMultiBucketAccess disables the ability for a BucketAccess to reference multiple
60+
// BucketClaims when set.
61+
// +optional
62+
DisallowMultiBucketAccess bool `json:"disallowMultiBucketAccess,omitempty"`
5963
}
6064

6165
// +kubebuilder:object:root=true
@@ -73,11 +77,8 @@ type BucketAccessClass struct {
7377

7478
// spec defines the desired state of BucketAccessClass
7579
// +required
80+
// +kubebuilder:validation:XValidation:message="BucketAccessClass spec is immutable",rule="self == oldSelf"
7681
Spec BucketAccessClassSpec `json:"spec"`
77-
78-
// status defines the observed state of BucketAccessClass
79-
// +optional
80-
Status BucketAccessClassStatus `json:"status,omitempty,omitzero"`
8182
}
8283

8384
// +kubebuilder:object:root=true

0 commit comments

Comments
 (0)