Skip to content

Commit

Permalink
Update dependencies, warnings webhook (#619)
Browse files Browse the repository at this point in the history
* Update controller-runtime, modify all required methods and recreate mocks

* Update tests after modifications to fakeClient

* Tools upgrades

* Fix cluster-wide cache, modify Makefile to not fetch kustomize on github actions

* Enable existing test that had a bug which caused incorrect assert error

* Remove linking from workflow, let Makefile handle it
  • Loading branch information
burmanm authored Mar 7, 2024
1 parent 9d320dd commit c273e27
Show file tree
Hide file tree
Showing 29 changed files with 6,192 additions and 5,518 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/operatorBuildAndDeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,6 @@ jobs:
platforms: linux/amd64
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
# The runners already have the latest versions of tools, no need to reinstall them
- name: Link tools
shell: bash
run: |
mkdir bin
ln -s /usr/local/bin/kustomize bin/kustomize
- name: Create bundle and validate
run: |
make IMG=k8ssandra/cass-operator:${{ steps.vars.outputs.version }} VERSION=${{ steps.vars.outputs.version }} CHANNEL=dev bundle
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Changelog for Cass Operator, new PRs should update the `main / unreleased` secti

## unreleased

* [CHANGE] [#618](https://github.com/k8ssandra/cass-operator/issues/618) Update dependencies to support controller-runtime 0.17.2, modify required parts.
* [ENHANCEMENT] [#532](https://github.com/k8ssandra/cass-operator/issues/532) Instead of rejecting updates/creates with deprecated fields, return kubectl warnings.

## v1.19.0

* [FEATURE] [#601](https://github.com/k8ssandra/cass-operator/pull/601) Add additionalAnnotations field to CR so that all resources created by the operator can be annotated.
Expand Down
19 changes: 12 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ IMG ?= $(IMAGE_TAG_BASE):v$(VERSION)
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS ?= "crd:generateEmbeddedObjectMeta=true"
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.27.x
ENVTEST_K8S_VERSION = 1.28.x

# Logger image
LOG_IMG_BASE ?= $(ORG)/system-logger
Expand Down Expand Up @@ -239,12 +239,12 @@ HELM ?= $(LOCALBIN)/helm
OPM ?= $(LOCALBIN)/opm

## Tool Versions
CERT_MANAGER_VERSION ?= v1.12.2
KUSTOMIZE_VERSION ?= v5.0.3
CONTROLLER_TOOLS_VERSION ?= v0.12.0
OPERATOR_SDK_VERSION ?= 1.29.0
HELM_VERSION ?= 3.12.0
OPM_VERSION ?= 1.26.5
CERT_MANAGER_VERSION ?= v1.14.3
KUSTOMIZE_VERSION ?= v5.3.0
CONTROLLER_TOOLS_VERSION ?= v0.14.0
OPERATOR_SDK_VERSION ?= 1.34.0
HELM_VERSION ?= 3.14.2
OPM_VERSION ?= 1.36.0
GOLINT_VERSION ?= 1.55.2

.PHONY: cert-manager
Expand All @@ -257,11 +257,16 @@ KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/k
.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.
$(KUSTOMIZE): $(LOCALBIN)
ifeq ($(GITHUB_ACTIONS), true)
@echo "Running in GitHub Actions, using the kustomize version provided by the runner."
test -e $(LOCALBIN)/kustomize || ln -s $(shell which kustomize) $(LOCALBIN)/kustomize
else
@if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \
echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \
rm -rf $(LOCALBIN)/kustomize; \
fi
test -s $(LOCALBIN)/kustomize || { curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); }
endif

.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten.
Expand Down
2 changes: 1 addition & 1 deletion PROJECT
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
domain: cassandra.datastax.com
layout:
- go.kubebuilder.io/v4-alpha
- go.kubebuilder.io/v4
multigroup: true
plugins:
manifests.sdk.operatorframework.io/v2: {}
Expand Down
43 changes: 30 additions & 13 deletions apis/cassandra/v1beta1/cassandradatacenter_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

const (
Expand Down Expand Up @@ -64,6 +65,17 @@ func attemptedTo(action string, actionStrArgs ...interface{}) error {
return fmt.Errorf("CassandraDatacenter write rejected, attempted to %s", msg)
}

func deprecatedWarning(field, instead, extra string) string {
warning := "CassandraDatacenter is using deprecated field '%s'"
if instead != "" {
warning += fmt.Sprintf(", use '%s' instead", instead)
}
if extra != "" {
warning += ". %s"
}
return warning
}

// ValidateSingleDatacenter checks that no values are improperly set on a CassandraDatacenter
func ValidateSingleDatacenter(dc CassandraDatacenter) error {
// Ensure serverVersion and serverType are compatible
Expand Down Expand Up @@ -219,18 +231,19 @@ func ValidateDatacenterFieldChanges(oldDc CassandraDatacenter, newDc CassandraDa
}

// ValidateDeprecatedFieldUsage prevents adding fields that are deprecated
func ValidateDeprecatedFieldUsage(dc CassandraDatacenter) error {
func ValidateDeprecatedFieldUsage(dc CassandraDatacenter) admission.Warnings {
warnings := admission.Warnings{}
for _, rack := range dc.GetRacks() {
if rack.DeprecatedZone != "" {
return attemptedTo("use deprecated parameter Zone, use NodeAffinityLabels instead.")
warnings = append(warnings, deprecatedWarning("zone", "NodeAffinityLabels", ""))
}
}

if dc.Spec.DeprecatedDockerImageRunsAsCassandra != nil && !(*dc.Spec.DeprecatedDockerImageRunsAsCassandra) {
return attemptedTo("use removed field dockerImageRunsAsCassandra, use SecurityContext instead")
warnings = append(warnings, deprecatedWarning("dockerImageRunsAsCassandra", "SecurityContext", ""))
}

return nil
return warnings
}

func ValidateAdditionalVolumes(dc CassandraDatacenter) error {
Expand All @@ -251,31 +264,35 @@ func ValidateAdditionalVolumes(dc CassandraDatacenter) error {
// +kubebuilder:webhook:path=/validate-cassandradatacenter,mutating=false,failurePolicy=ignore,groups=cassandra.datastax.com,resources=cassandradatacenters,verbs=create;update,versions=v1beta1,name=validate-cassandradatacenter-webhook
var _ webhook.Validator = &CassandraDatacenter{}

func (dc *CassandraDatacenter) ValidateCreate() error {
func (dc *CassandraDatacenter) ValidateCreate() (admission.Warnings, error) {
log.Info("Validating webhook called for create")
if err := ValidateSingleDatacenter(*dc); err != nil {
return err
return admission.Warnings{}, err
}

return ValidateDeprecatedFieldUsage(*dc)
return ValidateDeprecatedFieldUsage(*dc), nil
}

func (dc *CassandraDatacenter) ValidateUpdate(old runtime.Object) error {
func (dc *CassandraDatacenter) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
log.Info("Validating webhook called for update")
oldDc, ok := old.(*CassandraDatacenter)
if !ok {
return errors.New("old object in ValidateUpdate cannot be cast to CassandraDatacenter")
return nil, errors.New("old object in ValidateUpdate cannot be cast to CassandraDatacenter")
}

if err := ValidateSingleDatacenter(*dc); err != nil {
return err
return nil, err
}

return ValidateDatacenterFieldChanges(*oldDc, *dc)
if err := ValidateDatacenterFieldChanges(*oldDc, *dc); err != nil {
return nil, err
}

return ValidateDeprecatedFieldUsage(*dc), nil
}

func (dc *CassandraDatacenter) ValidateDelete() error {
return nil
func (dc *CassandraDatacenter) ValidateDelete() (admission.Warnings, error) {
return nil, nil
}

var (
Expand Down
17 changes: 11 additions & 6 deletions apis/cassandra/v1beta1/webhook_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
webhookserver "sigs.k8s.io/controller-runtime/pkg/webhook"
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
Expand Down Expand Up @@ -81,12 +83,15 @@ var _ = BeforeSuite(func() {
// start webhook server using Manager
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
LeaderElection: false,
MetricsBindAddress: "0",
Scheme: scheme,
WebhookServer: webhookserver.NewServer(webhookserver.Options{
Port: testEnv.WebhookInstallOptions.LocalServingPort,
Host: testEnv.WebhookInstallOptions.LocalServingHost,
CertDir: testEnv.WebhookInstallOptions.LocalServingCertDir,
TLSOpts: []func(*tls.Config){func(config *tls.Config) {}},
}),
LeaderElection: false,
Metrics: metricsserver.Options{BindAddress: "0"},
})
Expect(err).NotTo(HaveOccurred())

Expand Down
8 changes: 4 additions & 4 deletions apis/cassandra/v1beta1/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ func Test_ValidateDatacenterFieldChanges(t *testing.T) {
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: &storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
Resources: corev1.ResourceRequirements{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
Expand All @@ -390,7 +390,7 @@ func Test_ValidateDatacenterFieldChanges(t *testing.T) {
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: &storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
Resources: corev1.ResourceRequirements{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
Expand Down Expand Up @@ -517,7 +517,7 @@ func Test_ValidateDatacenterFieldChanges(t *testing.T) {
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: &storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
Resources: corev1.ResourceRequirements{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
Expand All @@ -533,7 +533,7 @@ func Test_ValidateDatacenterFieldChanges(t *testing.T) {
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: &storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteMany"},
Resources: corev1.ResourceRequirements{
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
Expand Down
1 change: 0 additions & 1 deletion apis/cassandra/v1beta1/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion apis/config/v1beta1/operatorconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package v1beta1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
cfg "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
cfg "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" //nolint:staticcheck
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
Expand Down
1 change: 0 additions & 1 deletion apis/config/v1beta1/zz_generated.deepcopy.go

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

1 change: 0 additions & 1 deletion apis/control/v1alpha1/zz_generated.deepcopy.go

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

18 changes: 11 additions & 7 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import (
controlcontrollers "github.com/k8ssandra/cass-operator/internal/controllers/control"
"github.com/k8ssandra/cass-operator/pkg/images"
"github.com/k8ssandra/cass-operator/pkg/utils"
//+kubebuilder:scaffold:imports
)

var (
Expand All @@ -55,7 +54,6 @@ func init() {
utilruntime.Must(api.AddToScheme(scheme))
utilruntime.Must(configv1beta1.AddToScheme(scheme))
utilruntime.Must(controlv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

func main() {
Expand All @@ -82,6 +80,7 @@ func main() {
operConfig := configv1beta1.OperatorConfig{}
options := ctrl.Options{Scheme: scheme}
if configFile != "" {
//nolint:staticcheck
options, err = options.AndFrom(ctrl.ConfigFile().AtPath(configFile).OfKind(&operConfig))
if err != nil {
setupLog.Error(err, "unable to load the config file")
Expand All @@ -97,15 +96,21 @@ func main() {
}
}

options.Cache = cache.Options{
DefaultNamespaces: map[string]cache.Config{},
}

// Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2)
if strings.Contains(ns, ",") {
setupLog.Info("manager set up with multiple namespaces", "namespaces", ns)
// configure cluster-scoped with MultiNamespacedCacheBuilder
options.Namespace = ""
options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(ns, ","))
} else {
namespaces := strings.Split(ns, ",")
for _, namespace := range namespaces {
options.Cache.DefaultNamespaces[namespace] = cache.Config{}
}
} else if ns != "" {
setupLog.Info("watch namespace configured", "namespace", ns)
options.Namespace = ns
options.Cache.DefaultNamespaces[ns] = cache.Config{}
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options)
Expand Down Expand Up @@ -137,7 +142,6 @@ func main() {
setupLog.Error(err, "unable to create controller", "controller", "CassandraTask")
os.Exit(1)
}
//+kubebuilder:scaffold:builder

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
Expand Down
Loading

0 comments on commit c273e27

Please sign in to comment.