Skip to content
Open
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
1 change: 1 addition & 0 deletions client/.kubeapilint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ linters:
- statussubresource
- optionalfields # instead of nonpointerstructs
- requiredfields # instead of nonpointerstructs
- maxlength
disable:
- nonpointerstructs # not intended for CRDs
- statusoptional
Expand Down
53 changes: 46 additions & 7 deletions client/apis/objectstorage/v1alpha2/bucket_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ const (
// +kubebuilder:validation:XValidation:message="existingBucketID cannot be added or removed after creation",rule="has(oldSelf.existingBucketID) == has(self.existingBucketID)"
type BucketSpec struct {
// driverName is the name of the driver that fulfills requests for this Bucket.
// See driver documentation to determine the correct value to set.
// Must be 63 characters or less, beginning and ending with an alphanumeric character
// ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([a-zA-Z0-9\-\.]{0,61}[a-zA-Z0-9])?$`
// +kubebuilder:validation:XValidation:message="driverName is immutable",rule="self == oldSelf"
DriverName string `json:"driverName,omitempty"`

Expand All @@ -57,29 +62,41 @@ type BucketSpec struct {

// parameters is an opaque map of driver-specific configuration items passed to the driver that
// fulfills requests for this Bucket.
// See driver documentation to determine supported parameters and their effects.
// A maximum of 512 parameters are allowed.
// +optional
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=512
// +kubebuilder:validation:XValidation:message="parameters map is immutable",rule="self == oldSelf"
Parameters map[string]string `json:"parameters,omitempty"`

// protocols lists object store protocols that the provisioned Bucket must support.
// If specified, COSI will verify that each item is advertised as supported by the driver.
// See driver documentation to determine supported protocols.
// Possible values: 'S3', 'Azure', 'GCS'.
// +optional
// +listType=set
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=3
// +kubebuilder:validation:XValidation:message="protocols list is immutable",rule="self == oldSelf"
Protocols []ObjectProtocol `json:"protocols,omitempty"`

// bucketClaim references the BucketClaim that resulted in the creation of this Bucket.
// bucketClaimRef references the BucketClaim that resulted in the creation of this Bucket.
// For statically-provisioned buckets, set the namespace and name of the BucketClaim that is
// allowed to bind to this Bucket.
// allowed to bind to this Bucket; UID may be left unset if desired and will be updated by COSI.
// +required
BucketClaimRef BucketClaimReference `json:"bucketClaim,omitzero"`
BucketClaimRef BucketClaimReference `json:"bucketClaimRef,omitzero"`

// existingBucketID is the unique identifier for an existing backend bucket known to the driver.
// Use driver documentation to determine how to set this value.
// This field is used only for Bucket static provisioning.
// Use driver documentation to determine the correct value to set.
// This field is used only for static Bucket provisioning.
// This field will be empty when the Bucket is dynamically provisioned from a BucketClaim.
// Must be at most 2048 characters and consist only of alphanumeric characters ([a-z0-9A-Z]),
// dashes (-), dots (.), underscores (_), and forward slash (/).
// +optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=2048
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9/._-]+$`
// +kubebuilder:validation:XValidation:message="existingBucketID is immutable",rule="self == oldSelf"
ExistingBucketID string `json:"existingBucketID,omitempty"`
}
Expand All @@ -89,21 +106,34 @@ type BucketSpec struct {
// +kubebuilder:validation:XValidation:message="uid cannot be removed once set",rule="!has(oldSelf.uid) || has(self.uid)"
type BucketClaimReference struct {
// name is the name of the BucketClaim being referenced.
// Must be a valid Kubernetes resource name: at most 253 characters, consisting only of
// lower-case alphanumeric characters, hyphens, and periods, starting and ending with an
// alphanumeric character.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:XValidation:message="name must be a valid resource name",rule="!format.dns1123Subdomain().validate(self).hasValue()"
// +kubebuilder:validation:XValidation:message="name is immutable",rule="self == oldSelf"
Name string `json:"name,omitempty"`

// namespace is the namespace of the BucketClaim being referenced.
// Must be a valid Kubernetes Namespace name: at most 63 characters, consisting only of
// lower-case alphanumeric characters and hyphens, starting and ending with alphanumerics.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:XValidation:message="namespace must be a valid namespace name",rule="!format.dns1123Label().validate(self).hasValue()"
// +kubebuilder:validation:XValidation:message="namespace is immutable",rule="self == oldSelf"
Namespace string `json:"namespace,omitempty"`

// uid is the UID of the BucketClaim being referenced.
// Must be a valid Kubernetes UID: RFC 4122 form with lowercase hexadecimal characters
// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
// +optional
// +kubebuilder:validation:MinLength=36
// +kubebuilder:validation:MaxLength=36
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern=`^[0-9a-f]{8}-([0-9a-f]{4}\-){3}[0-9a-f]{12}$`
// +kubebuilder:validation:XValidation:message="uid is immutable once set",rule="oldSelf == '' || self == oldSelf"
UID types.UID `json:"uid,omitempty"`
}
Expand All @@ -117,22 +147,31 @@ type BucketStatus struct {
ReadyToUse *bool `json:"readyToUse,omitempty"`

// bucketID is the unique identifier for the backend bucket known to the driver.
// Must be at most 2048 characters and consist only of alphanumeric characters ([a-z0-9A-Z]),
// dashes (-), dots (.), underscores (_), and forward slash (/).
// +optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=2048
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9/._-]+$`
// +kubebuilder:validation:XValidation:message="boundBucketName is immutable once set",rule="self == oldSelf"
BucketID string `json:"bucketID,omitempty"`

// protocols is the set of protocols the Bucket reports to support. BucketAccesses can request
// access to this BucketClaim using any of the protocols reported here.
// access to this Bucket using any of the protocols reported here.
// Possible values: 'S3', 'Azure', 'GCS'.
// +optional
// +listType=set
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=3
Protocols []ObjectProtocol `json:"protocols,omitempty"`

// bucketInfo contains info about the bucket reported by the driver, rendered in the same
// COSI_<PROTOCOL>_<KEY> format used for the BucketAccess Secret.
// e.g., COSI_S3_ENDPOINT, COSI_AZURE_STORAGE_ACCOUNT.
// This should not contain any sensitive information.
// +optional
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=128
BucketInfo map[string]string `json:"bucketInfo,omitempty"`

// error holds the most recent error message, with a timestamp.
Expand Down
49 changes: 44 additions & 5 deletions client/apis/objectstorage/v1alpha2/bucketaccess_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ type BucketAccessSpec struct {
// bucketClaims is a list of BucketClaims the provisioned access must have permissions for,
// along with per-BucketClaim access parameters and system output definitions.
// At least one BucketClaim must be referenced.
// A maximum of 128 BucketClaims may be referenced.
// Multiple references to the same BucketClaim are not permitted.
// +required
// +listType=map
// +listMapKey=bucketClaimName
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=128
// +kubebuilder:validation:XValidation:message="bucketClaims list is immutable",rule="self == oldSelf"
BucketClaims []BucketClaimAccess `json:"bucketClaims,omitempty"`

Expand All @@ -74,16 +76,18 @@ type BucketAccessSpec struct {
BucketAccessClassName string `json:"bucketAccessClassName,omitempty"`

// protocol is the object storage protocol that the provisioned access must use.
// Access can only be granted for BucketClaims that support the requested protocol.
// Each BucketClaim status reports which protocols are supported for the BucketClaim's bucket.
// Possible values: 'S3', 'Azure', 'GCS'.
// +required
// +kubebuilder:validation:XValidation:message="protocol is immutable",rule="self == oldSelf"
Protocol ObjectProtocol `json:"protocol,omitempty"`

// serviceAccountName is the name of the Kubernetes ServiceAccount that user application Pods
// intend to use for access to referenced BucketClaims.
// This has different behavior based on the BucketAccessClass's defined AuthenticationType:
// - Key: This field is ignored.
// - ServiceAccount: This field is required. The driver should configure the system so that Pods
// using the ServiceAccount authenticate to the object storage backend automatically.
// Required when the BucketAccessClass is configured to use ServiceAccount authentication type.
// Ignored for all other authentication types.
// It is recommended to specify this for all BucketAccesses to improve portability.
// +optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Expand All @@ -104,8 +108,12 @@ type BucketAccessStatus struct {

// accountID is the unique identifier for the backend access known to the driver.
// This field is populated by the COSI Sidecar once access has been successfully granted.
// Must be at most 2048 characters and consist only of alphanumeric characters ([a-z0-9A-Z]),
// dashes (-), dots (.), underscores (_), and forward slash (/).
// +optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=2048
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9/._-]+$`
// +kubebuilder:validation:XValidation:message="accountId is immutable once set",rule="self == oldSelf"
AccountID string `json:"accountID,omitempty"`

Expand All @@ -116,25 +124,35 @@ type BucketAccessStatus struct {
// +listType=map
// +listMapKey=bucketName
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=128
// +kubebuilder:validation:XValidation:message="accessedBuckets is immutable once set",rule="self == oldSelf"
AccessedBuckets []AccessedBucket `json:"accessedBuckets,omitempty"`

// driverName holds a copy of the BucketAccessClass driver name from the time of BucketAccess
// provisioning. This field is populated by the COSI Controller.
// Must be 63 characters or less, beginning and ending with an alphanumeric character
// ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between.
// +optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([a-zA-Z0-9\-\.]{0,61}[a-zA-Z0-9])?$`
// +kubebuilder:validation:XValidation:message="driverName is immutable once set",rule="self == oldSelf"
DriverName string `json:"driverName,omitempty"`

// authenticationType holds a copy of the BucketAccessClass authentication type from the time of
// BucketAccess provisioning. This field is populated by the COSI Controller.
// Possible values:
// - Key: clients may use a protocol-appropriate access key to authenticate to the backend object store.
// - ServiceAccount: Pods using the ServiceAccount given in spec.serviceAccountName may authenticate to the backend object store automatically.
// +optional
// +kubebuilder:validation:XValidation:message="authenticationType is immutable once set",rule="self == oldSelf"
AuthenticationType BucketAccessAuthenticationType `json:"authenticationType,omitempty"`

// parameters holds a copy of the BucketAccessClass parameters from the time of BucketAccess
// provisioning. This field is populated by the COSI Controller.
// +optional
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=512
// +kubebuilder:validation:XValidation:message="accessedBuckets is immutable once set",rule="self == oldSelf"
Parameters map[string]string `json:"parameters,omitempty"`

Expand All @@ -150,13 +168,22 @@ type BucketAccessStatus struct {
type BucketClaimAccess struct {
// bucketClaimName is the name of a BucketClaim the access should have permissions for.
// The BucketClaim must be in the same Namespace as the BucketAccess.
// Must be a valid Kubernetes resource name: at most 253 characters, consisting only of
// lower-case alphanumeric characters, hyphens, and periods, starting and ending with an
// alphanumeric character.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:XValidation:message="name must be a valid resource name",rule="!format.dns1123Subdomain().validate(self).hasValue()"
BucketClaimName string `json:"bucketClaimName,omitempty"`

// accessMode is the Read/Write access mode that the access should have for the bucket.
// Possible values: ReadWrite, ReadOnly, WriteOnly.
// The provisioned access will have the corresponding permissions to read and/or write objects
// the BucketClaim's bucket.
// The provisioned access can also assume to have corresponding permissions to read and/or write
// object metadata and object metadata (e.g., tags) except when metadata changes would change
// object store behaviors or permissions (e.g., changes to object caching behaviors).
// Possible values: 'ReadWrite', 'ReadOnly', 'WriteOnly'.
// +required
AccessMode BucketAccessMode `json:"accessMode,omitempty"`

Expand All @@ -166,24 +193,36 @@ type BucketClaimAccess struct {
// BucketAccess is deleted and deprovisioned.
// The Secret name must be unique across all bucketClaimRefs for all BucketAccesses in the same
// Namespace.
// Must be a valid Kubernetes resource name: at most 253 characters, consisting only of
// lower-case alphanumeric characters, hyphens, and periods, starting and ending with an
// alphanumeric character.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:XValidation:message="name must be a valid resource name",rule="!format.dns1123Subdomain().validate(self).hasValue()"
AccessSecretName string `json:"accessSecretName,omitempty"`
}

// AccessedBucket identifies a Bucket and correlates it to a BucketClaimAccess from the spec.
type AccessedBucket struct {
// bucketName is the name of a Bucket the access should have permissions for.
// Must be a valid Kubernetes resource name: at most 253 characters, consisting only of
// lower-case alphanumeric characters, hyphens, and periods, starting and ending with an
// alphanumeric character.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:XValidation:message="name must be a valid resource name",rule="!format.dns1123Subdomain().validate(self).hasValue()"
BucketName string `json:"bucketName,omitempty"`

// bucketClaimName must match a BucketClaimAccess's BucketClaimName from the spec.
// Must be a valid Kubernetes resource name: at most 253 characters, consisting only of
// lower-case alphanumeric characters, hyphens, and periods, starting and ending with an
// alphanumeric character.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:XValidation:message="name must be a valid resource name",rule="!format.dns1123Subdomain().validate(self).hasValue()"
BucketClaimName string `json:"bucketClaimName,omitempty"`
}

Expand Down
15 changes: 15 additions & 0 deletions client/apis/objectstorage/v1alpha2/bucketaccessclass_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@ import (
// BucketAccessClassSpec defines the desired state of BucketAccessClass
type BucketAccessClassSpec struct {
// driverName is the name of the driver that fulfills requests for this BucketAccessClass.
// See driver documentation to determine the correct value to set.
// Must be 63 characters or less, beginning and ending with an alphanumeric character
// ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([a-zA-Z0-9\-\.]{0,61}[a-zA-Z0-9])?$`
DriverName string `json:"driverName,omitempty"`

// authenticationType specifies which authentication mechanism is used bucket access.
// See driver documentation to determine which values are supported.
// Possible values:
// - Key: The driver should generate a protocol-appropriate access key that clients can use to
// authenticate to the backend object store.
Expand All @@ -38,7 +44,11 @@ type BucketAccessClassSpec struct {

// parameters is an opaque map of driver-specific configuration items passed to the driver that
// fulfills requests for this BucketAccessClass.
// See driver documentation to determine supported parameters and their effects.
// A maximum of 512 parameters are allowed.
// +optional
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=512
Parameters map[string]string `json:"parameters,omitempty"`

// featureOptions can be used to adjust various COSI access provisioning behaviors.
Expand All @@ -53,8 +63,13 @@ type BucketAccessFeatureOptions struct {
// disallowedBucketAccessModes is a list of disallowed Read/Write access modes. A BucketAccess
// using this class will not be allowed to request access to a BucketClaim with any access mode
// listed here.
// This is particularly useful for administrators to restrict access to a statically-provisioned
// bucket that is managed outside the BucketAccess Namespace or Kubernetes cluster.
// Possible values: 'ReadWrite', 'ReadOnly', 'WriteOnly'.
// +optional
// +listType=set
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=3
DisallowedBucketAccessModes []BucketAccessMode `json:"disallowedBucketAccessModes,omitempty"`

// disallowMultiBucketAccess disables the ability for a BucketAccess to reference multiple
Expand Down
Loading