Skip to content

Commit 66761e6

Browse files
authored
Merge pull request #169 from BlaineEXE/bucketaccess-types
add bucketaccess(class) types, and tidy all CEL rules
2 parents 6fe2318 + 811da8f commit 66761e6

17 files changed

+920
-348
lines changed

client/apis/objectstorage/v1alpha2/bucket_types.go

Lines changed: 14 additions & 6 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
@@ -81,36 +84,41 @@ type BucketSpec struct {
8184
}
8285

8386
// 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)"
8489
type BucketClaimReference struct {
8590
// name is the name of the BucketClaim being referenced.
8691
// +required
8792
// +kubebuilder:validation:MinLength=1
88-
// +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"
8995
Name string `json:"name"`
9096

9197
// namespace is the namespace of the BucketClaim being referenced.
9298
// If empty, the Kubernetes 'default' namespace is assumed.
9399
// namespace is immutable except to update '' to 'default'.
94100
// +optional
95101
// +kubebuilder:validation:MinLength=0
96-
// +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"
97104
Namespace string `json:"namespace"`
98105

99106
// uid is the UID of the BucketClaim being referenced.
100-
// Once set, the UID is immutable.
101107
// +optional
102-
// +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"
103109
UID types.UID `json:"uid"`
104110
}
105111

106112
// 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)"
107115
type BucketStatus struct {
108116
// readyToUse indicates that the bucket is ready for consumption by workloads.
109117
ReadyToUse bool `json:"readyToUse"`
110118

111119
// bucketID is the unique identifier for the backend bucket known to the driver.
112-
// Once set, this is immutable.
113-
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable",rule="oldSelf == '' || self == oldSelf"
120+
// +optional
121+
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable once set",rule="oldSelf == '' || self == oldSelf"
114122
BucketID string `json:"bucketID"`
115123

116124
// protocols is the set of protocols the Bucket reports to support. BucketAccesses can request

client/apis/objectstorage/v1alpha2/bucketaccess_types.go

Lines changed: 135 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ import (
2222

2323
// BucketAccessAuthenticationType specifies what authentication mechanism is used for provisioning
2424
// bucket access.
25+
// +enum
26+
// +kubebuilder:validation:Enum:="";Key;ServiceAccount
2527
type BucketAccessAuthenticationType string
2628

2729
const (
28-
// The driver will generate a protocol-appropriate access key that clients can use to
30+
// The driver should generate a protocol-appropriate access key that clients can use to
2931
// authenticate to the backend object store.
3032
BucketAccessAuthenticationTypeKey = "Key"
3133

@@ -34,39 +36,148 @@ const (
3436
BucketAccessAuthenticationTypeServiceAccount = "ServiceAccount"
3537
)
3638

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+
3755
// BucketAccessSpec defines the desired state of BucketAccess
56+
// +kubebuilder:validation:XValidation:message="serviceAccountName is immutable",rule="has(oldSelf.serviceAccountName) == has(self.serviceAccountName)"
3857
type BucketAccessSpec struct {
39-
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
40-
// Important: Run "make" to regenerate code after modifying this file
41-
// The following markers will use OpenAPI v3 schema to validate the value
42-
// 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"`
4368

44-
// 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.
4587
// +optional
46-
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"`
4791
}
4892

4993
// 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)"
5099
type BucketAccessStatus struct {
51-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
52-
// Important: Run "make" to regenerate code after modifying this file
53-
54-
// For Kubernetes API conventions, see:
55-
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
56-
57-
// conditions represent the current state of the BucketAccess resource.
58-
// Each condition has a unique type and reflects the status of a specific aspect of the resource.
59-
//
60-
// Standard condition types include:
61-
// - "Available": the resource is fully functional
62-
// - "Progressing": the resource is being created or updated
63-
// - "Degraded": the resource failed to reach or maintain its desired state
64-
//
65-
// 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
66113
// +listType=map
67-
// +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.
68120
// +optional
69-
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"`
70181
}
71182

72183
// +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

client/apis/objectstorage/v1alpha2/bucketclaim_types.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ import (
2222

2323
// BucketClaimSpec defines the desired state of BucketClaim
2424
// +kubebuilder:validation:ExactlyOneOf=bucketClassName;existingBucketName
25+
// +kubebuilder:validation:XValidation:message="bucketClassName is immutable",rule="has(oldSelf.bucketClassName) == has(self.bucketClassName)"
26+
// +kubebuilder:validation:XValidation:message="existingBucketName is immutable",rule="has(oldSelf.existingBucketName) == has(self.existingBucketName)"
27+
// +kubebuilder:validation:XValidation:message="protocols list is immutable",rule="has(oldSelf.protocols) == has(self.protocols)"
2528
type BucketClaimSpec struct {
2629
// bucketClassName selects the BucketClass for provisioning the BucketClaim.
2730
// This field is used only for BucketClaim dynamic provisioning.
2831
// If unspecified, existingBucketName must be specified for binding to an existing Bucket.
2932
// +optional
33+
// +kubebuilder:validation:MaxLength=253
3034
// +kubebuilder:validation:XValidation:message="bucketClassName is immutable",rule="self == oldSelf"
3135
BucketClassName string `json:"bucketClassName,omitempty"`
3236

@@ -41,15 +45,19 @@ type BucketClaimSpec struct {
4145
// This field is used only for BucketClaim static provisioning.
4246
// If unspecified, bucketClassName must be specified for dynamically provisioning a new bucket.
4347
// +optional
48+
// +kubebuilder:validation:MaxLength=253
4449
// +kubebuilder:validation:XValidation:message="existingBucketName is immutable",rule="self == oldSelf"
4550
ExistingBucketName string `json:"existingBucketName,omitempty"`
4651
}
4752

4853
// BucketClaimStatus defines the observed state of BucketClaim.
54+
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable once set",rule="!has(oldSelf.boundBucketName) || has(self.boundBucketName)"
55+
// +kubebuilder:validation:XValidation:message="protocols is immutable once set",rule="!has(oldSelf.protocols) || has(self.protocols)"
4956
type BucketClaimStatus struct {
5057
// boundBucketName is the name of the Bucket this BucketClaim is bound to.
51-
// Once set, this is immutable.
52-
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable",rule="oldSelf == '' || self == oldSelf"
58+
// +optional
59+
// +kubebuilder:validation:MaxLength=253
60+
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable once set",rule="oldSelf == '' || self == oldSelf"
5361
BoundBucketName string `json:"boundBucketName"`
5462

5563
// readyToUse indicates that the bucket is ready for consumption by workloads.

client/apis/objectstorage/v1alpha2/protocols.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This file describes the end-user representation of the various object store prot
2323
// TODO: can we write doc generation and linting for the definitions in this file?
2424

2525
// ObjectProtocol represents an object protocol type.
26+
// +kubebuilder:validation:Enum:=S3;Azure;GCS
2627
type ObjectProtocol string
2728

2829
const (

0 commit comments

Comments
 (0)