Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: ⚠️ updates from api audit #1404

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
60 changes: 40 additions & 20 deletions api/v1alpha1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
var ClusterExtensionKind = "ClusterExtension"

type (
UpgradeConstraintPolicy string
CRDUpgradeSafetyPolicy string
UpgradeConstraintPolicy string
CRDUpgradeSafetyEnforcement string
)

const (
Expand Down Expand Up @@ -58,6 +58,7 @@ type ClusterExtensionSpec struct {
// catalog:
// packageName: example-package
//
// +kubebuilder:validation:Required
Source SourceConfig `json:"source"`

// install is a required field used to configure the installation options
Expand All @@ -69,6 +70,7 @@ type ClusterExtensionSpec struct {
// namespace: example-namespace
// serviceAccount:
// name: example-sa
// +kubebuilder:validation:Required
Copy link
Member

Choose a reason for hiding this comment

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

Add an extra new line above the Required comment marker?

Install ClusterExtensionInstallConfig `json:"install"`
}

Expand All @@ -80,14 +82,16 @@ const SourceTypeCatalog = "Catalog"
type SourceConfig struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

// sourceType is a required reference to the type of install source.
//
// Allowed values are ["Catalog"]
// Allowed values are "Catalog"
//
// When this field is set to "Catalog", information for determining the appropriate
// bundle of content to install will be fetched from ClusterCatalog resources existing
// on the cluster. When using the Catalog sourceType, the catalog field must also be set.
// When this field is set to "Catalog", information for determining the
// appropriate bundle of content to install will be fetched from
// ClusterCatalog resources existing on the cluster.
// When using the Catalog sourceType, the catalog field must also be set.
//
// +unionDiscriminator
// +kubebuilder:validation:Enum:="Catalog"
// +kubebuilder:validation:Required
SourceType string `json:"sourceType"`

// catalog is used to configure how information is sourced from a catalog. This field must be defined when sourceType is set to "Catalog",
Copy link
Contributor

Choose a reason for hiding this comment

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

Should probably update this to reflect any updates we make to the CEL validation following my comment on this structs validations

Expand Down Expand Up @@ -130,6 +134,7 @@ type ClusterExtensionInstallConfig struct {
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use CEL here instead of pattern validation?

//+kubebuilder:validation:MaxLength:=63
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="namespace is immutable"
//+kubebuilder:validation:Required
Namespace string `json:"namespace"`
Copy link
Contributor

Choose a reason for hiding this comment

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

There were a few comments from Joel related to the GoDoc for this field that I don't see reflected here. Did we decide against accepting those suggestions or making adjustments to clarify some of the questions asked?

Ref:


// serviceAccount is a required reference to a ServiceAccount that exists
Expand All @@ -140,6 +145,7 @@ type ClusterExtensionInstallConfig struct {
// the ServiceAccount provided via this field should be configured with the
// appropriate permissions to perform the necessary operations on all the
// resources that are included in the bundle of content being applied.
//+kubebuilder:validation:Required
ServiceAccount ServiceAccountReference `json:"serviceAccount"`

// preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to be more descriptive about what the default preflight checks are?

Context: https://github.com/openshift/api/pull/2067/files#r1812435988

Expand Down Expand Up @@ -181,6 +187,7 @@ type CatalogSource struct {
//+kubebuilder:validation:MaxLength:=253
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this also be CEL validation?

//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="packageName is immutable"
//+kubebuilder:validation:Required
PackageName string `json:"packageName"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar question regarding Joel having comments on the GoDoc for this field - are we intentionally not changing the GoDoc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is has one, and I thought that the crux of confusion lay in the pattern getting barfed back to users on errors.
I'll look back over the comments to see if I misunderstood something.


// version is an optional semver constraint (a specific version or range of versions). When unspecified, the latest version available will be installed.
Expand Down Expand Up @@ -258,14 +265,14 @@ type CatalogSource struct {
// For more information on semver, please see https://semver.org/
//
//+kubebuilder:validation:MaxLength:=64
//+kubebuilder:validation:Pattern=`^(\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|[x|X|\*])(\.(0|[1-9]\d*|x|X|\*]))?(\.(0|[1-9]\d*|x|X|\*))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)((?:\s+|,\s*|\s*\|\|\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|x|X|\*])(\.(0|[1-9]\d*|x|X|\*))?(\.(0|[1-9]\d*|x|X|\*]))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)*$`
//+kubebuilder:validation:XValidation:rule="self.matches(\"^(\\\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\\\^)\\\\s*(v?(0|[1-9]\\\\d*|[x|X|\\\\*])(\\\\.(0|[1-9]\\\\d*|x|X|\\\\*]))?(\\\\.(0|[1-9]\\\\d*|x|X|\\\\*))?(-([0-9A-Za-z\\\\-]+(\\\\.[0-9A-Za-z\\\\-]+)*))?(\\\\+([0-9A-Za-z\\\\-]+(\\\\.[0-9A-Za-z\\\\-]+)*))?)\\\\s*)((?:\\\\s+|,\\\\s*|\\\\s*\\\\|\\\\|\\\\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\\\\^)\\\\s*(v?(0|[1-9]\\\\d*|x|X|\\\\*])(\\\\.(0|[1-9]\\\\d*|x|X|\\\\*))?(\\\\.(0|[1-9]\\\\d*|x|X|\\\\*]))?(-([0-9A-Za-z\\\\-]+(\\\\.[0-9A-Za-z\\\\-]+)*))?(\\\\+([0-9A-Za-z\\\\-]+(\\\\.[0-9A-Za-z\\\\-]+)*))?)\\\\s*)*$\")",message="invalid version expression in the catalog source"
//+optional
Version string `json:"version,omitempty"`

// channels is an optional reference to a set of channels belonging to
Copy link
Contributor

Choose a reason for hiding this comment

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

There is an open-question on if we should set a max number of items in the list of channels: https://github.com/openshift/api/pull/2067/files#r1812455558

I think it is reasonable to have a max number of entries in the slice and Joe's suggested 256 seems fine to me as well.

// the package specified in the packageName field.
//
// A "channel" is a package author defined stream of updates for an extension.
// A "channel" is a package-author-defined stream of updates for an extension.
//
// When specified, it is used to constrain the set of installable bundles and
// the automated upgrade path. This constraint is an AND operation with the
Expand Down Expand Up @@ -322,7 +329,7 @@ type CatalogSource struct {
// the upgrade path(s) defined in the catalog are enforced for the package
// referenced in the packageName field.
//
// Allowed values are: ["CatalogProvided", "SelfCertified"].
// Allowed values are: "CatalogProvided" or "SelfCertified".
//
// When this field is set to "CatalogProvided", automatic upgrades will only occur
// when upgrade constraints specified by the package author are met.
Expand Down Expand Up @@ -373,6 +380,7 @@ type ServiceAccountReference struct {
//+kubebuilder:validation:MaxLength:=253
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable"
//+kubebuilder:validation:Required
Name string `json:"name"`
}

Expand All @@ -386,28 +394,30 @@ type PreflightConfig struct {
// consequences of upgrading a CRD, such as data loss.
//
// This field is required if the spec.install.preflight field is specified.
//+kubebuilder:validation:Required
CRDUpgradeSafety *CRDUpgradeSafetyPreflightConfig `json:"crdUpgradeSafety"`
}

// CRDUpgradeSafetyPreflightConfig is the configuration for CRD upgrade safety preflight check.
type CRDUpgradeSafetyPreflightConfig struct {
// policy is used to configure the state of the CRD Upgrade Safety pre-flight check.
// enforcement is used to configure the state of the CRD Upgrade Safety pre-flight check.
//
// This field is required when the spec.install.preflight.crdUpgradeSafety field is
// specified.
Comment on lines 405 to 406
Copy link
Member

Choose a reason for hiding this comment

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

I think I saw a comment from Joel about not needing the conditional statement here. We can just say "enforcement is required" unconditionally (it is implicit that it being required is conditional on the parent struct being specified).

//
// Allowed values are ["Enabled", "Disabled"]. The default value is "Enabled".
// Allowed values are "None" or "Strict". The default value is "Strict".
//
// When set to "Disabled", the CRD Upgrade Safety pre-flight check will be skipped
// When set to "None", the CRD Upgrade Safety pre-flight check will be skipped
// when performing an upgrade operation. This should be used with caution as
// unintended consequences such as data loss can occur.
//
// When set to "Enabled", the CRD Upgrade Safety pre-flight check will be run when
// When set to "Strict", the CRD Upgrade Safety pre-flight check will be run when
// performing an upgrade operation.
//
//+kubebuilder:validation:Enum:="Enabled";"Disabled"
//+kubebuilder:default:=Enabled
Policy CRDUpgradeSafetyPolicy `json:"policy"`
//+kubebuilder:validation:Enum:="None";"Strict"
//+kubebuilder:default:=Strict
//+kubebuilder:validation:Required
Enforcement CRDUpgradeSafetyEnforcement `json:"enforcement"`
}

const (
Expand All @@ -428,8 +438,10 @@ const (
ReasonBlocked = "Blocked"
ReasonRetrying = "Retrying"

CRDUpgradeSafetyPolicyEnabled CRDUpgradeSafetyPolicy = "Enabled"
CRDUpgradeSafetyPolicyDisabled CRDUpgradeSafetyPolicy = "Disabled"
// None will not perform CRD upgrade safety checks.
CRDUpgradeSafetyEnforcementNone CRDUpgradeSafetyEnforcement = "None"
// Strict will enforce the CRD upgrade safety check and block the upgrade if the CRD would not pass the check.
CRDUpgradeSafetyEnforcementStrict CRDUpgradeSafetyEnforcement = "Strict"
)

func init() {
Expand All @@ -455,9 +467,11 @@ func init() {
type BundleMetadata struct {
// name is a required field and is a reference
// to the name of a bundle
//+kubebuilder:validation:Required
Name string `json:"name"`
// version is a required field and is a reference
// to the version that this bundle represents
//+kubebuilder:validation:Required
Version string `json:"version"`
}

Expand Down Expand Up @@ -496,6 +510,7 @@ type ClusterExtensionStatus struct {
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

Expand All @@ -504,6 +519,7 @@ type ClusterExtensionInstallStatus struct {
//
// A "bundle" is a versioned set of content that represents the resources that
// need to be applied to a cluster to install a package.
//+kubebuilder:validation:Required
Bundle BundleMetadata `json:"bundle"`
}

Expand All @@ -516,7 +532,9 @@ type ClusterExtension struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ClusterExtensionSpec `json:"spec,omitempty"`
//+optional
Spec ClusterExtensionSpec `json:"spec,omitempty"`
//+optional
Status ClusterExtensionStatus `json:"status,omitempty"`
}

Expand All @@ -525,8 +543,10 @@ type ClusterExtension struct {
// ClusterExtensionList contains a list of ClusterExtension
type ClusterExtensionList struct {
metav1.TypeMeta `json:",inline"`
//+optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterExtension `json:"items"`
//+kubebuilder:validation:Required
Items []ClusterExtension `json:"items"`
}

func init() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,28 +102,28 @@ spec:

This field is required if the spec.install.preflight field is specified.
properties:
policy:
default: Enabled
enforcement:
default: Strict
description: |-
policy is used to configure the state of the CRD Upgrade Safety pre-flight check.
enforcement is used to configure the state of the CRD Upgrade Safety pre-flight check.

This field is required when the spec.install.preflight.crdUpgradeSafety field is
specified.

Allowed values are ["Enabled", "Disabled"]. The default value is "Enabled".
Allowed values are "None" or "Strict". The default value is "Strict".

When set to "Disabled", the CRD Upgrade Safety pre-flight check will be skipped
When set to "None", the CRD Upgrade Safety pre-flight check will be skipped
when performing an upgrade operation. This should be used with caution as
unintended consequences such as data loss can occur.

When set to "Enabled", the CRD Upgrade Safety pre-flight check will be run when
When set to "Strict", the CRD Upgrade Safety pre-flight check will be run when
performing an upgrade operation.
enum:
- Enabled
- Disabled
- None
- Strict
type: string
required:
- policy
- enforcement
type: object
required:
- crdUpgradeSafety
Expand Down Expand Up @@ -208,7 +208,7 @@ spec:
channels is an optional reference to a set of channels belonging to
the package specified in the packageName field.

A "channel" is a package author defined stream of updates for an extension.
A "channel" is a package-author-defined stream of updates for an extension.

When specified, it is used to constrain the set of installable bundles and
the automated upgrade path. This constraint is an AND operation with the
Expand Down Expand Up @@ -340,7 +340,7 @@ spec:
the upgrade path(s) defined in the catalog are enforced for the package
referenced in the packageName field.

Allowed values are: ["CatalogProvided", "SelfCertified"].
Allowed values are: "CatalogProvided" or "SelfCertified".

When this field is set to "CatalogProvided", automatic upgrades will only occur
when upgrade constraints specified by the package author are met.
Expand Down Expand Up @@ -433,20 +433,23 @@ spec:

For more information on semver, please see https://semver.org/
maxLength: 64
pattern: ^(\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|[x|X|\*])(\.(0|[1-9]\d*|x|X|\*]))?(\.(0|[1-9]\d*|x|X|\*))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)((?:\s+|,\s*|\s*\|\|\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|x|X|\*])(\.(0|[1-9]\d*|x|X|\*))?(\.(0|[1-9]\d*|x|X|\*]))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)*$
type: string
x-kubernetes-validations:
- message: invalid version expression in the catalog source
rule: self.matches("^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|[x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*]))?(\\.(0|[1-9]\\d*|x|X|\\*))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)((?:\\s+|,\\s*|\\s*\\|\\|\\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*))?(\\.(0|[1-9]\\d*|x|X|\\*]))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)*$")
required:
- packageName
type: object
sourceType:
description: |-
sourceType is a required reference to the type of install source.

Allowed values are ["Catalog"]
Allowed values are "Catalog"

When this field is set to "Catalog", information for determining the appropriate
bundle of content to install will be fetched from ClusterCatalog resources existing
on the cluster. When using the Catalog sourceType, the catalog field must also be set.
When this field is set to "Catalog", information for determining the
appropriate bundle of content to install will be fetched from
ClusterCatalog resources existing on the cluster.
When using the Catalog sourceType, the catalog field must also be set.
enum:
- Catalog
type: string
Expand Down
Loading
Loading