Skip to content

Commit a934c27

Browse files
committed
make extension and clusterextension api consistent
Signed-off-by: Ankita Thomas <[email protected]>
1 parent 6d73b73 commit a934c27

22 files changed

+775
-394
lines changed

api/v1alpha1/clusterextension_types.go

Lines changed: 22 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,35 @@ package v1alpha1
1818

1919
import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21-
22-
"github.com/operator-framework/operator-controller/internal/conditionsets"
2321
)
2422

25-
type UpgradeConstraintPolicy string
26-
27-
const (
28-
// The extension will only upgrade if the new version satisfies
29-
// the upgrade constraints set by the package author.
30-
UpgradeConstraintPolicyEnforce UpgradeConstraintPolicy = "Enforce"
31-
32-
// Unsafe option which allows an extension to be
33-
// upgraded or downgraded to any available version of the package and
34-
// ignore the upgrade path designed by package authors.
35-
// This assumes that users independently verify the outcome of the changes.
36-
// Use with caution as this can lead to unknown and potentially
37-
// disastrous results such as data loss.
38-
UpgradeConstraintPolicyIgnore UpgradeConstraintPolicy = "Ignore"
39-
)
23+
// +kubebuilder:validation:XValidation:rule="self.sourceType=='package' && has(self.__package__)",message="sourceType must match populated union field"
24+
//
25+
// ClusterExtensionSource defines the source for this ClusterExtension, right now, only a package is supported.
26+
type ClusterExtensionSource struct {
27+
//+kubebuilder:validation:Enum:=package
28+
//+kubebuilder:validation:Required
29+
// SourceType is the discriminator for the source type
30+
SourceType string `json:"sourceType"`
31+
32+
// Package defines a reference for a bundle in a catalog defined by a name and a version and/or channel
33+
Package *SourcePackage `json:"package,omitempty"`
34+
}
4035

4136
// ClusterExtensionSpec defines the desired state of ClusterExtension
4237
type ClusterExtensionSpec struct {
43-
//+kubebuilder:validation:MaxLength:=48
44-
//+kubebuilder:validation:Pattern:=^[a-z0-9]+(-[a-z0-9]+)*$
45-
PackageName string `json:"packageName"`
46-
47-
//+kubebuilder:validation:MaxLength:=64
48-
//+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*)*$`
4938
//+kubebuilder:Optional
50-
// Version is an optional semver constraint on the package version. If not specified, the latest version available of the package will be installed.
51-
// If specified, the specific version of the package will be installed so long as it is available in any of the content sources available.
52-
// Examples: 1.2.3, 1.0.0-alpha, 1.0.0-rc.1
5339
//
54-
// For more information on semver, please see https://semver.org/
55-
Version string `json:"version,omitempty"`
40+
// paused controls the management state of the ClusterExtension. If paused, it will be ignored by the ClusterExtension controller.
41+
Paused bool `json:"paused,omitempty"`
5642

57-
//+kubebuilder:validation:MaxLength:=48
58-
//+kubebuilder:validation:Pattern:=^[a-z0-9]+([\.-][a-z0-9]+)*$
59-
// Channel constraint definition
60-
Channel string `json:"channel,omitempty"`
43+
// source of ClusterExtension to be installed
44+
Source ClusterExtensionSource `json:"source"`
6145

62-
//+kubebuilder:validation:Enum:=Enforce;Ignore
63-
//+kubebuilder:default:=Enforce
6446
//+kubebuilder:Optional
6547
//
66-
// Defines the policy for how to handle upgrade constraints
67-
UpgradeConstraintPolicy UpgradeConstraintPolicy `json:"upgradeConstraintPolicy,omitempty"`
48+
// skipCRDUpgradeSafetyCheck specifies whether the CRD upgrade safety checks should be skipped when attempting to install the ClusterExtension
49+
SkipCRDUpgradeSafetyCheck bool `json:"skipCRDUpgradeSafetyCheck,omitempty"`
6850

6951
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
7052
//+kubebuilder:validation:MaxLength:=63
@@ -75,54 +57,11 @@ type ClusterExtensionSpec struct {
7557
InstallNamespace string `json:"installNamespace"`
7658
}
7759

78-
const (
79-
// TODO(user): add more Types, here and into init()
80-
TypeInstalled = "Installed"
81-
TypeResolved = "Resolved"
82-
// TypeDeprecated is a rollup condition that is present when
83-
// any of the deprecated conditions are present.
84-
TypeDeprecated = "Deprecated"
85-
TypePackageDeprecated = "PackageDeprecated"
86-
TypeChannelDeprecated = "ChannelDeprecated"
87-
TypeBundleDeprecated = "BundleDeprecated"
88-
89-
ReasonBundleLookupFailed = "BundleLookupFailed"
90-
ReasonInstallationFailed = "InstallationFailed"
91-
ReasonInstallationStatusUnknown = "InstallationStatusUnknown"
92-
ReasonInstallationSucceeded = "InstallationSucceeded"
93-
ReasonInvalidSpec = "InvalidSpec"
94-
ReasonResolutionFailed = "ResolutionFailed"
95-
ReasonResolutionUnknown = "ResolutionUnknown"
96-
ReasonSuccess = "Success"
97-
ReasonDeprecated = "Deprecated"
98-
)
99-
100-
func init() {
101-
// TODO(user): add Types from above
102-
conditionsets.ConditionTypes = append(conditionsets.ConditionTypes,
103-
TypeInstalled,
104-
TypeResolved,
105-
TypeDeprecated,
106-
TypePackageDeprecated,
107-
TypeChannelDeprecated,
108-
TypeBundleDeprecated,
109-
)
110-
// TODO(user): add Reasons from above
111-
conditionsets.ConditionReasons = append(conditionsets.ConditionReasons,
112-
ReasonInstallationSucceeded,
113-
ReasonResolutionFailed,
114-
ReasonResolutionUnknown,
115-
ReasonBundleLookupFailed,
116-
ReasonInstallationFailed,
117-
ReasonInstallationStatusUnknown,
118-
ReasonInvalidSpec,
119-
ReasonSuccess,
120-
ReasonDeprecated,
121-
)
122-
}
123-
12460
// ClusterExtensionStatus defines the observed state of ClusterExtension
12561
type ClusterExtensionStatus struct {
62+
// Paused indicates the current reconciliation state of this ClusterExtension
63+
Paused bool `json:"paused"`
64+
12665
// +optional
12766
InstalledBundle *BundleMetadata `json:"installedBundle,omitempty"`
12867
// +optional
@@ -138,6 +77,7 @@ type ClusterExtensionStatus struct {
13877
//+kubebuilder:object:root=true
13978
//+kubebuilder:resource:scope=Cluster
14079
//+kubebuilder:subresource:status
80+
//+kubebuilder:printcolumn:name="Paused",type=string,JSONPath=`.status.paused`,description="The current reconciliation state of this ClusterExtension"
14181

14282
// ClusterExtension is the Schema for the clusterextensions API
14383
type ClusterExtension struct {

api/v1alpha1/common_types.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package v1alpha1
2+
3+
import "github.com/operator-framework/operator-controller/internal/conditionsets"
4+
5+
const (
6+
TypeInstalled = "Installed"
7+
TypeResolved = "Resolved"
8+
// TypeDeprecated is a rollup condition that is present when
9+
// any of the deprecated conditions are present.
10+
TypeDeprecated = "Deprecated"
11+
TypePackageDeprecated = "PackageDeprecated"
12+
TypeChannelDeprecated = "ChannelDeprecated"
13+
TypeBundleDeprecated = "BundleDeprecated"
14+
// TypeProgressing indicates whether operator-controller is
15+
// reconciling, installing, updating or deleting a ClusterExtension or Extension.
16+
TypeProgressing = "Progressing"
17+
// TODO(user): add more Types, here and into init()
18+
19+
ReasonBundleLookupFailed = "BundleLookupFailed"
20+
ReasonInstallationFailed = "InstallationFailed"
21+
ReasonInstallationStatusUnknown = "InstallationStatusUnknown"
22+
ReasonInstallationSucceeded = "InstallationSucceeded"
23+
ReasonInvalidSpec = "InvalidSpec"
24+
ReasonResolutionFailed = "ResolutionFailed"
25+
ReasonResolutionUnknown = "ResolutionUnknown"
26+
ReasonSuccess = "Success"
27+
ReasonDeprecated = "Deprecated"
28+
ReasonProgressing = "Progressing"
29+
ReasonFailedToReachDesiredIntent = "FailedToReachDesiredIntent"
30+
ReasonReachedDesiredIntent = "ReachedDesiredIntent"
31+
)
32+
33+
func init() {
34+
// TODO(user): add Types from above
35+
conditionsets.ConditionTypes = append(conditionsets.ConditionTypes,
36+
TypeInstalled,
37+
TypeResolved,
38+
TypeDeprecated,
39+
TypePackageDeprecated,
40+
TypeChannelDeprecated,
41+
TypeBundleDeprecated,
42+
TypeProgressing,
43+
)
44+
// TODO(user): add Reasons from above
45+
conditionsets.ConditionReasons = append(conditionsets.ConditionReasons,
46+
ReasonInstallationSucceeded,
47+
ReasonResolutionFailed,
48+
ReasonResolutionUnknown,
49+
ReasonBundleLookupFailed,
50+
ReasonInstallationFailed,
51+
ReasonInstallationStatusUnknown,
52+
ReasonInvalidSpec,
53+
ReasonSuccess,
54+
ReasonDeprecated,
55+
ReasonProgressing,
56+
ReasonFailedToReachDesiredIntent,
57+
ReasonReachedDesiredIntent,
58+
)
59+
}
60+
61+
const (
62+
SourceTypePackage = "package"
63+
)
64+
65+
type UpgradeConstraintPolicy string
66+
67+
const (
68+
// The UpgradeConstraintPolicyEnforce policy only allows upgrades if
69+
// the new version satisfies the upgrade constraints set by the package author.
70+
UpgradeConstraintPolicyEnforce UpgradeConstraintPolicy = "Enforce"
71+
72+
// The UpgradeConstraintPolicyIgnore policy allows upgrades or downgrades
73+
// to any available version of the package, ignoring any upgrade paths
74+
// designed by package authors.
75+
// This assumes that users independently verify the outcome of the changes.
76+
// Use with caution as this can lead to unknown and potentially
77+
// disastrous results such as data loss.
78+
UpgradeConstraintPolicyIgnore UpgradeConstraintPolicy = "Ignore"
79+
)
80+
81+
type SourcePackage struct {
82+
//+kubebuilder:validation:MaxLength:=48
83+
//+kubebuilder:validation:Pattern:=^[a-z0-9]+(-[a-z0-9]+)*$
84+
// name specifies the name of the name of the package
85+
Name string `json:"name"`
86+
87+
//+kubebuilder:validation:MaxLength:=64
88+
//+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*)*$`
89+
//+kubebuilder:Optional
90+
// Version is an optional semver constraint on the package version. If not specified, the latest version available of the package will be installed.
91+
// If specified, the specific version of the package will be installed so long as it is available in any of the content sources available.
92+
// Examples: 1.2.3, 1.0.0-alpha, 1.0.0-rc.1
93+
//
94+
// For more information on semver, please see https://semver.org/
95+
// version constraint definition
96+
Version string `json:"version,omitempty"`
97+
98+
//+kubebuilder:validation:MaxLength:=48
99+
//+kubebuilder:validation:Pattern:=^[a-z0-9]+([\.-][a-z0-9]+)*$
100+
// channel constraint definition
101+
Channel string `json:"channel,omitempty"`
102+
103+
//+kubebuilder:validation:Enum:=Enforce;Ignore
104+
//+kubebuilder:default:=Enforce
105+
//+kubebuilder:Optional
106+
//
107+
// upgradeConstraintPolicy Defines the policy for how to handle upgrade constraints
108+
UpgradeConstraintPolicy UpgradeConstraintPolicy `json:"upgradeConstraintPolicy,omitempty"`
109+
}

api/v1alpha1/clusterextension_types_test.go renamed to api/v1alpha1/condition_types_test.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ import (
1515
"github.com/operator-framework/operator-controller/internal/conditionsets"
1616
)
1717

18-
func TestClusterExtensionTypeRegistration(t *testing.T) {
18+
func TestConditionTypeRegistration(t *testing.T) {
1919
types, err := parseConstants("Type")
2020
if err != nil {
2121
t.Fatalf("unable to parse Type constants %v", err)
2222
}
2323

2424
for _, tt := range types {
25-
if !slices.Contains(conditionsets.ConditionTypes, tt) && !slices.Contains(conditionsets.ExtensionConditionTypes, tt) {
25+
if !slices.Contains(conditionsets.ConditionTypes, tt) {
2626
t.Errorf("append Type%s to conditionsets.ConditionTypes in this package's init function", tt)
2727
}
2828
}
@@ -32,21 +32,16 @@ func TestClusterExtensionTypeRegistration(t *testing.T) {
3232
t.Errorf("there must be a Type%[1]s string literal constant for type %[1]q (i.e. 'const Type%[1]s = %[1]q')", tt)
3333
}
3434
}
35-
for _, tt := range conditionsets.ExtensionConditionTypes {
36-
if !slices.Contains(types, tt) {
37-
t.Errorf("there must be a Type%[1]s string literal constant for type %[1]q (i.e. 'const Type%[1]s = %[1]q')", tt)
38-
}
39-
}
4035
}
4136

42-
func TestClusterExtensionReasonRegistration(t *testing.T) {
37+
func TestConditionReasonRegistration(t *testing.T) {
4338
reasons, err := parseConstants("Reason")
4439
if err != nil {
4540
t.Fatalf("unable to parse Reason constants %v", err)
4641
}
4742

4843
for _, r := range reasons {
49-
if !slices.Contains(conditionsets.ConditionReasons, r) && !slices.Contains(conditionsets.ExtensionConditionReasons, r) {
44+
if !slices.Contains(conditionsets.ConditionReasons, r) {
5045
t.Errorf("append Reason%s to conditionsets.ConditionReasons in this package's init function.", r)
5146
}
5247
}
@@ -55,11 +50,6 @@ func TestClusterExtensionReasonRegistration(t *testing.T) {
5550
t.Errorf("there must be a Reason%[1]s string literal constant for reason %[1]q (i.e. 'const Reason%[1]s = %[1]q')", r)
5651
}
5752
}
58-
for _, r := range conditionsets.ExtensionConditionReasons {
59-
if !slices.Contains(reasons, r) {
60-
t.Errorf("there must be a Reason%[1]s string literal constant for reason %[1]q (i.e. 'const Reason%[1]s = %[1]q')", r)
61-
}
62-
}
6353
}
6454

6555
// parseConstants parses the values of the top-level constants in the current

api/v1alpha1/extension_types.go

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,8 @@ package v1alpha1
1818

1919
import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21-
22-
"github.com/operator-framework/operator-controller/internal/conditionsets"
23-
)
24-
25-
const (
26-
SourceTypePackage = "package"
2721
)
2822

29-
type ExtensionSourcePackage struct {
30-
//+kubebuilder:validation:MaxLength:=48
31-
//+kubebuilder:validation:Pattern:=^[a-z0-9]+(-[a-z0-9]+)*$
32-
// name specifies the name of the name of the package
33-
Name string `json:"name"`
34-
35-
//+kubebuilder:validation:MaxLength:=64
36-
//+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*)*$`
37-
//+kubebuilder:Optional
38-
// Version is an optional semver constraint on the package version. If not specified, the latest version available of the package will be installed.
39-
// If specified, the specific version of the package will be installed so long as it is available in any of the content sources available.
40-
// Examples: 1.2.3, 1.0.0-alpha, 1.0.0-rc.1
41-
//
42-
// For more information on semver, please see https://semver.org/
43-
// version constraint definition
44-
Version string `json:"version,omitempty"`
45-
46-
//+kubebuilder:validation:MaxLength:=48
47-
//+kubebuilder:validation:Pattern:=^[a-z0-9]+([\.-][a-z0-9]+)*$
48-
// channel constraint definition
49-
Channel string `json:"channel,omitempty"`
50-
51-
//+kubebuilder:validation:Enum:=Enforce;Ignore
52-
//+kubebuilder:default:=Enforce
53-
//+kubebuilder:Optional
54-
//
55-
// upgradeConstraintPolicy Defines the policy for how to handle upgrade constraints
56-
UpgradeConstraintPolicy UpgradeConstraintPolicy `json:"upgradeConstraintPolicy,omitempty"`
57-
}
58-
5923
// +kubebuilder:validation:XValidation:rule="self.sourceType=='package' && has(self.__package__)",message="sourceType must match populated union field"
6024
//
6125
// ExtensionSource defines the source for this Extension, right now, only a package is supported.
@@ -66,7 +30,7 @@ type ExtensionSource struct {
6630
SourceType string `json:"sourceType"`
6731

6832
// package defines a reference for a bundle in a catalog defined by a name and a version and/or channel
69-
Package *ExtensionSourcePackage `json:"package,omitempty"`
33+
Package *SourcePackage `json:"package,omitempty"`
7034
}
7135

7236
// ExtensionSpec defines the desired state of Extension
@@ -135,25 +99,6 @@ type ExtensionList struct {
13599
Items []Extension `json:"items"`
136100
}
137101

138-
const (
139-
// TypeProgressing indicates whether operator-controller is
140-
// reconciling, installing, updating or deleting an extension.
141-
TypeProgressing = "Progressing"
142-
143-
ReasonProgressing = "Progressing"
144-
ReasonFailedToReachDesiredIntent = "FailedToReachDesiredIntent"
145-
ReasonReachedDesiredIntent = "ReachedDesiredIntent"
146-
)
147-
148102
func init() {
149103
SchemeBuilder.Register(&Extension{}, &ExtensionList{})
150-
151-
conditionsets.ExtensionConditionTypes = []string{
152-
TypeProgressing,
153-
}
154-
conditionsets.ExtensionConditionReasons = []string{
155-
ReasonProgressing,
156-
ReasonFailedToReachDesiredIntent,
157-
ReasonReachedDesiredIntent,
158-
}
159104
}

0 commit comments

Comments
 (0)