Skip to content

⚠️ updates from api audit #1404

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

Merged
merged 3 commits into from
Nov 8, 2024
Merged
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
306 changes: 147 additions & 159 deletions api/v1alpha1/clusterextension_types.go

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

213 changes: 107 additions & 106 deletions config/base/crd/bases/olm.operatorframework.io_clusterextensions.yaml

Large diffs are not rendered by default.

60 changes: 30 additions & 30 deletions docs/api-reference/operator-controller-api-reference.md

Large diffs are not rendered by default.

29 changes: 23 additions & 6 deletions internal/applier/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
apimachyaml "k8s.io/apimachinery/pkg/util/yaml"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

helmclient "github.com/operator-framework/helm-operator-plugins/pkg/client"

Expand Down Expand Up @@ -56,6 +57,26 @@ type Helm struct {
Preflights []Preflight
}

// shouldSkipPreflight is a helper to determine if the preflight check is CRDUpgradeSafety AND
// if it is set to enforcement None.
func shouldSkipPreflight(ctx context.Context, preflight Preflight, ext *ocv1alpha1.ClusterExtension, state string) bool {
l := log.FromContext(ctx)
hasCRDUpgradeSafety := ext.Spec.Install.Preflight != nil && ext.Spec.Install.Preflight.CRDUpgradeSafety != nil
_, isCRDUpgradeSafetyInstance := preflight.(*crdupgradesafety.Preflight)

if hasCRDUpgradeSafety && isCRDUpgradeSafetyInstance {
if state == StateNeedsInstall || state == StateNeedsUpgrade {
l.Info("crdUpgradeSafety ", "policy", ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement)
}
if ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement == ocv1alpha1.CRDUpgradeSafetyEnforcementNone {
// Skip this preflight check because it is of type *crdupgradesafety.Preflight and the CRD Upgrade Safety
// policy is set to None
return true
}
}
return false
}

func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1alpha1.ClusterExtension, objectLabels map[string]string, storageLabels map[string]string) ([]client.Object, string, error) {
chrt, err := convert.RegistryV1ToHelmChart(ctx, contentFS, ext.Spec.Install.Namespace, []string{corev1.NamespaceAll})
if err != nil {
Expand All @@ -78,12 +99,8 @@ func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1alpha1.Clust
}

for _, preflight := range h.Preflights {
if ext.Spec.Install.Preflight != nil && ext.Spec.Install.Preflight.CRDUpgradeSafety != nil {
if _, ok := preflight.(*crdupgradesafety.Preflight); ok && ext.Spec.Install.Preflight.CRDUpgradeSafety.Policy == ocv1alpha1.CRDUpgradeSafetyPolicyDisabled {
// Skip this preflight check because it is of type *crdupgradesafety.Preflight and the CRD Upgrade Safety
// preflight check has been disabled
continue
}
if shouldSkipPreflight(ctx, preflight, ext, state) {
continue
}
switch state {
case StateNeedsInstall:
Expand Down
24 changes: 21 additions & 3 deletions internal/conditionsets/conditionsets.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,27 @@ limitations under the License.

package conditionsets

import (
"github.com/operator-framework/operator-controller/api/v1alpha1"
)

// ConditionTypes is the full set of ClusterExtension condition Types.
// ConditionReasons is the full set of ClusterExtension condition Reasons.
//
// NOTE: These are populated by init() in api/v1alpha1/clusterextension_types.go
var ConditionTypes []string
var ConditionReasons []string
// NOTE: unit tests in clusterextension_types_test will enforce completeness.
var ConditionTypes = []string{
v1alpha1.TypeInstalled,
v1alpha1.TypeDeprecated,
v1alpha1.TypePackageDeprecated,
v1alpha1.TypeChannelDeprecated,
v1alpha1.TypeBundleDeprecated,
v1alpha1.TypeProgressing,
}

var ConditionReasons = []string{
v1alpha1.ReasonSucceeded,
v1alpha1.ReasonDeprecated,
v1alpha1.ReasonFailed,
v1alpha1.ReasonBlocked,
v1alpha1.ReasonRetrying,
}
10 changes: 5 additions & 5 deletions internal/controllers/clusterextension_admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func TestClusterExtensionSourceConfig(t *testing.T) {

func TestClusterExtensionAdmissionPackageName(t *testing.T) {
tooLongError := "spec.source.catalog.packageName: Too long: may not be longer than 253"
regexMismatchError := "spec.source.catalog.packageName in body should match"
regexMismatchError := "packageName must be a valid DNS1123 subdomain"

testCases := []struct {
name string
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestClusterExtensionAdmissionPackageName(t *testing.T) {

func TestClusterExtensionAdmissionVersion(t *testing.T) {
tooLongError := "spec.source.catalog.version: Too long: may not be longer than 64"
regexMismatchError := "spec.source.catalog.version in body should match"
regexMismatchError := "invalid version expression"

testCases := []struct {
name string
Expand Down Expand Up @@ -236,7 +236,7 @@ func TestClusterExtensionAdmissionVersion(t *testing.T) {

func TestClusterExtensionAdmissionChannel(t *testing.T) {
tooLongError := "spec.source.catalog.channels[0]: Too long: may not be longer than 253"
regexMismatchError := "spec.source.catalog.channels[0] in body should match"
regexMismatchError := "channels entries must be valid DNS1123 subdomains"

testCases := []struct {
name string
Expand Down Expand Up @@ -293,7 +293,7 @@ func TestClusterExtensionAdmissionChannel(t *testing.T) {

func TestClusterExtensionAdmissionInstallNamespace(t *testing.T) {
tooLongError := "spec.install.namespace: Too long: may not be longer than 63"
regexMismatchError := "spec.install.namespace in body should match"
regexMismatchError := "namespace must be a valid DNS1123 label"

testCases := []struct {
name string
Expand Down Expand Up @@ -348,7 +348,7 @@ func TestClusterExtensionAdmissionInstallNamespace(t *testing.T) {

func TestClusterExtensionAdmissionServiceAccount(t *testing.T) {
tooLongError := "spec.install.serviceAccount.name: Too long: may not be longer than 253"
regexMismatchError := "spec.install.serviceAccount.name in body should match"
regexMismatchError := "name must be a valid DNS1123 subdomain"

testCases := []struct {
name string
Expand Down
2 changes: 1 addition & 1 deletion internal/controllers/clusterextension_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ func TestClusterExtensionInstallationSucceeds(t *testing.T) {
t.Log("By checking the expected progressing conditions")
progressingCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeProgressing)
require.NotNil(t, progressingCond)
require.Equal(t, metav1.ConditionFalse, progressingCond.Status)
require.Equal(t, metav1.ConditionTrue, progressingCond.Status)
require.Equal(t, ocv1alpha1.ReasonSucceeded, progressingCond.Reason)

require.NoError(t, cl.DeleteAllOf(ctx, &ocv1alpha1.ClusterExtension{}))
Expand Down
3 changes: 1 addition & 2 deletions internal/controllers/common_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,13 @@ func setInstallStatus(ext *ocv1alpha1.ClusterExtension, installStatus *ocv1alpha
func setStatusProgressing(ext *ocv1alpha1.ClusterExtension, err error) {
progressingCond := metav1.Condition{
Type: ocv1alpha1.TypeProgressing,
Status: metav1.ConditionFalse,
Status: metav1.ConditionTrue,
Reason: ocv1alpha1.ReasonSucceeded,
Message: "desired state reached",
ObservedGeneration: ext.GetGeneration(),
}

if err != nil {
progressingCond.Status = metav1.ConditionTrue
progressingCond.Reason = ocv1alpha1.ReasonRetrying
progressingCond.Message = err.Error()
}
Expand Down
4 changes: 2 additions & 2 deletions internal/controllers/common_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ func TestSetStatusProgressing(t *testing.T) {
expected metav1.Condition
}{
{
name: "non-nil ClusterExtension, nil error, Progressing condition has status False with reason Success",
name: "non-nil ClusterExtension, nil error, Progressing condition has status True with reason Success",
err: nil,
clusterExtension: &ocv1alpha1.ClusterExtension{},
expected: metav1.Condition{
Type: ocv1alpha1.TypeProgressing,
Status: metav1.ConditionFalse,
Status: metav1.ConditionTrue,
Reason: ocv1alpha1.ReasonSucceeded,
Message: "desired state reached",
},
Expand Down
19 changes: 12 additions & 7 deletions internal/resolve/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,18 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1alpha1.ClusterEx
versionRange := ext.Spec.Source.Catalog.Version
channels := ext.Spec.Source.Catalog.Channels

selector, err := metav1.LabelSelectorAsSelector(&ext.Spec.Source.Catalog.Selector)
if err != nil {
return nil, nil, nil, fmt.Errorf("desired catalog selector is invalid: %w", err)
}
// A nothing (empty) seletor selects everything
if selector == labels.Nothing() {
selector = labels.Everything()
// unless overridden, default to selecting all bundles
var selector = labels.Everything()
var err error
if ext.Spec.Source.Catalog != nil {
selector, err = metav1.LabelSelectorAsSelector(ext.Spec.Source.Catalog.Selector)
if err != nil {
return nil, nil, nil, fmt.Errorf("desired catalog selector is invalid: %w", err)
}
// A nothing (empty) selector selects everything
if selector == labels.Nothing() {
selector = labels.Everything()
}
}

var versionRangeConstraints *mmsemver.Constraints
Expand Down
14 changes: 9 additions & 5 deletions internal/resolve/catalog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ func TestInvalidClusterExtensionCatalogMatchExpressions(t *testing.T) {
Source: ocv1alpha1.SourceConfig{
Catalog: &ocv1alpha1.CatalogSource{
PackageName: "foo",
Selector: metav1.LabelSelector{
Selector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "name",
Expand Down Expand Up @@ -802,7 +802,7 @@ func TestInvalidClusterExtensionCatalogMatchLabelsName(t *testing.T) {
Source: ocv1alpha1.SourceConfig{
Catalog: &ocv1alpha1.CatalogSource{
PackageName: "foo",
Selector: metav1.LabelSelector{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"": "value"},
},
},
Expand All @@ -828,7 +828,7 @@ func TestInvalidClusterExtensionCatalogMatchLabelsValue(t *testing.T) {
Source: ocv1alpha1.SourceConfig{
Catalog: &ocv1alpha1.CatalogSource{
PackageName: "foo",
Selector: metav1.LabelSelector{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"name": "&value"},
},
},
Expand All @@ -852,7 +852,9 @@ func TestClusterExtensionMatchLabel(t *testing.T) {
}
r := CatalogResolver{WalkCatalogsFunc: w.WalkCatalogs}
ce := buildFooClusterExtension(pkgName, []string{}, "", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
ce.Spec.Source.Catalog.Selector.MatchLabels = map[string]string{"olm.operatorframework.io/metadata.name": "b"}
ce.Spec.Source.Catalog.Selector = &metav1.LabelSelector{
MatchLabels: map[string]string{"olm.operatorframework.io/metadata.name": "b"},
}

_, _, _, err := r.Resolve(context.Background(), ce, nil)
require.NoError(t, err)
Expand All @@ -871,7 +873,9 @@ func TestClusterExtensionNoMatchLabel(t *testing.T) {
}
r := CatalogResolver{WalkCatalogsFunc: w.WalkCatalogs}
ce := buildFooClusterExtension(pkgName, []string{}, "", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
ce.Spec.Source.Catalog.Selector.MatchLabels = map[string]string{"olm.operatorframework.io/metadata.name": "a"}
ce.Spec.Source.Catalog.Selector = &metav1.LabelSelector{
MatchLabels: map[string]string{"olm.operatorframework.io/metadata.name": "a"},
}

_, _, _, err := r.Resolve(context.Background(), ce, nil)
require.Error(t, err)
Expand Down
Loading
Loading