Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8aef998
DNM: Bump API and client-go in go.work
chrischdi Oct 28, 2025
ae516b7
DNM: hack/vendor.sh
chrischdi Oct 28, 2025
7cf9bfb
pkg/conversion: fix tests due to k/k bump
chrischdi Oct 28, 2025
9fc0b1f
golangci-lint: add import aliases for apiextensions in o/api and o/cl…
chrischdi Oct 28, 2025
2ace9f5
crd-compatibility-checker: bootstrap binary
chrischdi Oct 28, 2025
9d19bcd
Add crd-compatibility-checker to Dockerfile and Makefile
chrischdi Oct 28, 2025
3692fed
manifests: add manifests for CompatibilityChecker
chrischdi Oct 28, 2025
1a84b81
crd-compatibility-checker: add schema for apiextensions.openshift.io
chrischdi Oct 28, 2025
adf1bb9
envtest: add apiextensions.openshift.io
chrischdi Oct 28, 2025
064ae18
test: expose GenerateCRD, implement GenerateTestCRD and GenerateTestC…
chrischdi Oct 28, 2025
5b82bdd
crdchecker: implement package to callout to crdify
chrischdi Oct 28, 2025
e8e43bd
crd-compatibility-checker: bootstrap CompatibilityRequirement reconciler
chrischdi Oct 28, 2025
045a85c
crd-compatibility-checker: bootstrap CRD validator
chrischdi Oct 28, 2025
902aee4
crd-compatibility-checker: bootstrap CR Object validator
chrischdi Oct 28, 2025
9be83e4
crd-compatibility-checker: CRD validator: implement logic and basic t…
chrischdi Oct 28, 2025
6fc7c0c
crd-compatibility-checker: implement first CompatibilityRequirement v…
chrischdi Oct 28, 2025
e08b4a0
crd-compatibility-checker: CR Object validator: first implementation WIP
chrischdi Oct 28, 2025
896e3f9
crd-compatibility-checker: first CompatibilityRequirement Reconcile i…
chrischdi Oct 28, 2025
15ebd3e
crd-compatibility-checker: CompatibilityRequirement tests
chrischdi Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ linters-settings:
alias: "mapiv1alpha1"
- pkg: "sigs.k8s.io/controller-runtime/pkg/log"
alias: "logf"
- pkg: "github.com/openshift/api/apiextensions/v1alpha1"
alias: "apiextensionsv1alpha1"
- pkg: "github.com/openshift/client-go/apiextensions/applyconfigurations/apiextensions/v1alpha1"
alias: "apiextensionsapplyconfig"
no-unaliased: true
nlreturn:
block-size: 2
Expand Down
1 change: 1 addition & 0 deletions Dockerfile.rhel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ RUN make build
FROM registry.ci.openshift.org/ocp/4.21:base-rhel9
COPY --from=builder /go/src/github.com/openshift/cluster-capi-operator/bin/cluster-capi-operator .
COPY --from=builder /go/src/github.com/openshift/cluster-capi-operator/bin/machine-api-migration .
COPY --from=builder /go/src/github.com/openshift/cluster-capi-operator/bin/crd-compatibility-checker .
COPY --from=builder /go/src/github.com/openshift/cluster-capi-operator/manifests /manifests

LABEL io.openshift.release.operator true
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ verify: fmt lint
test: verify unit

# Build binaries
build: operator migration manifests-gen
build: operator migration crd-compatibility-checker manifests-gen

.PHONY: manifests-gen
manifests-gen:
Expand All @@ -39,6 +39,10 @@ migration:
# building migration
go build -o bin/machine-api-migration cmd/machine-api-migration/main.go

crd-compatibility-checker:
# building crd-compatibility-checker
go build -o bin/crd-compatibility-checker cmd/crd-compatibility-checker/main.go

.PHONY: localtestenv
localtestenv: .localtestenv

Expand Down Expand Up @@ -95,6 +99,12 @@ image:
push:
docker push ${IMG}

.PHONY: crds-sync
api_module_dir ?= $(shell go list -f '{{.Dir}}' github.com/openshift/api)
crds := apiextensions/v1alpha1/zz_generated.crd-manifests/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml
crds-sync: $(crds:%=$(api_module_dir)/%)
cp $? ./manifests/

aws-cluster:
./hack/clusters/create-aws.sh

Expand Down
163 changes: 163 additions & 0 deletions cmd/crd-compatibility-checker/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright 2025 Red Hat, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main

import (
"flag"
"os"

"github.com/spf13/pflag"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/component-base/config"
"k8s.io/component-base/config/options"
klog "k8s.io/klog/v2"

apiextensionsv1alpha1 "github.com/openshift/api/apiextensions/v1alpha1"
"github.com/openshift/cluster-capi-operator/pkg/controllers/crdcompatibility"
"github.com/openshift/cluster-capi-operator/pkg/controllers/crdcompatibility/crdvalidation"
"github.com/openshift/cluster-capi-operator/pkg/controllers/crdcompatibility/objectvalidation"
"github.com/openshift/cluster-capi-operator/pkg/util"

capiflags "sigs.k8s.io/cluster-api/util/flags"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
crwebhook "sigs.k8s.io/controller-runtime/pkg/webhook"
)

func initScheme(scheme *runtime.Scheme) {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(apiextensionsv1.AddToScheme(scheme))
utilruntime.Must(apiextensionsv1alpha1.AddToScheme(scheme))
}

//nolint:funlen
func main() {
scheme := runtime.NewScheme()
initScheme(scheme)

leaderElectionConfig := config.LeaderElectionConfiguration{
LeaderElect: true,
LeaseDuration: util.LeaseDuration,
RenewDeadline: util.RenewDeadline,
RetryPeriod: util.RetryPeriod,
ResourceName: "crd-compatibility-checker-leader",
ResourceNamespace: "openshift-cluster-api",
}

healthAddr := flag.String(
"health-addr",
":9441",
"The address for health checking.",
)

webhookPort := flag.Int(
"webhook-port",
9443,
"The port for the webhook server to listen on.",
)
webhookCertDir := flag.String(
"webhook-cert-dir",
"/tmp/k8s-webhook-server/serving-certs/",
"Webhook cert dir, only used when webhook-port is specified.",
)

logToStderr := flag.Bool(
"logtostderr",
true,
"log to standard error instead of files",
)

// klog.Background will automatically use the right logger.
ctrl.SetLogger(klog.Background())

// Once all the flags are registered, switch to pflag
// to allow leader election flags to be bound
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
options.BindLeaderElectionFlags(&leaderElectionConfig, pflag.CommandLine)

// Register CAPI flags for the diagnostics endpoint.
capiManagerOptions := capiflags.ManagerOptions{}
capiflags.AddManagerOptions(pflag.CommandLine, &capiManagerOptions)

pflag.Parse()

if logToStderr != nil {
klog.LogToStderr(*logToStderr)
}

cfg := ctrl.GetConfigOrDie()

mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
HealthProbeBindAddress: *healthAddr,
LeaderElectionNamespace: leaderElectionConfig.ResourceNamespace,
LeaderElection: leaderElectionConfig.LeaderElect,
LeaseDuration: &leaderElectionConfig.LeaseDuration.Duration,
LeaderElectionID: leaderElectionConfig.ResourceName,
RetryPeriod: &leaderElectionConfig.RetryPeriod.Duration,
RenewDeadline: &leaderElectionConfig.RenewDeadline.Duration,
WebhookServer: crwebhook.NewServer(crwebhook.Options{
Port: *webhookPort,
CertDir: *webhookCertDir,
}),
})
if err != nil {
klog.Error(err, "unable to start manager")
os.Exit(1)
}

ctx := ctrl.SetupSignalHandler()

compatibilityRequirementReconciler := crdcompatibility.NewCompatibilityRequirementReconciler(mgr.GetClient())
// Setup the CRD compatibility controller
if err := compatibilityRequirementReconciler.SetupWithManager(ctx, mgr); err != nil {
klog.Error(err, "unable to create controller", "controller", "CompatibilityRequirement")
os.Exit(1)
}

// Setup the validator for CustomResourceDefinition Create/Update/Delete events.
crdValidator := crdvalidation.NewValidator(mgr.GetClient())
if err := crdValidator.SetupWithManager(ctx, mgr); err != nil {
klog.Error(err, "unable to create controller", "controller", "CRDValidator")
os.Exit(1)
}

objectValidator := objectvalidation.NewValidator()
// Setup the objectvalidation controller and webhook
if err := objectValidator.SetupWithManager(ctx, mgr); err != nil {
klog.Error(err, "unable to create controller", "controller", "ObjectValidator")
os.Exit(1)
}

if err := mgr.AddHealthzCheck("health", healthz.Ping); err != nil {
klog.Error(err, "unable to set up health check")
os.Exit(1)
}

if err := mgr.AddReadyzCheck("check", healthz.Ping); err != nil {
klog.Error(err, "unable to set up ready check")
os.Exit(1)
}

klog.Info("Starting CRD compatibility checker manager")

if err := mgr.Start(ctx); err != nil {
klog.Error(err, "problem running manager")
os.Exit(1)
}
}
51 changes: 27 additions & 24 deletions e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ require (
github.com/metal3-io/cluster-api-provider-metal3/api v1.10.1
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.38.0
github.com/openshift/api v0.0.0-20250731015415-ed654edbd7c6
github.com/openshift/api v0.0.0-20251015095338-264e80a2b6e7
github.com/openshift/cluster-api-actuator-pkg v0.0.0-20250729202911-167220318f40
github.com/openshift/cluster-api-provider-baremetal v0.0.0-20250619124612-fb678fec5f7e
k8s.io/api v0.33.3
k8s.io/apimachinery v0.33.3
k8s.io/client-go v0.33.3
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
k8s.io/api v0.34.1
k8s.io/apimachinery v0.34.1
k8s.io/client-go v0.34.1
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
sigs.k8s.io/cluster-api v1.10.4
sigs.k8s.io/cluster-api-provider-aws/v2 v2.9.0
sigs.k8s.io/cluster-api-provider-azure v1.20.2
sigs.k8s.io/cluster-api-provider-gcp v1.10.0
sigs.k8s.io/cluster-api-provider-ibmcloud v0.11.0
sigs.k8s.io/cluster-api-provider-vsphere v1.13.0
sigs.k8s.io/controller-runtime v0.20.4
sigs.k8s.io/yaml v1.4.0
sigs.k8s.io/yaml v1.6.0
)

require (
Expand All @@ -43,8 +43,8 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-openapi/errors v0.22.1 // indirect
Expand All @@ -60,7 +60,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.7.0-rc.1 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
Expand All @@ -74,15 +74,16 @@ require (
github.com/metal3-io/ip-address-manager/api v1.10.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/openshift/client-go v0.0.0-20250710075018-396b36f983ee // indirect
github.com/openshift/client-go v0.0.0-20251015124057-db0dee36e235 // indirect
github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20250821122144-fd0936342469 // indirect
github.com/openshift/cluster-autoscaler-operator v0.0.1-0.20250702183526-4eb64d553940 // indirect
github.com/openshift/library-go v0.0.0-20250729191057-91376e1b394e // indirect
github.com/openshift/library-go v0.0.0-20251016115829-235f9f1a273e // indirect
github.com/openshift/machine-api-operator v0.2.1-0.20250721183005-388c07321caf // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.64.0 // indirect
Expand All @@ -96,29 +97,31 @@ require (
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.42.0 // indirect
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/mod v0.27.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/term v0.35.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.33.0 // indirect
golang.org/x/tools v0.36.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.33.3 // indirect
k8s.io/component-base v0.33.3 // indirect
k8s.io/apiextensions-apiserver v0.34.1 // indirect
k8s.io/component-base v0.34.1 // indirect
k8s.io/klog v1.0.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)
Loading