diff --git a/Makefile b/Makefile index 73994d36c8..b905d9fe90 100644 --- a/Makefile +++ b/Makefile @@ -117,7 +117,7 @@ endif REPO?=tigera/operator PACKAGE_NAME?=github.com/tigera/operator LOCAL_USER_ID?=$(shell id -u $$USER) -GO_BUILD_VER?=1.24.6-llvm18.1.8-k8s1.33.3 +GO_BUILD_VER?=1.25.3-llvm18.1.8-k8s1.33.5 CALICO_BUILD?=calico/go-build:$(GO_BUILD_VER)-$(BUILDARCH) SRC_FILES=$(shell find ./pkg -name '*.go') SRC_FILES+=$(shell find ./api -name '*.go') diff --git a/cmd/main.go b/cmd/main.go index fad43b4692..f2228198c1 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -80,15 +80,17 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(apiextensions.AddToScheme(scheme)) utilruntime.Must(operatortigeraiov1.AddToScheme(scheme)) - utilruntime.Must(apis.AddToScheme(scheme)) + utilruntime.Must(apis.AddToScheme(scheme, useV3CRDS())) +} + +func useV3CRDS() bool { + return os.Getenv("CALICO_API_GROUP") == "projectcalico.org/v3" } func printVersion() { log.Info(fmt.Sprintf("Version: %v", version.VERSION)) log.Info(fmt.Sprintf("Go Version: %s", goruntime.Version())) log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", goruntime.GOOS, goruntime.GOARCH)) - // TODO: Add this back if we can - // log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version)) } func main() { @@ -441,6 +443,7 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe K8sClientset: clientset, MultiTenant: multiTenant, ElasticExternal: utils.UseExternalElastic(bootConfig), + UseV3CRDs: useV3CRDS(), } // Before we start any controllers, make sure our options are valid. diff --git a/git-hooks/files-to-skip b/git-hooks/files-to-skip index 949d953301..b678e9376d 100644 --- a/git-hooks/files-to-skip +++ b/git-hooks/files-to-skip @@ -1,2 +1 @@ api/v1/zz_generated.deepcopy.go -pkg/apis/crd.projectcalico.org/v1/zz_generated.deepcopy.go diff --git a/go.mod b/go.mod index 3ed0f61daa..7b248eddda 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/tigera/operator -go 1.24.6 +go 1.25.3 require ( github.com/aws/aws-sdk-go v1.55.5 @@ -15,17 +15,16 @@ require ( github.com/hashicorp/go-version v1.7.0 github.com/olivere/elastic/v7 v7.0.32 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.36.1 + github.com/onsi/ginkgo/v2 v2.23.4 + github.com/onsi/gomega v1.38.0 github.com/openshift/api v0.0.0-20240924220842-3c700b6cb32b github.com/openshift/library-go v0.0.0-20240930172803-190f286b06b1 github.com/pkg/errors v0.9.1 - github.com/projectcalico/api v0.0.0-20240708202104-e3f70b269c2c github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1 github.com/r3labs/diff/v2 v2.15.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 - github.com/tigera/api v0.0.0-20230406222214-ca74195900cb + github.com/tigera/api v0.0.0-20251017180206-9d7c2da4f711 github.com/tigera/operator/api v0.0.0-20250718195010-e4328952af47 github.com/urfave/cli/v3 v3.0.0-beta1 go.uber.org/zap v1.27.0 @@ -34,11 +33,11 @@ require ( gopkg.in/inf.v0 v0.9.1 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.33.3 + k8s.io/api v0.33.5 k8s.io/apiextensions-apiserver v0.33.3 - k8s.io/apimachinery v0.33.3 - k8s.io/apiserver v0.33.3 - k8s.io/client-go v0.33.3 + k8s.io/apimachinery v0.33.5 + k8s.io/apiserver v0.33.5 + k8s.io/client-go v0.33.5 k8s.io/kube-aggregator v0.33.3 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/controller-runtime v0.21.0 @@ -73,12 +72,12 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect + github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jinzhu/copier v0.3.5 // indirect + github.com/jinzhu/copier v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -104,6 +103,7 @@ require ( go.elastic.co/apm/module/apmzap/v2 v2.6.2 // indirect go.elastic.co/apm/v2 v2.6.2 // indirect go.elastic.co/fastjson v1.3.0 // indirect + go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/go.sum b/go.sum index 445c9b2e00..1f05029d50 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -127,8 +127,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= -github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -177,12 +177,12 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= +github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= -github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= +github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -199,8 +199,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/projectcalico/api v0.0.0-20240708202104-e3f70b269c2c h1:eFyfeRDV94LA3tgbG2EC5W02dg3QUdltHc2jxhTQMCw= -github.com/projectcalico/api v0.0.0-20240708202104-e3f70b269c2c/go.mod h1:9EPxrA4rUH306dCpvVsFb7IcEFt4ZSvqmfSowfb6c5U= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1 h1:DP+PUNVOc+Bkft8a4QunLzaZ0RspWuD3tBbcPHr2PeE= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1/go.mod h1:6x4x0t9BP35g4XcjkHE9EB3RxhyfxpdpmZKd/Qyk8+M= github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= @@ -232,8 +232,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tigera/api v0.0.0-20230406222214-ca74195900cb h1:Y7r5Al3V235KaEoAzGBz9RYXEbwDu8CPaZoCq2PlD8w= -github.com/tigera/api v0.0.0-20230406222214-ca74195900cb/go.mod h1:ZZghiX3CUsBAc0osBjRvV6y/eun2ObYdvSbjqXAoj/w= +github.com/tigera/api v0.0.0-20251017180206-9d7c2da4f711 h1:A75XdvxO3SlR5qydLSf+CovlwkRCONGcMhZD0l58kNM= +github.com/tigera/api v0.0.0-20251017180206-9d7c2da4f711/go.mod h1:5vkALOm1TWUzg3ElTWnTE3O6wkNB3F8cTkZtio7eFGw= github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg= github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= @@ -264,6 +264,8 @@ go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/Wgbsd go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -373,16 +375,16 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= -k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= +k8s.io/api v0.33.5 h1:YR+uhYj05jdRpcksv8kjSliW+v9hwXxn6Cv10aR8Juw= +k8s.io/api v0.33.5/go.mod h1:2gzShdwXKT5yPGiqrTrn/U/nLZ7ZyT4WuAj3XGDVgVs= k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs= k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8= -k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= -k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4= -k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E= -k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA= -k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= +k8s.io/apimachinery v0.33.5 h1:NiT64hln4TQXeYR18/ES39OrNsjGz8NguxsBgp+6QIo= +k8s.io/apimachinery v0.33.5/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/apiserver v0.33.5 h1:X1Gy33r4YkRLRqTjGjofk7X1/EjSLEVSJ/A+1qjoj60= +k8s.io/apiserver v0.33.5/go.mod h1:Q+b5Btbc8x0PqOCeh/xBTesKk+cXQRN+PF2wdrTKDeg= +k8s.io/client-go v0.33.5 h1:I8BdmQGxInpkMEnJvV6iG7dqzP3JRlpZZlib3OMFc3o= +k8s.io/client-go v0.33.5/go.mod h1:W8PQP4MxbM4ypgagVE65mUUqK1/ByQkSALF9tzuQ6u0= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-aggregator v0.33.3 h1:Pa6hQpKJMX0p0D2wwcxXJgu02++gYcGWXoW1z1ZJDfo= diff --git a/pkg/active/active_test.go b/pkg/active/active_test.go index f0988d5820..b9d98605f3 100644 --- a/pkg/active/active_test.go +++ b/pkg/active/active_test.go @@ -37,13 +37,13 @@ var _ = Describe("test active pkg", func() { c client.Client ctx context.Context scheme *runtime.Scheme - //log logr.Logger + // log logr.Logger ) BeforeEach(func() { // Create a Kubernetes client. scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -52,7 +52,7 @@ var _ = Describe("test active pkg", func() { c = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() ctx = context.Background() - //log = logf.Log.WithName("active-test-logger") + // log = logf.Log.WithName("active-test-logger") }) Context("GetActiveConfigMap", func() { It("should not error with no ConfigMap", func() { diff --git a/pkg/apis/addtoscheme_operator_v1.go b/pkg/apis/addtoscheme_operator_v1.go deleted file mode 100644 index 14ff530cf0..0000000000 --- a/pkg/apis/addtoscheme_operator_v1.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. - -// 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 apis - -import ( - esv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/elasticsearch/v1" - kbv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/kibana/v1" - configv1 "github.com/openshift/api/config/v1" - ocsv1 "github.com/openshift/api/security/v1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - tigera "github.com/tigera/api/pkg/apis/projectcalico/v3" - operator "github.com/tigera/operator/api/v1" - policyv1 "k8s.io/api/policy/v1" - policyv1beta1 "k8s.io/api/policy/v1beta1" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -) - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, operator.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, configv1.Install) - AddToSchemes = append(AddToSchemes, aggregator.AddToScheme) - AddToSchemes = append(AddToSchemes, apiextensions.AddToScheme) - AddToSchemes = append(AddToSchemes, tigera.AddToScheme) - AddToSchemes = append(AddToSchemes, ocsv1.AddToScheme) - AddToSchemes = append(AddToSchemes, esv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, kbv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, policyv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, policyv1beta1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, monitoringv1.SchemeBuilder.AddToScheme) -} diff --git a/pkg/apis/apis.go b/pkg/apis/apis.go deleted file mode 100644 index 0cc5f6fadb..0000000000 --- a/pkg/apis/apis.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2019-2025 Tigera, Inc. All rights reserved. - -// 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 apis - -import ( - "k8s.io/apimachinery/pkg/runtime" - - esv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/elasticsearch/v1" - kbv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/kibana/v1" - envoy "github.com/envoyproxy/gateway/api/v1alpha1" - configv1 "github.com/openshift/api/config/v1" - ocsv1 "github.com/openshift/api/security/v1" - tigera "github.com/tigera/api/pkg/apis/projectcalico/v3" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" - policyv1 "k8s.io/api/policy/v1" - policyv1beta1 "k8s.io/api/policy/v1beta1" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" - gateway "sigs.k8s.io/gateway-api/apis/v1" - csisecret "sigs.k8s.io/secrets-store-csi-driver/apis/v1" -) - -// AddToSchemes may be used to add all resources defined in the project to a Scheme -var AddToSchemes runtime.SchemeBuilder - -// AddToScheme adds all Resources to the Scheme -func AddToScheme(s *runtime.Scheme) error { - return AddToSchemes.AddToScheme(s) -} - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, configv1.Install) - AddToSchemes = append(AddToSchemes, aggregator.AddToScheme) - AddToSchemes = append(AddToSchemes, apiextensions.AddToScheme) - AddToSchemes = append(AddToSchemes, tigera.AddToScheme) - AddToSchemes = append(AddToSchemes, ocsv1.AddToScheme) - AddToSchemes = append(AddToSchemes, esv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, kbv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, policyv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, policyv1beta1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, crdv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, gateway.Install) - AddToSchemes = append(AddToSchemes, envoy.AddToScheme) - AddToSchemes = append(AddToSchemes, csisecret.AddToScheme) -} diff --git a/pkg/apis/crd.projectcalico.org/v1/bgpconfig.go b/pkg/apis/crd.projectcalico.org/v1/bgpconfig.go deleted file mode 100644 index 7ae451b579..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/bgpconfig.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. - -// 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 v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/projectcalico/api/pkg/lib/numorstring" - - k8sv1 "k8s.io/api/core/v1" -) - -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// BGPConfigurationList is a list of BGPConfiguration resources. -type BGPConfigurationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Items []BGPConfiguration `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -type BGPConfiguration struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Spec BGPConfigurationSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` -} - -// BGPConfigurationSpec contains the values of the BGP configuration. -type BGPConfigurationSpec struct { - // LogSeverityScreen is the log severity above which logs are sent to the stdout. [Default: INFO] - LogSeverityScreen string `json:"logSeverityScreen,omitempty" validate:"omitempty,logLevel" confignamev1:"loglevel"` - - // NodeToNodeMeshEnabled sets whether full node to node BGP mesh is enabled. [Default: true] - NodeToNodeMeshEnabled *bool `json:"nodeToNodeMeshEnabled,omitempty" validate:"omitempty" confignamev1:"node_mesh"` - - // ASNumber is the default AS number used by a node. [Default: 64512] - ASNumber *numorstring.ASNumber `json:"asNumber,omitempty" validate:"omitempty" confignamev1:"as_num"` - - // ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes Service LoadBalancer IPs. - // Kubernetes Service status.LoadBalancer.Ingress IPs will only be advertised if they are within one of these blocks. - ServiceLoadBalancerIPs []ServiceLoadBalancerIPBlock `json:"serviceLoadBalancerIPs,omitempty" validate:"omitempty,dive" confignamev1:"svc_loadbalancer_ips"` - - // ServiceExternalIPs are the CIDR blocks for Kubernetes Service External IPs. - // Kubernetes Service ExternalIPs will only be advertised if they are within one of these blocks. - ServiceExternalIPs []ServiceExternalIPBlock `json:"serviceExternalIPs,omitempty" validate:"omitempty,dive" confignamev1:"svc_external_ips"` - - // ServiceClusterIPs are the CIDR blocks from which service cluster IPs are allocated. - // If specified, Calico will advertise these blocks, as well as any cluster IPs within them. - ServiceClusterIPs []ServiceClusterIPBlock `json:"serviceClusterIPs,omitempty" validate:"omitempty,dive" confignamev1:"svc_cluster_ips"` - - // Communities is a list of BGP community values and their arbitrary names for tagging routes. - Communities []Community `json:"communities,omitempty" validate:"omitempty,dive" confignamev1:"communities"` - - // PrefixAdvertisements contains per-prefix advertisement configuration. - PrefixAdvertisements []PrefixAdvertisement `json:"prefixAdvertisements,omitempty" validate:"omitempty,dive" confignamev1:"prefix_advertisements"` - - // ListenPort is the port where BGP protocol should listen. Defaults to 179 - // +kubebuilder:validation:Minimum:=1 - // +kubebuilder:validation:Maximum:=65535 - ListenPort uint16 `json:"listenPort,omitempty" validate:"omitempty,gt=0" confignamev1:"listen_port"` - - // Optional BGP password for full node-to-mesh peerings. - // This field can only be set on the default BGPConfiguration instance and requires that NodeMesh is enabled - // +optional - NodeMeshPassword *BGPPassword `json:"nodeMeshPassword,omitempty" validate:"omitempty" confignamev1:"node_mesh_password"` - - // Time to allow for software restart for node-to-mesh peerings. When specified, this is configured - // as the graceful restart timeout. When not specified, the BIRD default of 120s is used. - // This field can only be set on the default BGPConfiguration instance and requires that NodeMesh is enabled - // +optional - NodeMeshMaxRestartTime *metav1.Duration `json:"nodeMeshMaxRestartTime,omitempty" confignamev1:"node_mesh_restart_time"` - - // BindMode indicates whether to listen for BGP connections on all addresses (None) - // or only on the node's canonical IP address Node.Spec.BGP.IPvXAddress (NodeIP). - BindMode string `json:"bindMode,omitempty" validate:"omitempty,oneof=None NodeIP"` -} - -// ServiceLoadBalancerIPBlock represents a single allowed LoadBalancer IP CIDR block. -type ServiceLoadBalancerIPBlock struct { - CIDR string `json:"cidr,omitempty" validate:"omitempty,net"` -} - -// ServiceExternalIPBlock represents a single allowed External IP CIDR block. -type ServiceExternalIPBlock struct { - CIDR string `json:"cidr,omitempty" validate:"omitempty,net"` -} - -// ServiceClusterIPBlock represents a single allowed ClusterIP CIDR block. -type ServiceClusterIPBlock struct { - CIDR string `json:"cidr,omitempty" validate:"omitempty,net"` -} - -// Community contains standard or large community value and its name. -type Community struct { - // Name given to community value. - Name string `json:"name,omitempty" validate:"required,name"` - // Value must be of format `aa:nn` or `aa:nn:mm`. - // For standard community use `aa:nn` format, where `aa` and `nn` are 16 bit number. - // For large community use `aa:nn:mm` format, where `aa`, `nn` and `mm` are 32 bit number. - // Where, `aa` is an AS Number, `nn` and `mm` are per-AS identifier. - // +kubebuilder:validation:Pattern=`^(\d+):(\d+)$|^(\d+):(\d+):(\d+)$` - Value string `json:"value,omitempty" validate:"required"` -} - -// PrefixAdvertisement configures advertisement properties for the specified CIDR. -type PrefixAdvertisement struct { - // CIDR for which properties should be advertised. - CIDR string `json:"cidr,omitempty" validate:"required,net"` - // Communities can be list of either community names already defined in `Specs.Communities` or community value of format `aa:nn` or `aa:nn:mm`. - // For standard community use `aa:nn` format, where `aa` and `nn` are 16 bit number. - // For large community use `aa:nn:mm` format, where `aa`, `nn` and `mm` are 32 bit number. - // Where,`aa` is an AS Number, `nn` and `mm` are per-AS identifier. - Communities []string `json:"communities,omitempty" validate:"required"` -} - -// BGPPassword contains ways to specify a BGP password. -type BGPPassword struct { - // Selects a key of a secret in the node pod's namespace. - SecretKeyRef *k8sv1.SecretKeySelector `json:"secretKeyRef,omitempty"` -} diff --git a/pkg/apis/crd.projectcalico.org/v1/clusterinfo.go b/pkg/apis/crd.projectcalico.org/v1/clusterinfo.go deleted file mode 100644 index a1ef7b9bba..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/clusterinfo.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2017, 2020-2025 Tigera, Inc. All rights reserved. - -// 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 v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - KindClusterInformation = "ClusterInformation" - KindClusterInformationList = "ClusterInformationList" -) - -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ClusterInformationList is a list of ClusterInformation objects. -type ClusterInformationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Items []ClusterInformation `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -type ClusterInformation struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Spec ClusterInformationSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` -} - -// ClusterInformationSpec contains the values of describing the cluster. -type ClusterInformationSpec struct { - // ClusterGUID is the GUID of the cluster - ClusterGUID string `json:"clusterGUID,omitempty" validate:"omitempty"` - // ClusterType describes the type of the cluster - ClusterType string `json:"clusterType,omitempty" validate:"omitempty"` - // CalicoVersion is the version of Calico that the cluster is running - CalicoVersion string `json:"calicoVersion,omitempty" validate:"omitempty"` - // DatastoreReady is used during significant datastore migrations to signal to components - // such as Felix that it should wait before accessing the datastore. - DatastoreReady *bool `json:"datastoreReady,omitempty"` - // Variant declares which variant of Calico should be active. - Variant string `json:"variant,omitempty"` -} diff --git a/pkg/apis/crd.projectcalico.org/v1/doc.go b/pkg/apis/crd.projectcalico.org/v1/doc.go deleted file mode 100644 index f49da1b575..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. - -// 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. - -// +k8s:deepcopy-gen=package,register -// +groupName=crd.projectcalico.org - -package v1 diff --git a/pkg/apis/crd.projectcalico.org/v1/externalnetwork.go b/pkg/apis/crd.projectcalico.org/v1/externalnetwork.go deleted file mode 100644 index cf2bf453a9..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/externalnetwork.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2023-2024 Tigera, Inc. All rights reserved. - -// 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 v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - KindExternalNetwork = "ExternalNetwork" - KindExternalNetworkList = "ExternalNetworkList" -) - -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ExternalNetworkList is a list of ExternalNetwork resources. -type ExternalNetworkList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Items []ExternalNetwork `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -type ExternalNetwork struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Spec ExternalNetworkSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` -} - -// ExternalNetworkSpec contains the specification for a external network resource. -type ExternalNetworkSpec struct { - // The index of a linux kernel routing table that should be used for the routes associated with the external network. - // The value should be unique for each external network. - // The value should not be in the range of `RouteTableRanges` field in FelixConfiguration. - // The kernel routing table index should not be used by other processes on the node. - RouteTableIndex *uint32 `json:"routeTableIndex" validate:"required"` -} diff --git a/pkg/apis/crd.projectcalico.org/v1/felixconfig.go b/pkg/apis/crd.projectcalico.org/v1/felixconfig.go deleted file mode 100644 index 35997f29ea..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/felixconfig.go +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright (c) 2017-2025 Tigera, Inc. All rights reserved. - -// 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 v1 - -import ( - "github.com/tigera/api/pkg/lib/numorstring" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type NFTablesMode string - -const ( - NFTablesModeEnabled NFTablesMode = "Enabled" - NFTablesModeDisabled NFTablesMode = "Disabled" -) - -type IptablesBackend string - -const ( - KindFelixConfiguration = "FelixConfiguration" - - IptablesBackendLegacy = "Legacy" - IptablesBackendNFTables = "NFT" -) - -// +kubebuilder:validation:Enum=DoNothing;Enable;Disable -type AWSSrcDstCheckOption string - -const ( - AWSSrcDstCheckOptionDoNothing AWSSrcDstCheckOption = "DoNothing" - AWSSrcDstCheckOptionEnable AWSSrcDstCheckOption = "Enable" - AWSSrcDstCheckOptionDisable AWSSrcDstCheckOption = "Disable" -) - -// +kubebuilder:validation:Enum=DoNothing;Enable;Disable -type TPROXYModeOption string - -const ( - TPROXYModeOptionEnabled TPROXYModeOption = "Enabled" - TPROXYModeOptionDisabled TPROXYModeOption = "Disabled" -) - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Felix Configuration contains the configuration for Felix. -type FelixConfiguration struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata. - metav1.ObjectMeta `json:"metadata,omitempty"` - // Specification of the FelixConfiguration. - Spec FelixConfigurationSpec `json:"spec,omitempty"` -} - -// FelixConfigurationSpec contains the values of the Felix configuration. -type FelixConfigurationSpec struct { - UseInternalDataplaneDriver *bool `json:"useInternalDataplaneDriver,omitempty"` - DataplaneDriver string `json:"dataplaneDriver,omitempty"` - - IPv6Support *bool `json:"ipv6Support,omitempty" confignamev1:"Ipv6Support"` - - // RouterefreshInterval is the period at which Felix re-checks the routes - // in the dataplane to ensure that no other process has accidentally broken Calico’s rules. - // Set to 0 to disable route refresh. [Default: 90s] - RouteRefreshInterval *metav1.Duration `json:"routeRefreshInterval,omitempty" configv1timescale:"seconds"` - // InterfaceRefreshInterval is the period at which Felix rescans local interfaces to verify their state. - // The rescan can be disabled by setting the interval to 0. - InterfaceRefreshInterval *metav1.Duration `json:"interfaceRefreshInterval,omitempty" configv1timescale:"seconds"` - // IptablesRefreshInterval is the period at which Felix re-checks the IP sets - // in the dataplane to ensure that no other process has accidentally broken Calico’s rules. - // Set to 0 to disable IP sets refresh. Note: the default for this value is lower than the - // other refresh intervals as a workaround for a Linux kernel bug that was fixed in kernel - // version 4.11. If you are using v4.11 or greater you may want to set this to, a higher value - // to reduce Felix CPU usage. [Default: 10s] - IptablesRefreshInterval *metav1.Duration `json:"iptablesRefreshInterval,omitempty" configv1timescale:"seconds"` - // IptablesPostWriteCheckInterval is the period after Felix has done a write - // to the dataplane that it schedules an extra read back in order to check the write was not - // clobbered by another process. This should only occur if another application on the system - // doesn’t respect the iptables lock. [Default: 1s] - IptablesPostWriteCheckInterval *metav1.Duration `json:"iptablesPostWriteCheckInterval,omitempty" configv1timescale:"seconds" confignamev1:"IptablesPostWriteCheckIntervalSecs"` - // IptablesLockFilePath is the location of the iptables lock file. You may need to change this - // if the lock file is not in its standard location (for example if you have mapped it into Felix’s - // container at a different path). [Default: /run/xtables.lock] - IptablesLockFilePath string `json:"iptablesLockFilePath,omitempty"` - // IptablesLockTimeout is the time that Felix will wait for the iptables lock, - // or 0, to disable. To use this feature, Felix must share the iptables lock file with all other - // processes that also take the lock. When running Felix inside a container, this requires the - // /run directory of the host to be mounted into the calico/node or calico/felix container. - // [Default: 0s disabled] - IptablesLockTimeout *metav1.Duration `json:"iptablesLockTimeout,omitempty" configv1timescale:"seconds" confignamev1:"IptablesLockTimeoutSecs"` - // IptablesLockProbeInterval is the time that Felix will wait between - // attempts to acquire the iptables lock if it is not available. Lower values make Felix more - // responsive when the lock is contended, but use more CPU. [Default: 50ms] - IptablesLockProbeInterval *metav1.Duration `json:"iptablesLockProbeInterval,omitempty" configv1timescale:"milliseconds" confignamev1:"IptablesLockProbeIntervalMillis"` - // FeatureDetectOverride is used to override the feature detection. - // Values are specified in a comma separated list with no spaces, example; - // "SNATFullyRandom=true,MASQFullyRandom=false,RestoreSupportsLock=". - // "true" or "false" will force the feature, empty or omitted values are - // auto-detected. - FeatureDetectOverride string `json:"featureDetectOverride,omitempty" validate:"omitempty,keyValueList"` - // IpsetsRefreshInterval is the period at which Felix re-checks all iptables - // state to ensure that no other process has accidentally broken Calico’s rules. Set to 0 to - // disable iptables refresh. [Default: 90s] - IpsetsRefreshInterval *metav1.Duration `json:"ipsetsRefreshInterval,omitempty" configv1timescale:"seconds"` - MaxIpsetSize *int `json:"maxIpsetSize,omitempty"` - // IptablesBackend specifies which backend of iptables will be used. The default is legacy. - IptablesBackend *IptablesBackend `json:"iptablesBackend,omitempty" validate:"omitempty,iptablesBackend"` - - // XDPRefreshInterval is the period at which Felix re-checks all XDP state to ensure that no - // other process has accidentally broken Calico's BPF maps or attached programs. Set to 0 to - // disable XDP refresh. [Default: 90s] - XDPRefreshInterval *metav1.Duration `json:"xdpRefreshInterval,omitempty" configv1timescale:"seconds"` - - NetlinkTimeout *metav1.Duration `json:"netlinkTimeout,omitempty" configv1timescale:"seconds" confignamev1:"NetlinkTimeoutSecs"` - - // MetadataAddr is the IP address or domain name of the server that can answer VM queries for - // cloud-init metadata. In OpenStack, this corresponds to the machine running nova-api (or in - // Ubuntu, nova-api-metadata). A value of none (case insensitive) means that Felix should not - // set up any NAT rule for the metadata path. [Default: 127.0.0.1] - MetadataAddr string `json:"metadataAddr,omitempty"` - // MetadataPort is the port of the metadata server. This, combined with global.MetadataAddr (if - // not ‘None’), is used to set up a NAT rule, from 169.254.169.254:80 to MetadataAddr:MetadataPort. - // In most cases this should not need to be changed [Default: 8775]. - MetadataPort *int `json:"metadataPort,omitempty"` - - // OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region - // Calico/OpenStack deployment, this must be configured somehow for each Felix (here in the datamodel, - // or in felix.cfg or the environment on each compute node), and must match the [calico] - // openstack_region value configured in neutron.conf on each node. [Default: Empty] - OpenstackRegion string `json:"openstackRegion,omitempty"` - - // InterfacePrefix is the interface name prefix that identifies workload endpoints and so distinguishes - // them from host endpoint interfaces. Note: in environments other than bare metal, the orchestrators - // configure this appropriately. For example our Kubernetes and Docker integrations set the ‘cali’ value, - // and our OpenStack integration sets the ‘tap’ value. [Default: cali] - InterfacePrefix string `json:"interfacePrefix,omitempty"` - // InterfaceExclude is a comma-separated list of interfaces that Felix should exclude when monitoring for host - // endpoints. The default value ensures that Felix ignores Kubernetes' IPVS dummy interface, which is used - // internally by kube-proxy. If you want to exclude multiple interface names using a single value, the list - // supports regular expressions. For regular expressions you must wrap the value with '/'. For example - // having values '/^kube/,veth1' will exclude all interfaces that begin with 'kube' and also the interface - // 'veth1'. [Default: kube-ipvs0] - InterfaceExclude string `json:"interfaceExclude,omitempty"` - - // ChainInsertMode controls whether Felix hooks the kernel’s top-level iptables chains by inserting a rule - // at the top of the chain or by appending a rule at the bottom. insert is the safe default since it prevents - // Calico’s rules from being bypassed. If you switch to append mode, be sure that the other rules in the chains - // signal acceptance by falling through to the Calico rules, otherwise the Calico policy will be bypassed. - // [Default: insert] - ChainInsertMode string `json:"chainInsertMode,omitempty"` - // DefaultEndpointToHostAction controls what happens to traffic that goes from a workload endpoint to the host - // itself (after the traffic hits the endpoint egress policy). By default Calico blocks traffic from workload - // endpoints to the host itself with an iptables “DROP” action. If you want to allow some or all traffic from - // endpoint to host, set this parameter to RETURN or ACCEPT. Use RETURN if you have your own rules in the iptables - // “INPUT” chain; Calico will insert its rules at the top of that chain, then “RETURN” packets to the “INPUT” chain - // once it has completed processing workload endpoint egress policy. Use ACCEPT to unconditionally accept packets - // from workloads after processing workload endpoint egress policy. [Default: Drop] - DefaultEndpointToHostAction string `json:"defaultEndpointToHostAction,omitempty" validate:"omitempty,dropAcceptReturn"` - IptablesFilterAllowAction string `json:"iptablesFilterAllowAction,omitempty" validate:"omitempty,acceptReturn"` - IptablesMangleAllowAction string `json:"iptablesMangleAllowAction,omitempty" validate:"omitempty,acceptReturn"` - // LogPrefix is the log prefix that Felix uses when rendering LOG rules. [Default: calico-packet] - LogPrefix string `json:"logPrefix,omitempty"` - - // LogFilePath is the full path to the Felix log. Set to none to disable file logging. [Default: /var/log/calico/felix.log] - LogFilePath string `json:"logFilePath,omitempty"` - - // LogSeverityFile is the log severity above which logs are sent to the log file. [Default: Info] - LogSeverityFile string `json:"logSeverityFile,omitempty" validate:"omitempty,logLevel"` - // LogSeverityScreen is the log severity above which logs are sent to the stdout. [Default: Info] - LogSeverityScreen string `json:"logSeverityScreen,omitempty" validate:"omitempty,logLevel"` - // LogSeveritySys is the log severity above which logs are sent to the syslog. Set to None for no logging to syslog. - // [Default: Info] - LogSeveritySys string `json:"logSeveritySys,omitempty" validate:"omitempty,logLevel"` - - IPIPEnabled *bool `json:"ipipEnabled,omitempty" confignamev1:"IpInIpEnabled"` - // IPIPMTU is the MTU to set on the tunnel device. See Configuring MTU [Default: 1440] - IPIPMTU *int `json:"ipipMTU,omitempty" confignamev1:"IpInIpMtu"` - - VXLANEnabled *bool `json:"vxlanEnabled,omitempty"` - // VXLANMTU is the MTU to set on the tunnel device. See Configuring MTU [Default: 1440] - VXLANMTU *int `json:"vxlanMTU,omitempty"` - VXLANPort *int `json:"vxlanPort,omitempty"` - VXLANVNI *int `json:"vxlanVNI,omitempty"` - - // ReportingInterval is the interval at which Felix reports its status into the datastore or 0 to disable. - // Must be non-zero in OpenStack deployments. [Default: 30s] - ReportingInterval *metav1.Duration `json:"reportingInterval,omitempty" configv1timescale:"seconds" confignamev1:"ReportingIntervalSecs"` - // ReportingTTL is the time-to-live setting for process-wide status reports. [Default: 90s] - ReportingTTL *metav1.Duration `json:"reportingTTL,omitempty" configv1timescale:"seconds" confignamev1:"ReportingTTLSecs"` - - EndpointReportingEnabled *bool `json:"endpointReportingEnabled,omitempty"` - EndpointReportingDelay *metav1.Duration `json:"endpointReportingDelay,omitempty" configv1timescale:"seconds" confignamev1:"EndpointReportingDelaySecs"` - - // EndpointStatusPathPrefix is the path to the directory - // where endpoint status will be written. Endpoint status - // file reporting is disabled if field is left empty. - // - // Chosen directory should match the directory used by the CNI for PodStartupDelay. - // [Default: empty] - EndpointStatusPathPrefix *string `json:"endpointStatusPathPrefix,omitempty"` - - // IptablesMarkMask is the mask that Felix selects its IPTables Mark bits from. Should be a 32 bit hexadecimal - // number with at least 8 bits set, none of which clash with any other mark bits in use on the system. - // [Default: 0xff000000] - IptablesMarkMask *uint32 `json:"iptablesMarkMask,omitempty"` - - DisableConntrackInvalidCheck *bool `json:"disableConntrackInvalidCheck,omitempty"` - - HealthEnabled *bool `json:"healthEnabled,omitempty"` - HealthHost *string `json:"healthHost,omitempty"` - HealthPort *int `json:"healthPort,omitempty"` - - // CgroupV2Path overrides the default location where to find the cgroup hierarchy. - CgroupV2Path string `json:"cgroupV2Path,omitempty"` - - // PrometheusMetricsEnabled enables the Prometheus metrics server in Felix if set to true. [Default: false] - PrometheusMetricsEnabled *bool `json:"prometheusMetricsEnabled,omitempty"` - // PrometheusMetricsHost is the host that the Prometheus metrics server should bind to. [Default: empty] - PrometheusMetricsHost string `json:"prometheusMetricsHost,omitempty" validate:"omitempty,prometheusHost"` - // PrometheusMetricsPort is the TCP port that the Prometheus metrics server should bind to. [Default: 9091] - PrometheusMetricsPort *int `json:"prometheusMetricsPort,omitempty"` - // PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when - // set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true] - PrometheusGoMetricsEnabled *bool `json:"prometheusGoMetricsEnabled,omitempty"` - // PrometheusProcessMetricsEnabled disables process metrics collection, which the Prometheus client does by default, when - // set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true] - PrometheusProcessMetricsEnabled *bool `json:"prometheusProcessMetricsEnabled,omitempty"` - // PrometheusReporterPort specifies the TCP port on which to report denied packet metrics. - PrometheusReporterPort *int `json:"prometheusReporterPort,omitempty"` - - // FailsafeInboundHostPorts is a comma-delimited list of UDP/TCP ports and CIDRs that Felix will allow incoming traffic to host endpoints - // on irrespective of the security policy. This is useful to avoid accidentally cutting off a host with incorrect configuration. Each - // port should be specified as tcp:: or udp::. For back-compatibility, if the protocol is not specified, it - // defaults to "tcp". If a CIDR is not specified, it will default to `0.0.0.0/0`. To disable all inbound host ports, use the value none. - // The default value allows ssh access and DHCP. - // [Default: tcp:0.0.0.0/0:22, udp:0.0.0.0/0:68, tcp:0.0.0.0/0:179, tcp:0.0.0.0/0:2379, tcp:0.0.0.0/0:2380, tcp:0.0.0.0/0:6443, tcp:0.0.0.0/0:6666, tcp:0.0.0.0/0:6667] - FailsafeInboundHostPorts *[]ProtoPort `json:"failsafeInboundHostPorts,omitempty"` - // FailsafeOutboundHostPorts is a comma-delimited list of UDP/TCP ports and CIDRs that Felix will allow outgoing traffic from host endpoints to - // irrespective of the security policy. This is useful to avoid accidentally cutting off a host with incorrect configuration. Each port - // should be specified as tcp:: or udp::. For back-compatibility, if the protocol is not specified, it defaults - // to "tcp". If a CIDR is not specified, it will default to `0.0.0.0/0`. To disable all outbound host ports, use the value none. - // The default value opens etcd's standard ports to ensure that Felix does not get cut off from etcd as well as allowing DHCP and DNS. - // [Default: tcp:0.0.0.0/0:179, tcp:0.0.0.0/0:2379, tcp:0.0.0.0/0:2380, tcp:0.0.0.0/0:6443, tcp:0.0.0.0/0:6666, tcp:0.0.0.0/0:6667, udp:0.0.0.0/0:53, udp:0.0.0.0/0:67] - FailsafeOutboundHostPorts *[]ProtoPort `json:"failsafeOutboundHostPorts,omitempty"` - - // KubeNodePortRanges holds list of port ranges used for service node ports. Only used if felix detects kube-proxy running in ipvs mode. - // Felix uses these ranges to separate host and workload traffic. [Default: 30000:32767]. - KubeNodePortRanges *[]numorstring.Port `json:"kubeNodePortRanges,omitempty" validate:"omitempty,dive"` - - // PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services, - // like Application layer policy. [Default: Empty] - PolicySyncPathPrefix string `json:"policySyncPathPrefix,omitempty"` - - // UsageReportingEnabled reports anonymous Calico version number and cluster size to projectcalico.org. Logs warnings returned by the usage - // server. For example, if a significant security vulnerability has been discovered in the version of Calico being used. [Default: true] - UsageReportingEnabled *bool `json:"usageReportingEnabled,omitempty"` - // UsageReportingInitialDelay controls the minimum delay before Felix makes a report. [Default: 300s] - UsageReportingInitialDelay *metav1.Duration `json:"usageReportingInitialDelay,omitempty" configv1timescale:"seconds" confignamev1:"UsageReportingInitialDelaySecs"` - // UsageReportingInterval controls the interval at which Felix makes reports. [Default: 86400s] - UsageReportingInterval *metav1.Duration `json:"usageReportingInterval,omitempty" configv1timescale:"seconds" confignamev1:"UsageReportingIntervalSecs"` - - // NATPortRange specifies the range of ports that is used for port mapping when doing outgoing NAT. When unset the default behavior of the - // network stack is used. - NATPortRange *numorstring.Port `json:"natPortRange,omitempty"` - - // NATOutgoingAddress specifies an address to use when performing source NAT for traffic in a natOutgoing pool that - // is leaving the network. By default the address used is an address on the interface the traffic is leaving on - // (ie it uses the iptables MASQUERADE target) - NATOutgoingAddress string `json:"natOutgoingAddress,omitempty"` - - // This is the source address to use on programmed device routes. By default the source address is left blank, - // leaving the kernel to choose the source address used. - DeviceRouteSourceAddress string `json:"deviceRouteSourceAddress,omitempty"` - - // This defines the route protocol added to programmed device routes, by default this will be RTPROT_BOOT - // when left blank. - DeviceRouteProtocol *int `json:"deviceRouteProtocol,omitempty"` - // Whether or not to remove device routes that have not been programmed by Felix. Disabling this will allow external - // applications to also add device routes. This is enabled by default which means we will remove externally added routes. - RemoveExternalRoutes *bool `json:"removeExternalRoutes,omitempty"` - - // ExternalNodesCIDRList is a list of CIDR's of external-non-calico-nodes which may source tunnel traffic and have - // the tunneled traffic be accepted at calico nodes. - ExternalNodesCIDRList *[]string `json:"externalNodesList,omitempty"` - - DebugMemoryProfilePath string `json:"debugMemoryProfilePath,omitempty"` - DebugDisableLogDropping *bool `json:"debugDisableLogDropping,omitempty"` - DebugSimulateCalcGraphHangAfter *metav1.Duration `json:"debugSimulateCalcGraphHangAfter,omitempty" configv1timescale:"seconds"` - DebugSimulateDataplaneHangAfter *metav1.Duration `json:"debugSimulateDataplaneHangAfter,omitempty" configv1timescale:"seconds"` - - IptablesNATOutgoingInterfaceFilter string `json:"iptablesNATOutgoingInterfaceFilter,omitempty" validate:"omitempty,ifaceFilter"` - - // SidecarAccelerationEnabled enables experimental sidecar acceleration [Default: false] - SidecarAccelerationEnabled *bool `json:"sidecarAccelerationEnabled,omitempty"` - - // XDPEnabled enables XDP acceleration for suitable untracked incoming deny rules. [Default: true] - XDPEnabled *bool `json:"xdpEnabled,omitempty" confignamev1:"XDPEnabled"` - - // GenericXDPEnabled enables Generic XDP so network cards that don't support XDP offload or driver - // modes can use XDP. This is not recommended since it doesn't provide better performance than - // iptables. [Default: false] - GenericXDPEnabled *bool `json:"genericXDPEnabled,omitempty" confignamev1:"GenericXDPEnabled"` - - // NFTablesMode configures nftables support in Felix. [Default: Disabled] - NFTablesMode *NFTablesMode `json:"nftablesMode,omitempty"` - - // BPFEnabled, if enabled Felix will use the BPF dataplane. [Default: false] - BPFEnabled *bool `json:"bpfEnabled,omitempty" validate:"omitempty"` - // BPFDisableUnprivileged, if enabled, Felix sets the kernel.unprivileged_bpf_disabled sysctl to disable - // unprivileged use of BPF. This ensures that unprivileged users cannot access Calico's BPF maps and - // cannot insert their own BPF programs to interfere with Calico's. [Default: true] - BPFDisableUnprivileged *bool `json:"bpfDisableUnprivileged,omitempty" validate:"omitempty"` - // BPFLogLevel controls the log level of the BPF programs when in BPF dataplane mode. One of "Off", "Info", or - // "Debug". The logs are emitted to the BPF trace pipe, accessible with the command `tc exec bpf debug`. - // [Default: Off]. - // +optional - BPFLogLevel string `json:"bpfLogLevel" validate:"omitempty,bpfLogLevel"` - // BPFDataIfacePattern is a regular expression that controls which interfaces Felix should attach BPF programs to - // in order to catch traffic to/from the network. This needs to match the interfaces that Calico workload traffic - // flows over as well as any interfaces that handle incoming traffic to nodeports and services from outside the - // cluster. It should not match the workload interfaces (usually named cali...). - // [Default: ^(en.*|eth.*|tunl0$)] - BPFDataIfacePattern string `json:"bpfDataIfacePattern,omitempty" validate:"omitempty,regexp"` - // BPFConnectTimeLoadBalancingEnabled when in BPF mode, controls whether Felix installs the connection-time load - // balancer. The connect-time load balancer is required for the host to be able to reach Kubernetes services - // and it improves the performance of pod-to-service connections. The only reason to disable it is for debugging - // purposes. [Default: true] - BPFConnectTimeLoadBalancingEnabled *bool `json:"bpfConnectTimeLoadBalancingEnabled,omitempty" validate:"omitempty"` - // BPFExternalServiceMode in BPF mode, controls how connections from outside the cluster to services (node ports - // and cluster IPs) are forwarded to remote workloads. If set to "Tunnel" then both request and response traffic - // is tunneled to the remote node. If set to "DSR", the request traffic is tunneled but the response traffic - // is sent directly from the remote node. In "DSR" mode, the remote node appears to use the IP of the ingress - // node; this requires a permissive L2 network. [Default: Tunnel] - BPFExternalServiceMode string `json:"bpfExternalServiceMode,omitempty" validate:"omitempty,bpfServiceMode"` - // BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF mode, Felix will proactively clean up the upstream - // Kubernetes kube-proxy's iptables chains. Should only be enabled if kube-proxy is not running. [Default: true] - BPFKubeProxyIptablesCleanupEnabled *bool `json:"bpfKubeProxyIptablesCleanupEnabled,omitempty" validate:"omitempty"` - // BPFKubeProxyMinSyncPeriod, in BPF mode, controls the minimum time between updates to the dataplane for Felix's - // embedded kube-proxy. Lower values give reduced set-up latency. Higher values reduce Felix CPU usage by - // batching up more work. [Default: 1s] - BPFKubeProxyMinSyncPeriod *metav1.Duration `json:"bpfKubeProxyMinSyncPeriod,omitempty" validate:"omitempty" configv1timescale:"seconds"` - // BPFKubeProxyEndpointSlicesEnabled in BPF mode, controls whether Felix's - // embedded kube-proxy accepts EndpointSlices or not. - BPFKubeProxyEndpointSlicesEnabled *bool `json:"bpfKubeProxyEndpointSlicesEnabled,omitempty" validate:"omitempty"` - // BPFHostConntrackBypass Controls whether to bypass Linux conntrack in BPF mode for - // workloads and services. [Default: true - bypass Linux conntrack] - BPFHostConntrackBypass *bool `json:"bpfHostConntrackBypass,omitempty"` - - // RouteSource configures where Felix gets its routing information. - // - WorkloadIPs: use workload endpoints to construct routes. - // - CalicoIPAM: the default - use IPAM data to construct routes. - RouteSource string `json:"routeSource,omitempty" validate:"omitempty,routeSource"` - - // Calico programs additional Linux route tables for various purposes. RouteTableRange - // specifies the indices of the route tables that Calico should use. - RouteTableRange *RouteTableRange `json:"routeTableRange,omitempty" validate:"omitempty"` - - // WireguardEnabled controls whether Wireguard is enabled for IPv4 (encapsulating IPv4 traffic over an IPv4 underlay network). [Default: false] - WireguardEnabled *bool `json:"wireguardEnabled,omitempty"` - // WireguardEnabledV6 controls whether Wireguard is enabled for IPv6 (encapsulating IPv6 traffic over an IPv6 underlay network). [Default: false] - WireguardEnabledV6 *bool `json:"wireguardEnabledV6,omitempty"` - // WireguardListeningPort controls the listening port used by IPv4 Wireguard. [Default: 51820] - WireguardListeningPort *int `json:"wireguardListeningPort,omitempty" validate:"omitempty,gt=0,lte=65535"` - // WireguardListeningPortV6 controls the listening port used by IPv6 Wireguard. [Default: 51821] - WireguardListeningPortV6 *int `json:"wireguardListeningPortV6,omitempty" validate:"omitempty,gt=0,lte=65535"` - // WireguardRoutingRulePriority controls the priority value to use for the Wireguard routing rule. [Default: 99] - WireguardRoutingRulePriority *int `json:"wireguardRoutingRulePriority,omitempty" validate:"omitempty,gt=0,lt=32766"` - // WireguardInterfaceName specifies the name to use for the IPv4 Wireguard interface. [Default: wireguard.cali] - WireguardInterfaceName string `json:"wireguardInterfaceName,omitempty" validate:"omitempty,interface"` - // WireguardInterfaceNameV6 specifies the name to use for the IPv6 Wireguard interface. [Default: wg-v6.cali] - WireguardInterfaceNameV6 string `json:"wireguardInterfaceNameV6,omitempty" validate:"omitempty,interface"` - // WireguardMTU controls the MTU on the IPv4 Wireguard interface. See Configuring MTU [Default: 1440] - WireguardMTU *int `json:"wireguardMTU,omitempty"` - // WireguardMTUV6 controls the MTU on the IPv6 Wireguard interface. See Configuring MTU [Default: 1420] - WireguardMTUV6 *int `json:"wireguardMTUV6,omitempty"` - // WireguardHostEncryptionEnabled controls whether Wireguard host-to-host encryption is enabled. [Default: false] - WireguardHostEncryptionEnabled *bool `json:"wireguardHostEncryptionEnabled,omitempty"` - // WireguardKeepAlive controls Wireguard PersistentKeepalive option. Set 0 to disable. [Default: 0] - WireguardPersistentKeepAlive *metav1.Duration `json:"wireguardKeepAlive,omitempty"` - - // Set source-destination-check on AWS EC2 instances. Accepted value must be one of "DoNothing", "Enabled" or "Disabled". - // [Default: DoNothing] - AWSSrcDstCheck *AWSSrcDstCheckOption `json:"awsSrcDstCheck,omitempty" validate:"omitempty,oneof=DoNothing Enable Disable"` - - // TPROXYMode sets whether traffic is directed through a transparent proxy for further processing or not - // [Default: Disabled] - TPROXYMode *TPROXYModeOption `json:"tproxyMode,omitempty"` - - // EgressIPVXLANPort is the port number of vxlan tunnel device for egress traffic. [Default: 4790] - EgressIPVXLANPort *int `json:"egressIPVXLANPort,omitempty"` - // EgressIPVXLANVNI is the VNI ID of vxlan tunnel device for egress traffic. [Default: 4097] - EgressIPVXLANVNI *int `json:"egressIPVXLANVNI,omitempty"` - - // The DNS servers that Felix should trust. Each entry here must be `[:]` - indicating an - // explicit DNS server IP - or `k8s-service:[/][:port]` - indicating a Kubernetes DNS - // service. `` defaults to the first service port, or 53 for an IP, and `` to - // `kube-system`. An IPv6 address with a port must use the square brackets convention, for example - // `[fd00:83a6::12]:5353`.Note that Felix (calico-node) will need RBAC permission to read the details of - // each service specified by a `k8s-service:...` form. [Default: "k8s-service:kube-dns"]. - DNSTrustedServers *[]string `json:"dnsTrustedServers,omitempty"` - - // WAFEventLogsFileEnabled controls logging WAFEvent logs to a file. If false no WAFEvent logging to file will occur. - // [Default: false] - WAFEventLogsFileEnabled *bool `json:"wafEventLogsFileEnabled,omitempty"` -} - -type RouteTableRange struct { - Min int `json:"min"` - Max int `json:"max"` -} - -// ProtoPort is combination of protocol, port, and CIDR. All three must be specified. -type ProtoPort struct { - Protocol string `json:"protocol"` - Port uint16 `json:"port"` - Net string `json:"net"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// FelixConfigurationList contains a list of FelixConfigurationList resources. -type FelixConfigurationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - Items []FelixConfiguration `json:"items"` -} diff --git a/pkg/apis/crd.projectcalico.org/v1/ippool.go b/pkg/apis/crd.projectcalico.org/v1/ippool.go deleted file mode 100644 index 05b275d3f9..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/ippool.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2020-2025 Tigera, Inc. All rights reserved. - -// 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 v1 - -import ( - operatorv1 "github.com/tigera/operator/api/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - KindIPPool = "IPPool" - KindIPPoolList = "IPPoolList" -) - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// IPPool contains information about an IPPool resource. -type IPPool struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata. - metav1.ObjectMeta `json:"metadata,omitempty"` - // Specification of the IPPool. - Spec IPPoolSpec `json:"spec,omitempty"` -} - -// IPPoolSpec contains the specification for an IPPool resource. -type IPPoolSpec struct { - // The pool CIDR. - CIDR string `json:"cidr" validate:"net"` - - // Contains configuration for VXLAN tunneling for this pool. If not specified, - // then this is defaulted to "Never" (i.e. VXLAN tunelling is disabled). - VXLANMode VXLANMode `json:"vxlanMode,omitempty" validate:"omitempty,vxlanMode"` - - // Contains configuration for IPIP tunneling for this pool. If not specified, - // then this is defaulted to "Never" (i.e. IPIP tunelling is disabled). - IPIPMode IPIPMode `json:"ipipMode,omitempty" validate:"omitempty,ipIpMode"` - - // When nat-outgoing is true, packets sent from Calico networked containers in - // this pool to destinations outside of this pool will be masqueraded. - NATOutgoing bool `json:"natOutgoing,omitempty"` - - // When disabled is true, Calico IPAM will not assign addresses from this pool. - Disabled bool `json:"disabled,omitempty"` - - // Disable exporting routes from this IP Pool's CIDR over BGP. [Default: false] - DisableBGPExport bool `json:"disableBGPExport,omitempty" validate:"omitempty"` - - // The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 112 for IPv6. - BlockSize int `json:"blockSize,omitempty"` - - // Allows IPPool to allocate for a specific node by label selector. - NodeSelector string `json:"nodeSelector,omitempty" validate:"omitempty,selector"` - - // AWSSubnetID if specified Calico will attempt to ensure that IPs chosen from this IP pool are routed - // to the corresponding node by adding one or more secondary ENIs to the node and explicitly assigning - // the IP to one of the secondary ENIs. Important: since subnets cannot cross availability zones, - // it's important to use Kubernetes node selectors to avoid scheduling pods to one availability zone - // using an IP pool that is backed by a subnet that belongs to another availability zone. If AWSSubnetID - // is specified, then the CIDR of the IP pool must be contained within the specified AWS subnet. - AWSSubnetID string `json:"awsSubnetID,omitempty" validate:"omitempty"` - - // AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to - // ["Tunnel", "Workload"] for back-compatibility - AllowedUses []IPPoolAllowedUse `json:"allowedUses,omitempty" validate:"omitempty"` - - // AssignmentMode determines if IP addresses from this pool should be assigned automatically or on request only - AssignmentMode operatorv1.AssignmentMode `json:"assignmentMode,omitempty" validate:"omitempty,assignmentMode"` -} - -type IPPoolAllowedUse string - -const ( - IPPoolAllowedUseWorkload IPPoolAllowedUse = "Workload" - IPPoolAllowedUseTunnel IPPoolAllowedUse = "Tunnel" - IPPoolsAllowedUseLoadBalancer IPPoolAllowedUse = "LoadBalancer" -) - -type VXLANMode string - -const ( - VXLANModeNever VXLANMode = "Never" - VXLANModeAlways VXLANMode = "Always" - VXLANModeCrossSubnet VXLANMode = "CrossSubnet" -) - -type IPIPMode string - -const ( - IPIPModeNever IPIPMode = "Never" - IPIPModeAlways IPIPMode = "Always" - IPIPModeCrossSubnet IPIPMode = "CrossSubnet" -) - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// IPPoolList contains a list of IPPool resources. -type IPPoolList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - Items []IPPool `json:"items"` -} - -// NewIPPool creates a new (zeroed) IPPool struct with the TypeMetadata initialised to the current -// version. -func NewIPPool() *IPPool { - return &IPPool{ - TypeMeta: metav1.TypeMeta{ - Kind: KindIPPool, - APIVersion: "crd.projectcalico.org/v1", - }, - } -} - -// NewIPPoolList creates a new (zeroed) IPPoolList struct with the TypeMetadata initialised to the current -// version. -func NewIPPoolList() *IPPoolList { - return &IPPoolList{ - TypeMeta: metav1.TypeMeta{ - Kind: KindIPPoolList, - APIVersion: "crd.projectcalico.org/v1", - }, - } -} diff --git a/pkg/apis/crd.projectcalico.org/v1/kubecontrollersconfiguration.go b/pkg/apis/crd.projectcalico.org/v1/kubecontrollersconfiguration.go deleted file mode 100644 index 0e964c09da..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/kubecontrollersconfiguration.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. - -// 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 v1 - -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// KubeControllersConfiguration contains the configuration for Calico Kubernetes Controllers. -type KubeControllersConfiguration struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - Spec KubeControllersConfigurationSpec `json:"spec,omitempty"` -} - -// KubeControllersConfigurationSpec contains the values of the Kubernetes controllers configuration. -type KubeControllersConfigurationSpec struct { - // PrometheusMetricsPort is the TCP port that the Prometheus metrics server should bind to. Set to 0 to disable. [Default: 9094] - PrometheusMetricsPort *int `json:"prometheusMetricsPort,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// KubeControllersConfigurationList contains a list of KubeControllersConfiguration resources. -type KubeControllersConfigurationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - Items []KubeControllersConfiguration `json:"items"` -} diff --git a/pkg/apis/crd.projectcalico.org/v1/register.go b/pkg/apis/crd.projectcalico.org/v1/register.go deleted file mode 100644 index 5230891713..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/register.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2023-2025 Tigera, Inc. All rights reserved. - -// 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 v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -// GroupName is the group name use in this package -const GroupName = "crd.projectcalico.org" - -// SchemeGroupVersion is group version used to register these objects - -var ( - SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme -) - -func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - &IPPool{}, - &IPPoolList{}, - &FelixConfiguration{}, - &FelixConfigurationList{}, - &KubeControllersConfiguration{}, - &KubeControllersConfigurationList{}, - &BGPConfiguration{}, - &BGPConfigurationList{}, - &ExternalNetwork{}, - &ExternalNetworkList{}, - &ClusterInformation{}, - &ClusterInformationList{}, - ) - metav1.AddToGroupVersion(scheme, SchemeGroupVersion) - return nil -} diff --git a/pkg/apis/crd.projectcalico.org/v1/zz_generated.deepcopy.go b/pkg/apis/crd.projectcalico.org/v1/zz_generated.deepcopy.go deleted file mode 100644 index e60842390f..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,1059 +0,0 @@ -//go:build !ignore_autogenerated - -// Copyright (c) 2024 Tigera, Inc. All rights reserved. -/* - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1 - -import ( - "github.com/projectcalico/api/pkg/lib/numorstring" - libnumorstring "github.com/tigera/api/pkg/lib/numorstring" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BGPConfiguration) DeepCopyInto(out *BGPConfiguration) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BGPConfiguration. -func (in *BGPConfiguration) DeepCopy() *BGPConfiguration { - if in == nil { - return nil - } - out := new(BGPConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BGPConfiguration) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BGPConfigurationList) DeepCopyInto(out *BGPConfigurationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]BGPConfiguration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BGPConfigurationList. -func (in *BGPConfigurationList) DeepCopy() *BGPConfigurationList { - if in == nil { - return nil - } - out := new(BGPConfigurationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BGPConfigurationList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BGPConfigurationSpec) DeepCopyInto(out *BGPConfigurationSpec) { - *out = *in - if in.NodeToNodeMeshEnabled != nil { - in, out := &in.NodeToNodeMeshEnabled, &out.NodeToNodeMeshEnabled - *out = new(bool) - **out = **in - } - if in.ASNumber != nil { - in, out := &in.ASNumber, &out.ASNumber - *out = new(numorstring.ASNumber) - **out = **in - } - if in.ServiceLoadBalancerIPs != nil { - in, out := &in.ServiceLoadBalancerIPs, &out.ServiceLoadBalancerIPs - *out = make([]ServiceLoadBalancerIPBlock, len(*in)) - copy(*out, *in) - } - if in.ServiceExternalIPs != nil { - in, out := &in.ServiceExternalIPs, &out.ServiceExternalIPs - *out = make([]ServiceExternalIPBlock, len(*in)) - copy(*out, *in) - } - if in.ServiceClusterIPs != nil { - in, out := &in.ServiceClusterIPs, &out.ServiceClusterIPs - *out = make([]ServiceClusterIPBlock, len(*in)) - copy(*out, *in) - } - if in.Communities != nil { - in, out := &in.Communities, &out.Communities - *out = make([]Community, len(*in)) - copy(*out, *in) - } - if in.PrefixAdvertisements != nil { - in, out := &in.PrefixAdvertisements, &out.PrefixAdvertisements - *out = make([]PrefixAdvertisement, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.NodeMeshPassword != nil { - in, out := &in.NodeMeshPassword, &out.NodeMeshPassword - *out = new(BGPPassword) - (*in).DeepCopyInto(*out) - } - if in.NodeMeshMaxRestartTime != nil { - in, out := &in.NodeMeshMaxRestartTime, &out.NodeMeshMaxRestartTime - *out = new(metav1.Duration) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BGPConfigurationSpec. -func (in *BGPConfigurationSpec) DeepCopy() *BGPConfigurationSpec { - if in == nil { - return nil - } - out := new(BGPConfigurationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BGPPassword) DeepCopyInto(out *BGPPassword) { - *out = *in - if in.SecretKeyRef != nil { - in, out := &in.SecretKeyRef, &out.SecretKeyRef - *out = new(corev1.SecretKeySelector) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BGPPassword. -func (in *BGPPassword) DeepCopy() *BGPPassword { - if in == nil { - return nil - } - out := new(BGPPassword) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterInformation) DeepCopyInto(out *ClusterInformation) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterInformation. -func (in *ClusterInformation) DeepCopy() *ClusterInformation { - if in == nil { - return nil - } - out := new(ClusterInformation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterInformation) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterInformationList) DeepCopyInto(out *ClusterInformationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ClusterInformation, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterInformationList. -func (in *ClusterInformationList) DeepCopy() *ClusterInformationList { - if in == nil { - return nil - } - out := new(ClusterInformationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterInformationList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterInformationSpec) DeepCopyInto(out *ClusterInformationSpec) { - *out = *in - if in.DatastoreReady != nil { - in, out := &in.DatastoreReady, &out.DatastoreReady - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterInformationSpec. -func (in *ClusterInformationSpec) DeepCopy() *ClusterInformationSpec { - if in == nil { - return nil - } - out := new(ClusterInformationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Community) DeepCopyInto(out *Community) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Community. -func (in *Community) DeepCopy() *Community { - if in == nil { - return nil - } - out := new(Community) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalNetwork) DeepCopyInto(out *ExternalNetwork) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalNetwork. -func (in *ExternalNetwork) DeepCopy() *ExternalNetwork { - if in == nil { - return nil - } - out := new(ExternalNetwork) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ExternalNetwork) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalNetworkList) DeepCopyInto(out *ExternalNetworkList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ExternalNetwork, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalNetworkList. -func (in *ExternalNetworkList) DeepCopy() *ExternalNetworkList { - if in == nil { - return nil - } - out := new(ExternalNetworkList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ExternalNetworkList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalNetworkSpec) DeepCopyInto(out *ExternalNetworkSpec) { - *out = *in - if in.RouteTableIndex != nil { - in, out := &in.RouteTableIndex, &out.RouteTableIndex - *out = new(uint32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalNetworkSpec. -func (in *ExternalNetworkSpec) DeepCopy() *ExternalNetworkSpec { - if in == nil { - return nil - } - out := new(ExternalNetworkSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FelixConfiguration) DeepCopyInto(out *FelixConfiguration) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FelixConfiguration. -func (in *FelixConfiguration) DeepCopy() *FelixConfiguration { - if in == nil { - return nil - } - out := new(FelixConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *FelixConfiguration) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FelixConfigurationList) DeepCopyInto(out *FelixConfigurationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]FelixConfiguration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FelixConfigurationList. -func (in *FelixConfigurationList) DeepCopy() *FelixConfigurationList { - if in == nil { - return nil - } - out := new(FelixConfigurationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *FelixConfigurationList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FelixConfigurationSpec) DeepCopyInto(out *FelixConfigurationSpec) { - *out = *in - if in.UseInternalDataplaneDriver != nil { - in, out := &in.UseInternalDataplaneDriver, &out.UseInternalDataplaneDriver - *out = new(bool) - **out = **in - } - if in.IPv6Support != nil { - in, out := &in.IPv6Support, &out.IPv6Support - *out = new(bool) - **out = **in - } - if in.RouteRefreshInterval != nil { - in, out := &in.RouteRefreshInterval, &out.RouteRefreshInterval - *out = new(metav1.Duration) - **out = **in - } - if in.InterfaceRefreshInterval != nil { - in, out := &in.InterfaceRefreshInterval, &out.InterfaceRefreshInterval - *out = new(metav1.Duration) - **out = **in - } - if in.IptablesRefreshInterval != nil { - in, out := &in.IptablesRefreshInterval, &out.IptablesRefreshInterval - *out = new(metav1.Duration) - **out = **in - } - if in.IptablesPostWriteCheckInterval != nil { - in, out := &in.IptablesPostWriteCheckInterval, &out.IptablesPostWriteCheckInterval - *out = new(metav1.Duration) - **out = **in - } - if in.IptablesLockTimeout != nil { - in, out := &in.IptablesLockTimeout, &out.IptablesLockTimeout - *out = new(metav1.Duration) - **out = **in - } - if in.IptablesLockProbeInterval != nil { - in, out := &in.IptablesLockProbeInterval, &out.IptablesLockProbeInterval - *out = new(metav1.Duration) - **out = **in - } - if in.IpsetsRefreshInterval != nil { - in, out := &in.IpsetsRefreshInterval, &out.IpsetsRefreshInterval - *out = new(metav1.Duration) - **out = **in - } - if in.MaxIpsetSize != nil { - in, out := &in.MaxIpsetSize, &out.MaxIpsetSize - *out = new(int) - **out = **in - } - if in.IptablesBackend != nil { - in, out := &in.IptablesBackend, &out.IptablesBackend - *out = new(IptablesBackend) - **out = **in - } - if in.XDPRefreshInterval != nil { - in, out := &in.XDPRefreshInterval, &out.XDPRefreshInterval - *out = new(metav1.Duration) - **out = **in - } - if in.NetlinkTimeout != nil { - in, out := &in.NetlinkTimeout, &out.NetlinkTimeout - *out = new(metav1.Duration) - **out = **in - } - if in.MetadataPort != nil { - in, out := &in.MetadataPort, &out.MetadataPort - *out = new(int) - **out = **in - } - if in.IPIPEnabled != nil { - in, out := &in.IPIPEnabled, &out.IPIPEnabled - *out = new(bool) - **out = **in - } - if in.IPIPMTU != nil { - in, out := &in.IPIPMTU, &out.IPIPMTU - *out = new(int) - **out = **in - } - if in.VXLANEnabled != nil { - in, out := &in.VXLANEnabled, &out.VXLANEnabled - *out = new(bool) - **out = **in - } - if in.VXLANMTU != nil { - in, out := &in.VXLANMTU, &out.VXLANMTU - *out = new(int) - **out = **in - } - if in.VXLANPort != nil { - in, out := &in.VXLANPort, &out.VXLANPort - *out = new(int) - **out = **in - } - if in.VXLANVNI != nil { - in, out := &in.VXLANVNI, &out.VXLANVNI - *out = new(int) - **out = **in - } - if in.ReportingInterval != nil { - in, out := &in.ReportingInterval, &out.ReportingInterval - *out = new(metav1.Duration) - **out = **in - } - if in.ReportingTTL != nil { - in, out := &in.ReportingTTL, &out.ReportingTTL - *out = new(metav1.Duration) - **out = **in - } - if in.EndpointReportingEnabled != nil { - in, out := &in.EndpointReportingEnabled, &out.EndpointReportingEnabled - *out = new(bool) - **out = **in - } - if in.EndpointReportingDelay != nil { - in, out := &in.EndpointReportingDelay, &out.EndpointReportingDelay - *out = new(metav1.Duration) - **out = **in - } - if in.EndpointStatusPathPrefix != nil { - in, out := &in.EndpointStatusPathPrefix, &out.EndpointStatusPathPrefix - *out = new(string) - **out = **in - } - if in.IptablesMarkMask != nil { - in, out := &in.IptablesMarkMask, &out.IptablesMarkMask - *out = new(uint32) - **out = **in - } - if in.DisableConntrackInvalidCheck != nil { - in, out := &in.DisableConntrackInvalidCheck, &out.DisableConntrackInvalidCheck - *out = new(bool) - **out = **in - } - if in.HealthEnabled != nil { - in, out := &in.HealthEnabled, &out.HealthEnabled - *out = new(bool) - **out = **in - } - if in.HealthHost != nil { - in, out := &in.HealthHost, &out.HealthHost - *out = new(string) - **out = **in - } - if in.HealthPort != nil { - in, out := &in.HealthPort, &out.HealthPort - *out = new(int) - **out = **in - } - if in.PrometheusMetricsEnabled != nil { - in, out := &in.PrometheusMetricsEnabled, &out.PrometheusMetricsEnabled - *out = new(bool) - **out = **in - } - if in.PrometheusMetricsPort != nil { - in, out := &in.PrometheusMetricsPort, &out.PrometheusMetricsPort - *out = new(int) - **out = **in - } - if in.PrometheusGoMetricsEnabled != nil { - in, out := &in.PrometheusGoMetricsEnabled, &out.PrometheusGoMetricsEnabled - *out = new(bool) - **out = **in - } - if in.PrometheusProcessMetricsEnabled != nil { - in, out := &in.PrometheusProcessMetricsEnabled, &out.PrometheusProcessMetricsEnabled - *out = new(bool) - **out = **in - } - if in.PrometheusReporterPort != nil { - in, out := &in.PrometheusReporterPort, &out.PrometheusReporterPort - *out = new(int) - **out = **in - } - if in.FailsafeInboundHostPorts != nil { - in, out := &in.FailsafeInboundHostPorts, &out.FailsafeInboundHostPorts - *out = new([]ProtoPort) - if **in != nil { - in, out := *in, *out - *out = make([]ProtoPort, len(*in)) - copy(*out, *in) - } - } - if in.FailsafeOutboundHostPorts != nil { - in, out := &in.FailsafeOutboundHostPorts, &out.FailsafeOutboundHostPorts - *out = new([]ProtoPort) - if **in != nil { - in, out := *in, *out - *out = make([]ProtoPort, len(*in)) - copy(*out, *in) - } - } - if in.KubeNodePortRanges != nil { - in, out := &in.KubeNodePortRanges, &out.KubeNodePortRanges - *out = new([]libnumorstring.Port) - if **in != nil { - in, out := *in, *out - *out = make([]libnumorstring.Port, len(*in)) - copy(*out, *in) - } - } - if in.UsageReportingEnabled != nil { - in, out := &in.UsageReportingEnabled, &out.UsageReportingEnabled - *out = new(bool) - **out = **in - } - if in.UsageReportingInitialDelay != nil { - in, out := &in.UsageReportingInitialDelay, &out.UsageReportingInitialDelay - *out = new(metav1.Duration) - **out = **in - } - if in.UsageReportingInterval != nil { - in, out := &in.UsageReportingInterval, &out.UsageReportingInterval - *out = new(metav1.Duration) - **out = **in - } - if in.NATPortRange != nil { - in, out := &in.NATPortRange, &out.NATPortRange - *out = new(libnumorstring.Port) - **out = **in - } - if in.DeviceRouteProtocol != nil { - in, out := &in.DeviceRouteProtocol, &out.DeviceRouteProtocol - *out = new(int) - **out = **in - } - if in.RemoveExternalRoutes != nil { - in, out := &in.RemoveExternalRoutes, &out.RemoveExternalRoutes - *out = new(bool) - **out = **in - } - if in.ExternalNodesCIDRList != nil { - in, out := &in.ExternalNodesCIDRList, &out.ExternalNodesCIDRList - *out = new([]string) - if **in != nil { - in, out := *in, *out - *out = make([]string, len(*in)) - copy(*out, *in) - } - } - if in.DebugDisableLogDropping != nil { - in, out := &in.DebugDisableLogDropping, &out.DebugDisableLogDropping - *out = new(bool) - **out = **in - } - if in.DebugSimulateCalcGraphHangAfter != nil { - in, out := &in.DebugSimulateCalcGraphHangAfter, &out.DebugSimulateCalcGraphHangAfter - *out = new(metav1.Duration) - **out = **in - } - if in.DebugSimulateDataplaneHangAfter != nil { - in, out := &in.DebugSimulateDataplaneHangAfter, &out.DebugSimulateDataplaneHangAfter - *out = new(metav1.Duration) - **out = **in - } - if in.SidecarAccelerationEnabled != nil { - in, out := &in.SidecarAccelerationEnabled, &out.SidecarAccelerationEnabled - *out = new(bool) - **out = **in - } - if in.XDPEnabled != nil { - in, out := &in.XDPEnabled, &out.XDPEnabled - *out = new(bool) - **out = **in - } - if in.GenericXDPEnabled != nil { - in, out := &in.GenericXDPEnabled, &out.GenericXDPEnabled - *out = new(bool) - **out = **in - } - if in.NFTablesMode != nil { - in, out := &in.NFTablesMode, &out.NFTablesMode - *out = new(NFTablesMode) - **out = **in - } - if in.BPFEnabled != nil { - in, out := &in.BPFEnabled, &out.BPFEnabled - *out = new(bool) - **out = **in - } - if in.BPFDisableUnprivileged != nil { - in, out := &in.BPFDisableUnprivileged, &out.BPFDisableUnprivileged - *out = new(bool) - **out = **in - } - if in.BPFConnectTimeLoadBalancingEnabled != nil { - in, out := &in.BPFConnectTimeLoadBalancingEnabled, &out.BPFConnectTimeLoadBalancingEnabled - *out = new(bool) - **out = **in - } - if in.BPFKubeProxyIptablesCleanupEnabled != nil { - in, out := &in.BPFKubeProxyIptablesCleanupEnabled, &out.BPFKubeProxyIptablesCleanupEnabled - *out = new(bool) - **out = **in - } - if in.BPFKubeProxyMinSyncPeriod != nil { - in, out := &in.BPFKubeProxyMinSyncPeriod, &out.BPFKubeProxyMinSyncPeriod - *out = new(metav1.Duration) - **out = **in - } - if in.BPFKubeProxyEndpointSlicesEnabled != nil { - in, out := &in.BPFKubeProxyEndpointSlicesEnabled, &out.BPFKubeProxyEndpointSlicesEnabled - *out = new(bool) - **out = **in - } - if in.BPFHostConntrackBypass != nil { - in, out := &in.BPFHostConntrackBypass, &out.BPFHostConntrackBypass - *out = new(bool) - **out = **in - } - if in.RouteTableRange != nil { - in, out := &in.RouteTableRange, &out.RouteTableRange - *out = new(RouteTableRange) - **out = **in - } - if in.WireguardEnabled != nil { - in, out := &in.WireguardEnabled, &out.WireguardEnabled - *out = new(bool) - **out = **in - } - if in.WireguardEnabledV6 != nil { - in, out := &in.WireguardEnabledV6, &out.WireguardEnabledV6 - *out = new(bool) - **out = **in - } - if in.WireguardListeningPort != nil { - in, out := &in.WireguardListeningPort, &out.WireguardListeningPort - *out = new(int) - **out = **in - } - if in.WireguardListeningPortV6 != nil { - in, out := &in.WireguardListeningPortV6, &out.WireguardListeningPortV6 - *out = new(int) - **out = **in - } - if in.WireguardRoutingRulePriority != nil { - in, out := &in.WireguardRoutingRulePriority, &out.WireguardRoutingRulePriority - *out = new(int) - **out = **in - } - if in.WireguardMTU != nil { - in, out := &in.WireguardMTU, &out.WireguardMTU - *out = new(int) - **out = **in - } - if in.WireguardMTUV6 != nil { - in, out := &in.WireguardMTUV6, &out.WireguardMTUV6 - *out = new(int) - **out = **in - } - if in.WireguardHostEncryptionEnabled != nil { - in, out := &in.WireguardHostEncryptionEnabled, &out.WireguardHostEncryptionEnabled - *out = new(bool) - **out = **in - } - if in.WireguardPersistentKeepAlive != nil { - in, out := &in.WireguardPersistentKeepAlive, &out.WireguardPersistentKeepAlive - *out = new(metav1.Duration) - **out = **in - } - if in.AWSSrcDstCheck != nil { - in, out := &in.AWSSrcDstCheck, &out.AWSSrcDstCheck - *out = new(AWSSrcDstCheckOption) - **out = **in - } - if in.TPROXYMode != nil { - in, out := &in.TPROXYMode, &out.TPROXYMode - *out = new(TPROXYModeOption) - **out = **in - } - if in.EgressIPVXLANPort != nil { - in, out := &in.EgressIPVXLANPort, &out.EgressIPVXLANPort - *out = new(int) - **out = **in - } - if in.EgressIPVXLANVNI != nil { - in, out := &in.EgressIPVXLANVNI, &out.EgressIPVXLANVNI - *out = new(int) - **out = **in - } - if in.DNSTrustedServers != nil { - in, out := &in.DNSTrustedServers, &out.DNSTrustedServers - *out = new([]string) - if **in != nil { - in, out := *in, *out - *out = make([]string, len(*in)) - copy(*out, *in) - } - } - if in.WAFEventLogsFileEnabled != nil { - in, out := &in.WAFEventLogsFileEnabled, &out.WAFEventLogsFileEnabled - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FelixConfigurationSpec. -func (in *FelixConfigurationSpec) DeepCopy() *FelixConfigurationSpec { - if in == nil { - return nil - } - out := new(FelixConfigurationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IPPool) DeepCopyInto(out *IPPool) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPool. -func (in *IPPool) DeepCopy() *IPPool { - if in == nil { - return nil - } - out := new(IPPool) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *IPPool) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IPPoolList) DeepCopyInto(out *IPPoolList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]IPPool, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPoolList. -func (in *IPPoolList) DeepCopy() *IPPoolList { - if in == nil { - return nil - } - out := new(IPPoolList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *IPPoolList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IPPoolSpec) DeepCopyInto(out *IPPoolSpec) { - *out = *in - if in.AllowedUses != nil { - in, out := &in.AllowedUses, &out.AllowedUses - *out = make([]IPPoolAllowedUse, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPoolSpec. -func (in *IPPoolSpec) DeepCopy() *IPPoolSpec { - if in == nil { - return nil - } - out := new(IPPoolSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeControllersConfiguration) DeepCopyInto(out *KubeControllersConfiguration) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeControllersConfiguration. -func (in *KubeControllersConfiguration) DeepCopy() *KubeControllersConfiguration { - if in == nil { - return nil - } - out := new(KubeControllersConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *KubeControllersConfiguration) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeControllersConfigurationList) DeepCopyInto(out *KubeControllersConfigurationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]KubeControllersConfiguration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeControllersConfigurationList. -func (in *KubeControllersConfigurationList) DeepCopy() *KubeControllersConfigurationList { - if in == nil { - return nil - } - out := new(KubeControllersConfigurationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *KubeControllersConfigurationList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeControllersConfigurationSpec) DeepCopyInto(out *KubeControllersConfigurationSpec) { - *out = *in - if in.PrometheusMetricsPort != nil { - in, out := &in.PrometheusMetricsPort, &out.PrometheusMetricsPort - *out = new(int) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeControllersConfigurationSpec. -func (in *KubeControllersConfigurationSpec) DeepCopy() *KubeControllersConfigurationSpec { - if in == nil { - return nil - } - out := new(KubeControllersConfigurationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PrefixAdvertisement) DeepCopyInto(out *PrefixAdvertisement) { - *out = *in - if in.Communities != nil { - in, out := &in.Communities, &out.Communities - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrefixAdvertisement. -func (in *PrefixAdvertisement) DeepCopy() *PrefixAdvertisement { - if in == nil { - return nil - } - out := new(PrefixAdvertisement) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProtoPort) DeepCopyInto(out *ProtoPort) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProtoPort. -func (in *ProtoPort) DeepCopy() *ProtoPort { - if in == nil { - return nil - } - out := new(ProtoPort) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RouteTableRange) DeepCopyInto(out *RouteTableRange) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTableRange. -func (in *RouteTableRange) DeepCopy() *RouteTableRange { - if in == nil { - return nil - } - out := new(RouteTableRange) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceClusterIPBlock) DeepCopyInto(out *ServiceClusterIPBlock) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceClusterIPBlock. -func (in *ServiceClusterIPBlock) DeepCopy() *ServiceClusterIPBlock { - if in == nil { - return nil - } - out := new(ServiceClusterIPBlock) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceExternalIPBlock) DeepCopyInto(out *ServiceExternalIPBlock) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceExternalIPBlock. -func (in *ServiceExternalIPBlock) DeepCopy() *ServiceExternalIPBlock { - if in == nil { - return nil - } - out := new(ServiceExternalIPBlock) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceLoadBalancerIPBlock) DeepCopyInto(out *ServiceLoadBalancerIPBlock) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLoadBalancerIPBlock. -func (in *ServiceLoadBalancerIPBlock) DeepCopy() *ServiceLoadBalancerIPBlock { - if in == nil { - return nil - } - out := new(ServiceLoadBalancerIPBlock) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/apis/register.go b/pkg/apis/register.go new file mode 100644 index 0000000000..6c3da3f445 --- /dev/null +++ b/pkg/apis/register.go @@ -0,0 +1,136 @@ +// Copyright (c) 2019-2025 Tigera, Inc. All rights reserved. + +// 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 apis + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + esv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/elasticsearch/v1" + kbv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/kibana/v1" + envoy "github.com/envoyproxy/gateway/api/v1alpha1" + configv1 "github.com/openshift/api/config/v1" + ocsv1 "github.com/openshift/api/security/v1" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" + operatorv1 "github.com/tigera/operator/api/v1" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" + gateway "sigs.k8s.io/gateway-api/apis/v1" + csisecret "sigs.k8s.io/secrets-store-csi-driver/apis/v1" +) + +// AddToSchemes may be used to add all resources defined in the project to a Scheme +var AddToSchemes runtime.SchemeBuilder + +// AddToScheme adds all Resources to the Scheme +func AddToScheme(s *runtime.Scheme, v3 bool) error { + AddToSchemes = append(AddToSchemes, calicoSchemeBuilder(v3)) + return AddToSchemes.AddToScheme(s) +} + +func init() { + // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, configv1.Install) + AddToSchemes = append(AddToSchemes, aggregator.AddToScheme) + AddToSchemes = append(AddToSchemes, apiextensions.AddToScheme) + AddToSchemes = append(AddToSchemes, ocsv1.AddToScheme) + AddToSchemes = append(AddToSchemes, esv1.SchemeBuilder.AddToScheme) + AddToSchemes = append(AddToSchemes, kbv1.SchemeBuilder.AddToScheme) + AddToSchemes = append(AddToSchemes, policyv1.SchemeBuilder.AddToScheme) + AddToSchemes = append(AddToSchemes, policyv1beta1.SchemeBuilder.AddToScheme) + AddToSchemes = append(AddToSchemes, gateway.Install) + AddToSchemes = append(AddToSchemes, envoy.AddToScheme) + AddToSchemes = append(AddToSchemes, csisecret.AddToScheme) + AddToSchemes = append(AddToSchemes, operatorv1.AddToScheme) + AddToSchemes = append(AddToSchemes, admissionregistrationv1.AddToScheme) + AddToSchemes = append(AddToSchemes, monitoringv1.AddToScheme) +} + +func calicoSchemeBuilder(useV3 bool) func(*runtime.Scheme) error { + // We need to register the correct API groups based on the backing API group in use. This + // is a bit tricky, because some types are always in the same group, while others vary based on + // whether we're using the crd.projectcalico.org or projectcalico.org API group. + return func(scheme *runtime.Scheme) error { + // Handle types that are always in the projectcalico.org/v3 API group. + v3Types := []runtime.Object{ + &v3.DeepPacketInspection{}, + &v3.DeepPacketInspectionList{}, + &v3.GlobalNetworkPolicy{}, + &v3.GlobalNetworkPolicyList{}, + &v3.GlobalReportType{}, + &v3.GlobalReportTypeList{}, + &v3.GlobalAlert{}, + &v3.GlobalAlertList{}, + &v3.GlobalAlertTemplate{}, + &v3.GlobalAlertTemplateList{}, + &v3.HostEndpoint{}, + &v3.HostEndpointList{}, + &v3.LicenseKey{}, + &v3.LicenseKeyList{}, + &v3.NetworkPolicy{}, + &v3.NetworkPolicyList{}, + &v3.PolicyRecommendationScope{}, + &v3.PolicyRecommendationScopeList{}, + &v3.Tier{}, + &v3.TierList{}, + &v3.UISettings{}, + &v3.UISettingsGroup{}, + &v3.UISettingsGroupList{}, + &v3.UISettingsList{}, + } + + // Handle types that are always in the crd.projectcalico.org/v1 API group. + v1Types := []runtime.Object{} + + // Handle types that vary based on backing API group. + variableTypes := []runtime.Object{ + &v3.BGPConfiguration{}, + &v3.BGPConfigurationList{}, + &v3.ClusterInformation{}, + &v3.ClusterInformationList{}, + &v3.ExternalNetwork{}, + &v3.ExternalNetworkList{}, + &v3.FelixConfiguration{}, + &v3.FelixConfigurationList{}, + &v3.IPAMConfiguration{}, + &v3.IPAMConfigurationList{}, + &v3.IPPool{}, + &v3.IPPoolList{}, + &v3.KubeControllersConfiguration{}, + &v3.KubeControllersConfigurationList{}, + } + if useV3 { + v3Types = append(v3Types, variableTypes...) + } else { + v1Types = append(v1Types, variableTypes...) + } + + // Register types with the crd.projectcalico.org API group. + v1GV := schema.GroupVersion{Group: "crd.projectcalico.org", Version: "v1"} + scheme.AddKnownTypes(v1GV, v1Types...) + + // Register types with the projectcalico.org API group. + v3GV := schema.GroupVersion{Group: "projectcalico.org", Version: "v3"} + scheme.AddKnownTypes(v3GV, v3Types...) + metav1.AddToGroupVersion(scheme, v3GV) + + return nil + } +} diff --git a/pkg/controller/apiserver/apiserver_controller_test.go b/pkg/controller/apiserver/apiserver_controller_test.go index e1c3fa43e6..3f759aaabe 100644 --- a/pkg/controller/apiserver/apiserver_controller_test.go +++ b/pkg/controller/apiserver/apiserver_controller_test.go @@ -71,7 +71,7 @@ var _ = Describe("apiserver controller tests", func() { BeforeEach(func() { // Set up the scheme scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(admregv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -106,9 +106,7 @@ var _ = Describe("apiserver controller tests", func() { certificateManager, err := certificatemanager.Create(cli, nil, "cluster.local", common.OperatorNamespace(), certificatemanager.AllowCACreation()) Expect(err).NotTo(HaveOccurred()) Expect(cli.Create(context.Background(), certificateManager.KeyPair().Secret(common.OperatorNamespace()))).NotTo(HaveOccurred()) - Expect(cli.Create(ctx, &operatorv1.APIServer{ - ObjectMeta: metav1.ObjectMeta{Name: "tigera-secure"}, - })).ToNot(HaveOccurred()) + Expect(cli.Create(ctx, &operatorv1.APIServer{ObjectMeta: metav1.ObjectMeta{Name: "tigera-secure"}})).ToNot(HaveOccurred()) Expect(cli.Create(ctx, &v3.Tier{ObjectMeta: metav1.ObjectMeta{Name: "allow-tigera"}})).NotTo(HaveOccurred()) cryptoCA, err := tls.MakeCA("byo-ca") Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/controller/applicationlayer/applicationlayer_controller.go b/pkg/controller/applicationlayer/applicationlayer_controller.go index 93ff9ae0fd..629e6d9730 100644 --- a/pkg/controller/applicationlayer/applicationlayer_controller.go +++ b/pkg/controller/applicationlayer/applicationlayer_controller.go @@ -19,8 +19,8 @@ import ( "errors" "fmt" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/controller/options" "github.com/tigera/operator/pkg/controller/status" @@ -137,7 +137,7 @@ func add(mgr manager.Manager, c ctrlruntime.Controller) error { } // Watch for changes to FelixConfiguration. - err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("applicationlayer-controller failed to watch FelixConfiguration resource: %w", err) } @@ -476,7 +476,7 @@ func (r *ReconcileApplicationLayer) isSidecarInjectionEnabled(applicationLayerSp *applicationLayerSpec.SidecarInjection == operatorv1.SidecarEnabled } -func (r *ReconcileApplicationLayer) getPolicySyncPathPrefix(fcSpec *crdv1.FelixConfigurationSpec, al *operatorv1.ApplicationLayer) string { +func (r *ReconcileApplicationLayer) getPolicySyncPathPrefix(fcSpec *v3.FelixConfigurationSpec, al *operatorv1.ApplicationLayer) string { // Respect existing policySyncPathPrefix if it's already set (e.g. EGW) // This will cause policySyncPathPrefix value to remain when ApplicationLayer is disabled. existing := fcSpec.PolicySyncPathPrefix @@ -498,31 +498,31 @@ func (r *ReconcileApplicationLayer) getPolicySyncPathPrefix(fcSpec *crdv1.FelixC return "" } -func (r *ReconcileApplicationLayer) getTProxyMode(al *operatorv1.ApplicationLayer) (bool, crdv1.TPROXYModeOption) { +func (r *ReconcileApplicationLayer) getTProxyMode(al *operatorv1.ApplicationLayer) (bool, string) { if al == nil { - return false, crdv1.TPROXYModeOptionDisabled + return false, "Disabled" } spec := &al.Spec if r.isALPEnabled(spec) || r.isWAFEnabled(spec) || r.isLogsCollectionEnabled(spec) { - return true, crdv1.TPROXYModeOptionEnabled + return true, "Enabled" } // alp config is not nil, but neither of the features are enabled - return true, crdv1.TPROXYModeOptionDisabled + return true, "Disabled" } // patchFelixConfiguration takes all application layer specs as arguments and patches felix config. // If at least one of the specs requires TPROXYMode as "Enabled" it'll be patched as "Enabled" otherwise it is "Disabled". func (r *ReconcileApplicationLayer) patchFelixConfiguration(ctx context.Context, al *operatorv1.ApplicationLayer) error { - _, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *crdv1.FelixConfiguration) (bool, error) { - var tproxyMode crdv1.TPROXYModeOption + _, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *v3.FelixConfiguration) (bool, error) { + var tproxyMode string if ok, v := r.getTProxyMode(al); ok { tproxyMode = v } else { - if fc.Spec.TPROXYMode == nil { + if fc.Spec.TPROXYMode == "" { // Workaround: we'd like to always force the value to be the correct one, matching the operator's // configuration. However, during an upgrade from a version that predates the TPROXYMode option, // Felix hits a bug and gets confused by the new config parameter, which in turn triggers a restart. @@ -536,12 +536,12 @@ func (r *ReconcileApplicationLayer) patchFelixConfiguration(ctx context.Context, // If the mode is already set, fall through to the normal logic, it's safe to force-set the field now. // This also avoids churning the config if a previous version of the operator set it to Disabled already, // we avoid setting it back to nil. - tproxyMode = crdv1.TPROXYModeOptionDisabled + tproxyMode = "Disabled" } policySyncPrefix := r.getPolicySyncPathPrefix(&fc.Spec, al) policySyncPrefixSetDesired := fc.Spec.PolicySyncPathPrefix == policySyncPrefix - tproxyModeSetDesired := fc.Spec.TPROXYMode != nil && *fc.Spec.TPROXYMode == tproxyMode + tproxyModeSetDesired := fc.Spec.TPROXYMode != "" && fc.Spec.TPROXYMode == string(tproxyMode) wafEventLogsFileEnabled := al != nil && ((al.Spec.SidecarInjection != nil && *al.Spec.SidecarInjection == operatorv1.SidecarEnabled) || (al.Spec.WebApplicationFirewall != nil && *al.Spec.WebApplicationFirewall == operatorv1.WAFEnabled)) wafEventLogsFileEnabledDesired := fc.Spec.WAFEventLogsFileEnabled != nil && *fc.Spec.WAFEventLogsFileEnabled == wafEventLogsFileEnabled @@ -551,7 +551,7 @@ func (r *ReconcileApplicationLayer) patchFelixConfiguration(ctx context.Context, return false, nil } - fc.Spec.TPROXYMode = &tproxyMode + fc.Spec.TPROXYMode = string(tproxyMode) fc.Spec.PolicySyncPathPrefix = policySyncPrefix fc.Spec.WAFEventLogsFileEnabled = &wafEventLogsFileEnabled diff --git a/pkg/controller/applicationlayer/applicationlayer_controller_test.go b/pkg/controller/applicationlayer/applicationlayer_controller_test.go index 3947c338f9..a571b70e9e 100644 --- a/pkg/controller/applicationlayer/applicationlayer_controller_test.go +++ b/pkg/controller/applicationlayer/applicationlayer_controller_test.go @@ -32,9 +32,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/components" "github.com/tigera/operator/pkg/controller/status" @@ -51,13 +51,13 @@ var _ = Describe("Application layer controller tests", func() { var scheme *runtime.Scheme var mockStatus *status.MockStatus var installation *operatorv1.Installation - var fc *crdv1.FelixConfiguration + var fc *v3.FelixConfiguration Context("image reconciliation", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -92,13 +92,11 @@ var _ = Describe("Application layer controller tests", func() { licenseAPIReady: &utils.ReadyFlag{}, } - fc = &crdv1.FelixConfiguration{ + fc = &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{ - TPROXYMode: nil, - }, + Spec: v3.FelixConfigurationSpec{}, } Expect(c.Create(ctx, fc)).NotTo(HaveOccurred()) @@ -137,7 +135,7 @@ var _ = Describe("Application layer controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) By("ensuring that felix configuration PolicySyncPathPrefix is set") - f1 := crdv1.FelixConfiguration{ + f1 := v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, @@ -151,7 +149,7 @@ var _ = Describe("Application layer controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) By("ensuring that felix configuration PolicySyncPathPrefix is left as is, even after ALP deletion") - f2 := crdv1.FelixConfiguration{ + f2 := v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, @@ -162,12 +160,11 @@ var _ = Describe("Application layer controller tests", func() { It("should leave PolicySyncPathPrefix as is if already exists", func() { Expect(c.Delete(ctx, fc)).NotTo(HaveOccurred()) - Expect(c.Create(ctx, &crdv1.FelixConfiguration{ + Expect(c.Create(ctx, &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{ - TPROXYMode: nil, + Spec: v3.FelixConfigurationSpec{ PolicySyncPathPrefix: "/var/run/myfelix", }, })).NotTo(HaveOccurred()) @@ -188,7 +185,7 @@ var _ = Describe("Application layer controller tests", func() { Expect(c.Create(ctx, alSpec)).NotTo(HaveOccurred()) By("ensuring that felix configuration PolicySyncPathPrefix, if preset, is retained") - f1 := crdv1.FelixConfiguration{ + f1 := v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, @@ -202,7 +199,7 @@ var _ = Describe("Application layer controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) By("ensuring that felix configuration PolicySyncPathPrefix is left as is, even after ALP deletion") - f2 := crdv1.FelixConfiguration{ + f2 := v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, @@ -211,7 +208,7 @@ var _ = Describe("Application layer controller tests", func() { Expect(f2.Spec.PolicySyncPathPrefix).To(Equal("/var/run/myfelix")) }) - It("should leave TPROXYMode as nil if log collection is disabled", func() { + It("should leave TPROXYMode unset if log collection is disabled", func() { // This test verifies a workaround for upgrade from versions that don't support TPROXY to versions // that do. Setting an unknown felix config field causes older versions of felix to cyclicly restart, // which causes a disruptive upgrade. @@ -221,13 +218,13 @@ var _ = Describe("Application layer controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) By("ensuring that felix configuration TPROXYMode is nil") - fc := crdv1.FelixConfiguration{ + fc := v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, } Expect(test.GetResource(c, &fc)).To(BeNil()) - Expect(fc.Spec.TPROXYMode).To(BeNil()) + Expect(fc.Spec.TPROXYMode).To(Equal("")) }) It("should render accurate resources for for log collection", func() { @@ -280,13 +277,13 @@ var _ = Describe("Application layer controller tests", func() { components.ComponentL7Collector.Image, components.ComponentL7Collector.Version))) By("ensuring that felix configuration updated to enabled") - fc := crdv1.FelixConfiguration{ + fc := v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, } Expect(test.GetResource(c, &fc)).To(BeNil()) - Expect(*fc.Spec.TPROXYMode).To(Equal(crdv1.TPROXYModeOptionEnabled)) + Expect(fc.Spec.TPROXYMode).To(Equal("Enabled")) By("deleting that ApplicationLayer CR") Expect(c.Delete(ctx, &operatorv1.ApplicationLayer{ @@ -297,13 +294,13 @@ var _ = Describe("Application layer controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) By("ensuring that felix configuration updated to disabled") - fc = crdv1.FelixConfiguration{ + fc = v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, } Expect(test.GetResource(c, &fc)).To(BeNil()) - Expect(*fc.Spec.TPROXYMode).To(Equal(crdv1.TPROXYModeOptionDisabled)) + Expect(fc.Spec.TPROXYMode).To(Equal("Disabled")) }) It("should render proper SidecarWebhook status", func() { diff --git a/pkg/controller/authentication/authentication_controller_test.go b/pkg/controller/authentication/authentication_controller_test.go index 5950688ab6..c22cb35fd8 100644 --- a/pkg/controller/authentication/authentication_controller_test.go +++ b/pkg/controller/authentication/authentication_controller_test.go @@ -70,7 +70,7 @@ var _ = Describe("authentication controller tests", func() { BeforeEach(func() { // Set up the scheme scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/certificatemanager/certificatemanager_test.go b/pkg/controller/certificatemanager/certificatemanager_test.go index a0e0e90e92..73ee9b66d4 100644 --- a/pkg/controller/certificatemanager/certificatemanager_test.go +++ b/pkg/controller/certificatemanager/certificatemanager_test.go @@ -123,7 +123,7 @@ var _ = Describe("Test CertificateManagement suite", func() { } // Create a Kubernetes client. scheme = k8sruntime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -728,7 +728,6 @@ var _ = Describe("Test CertificateManagement suite", func() { It("should create a hash for both secrets even if the same pem is used twice", func() { By("creating 2 secrets with identical pem in the datastore", func() { - byoSecretCopy := byoSecret.DeepCopyObject().(*corev1.Secret) byoSecret.Name, byoSecret.Namespace = "byo-secret", common.OperatorNamespace() diff --git a/pkg/controller/clusterconnection/clusterconnection_controller_test.go b/pkg/controller/clusterconnection/clusterconnection_controller_test.go index 7043da6544..e073f2c70c 100644 --- a/pkg/controller/clusterconnection/clusterconnection_controller_test.go +++ b/pkg/controller/clusterconnection/clusterconnection_controller_test.go @@ -75,7 +75,7 @@ var _ = Describe("ManagementClusterConnection controller tests", func() { BeforeEach(func() { // Create a Kubernetes client. clientScheme = runtime.NewScheme() - Expect(apis.AddToScheme(clientScheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(clientScheme, false)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(clientScheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(clientScheme)).ShouldNot(HaveOccurred()) err := operatorv1.SchemeBuilder.AddToScheme(clientScheme) diff --git a/pkg/controller/compliance/compliance_controller_test.go b/pkg/controller/compliance/compliance_controller_test.go index 84476d9f8c..d95517e16b 100644 --- a/pkg/controller/compliance/compliance_controller_test.go +++ b/pkg/controller/compliance/compliance_controller_test.go @@ -65,7 +65,7 @@ var _ = Describe("Compliance controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(operatorv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) diff --git a/pkg/controller/csr/csr_controller_test.go b/pkg/controller/csr/csr_controller_test.go index 99d44152d8..4a6df82680 100644 --- a/pkg/controller/csr/csr_controller_test.go +++ b/pkg/controller/csr/csr_controller_test.go @@ -73,7 +73,7 @@ var _ = Describe("CSR controller tests", func() { ctx = context.TODO() // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(certificatesv1.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(operatorv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) @@ -570,5 +570,4 @@ func invalidX509CR(invalidations ...invalidation) *x509.CertificateRequest { } } return cr - } diff --git a/pkg/controller/egressgateway/egressgateway_controller.go b/pkg/controller/egressgateway/egressgateway_controller.go index cd527c3c59..033014e739 100644 --- a/pkg/controller/egressgateway/egressgateway_controller.go +++ b/pkg/controller/egressgateway/egressgateway_controller.go @@ -35,9 +35,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/components" "github.com/tigera/operator/pkg/controller/options" "github.com/tigera/operator/pkg/controller/status" @@ -113,7 +113,7 @@ func add(_ manager.Manager, c ctrlruntime.Controller) error { } // Watch for changes to FelixConfiguration. - err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("egressGateway-controller failed to watch FelixConfiguration resource: %w", err) } @@ -297,7 +297,7 @@ func (r *ReconcileEgressGateway) Reconcile(ctx context.Context, request reconcil } // patch and get the felix configuration - fc, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *crdv1.FelixConfiguration) (bool, error) { + fc, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *v3.FelixConfiguration) (bool, error) { if fc.Spec.PolicySyncPathPrefix != "" { return false, nil // don't proceed with the patch } @@ -342,7 +342,7 @@ func (r *ReconcileEgressGateway) Reconcile(ctx context.Context, request reconcil } func (r *ReconcileEgressGateway) reconcileEgressGateway(ctx context.Context, egw *operatorv1.EgressGateway, reqLogger logr.Logger, - variant operatorv1.ProductVariant, fc *crdv1.FelixConfiguration, pullSecrets []*v1.Secret, + variant operatorv1.ProductVariant, fc *v3.FelixConfiguration, pullSecrets []*v1.Secret, installation *operatorv1.InstallationSpec, namespaceAndNames []string, ) error { preDefaultPatchFrom := client.MergeFrom(egw.DeepCopy()) @@ -583,7 +583,7 @@ func fillDefaults(egw *operatorv1.EgressGateway, installation *operatorv1.Instal // validateExternalNetwork validates if the specified external network exists. func validateExternalNetwork(ctx context.Context, cli client.Client, externalNetwork string) error { - instance := &crdv1.ExternalNetwork{} + instance := &v3.ExternalNetwork{} key := types.NamespacedName{Name: externalNetwork} err := cli.Get(ctx, key, instance) if err != nil { @@ -596,7 +596,7 @@ func validateExternalNetwork(ctx context.Context, cli client.Client, externalNet // to see if they match. func validateIPPool(ctx context.Context, cli client.Client, ipPool operatorv1.EgressGatewayIPPool, awsNativeIP operatorv1.NativeIP) error { if ipPool.Name != "" { - instance := &crdv1.IPPool{} + instance := &v3.IPPool{} key := types.NamespacedName{Name: ipPool.Name} err := cli.Get(ctx, key, instance) if err != nil { @@ -613,7 +613,7 @@ func validateIPPool(ctx context.Context, cli client.Client, ipPool operatorv1.Eg return nil } if ipPool.CIDR != "" { - instance := &crdv1.IPPoolList{} + instance := &v3.IPPoolList{} err := cli.List(ctx, instance) if err != nil { return err diff --git a/pkg/controller/egressgateway/egressgateway_controller_test.go b/pkg/controller/egressgateway/egressgateway_controller_test.go index 739aa21031..59af37fd38 100644 --- a/pkg/controller/egressgateway/egressgateway_controller_test.go +++ b/pkg/controller/egressgateway/egressgateway_controller_test.go @@ -41,9 +41,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/components" "github.com/tigera/operator/pkg/controller/status" "github.com/tigera/operator/pkg/controller/utils" @@ -64,7 +64,7 @@ var _ = Describe("Egress Gateway controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -97,11 +97,11 @@ var _ = Describe("Egress Gateway controller tests", func() { licenseAPIReady: &utils.ReadyFlag{}, } - Expect(c.Create(ctx, &crdv1.IPPool{ - ObjectMeta: metav1.ObjectMeta{Name: "ippool-1"}, Spec: crdv1.IPPoolSpec{ + Expect(c.Create(ctx, &v3.IPPool{ + ObjectMeta: metav1.ObjectMeta{Name: "ippool-1"}, Spec: v3.IPPoolSpec{ CIDR: "1.2.3.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, DisableBGPExport: true, @@ -109,11 +109,11 @@ var _ = Describe("Egress Gateway controller tests", func() { }, })).NotTo(HaveOccurred()) - Expect(c.Create(ctx, &crdv1.IPPool{ - ObjectMeta: metav1.ObjectMeta{Name: "ippool-2"}, Spec: crdv1.IPPoolSpec{ + Expect(c.Create(ctx, &v3.IPPool{ + ObjectMeta: metav1.ObjectMeta{Name: "ippool-2"}, Spec: v3.IPPoolSpec{ CIDR: "1.2.4.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, DisableBGPExport: true, @@ -121,32 +121,32 @@ var _ = Describe("Egress Gateway controller tests", func() { }, })).NotTo(HaveOccurred()) - Expect(c.Create(ctx, &crdv1.IPPool{ - ObjectMeta: metav1.ObjectMeta{Name: "ippool-4"}, Spec: crdv1.IPPoolSpec{ + Expect(c.Create(ctx, &v3.IPPool{ + ObjectMeta: metav1.ObjectMeta{Name: "ippool-4"}, Spec: v3.IPPoolSpec{ CIDR: "1.2.5.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, DisableBGPExport: true, }, })).NotTo(HaveOccurred()) - Expect(c.Create(ctx, &crdv1.FelixConfiguration{ + Expect(c.Create(ctx, &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, })).NotTo(HaveOccurred()) var routeTableIndex uint32 = 1 - Expect(c.Create(ctx, &crdv1.ExternalNetwork{ - ObjectMeta: metav1.ObjectMeta{Name: "one"}, Spec: crdv1.ExternalNetworkSpec{ + Expect(c.Create(ctx, &v3.ExternalNetwork{ + ObjectMeta: metav1.ObjectMeta{Name: "one"}, Spec: v3.ExternalNetworkSpec{ RouteTableIndex: &routeTableIndex, }, })).NotTo(HaveOccurred()) - Expect(c.Create(ctx, &crdv1.ExternalNetwork{ - ObjectMeta: metav1.ObjectMeta{Name: "two"}, Spec: crdv1.ExternalNetworkSpec{ + Expect(c.Create(ctx, &v3.ExternalNetwork{ + ObjectMeta: metav1.ObjectMeta{Name: "two"}, Spec: v3.ExternalNetworkSpec{ RouteTableIndex: &routeTableIndex, }, })).NotTo(HaveOccurred()) @@ -268,7 +268,7 @@ var _ = Describe("Egress Gateway controller tests", func() { for _, elem := range expectedEgwEnvVar { Expect(egwContainer.Env).To(ContainElement(elem)) } - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} Expect(c.Get(ctx, types.NamespacedName{Name: "default", Namespace: ""}, fc)).NotTo(HaveOccurred()) Expect(fc.Spec.PolicySyncPathPrefix).To(Equal("/var/run/nodeagent")) @@ -325,7 +325,7 @@ var _ = Describe("Egress Gateway controller tests", func() { Expect(initContainer.Env).To(ContainElement(elem)) Expect(initContainer_blue.Env).To(ContainElement(elem)) } - var backend crdv1.IptablesBackend + var backend v3.IptablesBackend backend = "Auto" fc.Spec.IptablesBackend = &backend Expect(c.Update(ctx, fc)).NotTo(HaveOccurred()) diff --git a/pkg/controller/gatewayapi/gatewayapi_controller.go b/pkg/controller/gatewayapi/gatewayapi_controller.go index 49f0e20d16..0e8edee837 100644 --- a/pkg/controller/gatewayapi/gatewayapi_controller.go +++ b/pkg/controller/gatewayapi/gatewayapi_controller.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -458,8 +458,8 @@ func GetGatewayAPI(ctx context.Context, client client.Client) (*operatorv1.Gatew // patchFelixConfiguration patches the FelixConfiguration resource with the desired policy sync path prefix. func (r *ReconcileGatewayAPI) patchFelixConfiguration(ctx context.Context) error { - _, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *crdv1.FelixConfiguration) (bool, error) { - policySyncPrefix := fc.Spec.PolicySyncPathPrefix + _, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *v3.FelixConfiguration) (bool, error) { + policySyncPrefix := r.getPolicySyncPathPrefix(&fc.Spec) policySyncPrefixSetDesired := DefaultPolicySyncPrefix == policySyncPrefix if !policySyncPrefixSetDesired && policySyncPrefix != "" { @@ -478,6 +478,17 @@ func (r *ReconcileGatewayAPI) patchFelixConfiguration(ctx context.Context) error return err } +func (r *ReconcileGatewayAPI) getPolicySyncPathPrefix(fcSpec *v3.FelixConfigurationSpec) string { + // Respect existing policySyncPathPrefix if it's already set (e.g. EGW) + // This will cause policySyncPathPrefix value to remain when ApplicationLayer is disabled. + existing := fcSpec.PolicySyncPathPrefix + if existing != "" { + return existing + } + + return DefaultPolicySyncPrefix +} + // maintainFinalizer manages this controller's finalizer on the Installation resource. // We add a finalizer to the Installation when the API server has been installed, and only remove that finalizer when // the API server has been deleted and its pods have stopped running. This allows for a graceful cleanup of API server resources diff --git a/pkg/controller/gatewayapi/gatewayapi_controller_test.go b/pkg/controller/gatewayapi/gatewayapi_controller_test.go index 7c30203f2c..c8eb873e2d 100644 --- a/pkg/controller/gatewayapi/gatewayapi_controller_test.go +++ b/pkg/controller/gatewayapi/gatewayapi_controller_test.go @@ -37,9 +37,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/yaml" // gopkg.in/yaml.v2 didn't parse all the fields but this package did + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/controller/status" "github.com/tigera/operator/pkg/controller/utils" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" @@ -58,7 +58,7 @@ var _ = Describe("Gateway API controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -632,9 +632,9 @@ var _ = Describe("Gateway API controller tests", func() { It("Check felix configuration patching is set if it's not alreadyconfigured", func() { Expect(c.Create(ctx, installation)).NotTo(HaveOccurred()) - felixConfig := &crdv1.FelixConfiguration{ + felixConfig := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{Name: "default"}, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ // PolicySyncPathPrefix is not set. }, } @@ -652,19 +652,18 @@ var _ = Describe("Gateway API controller tests", func() { Expect(err).NotTo(HaveOccurred()) By("checking felix configuration has been patched") - actualFelixConfig := &crdv1.FelixConfiguration{} + actualFelixConfig := &v3.FelixConfiguration{} err = c.Get(ctx, client.ObjectKey{Name: "default"}, actualFelixConfig) Expect(err).NotTo(HaveOccurred()) Expect(actualFelixConfig.Spec.PolicySyncPathPrefix).To(Equal(DefaultPolicySyncPrefix)) - }) It("Check felix configuration patching is set if it's not set", func() { Expect(c.Create(ctx, installation)).NotTo(HaveOccurred()) - felixConfig := &crdv1.FelixConfiguration{ + felixConfig := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{Name: "default"}, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ // PolicySyncPathPrefix is not set. PolicySyncPathPrefix: "/dev/null", }, @@ -683,12 +682,11 @@ var _ = Describe("Gateway API controller tests", func() { Expect(err).NotTo(HaveOccurred()) By("checking felix configuration has been patched") - actualFelixConfig := &crdv1.FelixConfiguration{} + actualFelixConfig := &v3.FelixConfiguration{} err = c.Get(ctx, client.ObjectKey{Name: "default"}, actualFelixConfig) Expect(err).NotTo(HaveOccurred()) Expect(actualFelixConfig.Spec.PolicySyncPathPrefix).ToNot(Equal(DefaultPolicySyncPrefix)) Expect(actualFelixConfig.Spec.PolicySyncPathPrefix).To(Equal("/dev/null")) - }) }) diff --git a/pkg/controller/installation/bpf.go b/pkg/controller/installation/bpf.go index aaf407c117..8e2c4865ad 100644 --- a/pkg/controller/installation/bpf.go +++ b/pkg/controller/installation/bpf.go @@ -19,9 +19,9 @@ import ( "reflect" "strconv" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/operator/pkg/controller/utils" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/render" appsv1 "k8s.io/api/apps/v1" @@ -29,7 +29,7 @@ import ( ) // bpfValidateAnnotations validate Felix Configuration annotations match BPF Enabled spec for all scenarios. -func bpfValidateAnnotations(fc *crdv1.FelixConfiguration) error { +func bpfValidateAnnotations(fc *v3.FelixConfiguration) error { var annotationValue *bool if fc.Annotations[render.BPFOperatorAnnotation] != "" { v, err := strconv.ParseBool(fc.Annotations[render.BPFOperatorAnnotation]) @@ -71,7 +71,7 @@ func isRolloutCompleteWithBPFVolumes(ds *appsv1.DaemonSet) bool { for _, volume := range ds.Spec.Template.Spec.Volumes { if volume.Name == render.BPFVolumeName { - //return ds.Status.CurrentNumberScheduled == ds.Status.UpdatedNumberScheduled && ds.Status.CurrentNumberScheduled == ds.Status.NumberAvailable + // return ds.Status.CurrentNumberScheduled == ds.Status.UpdatedNumberScheduled && ds.Status.CurrentNumberScheduled == ds.Status.NumberAvailable if ds.Status.CurrentNumberScheduled == ds.Status.UpdatedNumberScheduled && ds.Status.CurrentNumberScheduled == ds.Status.NumberAvailable { return true } else { @@ -82,7 +82,7 @@ func isRolloutCompleteWithBPFVolumes(ds *appsv1.DaemonSet) bool { return false } -func setBPFEnabledOnFelixConfiguration(fc *crdv1.FelixConfiguration, bpfEnabled bool) error { +func setBPFEnabledOnFelixConfiguration(fc *v3.FelixConfiguration, bpfEnabled bool) error { err := bpfValidateAnnotations(fc) if err != nil { return err @@ -121,11 +121,11 @@ func bpfEnabledOnDaemonsetWithEnvVar(ds *appsv1.DaemonSet) (bool, error) { return bpfEnabledStatus, err } -func bpfEnabledOnFelixConfig(fc *crdv1.FelixConfiguration) bool { +func bpfEnabledOnFelixConfig(fc *v3.FelixConfiguration) bool { return fc.Spec.BPFEnabled != nil && *fc.Spec.BPFEnabled } -func disableBPFHostConntrackBypass(fc *crdv1.FelixConfiguration) { +func disableBPFHostConntrackBypass(fc *v3.FelixConfiguration) { hostConntrackBypassDisabled := false fc.Spec.BPFHostConntrackBypass = &hostConntrackBypassDisabled } diff --git a/pkg/controller/installation/bpf_test.go b/pkg/controller/installation/bpf_test.go index d81e088b2b..93a3d62328 100644 --- a/pkg/controller/installation/bpf_test.go +++ b/pkg/controller/installation/bpf_test.go @@ -17,7 +17,7 @@ package installation import ( "strconv" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/render" @@ -31,9 +31,8 @@ import ( ) var _ = Describe("BPF functional tests", func() { - Context("Annotations validation tests", func() { - var fc *crdv1.FelixConfiguration + var fc *v3.FelixConfiguration var textTrue, textFalse string var enabled, notEnabled bool @@ -44,12 +43,12 @@ var _ = Describe("BPF functional tests", func() { notEnabled = false BeforeEach(func() { - fc = &crdv1.FelixConfiguration{ + fc = &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Annotations: map[string]string{"foo": "bar"}, }, - Spec: crdv1.FelixConfigurationSpec{}, + Spec: v3.FelixConfigurationSpec{}, } }) @@ -219,18 +218,18 @@ var _ = Describe("BPF functional tests", func() { }) Context("BPFEnabled on FelixConfiguration tests", func() { - var fc *crdv1.FelixConfiguration + var fc *v3.FelixConfiguration var enabled, notEnabled bool enabled = true notEnabled = false BeforeEach(func() { - fc = &crdv1.FelixConfiguration{ + fc = &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{}, + Spec: v3.FelixConfigurationSpec{}, } }) @@ -253,14 +252,14 @@ var _ = Describe("BPF functional tests", func() { }) Context("setBPFEnabledOnFelixConfiguration tests", func() { - var fc *crdv1.FelixConfiguration + var fc *v3.FelixConfiguration BeforeEach(func() { - fc = &crdv1.FelixConfiguration{ + fc = &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{}, + Spec: v3.FelixConfigurationSpec{}, } }) diff --git a/pkg/controller/installation/core_controller.go b/pkg/controller/installation/core_controller.go index f9892ae0a1..3689031baa 100644 --- a/pkg/controller/installation/core_controller.go +++ b/pkg/controller/installation/core_controller.go @@ -61,7 +61,6 @@ import ( operatorv1 "github.com/tigera/operator/api/v1" v1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/active" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/components" "github.com/tigera/operator/pkg/controller/certificatemanager" @@ -84,6 +83,7 @@ import ( "github.com/tigera/operator/pkg/render/goldmane" "github.com/tigera/operator/pkg/render/kubecontrollers" "github.com/tigera/operator/pkg/render/monitor" + "github.com/tigera/operator/pkg/render/tierrbac" "github.com/tigera/operator/pkg/tls/certificatemanagement" ) @@ -193,6 +193,7 @@ func newReconciler(mgr manager.Manager, opts options.AddOptions) (*ReconcileInst manageCRDs: opts.ManageCRDs, tierWatchReady: &utils.ReadyFlag{}, newComponentHandler: utils.NewComponentHandler, + v3CRDs: opts.UseV3CRDs, } r.status.Run(opts.ShutdownContext) r.typhaAutoscaler.start(opts.ShutdownContext) @@ -261,19 +262,19 @@ func add(c ctrlruntime.Controller, r *ReconcileInstallation) error { } // Watch for changes to KubeControllersConfiguration. - err = c.WatchObject(&crdv1.KubeControllersConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.KubeControllersConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-installation-controller failed to watch KubeControllersConfiguration resource: %w", err) } // Watch for changes to FelixConfiguration. - err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-installation-controller failed to watch FelixConfiguration resource: %w", err) } // Watch for changes to BGPConfiguration. - err = c.WatchObject(&crdv1.BGPConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.BGPConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-installation-controller failed to watch BGPConfiguration resource: %w", err) } @@ -316,7 +317,7 @@ func add(c ctrlruntime.Controller, r *ReconcileInstallation) error { } // Watch for changes to IPPool. - err = c.WatchObject(&crdv1.IPPool{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.IPPool{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-installation-controller failed to watch IPPool resource: %w", err) } @@ -378,17 +379,19 @@ type ReconcileInstallation struct { clusterDomain string manageCRDs bool tierWatchReady *utils.ReadyFlag + v3CRDs bool + // newComponentHandler returns a new component handler. Useful stub for unit testing. newComponentHandler func(log logr.Logger, client client.Client, scheme *runtime.Scheme, cr metav1.Object) utils.ComponentHandler } // getActivePools returns the full set of enabled IP pools in the cluster. -func getActivePools(ctx context.Context, client client.Client) (*crdv1.IPPoolList, error) { - allPools := crdv1.IPPoolList{} +func getActivePools(ctx context.Context, client client.Client) (*v3.IPPoolList, error) { + allPools := v3.IPPoolList{} if err := client.List(ctx, &allPools); err != nil && !apierrors.IsNotFound(err) { return nil, fmt.Errorf("unable to list IPPools: %s", err.Error()) } - filtered := crdv1.IPPoolList{} + filtered := v3.IPPoolList{} for _, pool := range allPools.Items { if pool.Spec.Disabled { continue @@ -431,7 +434,7 @@ func updateInstallationWithDefaults(ctx context.Context, client client.Client, i // MergeAndFillDefaults merges in configuration from the Kubernetes provider, if applicable, and then // populates defaults in the Installation instance. -func MergeAndFillDefaults(i *operator.Installation, awsNode *appsv1.DaemonSet, currentPools *crdv1.IPPoolList) error { +func MergeAndFillDefaults(i *operator.Installation, awsNode *appsv1.DaemonSet, currentPools *v3.IPPoolList) error { if awsNode != nil { if err := updateInstallationForAWSNode(i, awsNode); err != nil { return fmt.Errorf("could not resolve AWS node configuration: %s", err.Error()) @@ -442,7 +445,7 @@ func MergeAndFillDefaults(i *operator.Installation, awsNode *appsv1.DaemonSet, c } // fillDefaults populates the default values onto an Installation object. -func fillDefaults(instance *operator.Installation, currentPools *crdv1.IPPoolList) error { +func fillDefaults(instance *operator.Installation, currentPools *v3.IPPoolList) error { if len(instance.Spec.Variant) == 0 { // Default to installing Calico. instance.Spec.Variant = operator.Calico @@ -1138,7 +1141,7 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile } // Set any non-default FelixConfiguration values that we need. - felixConfiguration, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *crdv1.FelixConfiguration) (bool, error) { + felixConfiguration, err := utils.PatchFelixConfiguration(ctx, r.client, func(fc *v3.FelixConfiguration) (bool, error) { // Configure defaults. u, err := r.setDefaultsOnFelixConfiguration(ctx, instance, fc, reqLogger, needNsMigration) if err != nil { @@ -1309,6 +1312,12 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile } + webhookTLS, err := certificateManager.GetOrCreateKeyPair(r.client, "webhook-secret", common.OperatorNamespace(), dns.GetServiceDNSNames("tier-rbac-validator", "calico-system", r.clusterDomain)) + if err != nil { + r.status.SetDegraded(operator.ResourceCreateError, "Error creating webhook TLS certificate", err, reqLogger) + return reconcile.Result{}, err + } + components = append(components, rcertificatemanagement.CertificateManagement(&rcertificatemanagement.Config{ Namespace: common.CalicoNamespace, @@ -1319,6 +1328,7 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile rcertificatemanagement.NewKeyPairOption(typhaNodeTLS.TyphaSecret, true, true), rcertificatemanagement.NewKeyPairOption(typhaNodeTLS.TyphaSecretNonClusterHost, true, true), rcertificatemanagement.NewKeyPairOption(kubeControllerTLS, true, true), + rcertificatemanagement.NewKeyPairOption(webhookTLS, true, true), }, TrustedBundle: typhaNodeTLS.TrustedBundle, })) @@ -1409,7 +1419,7 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile } // Fetch any existing default BGPConfiguration object. - bgpConfiguration := &crdv1.BGPConfiguration{} + bgpConfiguration := &v3.BGPConfiguration{} err = r.client.Get(ctx, types.NamespacedName{Name: "default"}, bgpConfiguration) if err != nil && !apierrors.IsNotFound(err) { r.status.SetDegraded(operator.ResourceReadError, "Unable to read BGPConfiguration", err, reqLogger) @@ -1488,10 +1498,15 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile PrometheusServerTLS: nodePrometheusTLS, FelixHealthPort: *felixConfiguration.Spec.HealthPort, NodeCgroupV2Path: felixConfiguration.Spec.CgroupV2Path, - BindMode: bgpConfiguration.Spec.BindMode, FelixPrometheusMetricsEnabled: utils.IsFelixPrometheusMetricsEnabled(felixConfiguration), FelixPrometheusMetricsPort: felixPrometheusMetricsPort, + V3CRDs: r.v3CRDs, } + + if bgpConfiguration.Spec.BindMode != nil { + nodeCfg.BindMode = string(*bgpConfiguration.Spec.BindMode) + } + // Check if BPFNetworkBootstrap is Enabled and its requirements are met. bpfBootstrapReq, err := utils.BPFBootstrapRequirements(ctx, r.client, &instance.Spec) if err != nil { @@ -1545,6 +1560,13 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile } components = append(components, kubecontrollers.NewCalicoKubeControllers(&kubeControllersCfg)) + // Add in a validating webhook configuration for tier-based RBAC. + hookCfg := tierrbac.Configuration{ + PullSecrets: pullSecrets, + KeyPair: webhookTLS, + } + components = append(components, tierrbac.RBAC(&hookCfg)) + // v3 NetworkPolicy will fail to reconcile if the API server deployment is unhealthy. In case the API Server // deployment becomes unhealthy and reconciliation of non-NetworkPolicy resources in the core controller // would resolve it, we render the network policies of components last to prevent a chicken-and-egg scenario. @@ -1669,7 +1691,7 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile r.status.ReadyToMonitor() // If eBPF is enabled in the operator API, patch FelixConfiguration to enable it within Felix. - _, err = utils.PatchFelixConfiguration(ctx, r.client, func(fc *crdv1.FelixConfiguration) (bool, error) { + _, err = utils.PatchFelixConfiguration(ctx, r.client, func(fc *v3.FelixConfiguration) (bool, error) { return r.setBPFUpdatesOnFelixConfiguration(ctx, instance, fc, reqLogger) }) if err != nil { @@ -1806,7 +1828,7 @@ func getOrCreateTyphaNodeTLSConfig(cli client.Client, certificateManager certifi }, nil } -func (r *ReconcileInstallation) setNftablesMode(_ context.Context, install *operator.Installation, fc *crdv1.FelixConfiguration, reqLogger logr.Logger) (bool, error) { +func (r *ReconcileInstallation) setNftablesMode(_ context.Context, install *operator.Installation, fc *v3.FelixConfiguration, reqLogger logr.Logger) (bool, error) { updated := false // Set the FelixConfiguration nftables dataplane mode based on the operator configuration. We do this unconditonally because @@ -1815,13 +1837,13 @@ func (r *ReconcileInstallation) setNftablesMode(_ context.Context, install *oper if install.Spec.CalicoNetwork.LinuxDataplane != nil { if install.Spec.IsNftables() { // The operator is configured to use the nftables dataplane. Configure Felix to use nftables. - updated = fc.Spec.NFTablesMode == nil || *fc.Spec.NFTablesMode != crdv1.NFTablesModeEnabled - nftablesMode := crdv1.NFTablesModeEnabled + updated = fc.Spec.NFTablesMode == nil || *fc.Spec.NFTablesMode != v3.NFTablesModeEnabled + var nftablesMode v3.NFTablesMode = v3.NFTablesModeEnabled fc.Spec.NFTablesMode = &nftablesMode } else { // The operator is configured to use another dataplane. Disable nftables. - updated = fc.Spec.NFTablesMode == nil || *fc.Spec.NFTablesMode != crdv1.NFTablesModeDisabled - nftablesMode := crdv1.NFTablesModeDisabled + updated = fc.Spec.NFTablesMode == nil || *fc.Spec.NFTablesMode != v3.NFTablesModeDisabled + var nftablesMode v3.NFTablesMode = v3.NFTablesModeDisabled fc.Spec.NFTablesMode = &nftablesMode } } @@ -1833,7 +1855,7 @@ func (r *ReconcileInstallation) setNftablesMode(_ context.Context, install *oper // setDefaultOnFelixConfiguration will take the passed in fc and add any defaulting needed // based on the install config. -func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Context, install *operator.Installation, fc *crdv1.FelixConfiguration, reqLogger logr.Logger, needNsMigration bool) (bool, error) { +func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Context, install *operator.Installation, fc *v3.FelixConfiguration, reqLogger logr.Logger, needNsMigration bool) (bool, error) { updated := false switch install.Spec.CNI.Type { @@ -1849,7 +1871,7 @@ func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Cont // p4d.24xlarge is reported to support 4x15 ENI but it uses 4 cards // and AWS CNI only uses ENIs on card 0. // - The VLAN table ID + 100 (there is doubt if this is true) - fc.Spec.RouteTableRange = &crdv1.RouteTableRange{ + fc.Spec.RouteTableRange = &v3.RouteTableRange{ Min: 65, Max: 99, } @@ -1858,7 +1880,7 @@ func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Cont if fc.Spec.RouteTableRange == nil { updated = true // Don't conflict with the GKE CNI plugin's routes. - fc.Spec.RouteTableRange = &crdv1.RouteTableRange{ + fc.Spec.RouteTableRange = &v3.RouteTableRange{ Min: 10, Max: 250, } @@ -1984,7 +2006,7 @@ func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Cont // setBPFUpdatesOnFelixConfiguration will take the passed in fc and update any BPF properties needed // based on the install config and the daemonset. -func (r *ReconcileInstallation) setBPFUpdatesOnFelixConfiguration(ctx context.Context, install *operator.Installation, fc *crdv1.FelixConfiguration, reqLogger logr.Logger) (bool, error) { +func (r *ReconcileInstallation) setBPFUpdatesOnFelixConfiguration(ctx context.Context, install *operator.Installation, fc *v3.FelixConfiguration, reqLogger logr.Logger) (bool, error) { updated := false bpfEnabledOnInstall := install.Spec.BPFEnabled() @@ -2197,11 +2219,11 @@ func addCRDWatches(c ctrlruntime.Controller, v operator.ProductVariant) error { return nil } -func crdPoolsToOperator(crds []crdv1.IPPool) []operator.IPPool { +func crdPoolsToOperator(crds []v3.IPPool) []operator.IPPool { pools := []v1.IPPool{} for _, p := range crds { op := v1.IPPool{} - ippool.FromProjectCalicoV1(&op, p) + ippool.FromProjectCalico(&op, p) pools = append(pools, op) } return pools diff --git a/pkg/controller/installation/core_controller_test.go b/pkg/controller/installation/core_controller_test.go index e1809acdb6..8d17a44a3c 100644 --- a/pkg/controller/installation/core_controller_test.go +++ b/pkg/controller/installation/core_controller_test.go @@ -47,7 +47,6 @@ import ( operator "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/components" "github.com/tigera/operator/pkg/controller/certificatemanager" @@ -119,7 +118,7 @@ var _ = Describe("Testing core-controller installation", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -220,14 +219,14 @@ var _ = Describe("Testing core-controller installation", func() { // In most clusters, the IP pool controller is responsible for creating IP pools. The Installation controller waits for this, // so we need to create those pools here. - pool := crdv1.IPPool{ + pool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-pool-v4"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/16", NATOutgoing: true, BlockSize: 26, NodeSelector: "all()", - VXLANMode: crdv1.VXLANModeAlways, + VXLANMode: v3.VXLANModeAlways, }, } Expect(c.Create(ctx, &pool)).NotTo(HaveOccurred()) @@ -580,15 +579,15 @@ var _ = Describe("Testing core-controller installation", func() { KubernetesProvider: operator.ProviderDockerEE, }, } - currentPools := crdv1.IPPoolList{} - currentPools.Items = append(currentPools.Items, crdv1.IPPool{ + currentPools := v3.IPPoolList{} + currentPools.Items = append(currentPools.Items, v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-pool-v4"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/16", NATOutgoing: true, BlockSize: 26, NodeSelector: "all()", - VXLANMode: crdv1.VXLANModeAlways, + VXLANMode: v3.VXLANModeAlways, }, }) Expect(MergeAndFillDefaults(installation, nil, ¤tPools)).To(BeNil()) @@ -643,7 +642,7 @@ var _ = Describe("Testing core-controller installation", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -735,14 +734,14 @@ var _ = Describe("Testing core-controller installation", func() { // In most clusters, the IP pool controller is responsible for creating IP pools. The Installation controller waits for this, // so we need to create those pools here. - pool := crdv1.IPPool{ + pool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-pool-v4"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/16", NATOutgoing: true, BlockSize: 26, NodeSelector: "all()", - VXLANMode: crdv1.VXLANModeAlways, + VXLANMode: v3.VXLANModeAlways, }, } Expect(c.Create(ctx, &pool)).NotTo(HaveOccurred()) @@ -849,7 +848,7 @@ var _ = Describe("Testing core-controller installation", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -939,14 +938,14 @@ var _ = Describe("Testing core-controller installation", func() { // In most clusters, the IP pool controller is responsible for creating IP pools. The Installation controller waits for this, // so we need to create those pools here. - pool := crdv1.IPPool{ + pool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-pool-v4"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/16", NATOutgoing: true, BlockSize: 26, NodeSelector: "all()", - VXLANMode: crdv1.VXLANModeAlways, + VXLANMode: v3.VXLANModeAlways, }, } Expect(c.Create(ctx, &pool)).NotTo(HaveOccurred()) @@ -989,11 +988,11 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) By("Checking that the FelixConfiguration has NFTablesMode Enabled") - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.NFTablesMode).ToNot(BeNil()) - Expect(*fc.Spec.NFTablesMode).To(Equal(crdv1.NFTablesModeEnabled)) + Expect(*fc.Spec.NFTablesMode).To(Equal(v3.NFTablesMode(v3.NFTablesModeEnabled))) }) It("should set NFTablesMode to Disabled if nftables mode is changed", func() { @@ -1013,11 +1012,11 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) By("checking that the FelixConfiguration has NFTablesMode Disabled") - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.NFTablesMode).NotTo(BeNil()) - Expect(*fc.Spec.NFTablesMode).To(Equal(crdv1.NFTablesModeDisabled)) + Expect(*fc.Spec.NFTablesMode).To(Equal(v3.NFTablesMode(v3.NFTablesModeDisabled))) }) }) @@ -1127,11 +1126,11 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) By("Checking that the FelixConfiguration has NFTablesMode Enabled") - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.NFTablesMode).ToNot(BeNil()) - Expect(*fc.Spec.NFTablesMode).To(Equal(crdv1.NFTablesModeEnabled)) + Expect(*fc.Spec.NFTablesMode).To(Equal(v3.NFTablesMode(v3.NFTablesModeEnabled))) }) It("should push env vars to ebpf-bootstrap", func() { @@ -1152,7 +1151,7 @@ var _ = Describe("Testing core-controller installation", func() { Expect(install.Spec.BPFNetworkBootstrapEnabled()).To(BeTrue()) By("Checking that the FelixConfiguration has BPF Enabled") - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.BPFEnabled).ToNot(BeNil()) @@ -1225,11 +1224,11 @@ var _ = Describe("Testing core-controller installation", func() { It("should push 'CALICO_CGROUP_PATH' env var to ebpf-bootstrap if specified in FelixConfiguration", func() { customPath := "/foo/bar/path" - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ CgroupV2Path: customPath, }, } @@ -1258,7 +1257,7 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // We should get a felix configuration with the health port defaulted (but nothing else). - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.HealthPort).NotTo(BeNil()) @@ -1280,7 +1279,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err := r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1295,13 +1294,13 @@ var _ = Describe("Testing core-controller installation", func() { Expect(c.Create(ctx, cr)).NotTo(HaveOccurred()) _, err := r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.VXLANPort).NotTo(BeNil()) Expect(*fc.Spec.VXLANPort).To(Equal(8472)) Expect(fc.Spec.NFTablesMode).NotTo(BeNil()) - Expect(*fc.Spec.NFTablesMode).To(Equal(crdv1.NFTablesModeDisabled)) + Expect(*fc.Spec.NFTablesMode).To(Equal(v3.NFTablesMode(v3.NFTablesModeDisabled))) }) It("should set bpfHostConntrackByPass to false when provider is DockerEE and BPF enabled", func() { @@ -1312,7 +1311,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err := r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1329,7 +1328,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err := r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1347,7 +1346,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err := r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1368,7 +1367,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err := r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1387,7 +1386,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err = r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc = &crdv1.FelixConfiguration{} + fc = &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1417,7 +1416,7 @@ var _ = Describe("Testing core-controller installation", func() { _, err = r.Reconcile(ctx, reconcile.Request{}) Expect(err).ShouldNot(HaveOccurred()) - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) @@ -1435,7 +1434,7 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // We should get a felix configuration with Rancher's DNS service. - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.DNSTrustedServers).NotTo(BeNil()) @@ -1449,11 +1448,11 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // Check that FelixConfiguration is created with RouteTableRange - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.RouteTableRange).NotTo(BeNil()) - Expect(*fc.Spec.RouteTableRange).To(Equal(crdv1.RouteTableRange{Min: 65, Max: 99})) + Expect(*fc.Spec.RouteTableRange).To(Equal(v3.RouteTableRange{Min: 65, Max: 99})) }) It("should Reconcile with GKE CNI config", func() { @@ -1463,20 +1462,20 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // Check that FelixConfiguration is created with RouteTableRange - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.RouteTableRange).NotTo(BeNil()) - Expect(*fc.Spec.RouteTableRange).To(Equal(crdv1.RouteTableRange{Min: 10, Max: 250})) + Expect(*fc.Spec.RouteTableRange).To(Equal(v3.RouteTableRange{Min: 10, Max: 250})) }) It("should Reconcile with AWS CNI and not change existing FelixConfig", func() { - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{ - RouteTableRange: &crdv1.RouteTableRange{Min: 15, Max: 55}, + Spec: v3.FelixConfigurationSpec{ + RouteTableRange: &v3.RouteTableRange{Min: 15, Max: 55}, LogSeverityScreen: "Error", }, } @@ -1488,20 +1487,20 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // Check that FelixConfiguration has not changed - fc = &crdv1.FelixConfiguration{} + fc = &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.RouteTableRange).NotTo(BeNil()) - Expect(*fc.Spec.RouteTableRange).To(Equal(crdv1.RouteTableRange{Min: 15, Max: 55})) + Expect(*fc.Spec.RouteTableRange).To(Equal(v3.RouteTableRange{Min: 15, Max: 55})) Expect(fc.Spec.LogSeverityScreen).To(Equal("Error")) }) It("should Reconcile with AWS CNI and update existing FelixConfig", func() { - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ LogSeverityScreen: "Error", }, } @@ -1513,20 +1512,20 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // Check that FelixConfiguration is created with RouteTableRange - fc = &crdv1.FelixConfiguration{} + fc = &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.RouteTableRange).NotTo(BeNil()) - Expect(*fc.Spec.RouteTableRange).To(Equal(crdv1.RouteTableRange{Min: 65, Max: 99})) + Expect(*fc.Spec.RouteTableRange).To(Equal(v3.RouteTableRange{Min: 65, Max: 99})) Expect(fc.Spec.LogSeverityScreen).To(Equal("Error")) }) It("should Reconcile with FelixConfig natPortRange set", func() { - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ NATPortRange: &numorstring.Port{MinPort: 15, MaxPort: 55}, }, } @@ -1538,7 +1537,7 @@ var _ = Describe("Testing core-controller installation", func() { Expect(err).ShouldNot(HaveOccurred()) // Check that FelixConfiguration has not changed - fc = &crdv1.FelixConfiguration{} + fc = &v3.FelixConfiguration{} err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) Expect(err).ShouldNot(HaveOccurred()) Expect(fc.Spec.NATPortRange).NotTo(BeNil()) @@ -1951,7 +1950,7 @@ var _ = Describe("Testing core-controller installation", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -2087,7 +2086,7 @@ var _ = Describe("Testing core-controller installation", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -2190,14 +2189,14 @@ var _ = Describe("Testing core-controller installation", func() { // In most clusters, the IP pool controller is responsible for creating IP pools. The Installation controller waits for this, // so we need to create those pools here. - pool := crdv1.IPPool{ + pool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-pool-v4"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/16", NATOutgoing: true, BlockSize: 26, NodeSelector: "all()", - VXLANMode: crdv1.VXLANModeAlways, + VXLANMode: v3.VXLANModeAlways, }, } Expect(c.Create(ctx, &pool)).NotTo(HaveOccurred()) diff --git a/pkg/controller/installation/defaults_test.go b/pkg/controller/installation/defaults_test.go index 27e62346fc..e0b3926695 100644 --- a/pkg/controller/installation/defaults_test.go +++ b/pkg/controller/installation/defaults_test.go @@ -23,8 +23,8 @@ import ( . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operator "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/components" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -36,10 +36,10 @@ var _ = Describe("Defaulting logic tests", func() { // IP pools are defaulted by the IP pool controller, and passed in as input to the defaulting // performed in the Installation controller. For the purposes of this test, // define them here. - currentPools := crdv1.IPPoolList{ - Items: []crdv1.IPPool{ + currentPools := v3.IPPoolList{ + Items: []v3.IPPool{ { - Spec: crdv1.IPPoolSpec{CIDR: "192.168.0.0/16"}, + Spec: v3.IPPoolSpec{CIDR: "192.168.0.0/16"}, }, }, } @@ -76,10 +76,10 @@ var _ = Describe("Defaulting logic tests", func() { // IP pools are defaulted by the IP pool controller, and passed in as input to the defaulting // performed in the Installation controller. For the purposes of this test, // define them here. - currentPools := crdv1.IPPoolList{ - Items: []crdv1.IPPool{ + currentPools := v3.IPPoolList{ + Items: []v3.IPPool{ { - Spec: crdv1.IPPoolSpec{CIDR: "192.168.0.0/16"}, + Spec: v3.IPPoolSpec{CIDR: "192.168.0.0/16"}, }, }, } @@ -380,10 +380,10 @@ var _ = Describe("Defaulting logic tests", func() { CalicoNetwork: &operator.CalicoNetworkSpec{}, }, } - currentPools := crdv1.IPPoolList{ - Items: []crdv1.IPPool{ + currentPools := v3.IPPoolList{ + Items: []v3.IPPool{ { - Spec: crdv1.IPPoolSpec{CIDR: "fd00::0/64"}, + Spec: v3.IPPoolSpec{CIDR: "fd00::0/64"}, }, }, } @@ -647,9 +647,9 @@ var _ = Describe("Defaulting logic tests", func() { // in the cluster. The input - currentPools - represents the IP pools that we have discovered from the cluster's API server, // and may have been provisioned either by the user directly, or via the IP pool controller in this operator. table.DescribeTable("should handle various pool configurations", - func(currentPools []crdv1.IPPool) { + func(currentPools []v3.IPPool) { instance := &operator.Installation{} - Expect(fillDefaults(instance, &crdv1.IPPoolList{Items: currentPools})).NotTo(HaveOccurred()) + Expect(fillDefaults(instance, &v3.IPPoolList{Items: currentPools})).NotTo(HaveOccurred()) // The resulting instance should be valid. Expect(validateCustomResource(instance)).NotTo(HaveOccurred()) @@ -678,21 +678,21 @@ var _ = Describe("Defaulting logic tests", func() { } }, - table.Entry("one IPv4 pool", []crdv1.IPPool{{Spec: crdv1.IPPoolSpec{CIDR: "192.168.0.0/16"}}}), - table.Entry("one IPv6 pool", []crdv1.IPPool{{Spec: crdv1.IPPoolSpec{CIDR: "fd80:24e2:f998:72d6::/64"}}}), - table.Entry("two IPv6 pools", []crdv1.IPPool{ - {Spec: crdv1.IPPoolSpec{CIDR: "fd80:24e2:f998:72d6::/64"}}, - {Spec: crdv1.IPPoolSpec{CIDR: "feed:beef:72e5:a94b::/64"}}, + table.Entry("one IPv4 pool", []v3.IPPool{{Spec: v3.IPPoolSpec{CIDR: "192.168.0.0/16"}}}), + table.Entry("one IPv6 pool", []v3.IPPool{{Spec: v3.IPPoolSpec{CIDR: "fd80:24e2:f998:72d6::/64"}}}), + table.Entry("two IPv6 pools", []v3.IPPool{ + {Spec: v3.IPPoolSpec{CIDR: "fd80:24e2:f998:72d6::/64"}}, + {Spec: v3.IPPoolSpec{CIDR: "feed:beef:72e5:a94b::/64"}}, }), - table.Entry("two IPv4 pools", []crdv1.IPPool{ - {Spec: crdv1.IPPoolSpec{CIDR: "192.168.0.0/16"}}, - {Spec: crdv1.IPPoolSpec{CIDR: "172.168.0.0/16"}}, + table.Entry("two IPv4 pools", []v3.IPPool{ + {Spec: v3.IPPoolSpec{CIDR: "192.168.0.0/16"}}, + {Spec: v3.IPPoolSpec{CIDR: "172.168.0.0/16"}}, }), - table.Entry("dual-spec", []crdv1.IPPool{ - {Spec: crdv1.IPPoolSpec{CIDR: "192.168.0.0/16"}}, - {Spec: crdv1.IPPoolSpec{CIDR: "172.168.0.0/16"}}, - {Spec: crdv1.IPPoolSpec{CIDR: "fd80:24e2:f998:72d6::/64"}}, - {Spec: crdv1.IPPoolSpec{CIDR: "feed:beef:72e5:a94b::/64"}}, + table.Entry("dual-spec", []v3.IPPool{ + {Spec: v3.IPPoolSpec{CIDR: "192.168.0.0/16"}}, + {Spec: v3.IPPoolSpec{CIDR: "172.168.0.0/16"}}, + {Spec: v3.IPPoolSpec{CIDR: "fd80:24e2:f998:72d6::/64"}}, + {Spec: v3.IPPoolSpec{CIDR: "feed:beef:72e5:a94b::/64"}}, }), ) }) diff --git a/pkg/controller/installation/windows_controller.go b/pkg/controller/installation/windows_controller.go index ed22902526..b988b9bda6 100644 --- a/pkg/controller/installation/windows_controller.go +++ b/pkg/controller/installation/windows_controller.go @@ -39,10 +39,10 @@ import ( configv1 "github.com/openshift/api/config/v1" apiv3 "github.com/tigera/api/pkg/apis/projectcalico/v3" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/active" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/controller/certificatemanager" "github.com/tigera/operator/pkg/controller/k8sapi" @@ -143,7 +143,7 @@ func AddWindowsController(mgr manager.Manager, opts options.AddOptions) error { } // Watch for changes to FelixConfiguration. - err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-windows-controller failed to watch FelixConfiguration resource: %w", err) } @@ -303,7 +303,7 @@ func (r *ReconcileWindows) Reconcile(ctx context.Context, request reconcile.Requ } // Fetch default FelixConfiguration - felixConfiguration := &crdv1.FelixConfiguration{} + felixConfiguration := &v3.FelixConfiguration{} err = r.client.Get(ctx, types.NamespacedName{Name: "default"}, felixConfiguration) if err != nil && !apierrors.IsNotFound(err) { r.status.SetDegraded(operatorv1.ResourceReadError, "Unable to read FelixConfiguration", err, reqLogger) diff --git a/pkg/controller/installation/windows_controller_test.go b/pkg/controller/installation/windows_controller_test.go index 8f2a4e87e6..6c4adfb8e2 100644 --- a/pkg/controller/installation/windows_controller_test.go +++ b/pkg/controller/installation/windows_controller_test.go @@ -26,7 +26,6 @@ import ( v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operator "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/components" "github.com/tigera/operator/pkg/controller/certificatemanager" @@ -64,7 +63,7 @@ var _ = Describe("windows-controller installation tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -100,12 +99,12 @@ var _ = Describe("windows-controller installation tests", func() { // Create default FelixConfiguration with VXLANVNI set up vni := 4096 Expect(c.Create(ctx, - &crdv1.FelixConfiguration{ + &v3.FelixConfiguration{ TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{VXLANVNI: &vni}, + Spec: v3.FelixConfigurationSpec{VXLANVNI: &vni}, })).ToNot(HaveOccurred()) // Create default IPAMConfiguration with StrictAffinity @@ -433,17 +432,17 @@ var _ = Describe("windows-controller installation tests", func() { It("should not render the Windows daemonset when FelixConfiguration.Spec.VXLANVNI is nil", func() { // Delete existing default FelixConfig and recreate with no VXLANVNI Expect(c.Delete(ctx, - &crdv1.FelixConfiguration{ + &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, })).ToNot(HaveOccurred()) Expect(c.Create(ctx, - &crdv1.FelixConfiguration{ + &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{}, + Spec: v3.FelixConfigurationSpec{}, })).ToNot(HaveOccurred()) hns := operator.WindowsDataplaneHNS @@ -535,7 +534,7 @@ var _ = Describe("windows-controller installation tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -560,12 +559,12 @@ var _ = Describe("windows-controller installation tests", func() { // Create default FelixConfiguration with VXLANVNI set up vni := 4096 Expect(c.Create(ctx, - &crdv1.FelixConfiguration{ + &v3.FelixConfiguration{ TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "default", }, - Spec: crdv1.FelixConfigurationSpec{VXLANVNI: &vni}, + Spec: v3.FelixConfigurationSpec{VXLANVNI: &vni}, })).ToNot(HaveOccurred()) // Create default IPAMConfiguration with StrictAffinity diff --git a/pkg/controller/intrusiondetection/intrusiondetection_controller_test.go b/pkg/controller/intrusiondetection/intrusiondetection_controller_test.go index 16e9943432..10c1702813 100644 --- a/pkg/controller/intrusiondetection/intrusiondetection_controller_test.go +++ b/pkg/controller/intrusiondetection/intrusiondetection_controller_test.go @@ -65,7 +65,7 @@ var _ = Describe("IntrusionDetection controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/ippool/defaults.go b/pkg/controller/ippool/defaults.go index 6e07ab5a4a..30b2efb89e 100644 --- a/pkg/controller/ippool/defaults.go +++ b/pkg/controller/ippool/defaults.go @@ -22,8 +22,8 @@ import ( "strings" configv1 "github.com/openshift/api/config/v1" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operator "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/ptr" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -67,7 +67,7 @@ func cidrToName(cidr string) (string, error) { // fillDefaults fills in IP pool defaults on the Installation object. Defaulting of fields other than IP pools occurs // in pkg/controller/installation/ -func fillDefaults(ctx context.Context, client client.Client, instance *operator.Installation, currentPools *crdv1.IPPoolList) error { +func fillDefaults(ctx context.Context, client client.Client, instance *operator.Installation, currentPools *v3.IPPoolList) error { if instance.Spec.CNI == nil || instance.Spec.CNI.IPAM == nil { // These fields are needed for IP pool defaulting but defaulted themselves by the core Installation controller, which this controller waits for before // running. We should never hit this branch, but handle it just in case. diff --git a/pkg/controller/ippool/pool_controller.go b/pkg/controller/ippool/pool_controller.go index 17ffe2d973..4efa5e8180 100644 --- a/pkg/controller/ippool/pool_controller.go +++ b/pkg/controller/ippool/pool_controller.go @@ -19,13 +19,13 @@ import ( "encoding/json" "fmt" "reflect" + "slices" "time" configv1 "github.com/openshift/api/config/v1" v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/controller/options" "github.com/tigera/operator/pkg/controller/status" "github.com/tigera/operator/pkg/controller/utils" @@ -57,6 +57,7 @@ func Add(mgr manager.Manager, opts options.AddOptions) error { scheme: mgr.GetScheme(), watches: make(map[runtime.Object]struct{}), autoDetectedProvider: opts.DetectedProvider, + opts: opts, status: status.New(mgr.GetClient(), tigeraStatusName, opts.KubernetesVersion), } r.status.Run(opts.ShutdownContext) @@ -85,7 +86,7 @@ func Add(mgr manager.Manager, opts options.AddOptions) error { } // Watch for changes to IPPool. - err = c.WatchObject(&crdv1.IPPool{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.IPPool{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-ippool-controller failed to watch IPPool resource: %w", err) } @@ -118,6 +119,7 @@ type Reconciler struct { watches map[runtime.Object]struct{} autoDetectedProvider operatorv1.Provider status status.StatusManager + opts options.AddOptions } const ( @@ -128,7 +130,7 @@ const ( ) // hasOwnerLabel returns true if the given IP pool is owned by the tigera/operator, and false otheriwse. -func hasOwnerLabel(pool *crdv1.IPPool) bool { +func hasOwnerLabel(pool *v3.IPPool) bool { if val, ok := pool.Labels[managedByLabel]; ok && val == managedByValue { return true } @@ -168,13 +170,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( // This controller relies on the core Installation controller to perform initial defaulting before it can continue. // The core installation controller adds a specific finalizer as part of performing defaulting, // so wait for that before we continue. - readyToGo := false - for _, finalizer := range installation.GetFinalizers() { - if finalizer == render.OperatorCompleteFinalizer { - readyToGo = true - break - } - } + readyToGo := slices.Contains(installation.GetFinalizers(), render.OperatorCompleteFinalizer) if !readyToGo { r.status.SetDegraded(operatorv1.ResourceNotReady, "Waiting for Installation defaulting to occur", nil, reqLogger) return reconcile.Result{}, nil @@ -185,7 +181,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( } // Get all IP pools currently in the cluster. - currentPools := &crdv1.IPPoolList{} + currentPools := &v3.IPPoolList{} err := r.client.List(ctx, currentPools) if err != nil && !errors.IsNotFound(err) { r.status.SetDegraded(operatorv1.ResourceReadError, "error querying IP pools", err, reqLogger) @@ -223,14 +219,18 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( r.status.SetDegraded(operatorv1.ResourceNotReady, "Error querying APIServer", err, reqLogger) return reconcile.Result{}, err } - apiAvailable := apiserver != nil && apiserver.Status.State == operatorv1.TigeraStatusReady + + // Determine if the v3 API is available. This is trie if either: + // - The APIServer resource exists and is ready. + // - We're using v3 CRDs directly (i.e., not via the Calico API server). + apiAvailable := apiserver != nil && apiserver.Status.State == operatorv1.TigeraStatusReady || r.opts.UseV3CRDs // Create a lookup map of pools owned by this controller for easy access. // This controller will only modify IP pools if: // - The pool was created by or last updated by this controller (as indicated by the managed-by label). // - The IP pool is present in the cluster, present in the Installation, and both match exactly. // The latter case exists for upgrade scenarios, allowing the operator to assume control of existing IP pools gracefully. - ourPools := map[string]crdv1.IPPool{} + ourPools := map[string]v3.IPPool{} notOurs := map[string]bool{} for _, p := range currentPools.Items { if hasOwnerLabel(&p) { @@ -247,7 +247,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( // when it attempts to create overlappin IP pools. for _, cnp := range installation.Spec.CalicoNetwork.IPPools { v1p := operatorv1.IPPool{} - FromProjectCalicoV1(&v1p, p) + FromProjectCalico(&v1p, p) reqLogger.V(1).Info("Comparing IP pool", "clusterPool", p, "installationPool", cnp) if !reflect.DeepEqual(cnp, v1p) { // The IP pool in the cluster doesn't match the IP pool in the Installation - ignore it. @@ -276,8 +276,8 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( toCreateOrUpdate := []client.Object{} for _, p := range installation.Spec.CalicoNetwork.IPPools { // We need to check if updates are required, but the installation uses the operator API format and the queried - // pools are in crd.projectcalico.org/v1 format. Compare the pools using the crd.projectcalico.org/v1 format. - v1res, err := ToProjectCalicoV1(p) + // pools are in projectcalico.org/v3 format. Compare the pools using the projectcalico.org/v3 format. + v1res, err := ToProjectCalico(p) if err != nil { r.status.SetDegraded(operatorv1.ResourceValidationError, "error handling IP pool", err, reqLogger) return reconcile.Result{}, err @@ -317,7 +317,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( return reconcile.Result{}, err } toCreateOrUpdate = append(toCreateOrUpdate, v3res) - } else { // The v3 API is not available, and there are existing pools in the cluster. We cannot create new pools until the v3 API is available. // The user may need to manually delete or update pools in order to allow the v3 API to launch successfully. @@ -392,31 +391,31 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( return reconcile.Result{}, nil } -// ToProjectCalicoV1 converts an IPPool to a crd.projectcalico.org/v1 IPPool resource. -func ToProjectCalicoV1(p operatorv1.IPPool) (*crdv1.IPPool, error) { - pool := crdv1.IPPool{ - TypeMeta: metav1.TypeMeta{Kind: "IPPool", APIVersion: "crd.projectcalico.org/v1"}, +// ToProjectCalico converts an operator IPPool to a projectcalico.org/v3 IPPool resource. +func ToProjectCalico(p operatorv1.IPPool) (*v3.IPPool, error) { + pool := v3.IPPool{ + TypeMeta: metav1.TypeMeta{Kind: "IPPool", APIVersion: "projectcalico.org/v3"}, ObjectMeta: metav1.ObjectMeta{ Name: p.Name, Labels: map[string]string{}, }, - Spec: crdv1.IPPoolSpec{CIDR: p.CIDR}, + Spec: v3.IPPoolSpec{CIDR: p.CIDR}, } // Set encap. switch p.Encapsulation { case operatorv1.EncapsulationIPIP: - pool.Spec.IPIPMode = crdv1.IPIPModeAlways - pool.Spec.VXLANMode = crdv1.VXLANModeNever + pool.Spec.IPIPMode = v3.IPIPModeAlways + pool.Spec.VXLANMode = v3.VXLANModeNever case operatorv1.EncapsulationIPIPCrossSubnet: - pool.Spec.IPIPMode = crdv1.IPIPModeCrossSubnet - pool.Spec.VXLANMode = crdv1.VXLANModeNever + pool.Spec.IPIPMode = v3.IPIPModeCrossSubnet + pool.Spec.VXLANMode = v3.VXLANModeNever case operatorv1.EncapsulationVXLAN: - pool.Spec.VXLANMode = crdv1.VXLANModeAlways - pool.Spec.IPIPMode = crdv1.IPIPModeNever + pool.Spec.VXLANMode = v3.VXLANModeAlways + pool.Spec.IPIPMode = v3.IPIPModeNever case operatorv1.EncapsulationVXLANCrossSubnet: - pool.Spec.VXLANMode = crdv1.VXLANModeCrossSubnet - pool.Spec.IPIPMode = crdv1.IPIPModeNever + pool.Spec.VXLANMode = v3.VXLANModeCrossSubnet + pool.Spec.IPIPMode = v3.IPIPModeNever } // Set NAT @@ -443,32 +442,33 @@ func ToProjectCalicoV1(p operatorv1.IPPool) (*crdv1.IPPool, error) { } for _, use := range p.AllowedUses { - pool.Spec.AllowedUses = append(pool.Spec.AllowedUses, crdv1.IPPoolAllowedUse(use)) + pool.Spec.AllowedUses = append(pool.Spec.AllowedUses, v3.IPPoolAllowedUse(use)) } - pool.Spec.AssignmentMode = p.AssignmentMode + m := v3.AssignmentMode(p.AssignmentMode) + pool.Spec.AssignmentMode = &m return &pool, nil } -// FromProjectCalicoV1 populates the IP pool with the data from the given -// crd.projectcalico.org/v1 IP pool. It is the direct inverse of ToProjectCalicoV1, +// FromProjectCalico populates the IP pool with the data from the given +// projectcalico.org/v3 IP pool. It is the direct inverse of ToProjectCalicoV1, // and should be updated with every new field added to the IP pool structure. -func FromProjectCalicoV1(p *operatorv1.IPPool, crd crdv1.IPPool) { +func FromProjectCalico(p *operatorv1.IPPool, crd v3.IPPool) { p.Name = crd.Name p.CIDR = crd.Spec.CIDR // Set encap. switch crd.Spec.IPIPMode { - case crdv1.IPIPModeAlways: + case v3.IPIPModeAlways: p.Encapsulation = operatorv1.EncapsulationIPIP - case crdv1.IPIPModeCrossSubnet: + case v3.IPIPModeCrossSubnet: p.Encapsulation = operatorv1.EncapsulationIPIPCrossSubnet } switch crd.Spec.VXLANMode { - case crdv1.VXLANModeAlways: + case v3.VXLANModeAlways: p.Encapsulation = operatorv1.EncapsulationVXLAN - case crdv1.VXLANModeCrossSubnet: + case v3.VXLANModeCrossSubnet: p.Encapsulation = operatorv1.EncapsulationVXLANCrossSubnet } @@ -504,20 +504,23 @@ func FromProjectCalicoV1(p *operatorv1.IPPool, crd crdv1.IPPool) { p.AllowedUses = append(p.AllowedUses, operatorv1.IPPoolAllowedUse(use)) } - p.AssignmentMode = crd.Spec.AssignmentMode + if crd.Spec.AssignmentMode != nil { + m := operatorv1.AssignmentMode(*crd.Spec.AssignmentMode) + p.AssignmentMode = m + } } -func CRDPoolsToOperator(crds []crdv1.IPPool) []operatorv1.IPPool { +func CRDPoolsToOperator(crds []v3.IPPool) []operatorv1.IPPool { pools := []operatorv1.IPPool{} for _, p := range crds { op := operatorv1.IPPool{} - FromProjectCalicoV1(&op, p) + FromProjectCalico(&op, p) pools = append(pools, op) } return pools } -func v1ToV3(v1pool *crdv1.IPPool) (*v3.IPPool, error) { +func v1ToV3(v1pool *v3.IPPool) (*v3.IPPool, error) { bs, err := json.Marshal(v1pool) if err != nil { return nil, err @@ -535,7 +538,7 @@ func v1ToV3(v1pool *crdv1.IPPool) (*v3.IPPool, error) { return &v3pool, nil } -func restoreV3Metadata(v1pool *crdv1.IPPool) error { +func restoreV3Metadata(v1pool *v3.IPPool) error { // v1 IP pools store v3 metadata in an annotation. Extract it and use it to restore the v3 metadata. if v3metaJSON, ok := v1pool.Annotations["projectcalico.org/metadata"]; ok { v3meta := metav1.ObjectMeta{} diff --git a/pkg/controller/ippool/pool_controller_test.go b/pkg/controller/ippool/pool_controller_test.go index e30c13fa38..77e776a567 100644 --- a/pkg/controller/ippool/pool_controller_test.go +++ b/pkg/controller/ippool/pool_controller_test.go @@ -27,9 +27,9 @@ import ( configv1 "github.com/openshift/api/config/v1" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operator "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/controller/status" "github.com/tigera/operator/pkg/controller/utils" "github.com/tigera/operator/pkg/render" @@ -46,9 +46,6 @@ import ( var twentySix int32 = 26 var _ = Describe("IP Pool controller tests", func() { - // var cli client.Client - // var currentPools *crdv1.IPPoolList - // var instance *operator.Installation var ctx context.Context var cancel context.CancelFunc var c client.Client @@ -58,7 +55,7 @@ var _ = Describe("IP Pool controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(schedv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -151,7 +148,7 @@ var _ = Describe("IP Pool controller tests", func() { Expect(pool.CIDR).To(Equal("192.168.0.0/16")) // Expect the IP pool to be created in the API server as well. - ipPools := crdv1.IPPoolList{} + ipPools := v3.IPPoolList{} err = c.List(ctx, &ipPools) Expect(err).ShouldNot(HaveOccurred()) Expect(ipPools.Items).To(HaveLen(1)) @@ -176,9 +173,9 @@ var _ = Describe("IP Pool controller tests", func() { Expect(c.Create(ctx, instance)).ShouldNot(HaveOccurred()) // Create an IP pool. This simulates a user creating an IP pool before the operator has a chance to. - ipPool := crdv1.IPPool{ + ipPool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "test-pool"}, - Spec: crdv1.IPPoolSpec{}, + Spec: v3.IPPoolSpec{}, } Expect(c.Create(ctx, &ipPool)).ShouldNot(HaveOccurred()) @@ -202,7 +199,7 @@ var _ = Describe("IP Pool controller tests", func() { Expect(installation.Spec.CalicoNetwork.IPPools).To(HaveLen(0)) // No new IP pools should exist. - ipPools := crdv1.IPPoolList{} + ipPools := v3.IPPoolList{} err = c.List(ctx, &ipPools) Expect(err).ShouldNot(HaveOccurred()) Expect(ipPools.Items).To(HaveLen(1)) @@ -245,13 +242,13 @@ var _ = Describe("IP Pool controller tests", func() { mockStatus.AssertExpectations(GinkgoT()) // Expect all IP pools to have been created. - ipPools := crdv1.IPPoolList{} + ipPools := v3.IPPoolList{} err = c.List(ctx, &ipPools) Expect(err).ShouldNot(HaveOccurred()) Expect(ipPools.Items).To(HaveLen(len(instance.Spec.CalicoNetwork.IPPools))) // Verify basic data about the created pools. - poolsByCIDR := map[string]crdv1.IPPool{} + poolsByCIDR := map[string]v3.IPPool{} for _, pool := range ipPools.Items { poolsByCIDR[pool.Spec.CIDR] = pool } @@ -353,7 +350,7 @@ var _ = Describe("IP Pool controller tests", func() { mockStatus.AssertExpectations(GinkgoT()) // Expect the IP pool to still exist. - ipPools := crdv1.IPPoolList{} + ipPools := v3.IPPoolList{} err = c.List(ctx, &ipPools) Expect(err).ShouldNot(HaveOccurred()) Expect(ipPools.Items).To(HaveLen(1)) @@ -385,7 +382,7 @@ var _ = table.DescribeTable("Test OpenShift IP pool defaulting", func(i *operator.Installation, on *configv1.Network, expectSuccess bool, expected *operator.CalicoNetworkSpec) { // Perform test setup. scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(configv1.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(operator.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) @@ -395,7 +392,7 @@ var _ = table.DescribeTable("Test OpenShift IP pool defaulting", on.Name = "cluster" Expect(cli.Create(ctx, on)).To(BeNil()) } - currentPools := &crdv1.IPPoolList{} + currentPools := &v3.IPPoolList{} // The core Installation controller will normally handle defaulting the provider based on user input and // auto-detected cluster information. For this test, explicitly set it to OpenShift. @@ -590,13 +587,13 @@ var _ = table.DescribeTable("Test OpenShift IP pool defaulting", var _ = Describe("fillDefaults()", func() { var cli client.Client var ctx context.Context - var currentPools *crdv1.IPPoolList + var currentPools *v3.IPPoolList var instance *operator.Installation BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(configv1.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(operator.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) diff --git a/pkg/controller/ippool/pool_conversion_test.go b/pkg/controller/ippool/pool_conversion_test.go index 64550cc8c1..85171195d6 100644 --- a/pkg/controller/ippool/pool_conversion_test.go +++ b/pkg/controller/ippool/pool_conversion_test.go @@ -25,15 +25,15 @@ var ( false_ = false ) -var _ = table.DescribeTable("IPPool operator.tigera.io <-> crd.projectcalico.org/v1 conversion tests", +var _ = table.DescribeTable("IPPool operator.tigera.io <-> projectcalico.org/v3 conversion tests", func(input operator.IPPool) { - // Convert to crd.projectcalico.org/v1 - crdPool, err := ToProjectCalicoV1(input) + // Convert to projectcalico.org/v3 + crdPool, err := ToProjectCalico(input) Expect(err).NotTo(HaveOccurred()) // Convert back to operator.tigera.io, expect it to be equal to the input. operPool := operator.IPPool{} - FromProjectCalicoV1(&operPool, *crdPool) + FromProjectCalico(&operPool, *crdPool) Expect(operPool).To(Equal(input)) }, diff --git a/pkg/controller/kubeproxy/controller.go b/pkg/controller/kubeproxy/controller.go index 52ca5e8cbd..00a3d186e9 100644 --- a/pkg/controller/kubeproxy/controller.go +++ b/pkg/controller/kubeproxy/controller.go @@ -28,8 +28,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/controller/options" "github.com/tigera/operator/pkg/controller/status" "github.com/tigera/operator/pkg/controller/utils" @@ -59,7 +59,7 @@ func Add(mgr manager.Manager, opts options.AddOptions) error { return fmt.Errorf("%s failed to watch Installation resource: %w", controllerName, err) } - if err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}); err != nil { + if err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}); err != nil { return fmt.Errorf("%s failed to watch for Felix Configuration resource: %w", controllerName, err) } diff --git a/pkg/controller/kubeproxy/kubeproxy_controller_test.go b/pkg/controller/kubeproxy/kubeproxy_controller_test.go index 6b554d5a73..cafd3ddb16 100644 --- a/pkg/controller/kubeproxy/kubeproxy_controller_test.go +++ b/pkg/controller/kubeproxy/kubeproxy_controller_test.go @@ -32,9 +32,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" // gopkg.in/yaml.v2 didn't parse all the fields but this package did + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/controller/status" "github.com/tigera/operator/pkg/controller/utils" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" @@ -57,7 +57,7 @@ var _ = Describe("kube-proxy controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(discoveryv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(operatorv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) @@ -135,9 +135,9 @@ var _ = Describe("kube-proxy controller tests", func() { }) } createFelixConfiguration := func(bpfEnabled bool) { - createResource(&crdv1.FelixConfiguration{ + createResource(&v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{Name: "default"}, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ BPFEnabled: ptr.BoolToPtr(bpfEnabled), }, }) @@ -232,5 +232,4 @@ var _ = Describe("kube-proxy controller tests", func() { ), ) }) - }) diff --git a/pkg/controller/logcollector/logcollector_controller_test.go b/pkg/controller/logcollector/logcollector_controller_test.go index 3a4ded164c..c5cdf04c31 100644 --- a/pkg/controller/logcollector/logcollector_controller_test.go +++ b/pkg/controller/logcollector/logcollector_controller_test.go @@ -58,7 +58,7 @@ var _ = Describe("LogCollector controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/dashboards/dashboards_controller_test.go b/pkg/controller/logstorage/dashboards/dashboards_controller_test.go index 94d72f54f5..6a7c83302f 100644 --- a/pkg/controller/logstorage/dashboards/dashboards_controller_test.go +++ b/pkg/controller/logstorage/dashboards/dashboards_controller_test.go @@ -102,7 +102,7 @@ var _ = Describe("LogStorage Dashboards controller", func() { // This BeforeEach contains common preparation for all tests - both single-tenant and multi-tenant. // Any test-specific preparation should be done in subsequen BeforeEach blocks in the Contexts below. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/elastic/elastic_controller_test.go b/pkg/controller/logstorage/elastic/elastic_controller_test.go index db29e22efc..54e1078114 100644 --- a/pkg/controller/logstorage/elastic/elastic_controller_test.go +++ b/pkg/controller/logstorage/elastic/elastic_controller_test.go @@ -120,7 +120,7 @@ var _ = Describe("LogStorage controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/elastic/external_elastic_controller_test.go b/pkg/controller/logstorage/elastic/external_elastic_controller_test.go index 78d4a176f7..7e26b4be00 100644 --- a/pkg/controller/logstorage/elastic/external_elastic_controller_test.go +++ b/pkg/controller/logstorage/elastic/external_elastic_controller_test.go @@ -61,7 +61,7 @@ var _ = Describe("External ES Controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/esmetrics/esmetrics_controller_test.go b/pkg/controller/logstorage/esmetrics/esmetrics_controller_test.go index 2c848717a4..79f851caff 100644 --- a/pkg/controller/logstorage/esmetrics/esmetrics_controller_test.go +++ b/pkg/controller/logstorage/esmetrics/esmetrics_controller_test.go @@ -56,7 +56,6 @@ func NewESMetricsControllerWithShims( multiTenant bool, readyFlag *utils.ReadyFlag, ) (*ESMetricsSubController, error) { - opts := options.AddOptions{ DetectedProvider: provider, ClusterDomain: clusterDomain, @@ -87,7 +86,7 @@ var _ = Describe("LogStorage Linseed controller", func() { ) BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/initializer/conditions_controller_test.go b/pkg/controller/logstorage/initializer/conditions_controller_test.go index 72fe138b9b..e5b56f2ac9 100644 --- a/pkg/controller/logstorage/initializer/conditions_controller_test.go +++ b/pkg/controller/logstorage/initializer/conditions_controller_test.go @@ -68,7 +68,7 @@ var _ = Describe("LogStorage Conditions controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -83,11 +83,12 @@ var _ = Describe("LogStorage Conditions controller", func() { }) generation := int64(2) - subControllers := []string{TigeraStatusName, TigeraStatusLogStorageAccess, - TigeraStatusLogStorageElastic, TigeraStatusLogStorageSecrets} + subControllers := []string{ + TigeraStatusName, TigeraStatusLogStorageAccess, + TigeraStatusLogStorageElastic, TigeraStatusLogStorageSecrets, + } It("should reconcile with one item in tigerastatus conditions", func() { - lsControllers := append(subControllers, TigeraStatusLogStorageESMetrics, TigeraStatusLogStorageKubeController, TigeraStatusLogStorageDashboards) for _, ls := range lsControllers { createTigeraStatus(cli, ctx, ls, generation, []operatorv1.TigeraStatusCondition{{ @@ -149,11 +150,9 @@ var _ = Describe("LogStorage Conditions controller", func() { Expect(string(progCondition.Status)).To(Equal(string(operatorv1.ConditionFalse))) Expect(progCondition.Reason).To(Equal(string(operatorv1.Unknown))) Expect(progCondition.Message).To(Equal("")) - }) It("should reconcile with empty tigerastatus conditions", func() { - lsControllers := append(subControllers, TigeraStatusLogStorageESMetrics, TigeraStatusLogStorageKubeController, TigeraStatusLogStorageDashboards) for _, ls := range lsControllers { ts := &operatorv1.TigeraStatus{ @@ -214,7 +213,6 @@ var _ = Describe("LogStorage Conditions controller", func() { }) It("should reconcile multiple conditions as true", func() { - lsControllers := append(subControllers, TigeraStatusLogStorageKubeController, TigeraStatusLogStorageDashboards) for _, ls := range lsControllers { createTigeraStatus(cli, ctx, ls, generation, []operatorv1.TigeraStatusCondition{}) @@ -301,7 +299,6 @@ var _ = Describe("LogStorage Conditions controller", func() { Expect(string(readyCondition.Status)).To(Equal(string(operatorv1.ConditionTrue))) Expect(readyCondition.Reason).To(Equal(string(operatorv1.AllObjectsAvailable))) Expect(readyCondition.ObservedGeneration).To(Equal(int64(2))) - }) It("should reconcile with all log-storage-* tigerastatus conditions as Available and later move to degraded", func() { @@ -469,7 +466,6 @@ func CreateLogStorage(client client.Client, ls *operatorv1.LogStorage) { } func createTigeraStatus(cli client.Client, ctx context.Context, name string, generation int64, conditions []operatorv1.TigeraStatusCondition) { - // set All objects Available by default if len(conditions) == 0 { conditions = []operatorv1.TigeraStatusCondition{ diff --git a/pkg/controller/logstorage/initializer/initializing_controller_test.go b/pkg/controller/logstorage/initializer/initializing_controller_test.go index 855e6fc069..de1068c600 100644 --- a/pkg/controller/logstorage/initializer/initializing_controller_test.go +++ b/pkg/controller/logstorage/initializer/initializing_controller_test.go @@ -83,7 +83,7 @@ var _ = Describe("LogStorage Initializing controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/kubecontrollers/es_kube_controllers_test.go b/pkg/controller/logstorage/kubecontrollers/es_kube_controllers_test.go index 14737eb9fb..fce1ed537b 100644 --- a/pkg/controller/logstorage/kubecontrollers/es_kube_controllers_test.go +++ b/pkg/controller/logstorage/kubecontrollers/es_kube_controllers_test.go @@ -100,7 +100,7 @@ var _ = Describe("LogStorage ES kube-controllers controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/linseed/linseed_controller_test.go b/pkg/controller/logstorage/linseed/linseed_controller_test.go index 946fd83578..bb517c95b9 100644 --- a/pkg/controller/logstorage/linseed/linseed_controller_test.go +++ b/pkg/controller/logstorage/linseed/linseed_controller_test.go @@ -103,7 +103,7 @@ var _ = Describe("LogStorage Linseed controller", func() { // This BeforeEach contains common preparation for all tests - both single-tenant and multi-tenant. // Any test-specific preparation should be done in subsequen BeforeEach blocks in the Contexts below. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/managedcluster/managed_cluster_controller_test.go b/pkg/controller/logstorage/managedcluster/managed_cluster_controller_test.go index a5ef7c1191..e7b2f302e6 100644 --- a/pkg/controller/logstorage/managedcluster/managed_cluster_controller_test.go +++ b/pkg/controller/logstorage/managedcluster/managed_cluster_controller_test.go @@ -68,7 +68,7 @@ var _ = Describe("LogStorageManagedCluster controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/logstorage/secrets/secret_controller_test.go b/pkg/controller/logstorage/secrets/secret_controller_test.go index b16c14c06d..17698a673f 100644 --- a/pkg/controller/logstorage/secrets/secret_controller_test.go +++ b/pkg/controller/logstorage/secrets/secret_controller_test.go @@ -139,7 +139,7 @@ var _ = Describe("LogStorage Secrets controller", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -264,7 +264,6 @@ var _ = Describe("LogStorage Secrets controller", func() { }) It("should not trip up when a cert with missing key usages is configured for other components", func() { - // Create a LogStorage instance with a default configuration. ls := &operatorv1.LogStorage{} ls.Name = "tigera-secure" diff --git a/pkg/controller/manager/manager_controller_test.go b/pkg/controller/manager/manager_controller_test.go index fb5bebd289..8792956188 100644 --- a/pkg/controller/manager/manager_controller_test.go +++ b/pkg/controller/manager/manager_controller_test.go @@ -70,7 +70,7 @@ var _ = Describe("Manager controller tests", func() { BeforeEach(func() { // Create a Kubernetes client. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) c = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() diff --git a/pkg/controller/migration/convert/bpf.go b/pkg/controller/migration/convert/bpf.go index e1940c66d7..01298c91a6 100644 --- a/pkg/controller/migration/convert/bpf.go +++ b/pkg/controller/migration/convert/bpf.go @@ -18,8 +18,8 @@ import ( "fmt" "strings" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/render" corev1 "k8s.io/api/core/v1" @@ -61,7 +61,7 @@ func copyK8sServicesEPConfigMap(c *components) error { // handleBPF is a migration handler which ensures BPF configuration is carried forward. func handleBPF(c *components, install *operatorv1.Installation) error { - felixConfiguration := &crdv1.FelixConfiguration{} + felixConfiguration := &v3.FelixConfiguration{} bpf := operatorv1.LinuxDataplaneBPF err := c.client.Get(ctx, types.NamespacedName{Name: "default"}, felixConfiguration) if err != nil { diff --git a/pkg/controller/migration/convert/bpf_test.go b/pkg/controller/migration/convert/bpf_test.go index cdfbf0a28f..2d5f75173e 100644 --- a/pkg/controller/migration/convert/bpf_test.go +++ b/pkg/controller/migration/convert/bpf_test.go @@ -19,9 +19,9 @@ import ( . "github.com/onsi/gomega" "sigs.k8s.io/controller-runtime/pkg/client/fake" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" "github.com/tigera/operator/pkg/render" @@ -35,8 +35,10 @@ import ( var ( cmName = render.K8sSvcEndpointConfigMapName - cmData = map[string]string{"KUBERNETES_SERVICE_HOST": "1.1.1.1", - "KUBERNETES_SERVICE_PORT": "1234"} + cmData = map[string]string{ + "KUBERNETES_SERVICE_HOST": "1.1.1.1", + "KUBERNETES_SERVICE_PORT": "1234", + } endPointCM = &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: cmName, @@ -63,7 +65,7 @@ var _ = Describe("convert bpf config", func() { var ( comps = emptyComponents() i = &operatorv1.Installation{} - f = &crdv1.FelixConfiguration{} + f = &v3.FelixConfiguration{} scheme = kscheme.Scheme ) @@ -71,7 +73,7 @@ var _ = Describe("convert bpf config", func() { comps = emptyComponents() i = &operatorv1.Installation{} f = emptyFelixConfig() - Expect(apis.AddToScheme(scheme)).ToNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ToNot(HaveOccurred()) }) It("converts bpfenabled felixconfig set to true", func() { diff --git a/pkg/controller/migration/convert/convert_test.go b/pkg/controller/migration/convert/convert_test.go index 3c5e7cd91f..d649a4813f 100644 --- a/pkg/controller/migration/convert/convert_test.go +++ b/pkg/controller/migration/convert/convert_test.go @@ -21,8 +21,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" appsv1 "k8s.io/api/apps/v1" @@ -33,17 +33,17 @@ import ( ) var _ = Describe("Parser", func() { - var ctx = context.Background() - var pool *crdv1.IPPool + ctx := context.Background() + var pool *v3.IPPool var scheme *runtime.Scheme BeforeEach(func() { scheme = kscheme.Scheme - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) - pool = crdv1.NewIPPool() - pool.Spec = crdv1.IPPoolSpec{ + pool = v3.NewIPPool() + pool.Spec = v3.IPPoolSpec{ CIDR: "192.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } }) @@ -121,7 +121,7 @@ var _ = Describe("Parser", func() { }) Context("CNI", func() { - var _ = Describe("CNI", func() { + _ = Describe("CNI", func() { It("should load cni from correct fields on calico-node", func() { ds := emptyNodeSpec() ds.Spec.Template.Spec.InitContainers[0].Env = []corev1.EnvVar{ diff --git a/pkg/controller/migration/convert/felix_vars.go b/pkg/controller/migration/convert/felix_vars.go index fc56901053..a01549f853 100644 --- a/pkg/controller/migration/convert/felix_vars.go +++ b/pkg/controller/migration/convert/felix_vars.go @@ -22,9 +22,9 @@ import ( "strings" "time" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/api/pkg/lib/numorstring" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -102,7 +102,7 @@ func handleFelixVars(c *components) error { } - return c.client.Patch(ctx, &crdv1.FelixConfiguration{ + return c.client.Patch(ctx, &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{Name: "default"}, }, p) } @@ -112,7 +112,7 @@ func patchFromVal(key, val string) (patch, error) { // the given env var. to do this, loop through the felixconfigspec // using reflection, finding the struct field where the downcased name // matches the downcased env var name. - fc := reflect.ValueOf(crdv1.FelixConfigurationSpec{}) + fc := reflect.ValueOf(v3.FelixConfigurationSpec{}) for ii := 0; ii < fc.Type().NumField(); ii++ { field := fc.Type().Field(ii) value := fc.Field(ii) @@ -172,15 +172,15 @@ func convert(t interface{}, str string) (interface{}, error) { u := uint32(i) return &u, nil - case *crdv1.IptablesBackend: - v := crdv1.IptablesBackend(str) + case *v3.IptablesBackend: + v := v3.IptablesBackend(str) return &v, nil - case *crdv1.AWSSrcDstCheckOption: - v := crdv1.AWSSrcDstCheckOption(str) + case *v3.AWSSrcDstCheckOption: + v := v3.AWSSrcDstCheckOption(str) return &v, nil - case *[]crdv1.ProtoPort: - pps := []crdv1.ProtoPort{} + case *[]v3.ProtoPort: + pps := []v3.ProtoPort{} if str == "none" { // Failsafe ports support the value "none", which is represented as // an empty slice on the FelixConfiguration API. @@ -196,7 +196,7 @@ func convert(t interface{}, str string) (interface{}, error) { if err != nil { return nil, fmt.Errorf("could not convert port to number: %s", vals[0]) } - pps = append(pps, crdv1.ProtoPort{ + pps = append(pps, v3.ProtoPort{ Port: uint16(port), Protocol: vals[0], }) @@ -229,7 +229,7 @@ func convert(t interface{}, str string) (interface{}, error) { } return &metav1.Duration{Duration: d}, nil - case *crdv1.RouteTableRange: + case *v3.RouteTableRange: minMax := strings.Split(str, "-") if len(minMax) != 2 { return nil, fmt.Errorf("") @@ -243,7 +243,7 @@ func convert(t interface{}, str string) (interface{}, error) { return nil, err } - return &crdv1.RouteTableRange{ + return &v3.RouteTableRange{ Min: min, Max: max, }, nil diff --git a/pkg/controller/migration/convert/felix_vars_test.go b/pkg/controller/migration/convert/felix_vars_test.go index de8300e59a..6d018531fb 100644 --- a/pkg/controller/migration/convert/felix_vars_test.go +++ b/pkg/controller/migration/convert/felix_vars_test.go @@ -25,11 +25,10 @@ import ( "k8s.io/apimachinery/pkg/types" kscheme "k8s.io/client-go/kubernetes/scheme" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/api/pkg/lib/numorstring" "github.com/tigera/operator/pkg/apis" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" - - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ) var _ = Describe("felix env parser", func() { @@ -81,7 +80,7 @@ var _ = Describe("felix env parser", func() { Expect(fe).To(Equal(patch{ Op: "replace", Path: "/spec/failsafeInboundHostPorts", - Value: &[]crdv1.ProtoPort{{Port: 10250, Protocol: "tcp"}}, + Value: &[]v3.ProtoPort{{Port: 10250, Protocol: "tcp"}}, })) }) @@ -91,12 +90,12 @@ var _ = Describe("felix env parser", func() { Expect(fe).To(Equal(patch{ Op: "replace", Path: "/spec/routeTableRange", - Value: &crdv1.RouteTableRange{Min: 22, Max: 44}, + Value: &v3.RouteTableRange{Min: 22, Max: 44}, })) }) It("converts a AWSSrcDstCheckOption", func() { - d := crdv1.AWSSrcDstCheckOption(crdv1.AWSSrcDstCheckOptionDisable) + d := v3.AWSSrcDstCheckOption(v3.AWSSrcDstCheckOptionDisable) fe, err := patchFromVal("awssrcdstcheck", "Disable") Expect(err).ToNot(HaveOccurred()) Expect(fe.Value).To(Equal(&d)) @@ -134,7 +133,7 @@ var _ = Describe("felix env parser", func() { c = emptyComponents() scheme := kscheme.Scheme - Expect(apis.AddToScheme(scheme)).ToNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ToNot(HaveOccurred()) c.client = ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(emptyFelixConfig()).Build() }) @@ -143,7 +142,7 @@ var _ = Describe("felix env parser", func() { Expect(handleFelixVars(&c)).ToNot(HaveOccurred()) - f := crdv1.FelixConfiguration{} + f := v3.FelixConfiguration{} Expect(c.client.Get(ctx, types.NamespacedName{Name: "default"}, &f)).ToNot(HaveOccurred()) Expect(f.Spec.BPFEnabled).To(BeNil()) }) @@ -156,10 +155,10 @@ var _ = Describe("felix env parser", func() { Expect(handleFelixVars(&c)).ToNot(HaveOccurred()) - f := crdv1.FelixConfiguration{} + f := v3.FelixConfiguration{} Expect(c.client.Get(ctx, types.NamespacedName{Name: "default"}, &f)).ToNot(HaveOccurred()) Expect(f.Spec.FailsafeInboundHostPorts).ToNot(BeNil()) - Expect(f.Spec.FailsafeInboundHostPorts).To(Equal(&[]crdv1.ProtoPort{})) + Expect(f.Spec.FailsafeInboundHostPorts).To(Equal(&[]v3.ProtoPort{})) }) It("handles 'none' failsafe outbound ports", func() { @@ -170,10 +169,10 @@ var _ = Describe("felix env parser", func() { Expect(handleFelixVars(&c)).ToNot(HaveOccurred()) - f := crdv1.FelixConfiguration{} + f := v3.FelixConfiguration{} Expect(c.client.Get(ctx, types.NamespacedName{Name: "default"}, &f)).ToNot(HaveOccurred()) Expect(f.Spec.FailsafeOutboundHostPorts).ToNot(BeNil()) - Expect(f.Spec.FailsafeOutboundHostPorts).To(Equal(&[]crdv1.ProtoPort{})) + Expect(f.Spec.FailsafeOutboundHostPorts).To(Equal(&[]v3.ProtoPort{})) }) It("handles natPortRange", func() { @@ -184,7 +183,7 @@ var _ = Describe("felix env parser", func() { Expect(handleFelixVars(&c)).ToNot(HaveOccurred()) - f := crdv1.FelixConfiguration{} + f := v3.FelixConfiguration{} Expect(c.client.Get(ctx, types.NamespacedName{Name: "default"}, &f)).ToNot(HaveOccurred()) Expect(f.Spec.NATPortRange).ToNot(BeNil()) Expect(f.Spec.NATPortRange).To(Equal(&numorstring.Port{MinPort: 32768, MaxPort: 65535})) @@ -198,7 +197,7 @@ var _ = Describe("felix env parser", func() { Expect(handleFelixVars(&c)).ToNot(HaveOccurred()) - f := crdv1.FelixConfiguration{} + f := v3.FelixConfiguration{} Expect(c.client.Get(ctx, types.NamespacedName{Name: "default"}, &f)).ToNot(HaveOccurred()) Expect(f.Spec.IptablesRefreshInterval).ToNot(BeNil()) Expect(f.Spec.IptablesRefreshInterval).To(Equal(&metav1.Duration{Duration: 20 * time.Second})) @@ -212,10 +211,10 @@ var _ = Describe("felix env parser", func() { Expect(handleFelixVars(&c)).ToNot(HaveOccurred()) - f := crdv1.FelixConfiguration{} + f := v3.FelixConfiguration{} Expect(c.client.Get(ctx, types.NamespacedName{Name: "default"}, &f)).ToNot(HaveOccurred()) Expect(f.Spec.IptablesBackend).ToNot(BeNil()) - legacy := crdv1.IptablesBackend(crdv1.IptablesBackendLegacy) + legacy := v3.IptablesBackend(v3.IptablesBackendLegacy) Expect(f.Spec.IptablesBackend).To(Equal(&legacy)) }) }) diff --git a/pkg/controller/migration/convert/ippools.go b/pkg/controller/migration/convert/ippools.go index 2ddb331a01..8bccac2c06 100644 --- a/pkg/controller/migration/convert/ippools.go +++ b/pkg/controller/migration/convert/ippools.go @@ -19,8 +19,8 @@ import ( "net" "strings" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/render" kerrors "k8s.io/apimachinery/pkg/api/errors" ) @@ -32,7 +32,7 @@ import ( // Since the operator only supports one v4 and one v6 only one of each will be picked // if they exist. func handleIPPools(c *components, install *operatorv1.Installation) error { - pools := crdv1.IPPoolList{} + pools := v3.IPPoolList{} if err := c.client.List(ctx, &pools); err != nil && !kerrors.IsNotFound(err) { return fmt.Errorf("failed to list IPPools %v", err) } @@ -153,7 +153,7 @@ func handleIPPools(c *components, install *operatorv1.Installation) error { // should be selected, the first pool that the matcher returns true on is returned. // If there is an error returned from the matcher then that error is returned. // If no pool is found and there is no error then nil,nil is returned. -func getIPPool(pools []crdv1.IPPool, matcher func(crdv1.IPPool) (bool, error)) (*crdv1.IPPool, error) { +func getIPPool(pools []v3.IPPool, matcher func(v3.IPPool) (bool, error)) (*v3.IPPool, error) { for _, pool := range pools { if pool.Spec.Disabled { continue @@ -186,9 +186,9 @@ func isIpv6(ip net.IP) bool { // // if none match then nil, nil is returned // if there is an error parsing the cidr in a pool then that error will be returned -func selectInitialPool(pools []crdv1.IPPool, isver func(ip net.IP) bool) (*crdv1.IPPool, error) { +func selectInitialPool(pools []v3.IPPool, isver func(ip net.IP) bool) (*v3.IPPool, error) { // Select pools prefixed with 'default-ipv' and isver is true - pool, err := getIPPool(pools, func(p crdv1.IPPool) (bool, error) { + pool, err := getIPPool(pools, func(p v3.IPPool) (bool, error) { ip, _, err := net.ParseCIDR(p.Spec.CIDR) if err != nil { return false, fmt.Errorf("failed to parse IPPool %s in datastore: %v", p.Name, err) @@ -208,7 +208,7 @@ func selectInitialPool(pools []crdv1.IPPool, isver func(ip net.IP) bool) (*crdv1 } // If we don't have a pool then just grab any that has the right version - pool, err = getIPPool(pools, func(p crdv1.IPPool) (bool, error) { + pool, err = getIPPool(pools, func(p v3.IPPool) (bool, error) { ip, _, err := net.ParseCIDR(p.Spec.CIDR) if err != nil { return false, fmt.Errorf("failed to parse IPPool %s in datastore: %v", p.Name, err) @@ -225,27 +225,27 @@ func selectInitialPool(pools []crdv1.IPPool, isver func(ip net.IP) bool) (*crdv1 } // convertPool converts the src (CRD) pool into an Installation/Operator IPPool -func convertPool(src crdv1.IPPool) (operatorv1.IPPool, error) { +func convertPool(src v3.IPPool) (operatorv1.IPPool, error) { p := operatorv1.IPPool{CIDR: src.Spec.CIDR} ip := src.Spec.IPIPMode if ip == "" { - ip = crdv1.IPIPModeNever + ip = v3.IPIPModeNever } vx := src.Spec.VXLANMode if vx == "" { - vx = crdv1.VXLANModeNever + vx = v3.VXLANModeNever } switch { - case ip == crdv1.IPIPModeNever && vx == crdv1.VXLANModeNever: + case ip == v3.IPIPModeNever && vx == v3.VXLANModeNever: p.Encapsulation = operatorv1.EncapsulationNone - case ip == crdv1.IPIPModeNever && vx == crdv1.VXLANModeAlways: + case ip == v3.IPIPModeNever && vx == v3.VXLANModeAlways: p.Encapsulation = operatorv1.EncapsulationVXLAN - case ip == crdv1.IPIPModeNever && vx == crdv1.VXLANModeCrossSubnet: + case ip == v3.IPIPModeNever && vx == v3.VXLANModeCrossSubnet: p.Encapsulation = operatorv1.EncapsulationVXLANCrossSubnet - case vx == crdv1.VXLANModeNever && ip == crdv1.IPIPModeAlways: + case vx == v3.VXLANModeNever && ip == v3.IPIPModeAlways: p.Encapsulation = operatorv1.EncapsulationIPIP - case vx == crdv1.VXLANModeNever && ip == crdv1.IPIPModeCrossSubnet: + case vx == v3.VXLANModeNever && ip == v3.IPIPModeCrossSubnet: p.Encapsulation = operatorv1.EncapsulationIPIPCrossSubnet default: return p, fmt.Errorf("unexpected encapsulation combination for pool %+v", src) @@ -263,7 +263,17 @@ func convertPool(src crdv1.IPPool) (operatorv1.IPPool, error) { p.NodeSelector = src.Spec.NodeSelector p.DisableBGPExport = &src.Spec.DisableBGPExport - p.AssignmentMode = src.Spec.AssignmentMode + + if src.Spec.AssignmentMode != nil { + switch *src.Spec.AssignmentMode { + case v3.Automatic: + p.AssignmentMode = operatorv1.AssignmentModeAutomatic + case v3.Manual: + p.AssignmentMode = operatorv1.AssignmentModeManual + default: + return p, fmt.Errorf("unexpected assignment mode %s for pool %+v", *src.Spec.AssignmentMode, src) + } + } return p, nil } diff --git a/pkg/controller/migration/convert/ippools_test.go b/pkg/controller/migration/convert/ippools_test.go index 7c37ad4882..2b7082d6e3 100644 --- a/pkg/controller/migration/convert/ippools_test.go +++ b/pkg/controller/migration/convert/ippools_test.go @@ -22,9 +22,9 @@ import ( . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" corev1 "k8s.io/api/core/v1" @@ -33,73 +33,73 @@ import ( ) var _ = Describe("Convert network tests", func() { - var ctx = context.Background() - var pool *crdv1.IPPool + ctx := context.Background() + var pool *v3.IPPool var scheme *runtime.Scheme var trueValue bool var falseValue bool BeforeEach(func() { scheme = kscheme.Scheme - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) - pool = crdv1.NewIPPool() - pool.Spec = crdv1.IPPoolSpec{ + pool = v3.NewIPPool() + pool.Spec = v3.IPPoolSpec{ CIDR: "192.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } trueValue = true falseValue = false }) Describe("handle IPPool migration", func() { - var v4pool1 *crdv1.IPPool - var v4pool2 *crdv1.IPPool - var v4pooldefault *crdv1.IPPool - var v6pool1 *crdv1.IPPool - var v6pool2 *crdv1.IPPool - var v6pooldefault *crdv1.IPPool + var v4pool1 *v3.IPPool + var v4pool2 *v3.IPPool + var v4pooldefault *v3.IPPool + var v6pool1 *v3.IPPool + var v6pool2 *v3.IPPool + var v6pooldefault *v3.IPPool BeforeEach(func() { - v4pool1 = crdv1.NewIPPool() + v4pool1 = v3.NewIPPool() v4pool1.Name = "not-default" - v4pool1.Spec = crdv1.IPPoolSpec{ + v4pool1.Spec = v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } - v4pool2 = crdv1.NewIPPool() + v4pool2 = v3.NewIPPool() v4pool2.Name = "not-default2" - v4pool2.Spec = crdv1.IPPoolSpec{ + v4pool2.Spec = v3.IPPoolSpec{ CIDR: "2.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } - v4pooldefault = crdv1.NewIPPool() + v4pooldefault = v3.NewIPPool() v4pooldefault.Name = "default-ipv4-pool" - v4pooldefault.Spec = crdv1.IPPoolSpec{ + v4pooldefault.Spec = v3.IPPoolSpec{ CIDR: "3.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } - v6pool1 = crdv1.NewIPPool() + v6pool1 = v3.NewIPPool() v6pool1.Name = "not-default1-v6" - v6pool1.Spec = crdv1.IPPoolSpec{ + v6pool1.Spec = v3.IPPoolSpec{ CIDR: "ff00:0001::/24", - IPIPMode: crdv1.IPIPModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, } - v6pool2 = crdv1.NewIPPool() + v6pool2 = v3.NewIPPool() v6pool2.Name = "not-default2" - v6pool2.Spec = crdv1.IPPoolSpec{ + v6pool2.Spec = v3.IPPoolSpec{ CIDR: "ff00:0002::/24", - IPIPMode: crdv1.IPIPModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, } - v6pooldefault = crdv1.NewIPPool() + v6pooldefault = v3.NewIPPool() v6pooldefault.Name = "default-ipv6-pool" - v6pooldefault.Spec = crdv1.IPPoolSpec{ + v6pooldefault.Spec = v3.IPPoolSpec{ CIDR: "ff00:0003::/24", - IPIPMode: crdv1.IPIPModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, } }) @@ -233,11 +233,11 @@ var _ = Describe("Convert network tests", func() { }} pools := []runtime.Object{} for i, c := range cidrs { - p := crdv1.NewIPPool() + p := v3.NewIPPool() p.Name = fmt.Sprintf("not-default-%d", i) - p.Spec = crdv1.IPPoolSpec{ + p.Spec = v3.IPPoolSpec{ CIDR: c, - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } pools = append(pools, p) @@ -255,7 +255,7 @@ var _ = Describe("Convert network tests", func() { Entry("v4 and v6 pool but no assigning v6", `"assign_ipv4": "true", "assign_ipv6": "false"`, "1.168.4.0/24", "ff00:0001::/24"), ) - DescribeTable("test convert pool flags", func(success bool, crdPool crdv1.IPPool, opPool operatorv1.IPPool) { + DescribeTable("test convert pool flags", func(success bool, crdPool v3.IPPool, opPool operatorv1.IPPool) { p, err := convertPool(crdPool) if success { Expect(err).NotTo(HaveOccurred()) @@ -264,10 +264,10 @@ var _ = Describe("Convert network tests", func() { Expect(err).To(HaveOccurred()) } }, - Entry("ipv4, no encap, nat, block 27", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, no encap, nat, block 27", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeNever, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, BlockSize: 27, @@ -280,10 +280,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, vxlan encap, nat, block 27", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, vxlan encap, nat, block 27", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, BlockSize: 27, @@ -296,10 +296,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, ipip encap, nat, block 27", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, ipip encap, nat, block 27", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeNever, - IPIPMode: crdv1.IPIPModeAlways, + VXLANMode: v3.VXLANModeNever, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, Disabled: false, BlockSize: 27, @@ -312,10 +312,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, vxlancross encap, nat, block 27", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, vxlancross encap, nat, block 27", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeCrossSubnet, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeCrossSubnet, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, BlockSize: 27, @@ -328,10 +328,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, ipipcross encap, nat, block 27", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, ipipcross encap, nat, block 27", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeNever, - IPIPMode: crdv1.IPIPModeCrossSubnet, + VXLANMode: v3.VXLANModeNever, + IPIPMode: v3.IPIPModeCrossSubnet, NATOutgoing: true, Disabled: false, BlockSize: 27, @@ -344,10 +344,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, no encap, no nat, block 27", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, no encap, no nat, block 27", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeNever, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: false, Disabled: false, BlockSize: 27, @@ -360,10 +360,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, no encap, nat, block 24", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, no encap, nat, block 24", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeNever, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, BlockSize: 24, @@ -376,10 +376,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "nodeselectorstring", DisableBGPExport: &falseValue, }), - Entry("ipv4, no encap, nat, block 27, different nodeselector", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, no encap, nat, block 27, different nodeselector", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeNever, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeNever, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, BlockSize: 27, @@ -393,28 +393,28 @@ var _ = Describe("Convert network tests", func() { DisableBGPExport: &falseValue, }), - Entry("ipv4, invalid encap, nat, block 27", false, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, invalid encap, nat, block 27", false, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeAlways, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, Disabled: false, BlockSize: 27, NodeSelector: "nodeselectorstring", }}, operatorv1.IPPool{}), - Entry("ipv4, invalid encap2, nat, block 27", false, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, invalid encap2, nat, block 27", false, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeCrossSubnet, - IPIPMode: crdv1.IPIPModeAlways, + VXLANMode: v3.VXLANModeCrossSubnet, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, Disabled: false, BlockSize: 27, NodeSelector: "nodeselectorstring", }}, operatorv1.IPPool{}), - Entry("ipv4, vxlan encap, nat, disableBGPExport true", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, vxlan encap, nat, disableBGPExport true", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, DisableBGPExport: true, @@ -425,10 +425,10 @@ var _ = Describe("Convert network tests", func() { NodeSelector: "", DisableBGPExport: &trueValue, }), - Entry("ipv4, vxlan encap, nat, disableBGPExport false", true, crdv1.IPPool{Spec: crdv1.IPPoolSpec{ + Entry("ipv4, vxlan encap, nat, disableBGPExport false", true, v3.IPPool{Spec: v3.IPPoolSpec{ CIDR: "1.168.4.0/24", - VXLANMode: crdv1.VXLANModeAlways, - IPIPMode: crdv1.IPIPModeNever, + VXLANMode: v3.VXLANModeAlways, + IPIPMode: v3.IPIPModeNever, NATOutgoing: true, Disabled: false, DisableBGPExport: false, @@ -441,5 +441,4 @@ var _ = Describe("Convert network tests", func() { }), ) }) - }) diff --git a/pkg/controller/migration/convert/network_test.go b/pkg/controller/migration/convert/network_test.go index 924b16892a..9882cff1a0 100644 --- a/pkg/controller/migration/convert/network_test.go +++ b/pkg/controller/migration/convert/network_test.go @@ -30,9 +30,9 @@ import ( kscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" ) @@ -42,27 +42,27 @@ func int32Ptr(x int32) *int32 { var _ = Describe("Convert network tests", func() { ctx := context.Background() - var v4pool *crdv1.IPPool - var v6pool *crdv1.IPPool + var v4pool *v3.IPPool + var v6pool *v3.IPPool var scheme *runtime.Scheme var falseValue bool BeforeEach(func() { scheme = kscheme.Scheme - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) - v4pool = crdv1.NewIPPool() + v4pool = v3.NewIPPool() v4pool.Name = "test-ipv4-pool" - v4pool.Spec = crdv1.IPPoolSpec{ + v4pool.Spec = v3.IPPoolSpec{ CIDR: "192.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } - v6pool = crdv1.NewIPPool() + v6pool = v3.NewIPPool() v6pool.Name = "test-ipv6-pool" - v6pool.Spec = crdv1.IPPoolSpec{ + v6pool.Spec = v3.IPPoolSpec{ CIDR: "2001:db8::1/120", NATOutgoing: true, } @@ -450,8 +450,8 @@ var _ = Describe("Convert network tests", func() { }, ) - v6pool.Spec.IPIPMode = crdv1.IPIPModeNever - v6pool.Spec.VXLANMode = crdv1.VXLANModeAlways + v6pool.Spec.IPIPMode = v3.IPIPModeNever + v6pool.Spec.VXLANMode = v3.VXLANModeAlways c := ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(v6pool, ds, emptyKubeControllerSpec(), emptyFelixConfig()).Build() cfg, err := Convert(ctx, c) Expect(err).ToNot(HaveOccurred()) @@ -487,10 +487,10 @@ var _ = Describe("Convert network tests", func() { }, ) - v4pool.Spec.IPIPMode = crdv1.IPIPModeNever - v4pool.Spec.VXLANMode = crdv1.VXLANModeAlways - v6pool.Spec.IPIPMode = crdv1.IPIPModeNever - v6pool.Spec.VXLANMode = crdv1.VXLANModeAlways + v4pool.Spec.IPIPMode = v3.IPIPModeNever + v4pool.Spec.VXLANMode = v3.VXLANModeAlways + v6pool.Spec.IPIPMode = v3.IPIPModeNever + v6pool.Spec.VXLANMode = v3.VXLANModeAlways c := ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(v4pool, v6pool, ds, emptyKubeControllerSpec(), emptyFelixConfig()).Build() cfg, err := Convert(ctx, c) Expect(err).ToNot(HaveOccurred()) diff --git a/pkg/controller/migration/convert/nftables.go b/pkg/controller/migration/convert/nftables.go index 588dce2fdc..8792fb3278 100644 --- a/pkg/controller/migration/convert/nftables.go +++ b/pkg/controller/migration/convert/nftables.go @@ -17,15 +17,14 @@ import ( "fmt" "strings" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" - v1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "k8s.io/apimachinery/pkg/types" ) // handleNftables is a migration handler which ensures nftables configuration is carried forward. func handleNftables(c *components, install *operatorv1.Installation) error { - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err := c.client.Get(ctx, types.NamespacedName{Name: "default"}, fc) if err != nil { return fmt.Errorf("error reading felixconfiguration %w", err) @@ -36,7 +35,7 @@ func handleNftables(c *components, install *operatorv1.Installation) error { return fmt.Errorf("error reading FELIX_NFTABLESMODE env var %w", err) } - inFelixConfig := fc.Spec.NFTablesMode != nil && *fc.Spec.NFTablesMode == v1.NFTablesModeEnabled + inFelixConfig := fc.Spec.NFTablesMode != nil && *fc.Spec.NFTablesMode == v3.NFTablesModeEnabled enabledEnvVar := envMode != nil && strings.ToLower(*envMode) == "enabled" // A disabled env var will override any other configuration. It's possible to have a feature enabled in the FelixConfiguration diff --git a/pkg/controller/migration/convert/nftables_test.go b/pkg/controller/migration/convert/nftables_test.go index f884d08396..e34a678d06 100644 --- a/pkg/controller/migration/convert/nftables_test.go +++ b/pkg/controller/migration/convert/nftables_test.go @@ -17,21 +17,21 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" - pcv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" v1 "k8s.io/api/core/v1" kscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/utils/ptr" ) var _ = Describe("convert nftables mode", func() { var ( comps = emptyComponents() i = &operatorv1.Installation{} - f = &crdv1.FelixConfiguration{} + f = &v3.FelixConfiguration{} scheme = kscheme.Scheme ) @@ -39,12 +39,11 @@ var _ = Describe("convert nftables mode", func() { comps = emptyComponents() i = &operatorv1.Installation{} f = emptyFelixConfig() - Expect(apis.AddToScheme(scheme)).ToNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ToNot(HaveOccurred()) }) It("converts nftables mode from FelixConfiguration Enabled", func() { - nftMode := pcv1.NFTablesModeEnabled - f.Spec.NFTablesMode = &nftMode + f.Spec.NFTablesMode = ptr.To(v3.NFTablesMode(v3.NFTablesModeEnabled)) comps.client = ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(endPointCM, f).Build() err := handleNftables(&comps, i) @@ -54,8 +53,7 @@ var _ = Describe("convert nftables mode", func() { }) It("converts nftables mode from FelixConfiguration Disabled", func() { - nftMode := pcv1.NFTablesModeDisabled - f.Spec.NFTablesMode = &nftMode + f.Spec.NFTablesMode = ptr.To(v3.NFTablesMode(v3.NFTablesModeDisabled)) comps.client = ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(endPointCM, f).Build() err := handleNftables(&comps, i) Expect(err).ToNot(HaveOccurred()) @@ -63,8 +61,7 @@ var _ = Describe("convert nftables mode", func() { }) It("rejects migration if another dataplane is already set", func() { - nftMode := pcv1.NFTablesModeEnabled - f.Spec.NFTablesMode = &nftMode + f.Spec.NFTablesMode = ptr.To(v3.NFTablesMode(v3.NFTablesModeEnabled)) comps.client = ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(endPointCM, f).Build() // Set the Installation to already have a dataplane mode set. diff --git a/pkg/controller/migration/convert/testutils_test.go b/pkg/controller/migration/convert/testutils_test.go index 8e17c87a58..6c3f94d5c4 100644 --- a/pkg/controller/migration/convert/testutils_test.go +++ b/pkg/controller/migration/convert/testutils_test.go @@ -1,8 +1,7 @@ package convert import ( - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" - + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -160,8 +159,8 @@ func emptyComponents() components { } } -func emptyFelixConfig() *crdv1.FelixConfiguration { - return &crdv1.FelixConfiguration{ +func emptyFelixConfig() *v3.FelixConfiguration { + return &v3.FelixConfiguration{ ObjectMeta: v1.ObjectMeta{ Name: "default", }, diff --git a/pkg/controller/migration/convert/typha_test.go b/pkg/controller/migration/convert/typha_test.go index 7448fc0418..eb21686fa9 100644 --- a/pkg/controller/migration/convert/typha_test.go +++ b/pkg/controller/migration/convert/typha_test.go @@ -26,9 +26,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" kscheme "k8s.io/client-go/kubernetes/scheme" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" ) @@ -47,17 +47,17 @@ func getK8sNodes(x int) *corev1.NodeList { } var _ = Describe("Convert typha check tests", func() { - var ctx = context.Background() + ctx := context.Background() var scheme *runtime.Scheme - var pool *crdv1.IPPool + var pool *v3.IPPool BeforeEach(func() { scheme = kscheme.Scheme - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) - pool = crdv1.NewIPPool() - pool.Spec = crdv1.IPPoolSpec{ + pool = v3.NewIPPool() + pool.Spec = v3.IPPoolSpec{ CIDR: "192.168.4.0/24", - IPIPMode: crdv1.IPIPModeAlways, + IPIPMode: v3.IPIPModeAlways, NATOutgoing: true, } }) @@ -139,7 +139,6 @@ var _ = Describe("Convert typha check tests", func() { Expect(*i.Spec.TyphaMetricsPort).To(Equal(int32(9091))) }) It("defaults prometheus off when no prometheus environment variables set", func() { - Expect(handleFelixNodeMetrics(&comps, i)).ToNot(HaveOccurred()) Expect(i.Spec.TyphaMetricsPort).To(BeNil()) }) diff --git a/pkg/controller/monitor/monitor_controller.go b/pkg/controller/monitor/monitor_controller.go index 0b9fa4d664..6f5ee40077 100644 --- a/pkg/controller/monitor/monitor_controller.go +++ b/pkg/controller/monitor/monitor_controller.go @@ -20,8 +20,6 @@ import ( "fmt" "reflect" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -139,7 +137,7 @@ func add(_ manager.Manager, c ctrlruntime.Controller) error { return fmt.Errorf("monitor-controller failed to watch ManagementClusterConnection resource: %w", err) } - if err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}); err != nil { + if err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}); err != nil { return fmt.Errorf("monitor-controller failed to watch FelixConfiguration resource: %w", err) } diff --git a/pkg/controller/monitor/monitor_controller_test.go b/pkg/controller/monitor/monitor_controller_test.go index 6960bcea18..574e6018b6 100644 --- a/pkg/controller/monitor/monitor_controller_test.go +++ b/pkg/controller/monitor/monitor_controller_test.go @@ -65,7 +65,7 @@ var _ = Describe("Monitor controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) diff --git a/pkg/controller/nonclusterhost/nonclusterhost_controller_test.go b/pkg/controller/nonclusterhost/nonclusterhost_controller_test.go index af756e2178..27dfd09c83 100644 --- a/pkg/controller/nonclusterhost/nonclusterhost_controller_test.go +++ b/pkg/controller/nonclusterhost/nonclusterhost_controller_test.go @@ -48,7 +48,7 @@ var _ = Describe("NonClusterHost controller tests", func() { BeforeEach(func() { scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) diff --git a/pkg/controller/options/options.go b/pkg/controller/options/options.go index da30ec6014..92e7b817d7 100644 --- a/pkg/controller/options/options.go +++ b/pkg/controller/options/options.go @@ -46,4 +46,7 @@ type AddOptions struct { // use external elasticsearch. When set, the operator will not install Elasticsearch // and instead will configure the cluster to use an external Elasticsearch. ElasticExternal bool + + // Whether or not to use crd.projectcalico.org/v1 or projectcalico.org/v3 for Calico CRDs. + UseV3CRDs bool } diff --git a/pkg/controller/packetcapture/packetcapture_controller_test.go b/pkg/controller/packetcapture/packetcapture_controller_test.go index 73a56dfcc0..a06910efcf 100644 --- a/pkg/controller/packetcapture/packetcapture_controller_test.go +++ b/pkg/controller/packetcapture/packetcapture_controller_test.go @@ -68,7 +68,7 @@ var _ = Describe("packet capture controller tests", func() { BeforeEach(func() { // Set up the scheme scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/policyrecommendation/policyrecommendation_controller_test.go b/pkg/controller/policyrecommendation/policyrecommendation_controller_test.go index 80895c1c1a..a28f591b31 100644 --- a/pkg/controller/policyrecommendation/policyrecommendation_controller_test.go +++ b/pkg/controller/policyrecommendation/policyrecommendation_controller_test.go @@ -61,7 +61,7 @@ var _ = Describe("PolicyRecommendation controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -470,7 +470,7 @@ var _ = Describe("PolicyRecommendation controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/secrets/cluster_ca_controller_test.go b/pkg/controller/secrets/cluster_ca_controller_test.go index 18e3c92f55..b2d20d345f 100644 --- a/pkg/controller/secrets/cluster_ca_controller_test.go +++ b/pkg/controller/secrets/cluster_ca_controller_test.go @@ -68,7 +68,7 @@ var _ = Describe("ClusterCA controller", func() { BeforeEach(func() { // Any test-specific preparation should be done in subsequen BeforeEach blocks in the Contexts below. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/secrets/tenant_controller_test.go b/pkg/controller/secrets/tenant_controller_test.go index 8ce9cbb0a4..38c8a8d5cf 100644 --- a/pkg/controller/secrets/tenant_controller_test.go +++ b/pkg/controller/secrets/tenant_controller_test.go @@ -83,7 +83,7 @@ var _ = Describe("Tenant controller", func() { // This BeforeEach contains common preparation for all tests - both single-tenant and multi-tenant. // Any test-specific preparation should be done in subsequen BeforeEach blocks in the Contexts below. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).ShouldNot(HaveOccurred()) Expect(storagev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(appsv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(rbacv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/status/status_test.go b/pkg/controller/status/status_test.go index 856e13e6fc..5f150c86c3 100644 --- a/pkg/controller/status/status_test.go +++ b/pkg/controller/status/status_test.go @@ -53,7 +53,7 @@ var _ = Describe("Status reporting tests", func() { // Setup Scheme for all resources scheme := runtime.NewScheme() Expect(certV1.AddToScheme(scheme)).ShouldNot(HaveOccurred()) - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(appsv1.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(corev1.AddToScheme(scheme)).NotTo(HaveOccurred()) @@ -64,7 +64,7 @@ var _ = Describe("Status reporting tests", func() { oldScheme := runtime.NewScheme() Expect(certV1beta1.AddToScheme(oldScheme)).ShouldNot(HaveOccurred()) - err = apis.AddToScheme(oldScheme) + err = apis.AddToScheme(oldScheme, false) Expect(err).NotTo(HaveOccurred()) oldVersionClient = fake.NewClientBuilder().WithScheme(oldScheme).Build() @@ -548,44 +548,67 @@ var _ = Describe("Status reporting tests", func() { Entry("no CSR is present - k8s v1.18", nil, false, false), Entry("1 pending CSR is present - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}}}, + {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}}, + }, false, true), Entry("1 pending CSR is present, but no labels - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1"}}}, + {ObjectMeta: metav1.ObjectMeta{Name: "csr1"}}, + }, false, false), Entry("1 approved CSR is present - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1beta1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1beta1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}, + }, + }, }, false, false), Entry("2 approved CSR are present - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1beta1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}}}, - {ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}, - Status: certV1beta1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1beta1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}, + Status: certV1beta1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}, + }, + }, }, false, false), Entry("1 approved, 1 pending CSR are present - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1beta1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1beta1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}, + }, + }, {ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}}, }, false, true), Entry("1 pending CSR are present (approved: no, cert: yes) - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1beta1.CertificateSigningRequestStatus{Certificate: []byte("cert")}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1beta1.CertificateSigningRequestStatus{Certificate: []byte("cert")}, + }, }, false, true), Entry("1 pending CSR are present (approved: yes, cert: no) - k8s v1.18", []*certV1beta1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, Status: certV1beta1.CertificateSigningRequestStatus{ - Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}}}, + Conditions: []certV1beta1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1beta1.CertificateApproved}}, + }, + }, {ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}}, }, false, true), ) @@ -602,44 +625,67 @@ var _ = Describe("Status reporting tests", func() { Entry("no CSR is present - k8s v1.19", nil, false, false), Entry("1 pending CSR is present - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}}}, + {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}}, + }, false, true), Entry("1 pending CSR is present, but no labels - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1"}}}, + {ObjectMeta: metav1.ObjectMeta{Name: "csr1"}}, + }, false, false), Entry("1 approved CSR is present - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}, + }, + }, }, false, false), Entry("2 approved CSR are present - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}}}, - {ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}, - Status: certV1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}, + Status: certV1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}, + }, + }, }, false, false), Entry("1 approved, 1 pending CSR are present - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1.CertificateSigningRequestStatus{Certificate: []byte("cert"), - Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1.CertificateSigningRequestStatus{ + Certificate: []byte("cert"), + Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}, + }, + }, {ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}}, }, false, true), Entry("1 pending CSR are present (approved: no, cert: yes) - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, - Status: certV1.CertificateSigningRequestStatus{Certificate: []byte("cert")}}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + Status: certV1.CertificateSigningRequestStatus{Certificate: []byte("cert")}, + }, }, false, true), Entry("1 pending CSR are present (approved: yes, cert: no) - k8s v1.19", []*certV1.CertificateSigningRequest{ - {ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, + { + ObjectMeta: metav1.ObjectMeta{Name: "csr1", Labels: labels}, Status: certV1.CertificateSigningRequestStatus{ - Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}}}, + Conditions: []certV1.CertificateSigningRequestCondition{{Status: corev1.ConditionTrue, Type: certV1.CertificateApproved}}, + }, + }, {ObjectMeta: metav1.ObjectMeta{Name: "csr2", Labels: labels}}, }, false, true), ) diff --git a/pkg/controller/tiers/tiers_controller_test.go b/pkg/controller/tiers/tiers_controller_test.go index d202840917..7c7c6d950f 100644 --- a/pkg/controller/tiers/tiers_controller_test.go +++ b/pkg/controller/tiers/tiers_controller_test.go @@ -48,7 +48,7 @@ var _ = Describe("tier controller tests", func() { BeforeEach(func() { // The schema contains all objects that should be known to the fake client when the test runs. scheme = runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(operatorv1.SchemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred()) Expect(appsv1.AddToScheme(scheme)) diff --git a/pkg/controller/utils/auth_test.go b/pkg/controller/utils/auth_test.go index d313a37ddb..949783e852 100644 --- a/pkg/controller/utils/auth_test.go +++ b/pkg/controller/utils/auth_test.go @@ -44,7 +44,7 @@ var _ = Describe("LDAP secrets tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) Expect(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) Expect(operatorv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/utils/component.go b/pkg/controller/utils/component.go index dfb0e23dd6..dc364669d6 100644 --- a/pkg/controller/utils/component.go +++ b/pkg/controller/utils/component.go @@ -568,6 +568,15 @@ func mergeState(desired client.Object, current runtime.Object) client.Object { desiredMeta.SetCreationTimestamp(currentMeta.GetCreationTimestamp()) } + // Maintain any finalizers on objects that are not owned by the tigera/operator. + finalizers := desiredMeta.GetFinalizers() + for _, f := range currentMeta.GetFinalizers() { + if !strings.Contains(f, "tigera.io") { + finalizers = append(finalizers, f) + } + } + desiredMeta.SetFinalizers(finalizers) + // Update the generation on the desired object to match the current object. desiredMeta.SetGeneration(currentMeta.GetGeneration()) diff --git a/pkg/controller/utils/component_test.go b/pkg/controller/utils/component_test.go index bf5779e1f1..17e898d687 100644 --- a/pkg/controller/utils/component_test.go +++ b/pkg/controller/utils/component_test.go @@ -71,7 +71,7 @@ var _ = Describe("Component handler tests", func() { BeforeEach(func() { // Create a Kubernetes client. scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) diff --git a/pkg/controller/utils/elasticsearch_test.go b/pkg/controller/utils/elasticsearch_test.go index 4982aaeb62..2657fd2bb6 100644 --- a/pkg/controller/utils/elasticsearch_test.go +++ b/pkg/controller/utils/elasticsearch_test.go @@ -51,179 +51,181 @@ const ( indexName = "tigera_secure_ee_test_index" ) -var newPolicies bool -var updateToReadonly bool -var _ = Describe("Elasticsearch tests", func() { - Context("Create elasticsearch client", func() { - var ( - c client.Client - ctx context.Context - scheme *runtime.Scheme - ) - - BeforeEach(func() { - // Create a Kubernetes client. - scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - Expect(v1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) - Expect(apps.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) - Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) - - c = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() - ctx = context.Background() - - Expect(c.Create(ctx, &operatorv1.Installation{ - ObjectMeta: metav1.ObjectMeta{Name: "default"}, - })).ShouldNot(HaveOccurred()) - }) - - It("creates an client for internal elastic", func() { - Expect(c.Create(ctx, &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{Namespace: common.OperatorNamespace(), Name: render.ElasticsearchAdminUserSecret}, - Data: map[string][]byte{"elastic": []byte("anyPass")}, - })).ShouldNot(HaveOccurred()) - - esInternalCert, err := secret.CreateTLSSecret( - nil, - render.TigeraElasticsearchInternalCertSecret, - common.OperatorNamespace(), - "tls.key", - "tls.crt", - tls.DefaultCertificateDuration, - nil, +var ( + newPolicies bool + updateToReadonly bool + _ = Describe("Elasticsearch tests", func() { + Context("Create elasticsearch client", func() { + var ( + c client.Client + ctx context.Context + scheme *runtime.Scheme ) - Expect(err).ShouldNot(HaveOccurred()) - Expect(c.Create(ctx, esInternalCert)).ShouldNot(HaveOccurred()) - mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(http.StatusOK) - })) - defer mockServer.Close() + BeforeEach(func() { + // Create a Kubernetes client. + scheme = runtime.NewScheme() + err := apis.AddToScheme(scheme, false) + Expect(err).NotTo(HaveOccurred()) - _, err = NewElasticClient(c, ctx, mockServer.URL, false) - Expect(err).NotTo(HaveOccurred()) - }) + Expect(v1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(apps.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) + Expect(batchv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) - It("creates an client for external elastic", func() { - Expect(c.Create(ctx, &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{Namespace: common.OperatorNamespace(), Name: render.ElasticsearchAdminUserSecret}, - Data: map[string][]byte{"tigera-mgmt": []byte("anyPass")}, - })).ShouldNot(HaveOccurred()) - - esExternalCert, err := secret.CreateTLSSecret( - nil, - logstorage.ExternalESPublicCertName, - common.OperatorNamespace(), - "tls.key", - "tls.crt", - tls.DefaultCertificateDuration, - nil, - "elastic.tigera.io", - ) - Expect(err).ShouldNot(HaveOccurred()) - Expect(c.Create(ctx, esExternalCert)).ShouldNot(HaveOccurred()) - - clientCert, err := secret.CreateTLSSecret( - nil, - logstorage.ExternalCertsSecret, - common.OperatorNamespace(), - "client.key", - "client.crt", - tls.DefaultCertificateDuration, - nil, - ) - Expect(err).ShouldNot(HaveOccurred()) - Expect(c.Create(ctx, clientCert)).ShouldNot(HaveOccurred()) + c = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() + ctx = context.Background() - mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(http.StatusOK) - })) - defer mockServer.Close() + Expect(c.Create(ctx, &operatorv1.Installation{ + ObjectMeta: metav1.ObjectMeta{Name: "default"}, + })).ShouldNot(HaveOccurred()) + }) - _, err = NewElasticClient(c, ctx, mockServer.URL, true) - Expect(err).NotTo(HaveOccurred()) - }) - }) + It("creates an client for internal elastic", func() { + Expect(c.Create(ctx, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{Namespace: common.OperatorNamespace(), Name: render.ElasticsearchAdminUserSecret}, + Data: map[string][]byte{"elastic": []byte("anyPass")}, + })).ShouldNot(HaveOccurred()) + + esInternalCert, err := secret.CreateTLSSecret( + nil, + render.TigeraElasticsearchInternalCertSecret, + common.OperatorNamespace(), + "tls.key", + "tls.crt", + tls.DefaultCertificateDuration, + nil, + ) + Expect(err).ShouldNot(HaveOccurred()) + Expect(c.Create(ctx, esInternalCert)).ShouldNot(HaveOccurred()) + + mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(http.StatusOK) + })) + defer mockServer.Close() + + _, err = NewElasticClient(c, ctx, mockServer.URL, false) + Expect(err).NotTo(HaveOccurred()) + }) - Context("ILM", func() { - var ( - eClient *esClient - ctx context.Context - rolloverMax = resource.MustParse(fmt.Sprintf("%dGi", DefaultMaxIndexSizeGi)) - trt *testRoundTripper - ) - BeforeEach(func() { - trt = &testRoundTripper{} - client := &http.Client{ - Transport: http.RoundTripper(trt), - } - eClient = mockElasticClient(client, baseURI) - ctx = context.Background() + It("creates an client for external elastic", func() { + Expect(c.Create(ctx, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{Namespace: common.OperatorNamespace(), Name: render.ElasticsearchAdminUserSecret}, + Data: map[string][]byte{"tigera-mgmt": []byte("anyPass")}, + })).ShouldNot(HaveOccurred()) + + esExternalCert, err := secret.CreateTLSSecret( + nil, + logstorage.ExternalESPublicCertName, + common.OperatorNamespace(), + "tls.key", + "tls.crt", + tls.DefaultCertificateDuration, + nil, + "elastic.tigera.io", + ) + Expect(err).ShouldNot(HaveOccurred()) + Expect(c.Create(ctx, esExternalCert)).ShouldNot(HaveOccurred()) + + clientCert, err := secret.CreateTLSSecret( + nil, + logstorage.ExternalCertsSecret, + common.OperatorNamespace(), + "client.key", + "client.crt", + tls.DefaultCertificateDuration, + nil, + ) + Expect(err).ShouldNot(HaveOccurred()) + Expect(c.Create(ctx, clientCert)).ShouldNot(HaveOccurred()) + + mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(http.StatusOK) + })) + defer mockServer.Close() + + _, err = NewElasticClient(c, ctx, mockServer.URL, true) + Expect(err).NotTo(HaveOccurred()) + }) }) - It("max rollover size should be set if ES disk is large", func() { - Expect(nil).Should(BeNil()) - defaultStorage := resource.MustParse(fmt.Sprintf("%dGi", 800)) - expectedRolloverSize := rolloverMax.Value() - - totalEsStorage := defaultStorage.Value() - // using flow logs disk allocation value - diskPercentage := 0.7 - diskForLogType := 0.9 + Context("ILM", func() { + var ( + eClient *esClient + ctx context.Context + rolloverMax = resource.MustParse(fmt.Sprintf("%dGi", DefaultMaxIndexSizeGi)) + trt *testRoundTripper + ) + BeforeEach(func() { + trt = &testRoundTripper{} + client := &http.Client{ + Transport: http.RoundTripper(trt), + } + eClient = mockElasticClient(client, baseURI) + ctx = context.Background() + }) - rolloverSize := calculateRolloverSize(totalEsStorage, diskPercentage, diskForLogType) - Expect(rolloverSize).To(Equal(fmt.Sprintf("%db", expectedRolloverSize))) - }) - It("rollover age", func() { - By("for retention period lesser than retention factor") - Expect("1d").To(Equal(calculateRolloverAge(2))) + It("max rollover size should be set if ES disk is large", func() { + Expect(nil).Should(BeNil()) + defaultStorage := resource.MustParse(fmt.Sprintf("%dGi", 800)) + expectedRolloverSize := rolloverMax.Value() - By("for retention period 0") - Expect("1h").To(Equal(calculateRolloverAge(0))) - }) - It("apply new lifecycle policy", func() { - newPolicies = true - totalDiskSize := resource.MustParse("100Gi") - pd := buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 10, true) + totalEsStorage := defaultStorage.Value() + // using flow logs disk allocation value + diskPercentage := 0.7 + diskForLogType := 0.9 - err := eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ - indexName: pd, + rolloverSize := calculateRolloverSize(totalEsStorage, diskPercentage, diskForLogType) + Expect(rolloverSize).To(Equal(fmt.Sprintf("%db", expectedRolloverSize))) }) - Expect(err).To(BeNil()) - }) - It("update existing lifecycle policy", func() { - newPolicies = false - totalDiskSize := resource.MustParse("100Gi") - pd := buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 5, false) - err := eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ - indexName: pd, + It("rollover age", func() { + By("for retention period lesser than retention factor") + Expect("1d").To(Equal(calculateRolloverAge(2))) + + By("for retention period 0") + Expect("1h").To(Equal(calculateRolloverAge(0))) }) - Expect(err).To(BeNil()) - Expect(trt.hasUpdatedPolicy).To(BeTrue()) - - // Applying the same policy has no effect (since there is no change) - trt.hasUpdatedPolicy = false - trt.getPolicyOverride = "test_files/02_get_policy.json" - pd = buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 5, false) - err = eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ - indexName: pd, + It("apply new lifecycle policy", func() { + newPolicies = true + totalDiskSize := resource.MustParse("100Gi") + pd := buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 10, true) + + err := eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ + indexName: pd, + }) + Expect(err).To(BeNil()) }) - Expect(err).To(BeNil()) - Expect(trt.hasUpdatedPolicy).To(BeFalse()) - - // Applying an updated policy (warm index writable) triggers an update (since there is a change) - updateToReadonly = true - pd = buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 5, true) - err = eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ - indexName: pd, + It("update existing lifecycle policy", func() { + newPolicies = false + totalDiskSize := resource.MustParse("100Gi") + pd := buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 5, false) + err := eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ + indexName: pd, + }) + Expect(err).To(BeNil()) + Expect(trt.hasUpdatedPolicy).To(BeTrue()) + + // Applying the same policy has no effect (since there is no change) + trt.hasUpdatedPolicy = false + trt.getPolicyOverride = "test_files/02_get_policy.json" + pd = buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 5, false) + err = eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ + indexName: pd, + }) + Expect(err).To(BeNil()) + Expect(trt.hasUpdatedPolicy).To(BeFalse()) + + // Applying an updated policy (warm index writable) triggers an update (since there is a change) + updateToReadonly = true + pd = buildILMPolicy(totalDiskSize.Value(), 0.7, .9, 5, true) + err = eClient.createOrUpdatePolicies(ctx, map[string]policyDetail{ + indexName: pd, + }) + Expect(err).To(BeNil()) + Expect(trt.hasUpdatedPolicy).To(BeTrue()) }) - Expect(err).To(BeNil()) - Expect(trt.hasUpdatedPolicy).To(BeTrue()) }) }) -}) +) type testRoundTripper struct { e error diff --git a/pkg/controller/utils/felix_configuration.go b/pkg/controller/utils/felix_configuration.go index 4c100d764c..bd82f6690c 100644 --- a/pkg/controller/utils/felix_configuration.go +++ b/pkg/controller/utils/felix_configuration.go @@ -18,15 +18,15 @@ import ( "context" "fmt" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" ) -func PatchFelixConfiguration(ctx context.Context, c client.Client, patchFn func(fc *crdv1.FelixConfiguration) (bool, error)) (*crdv1.FelixConfiguration, error) { +func PatchFelixConfiguration(ctx context.Context, c client.Client, patchFn func(fc *v3.FelixConfiguration) (bool, error)) (*v3.FelixConfiguration, error) { // Fetch any existing default FelixConfiguration object. - fc := &crdv1.FelixConfiguration{} + fc := &v3.FelixConfiguration{} err := c.Get(ctx, types.NamespacedName{Name: "default"}, fc) if err != nil && !errors.IsNotFound(err) { return nil, fmt.Errorf("unable to read FelixConfiguration: %w", err) @@ -57,8 +57,8 @@ func PatchFelixConfiguration(ctx context.Context, c client.Client, patchFn func( return fc, nil } -func GetFelixConfiguration(ctx context.Context, c client.Client) (*crdv1.FelixConfiguration, error) { - fc := &crdv1.FelixConfiguration{} +func GetFelixConfiguration(ctx context.Context, c client.Client) (*v3.FelixConfiguration, error) { + fc := &v3.FelixConfiguration{} err := c.Get(ctx, types.NamespacedName{Name: "default"}, fc) if err != nil && !errors.IsNotFound(err) { return nil, fmt.Errorf("unable to read FelixConfiguration: %w", err) @@ -66,7 +66,7 @@ func GetFelixConfiguration(ctx context.Context, c client.Client) (*crdv1.FelixCo return fc, nil } -func IsFelixPrometheusMetricsEnabled(felixConfiguration *crdv1.FelixConfiguration) bool { +func IsFelixPrometheusMetricsEnabled(felixConfiguration *v3.FelixConfiguration) bool { if felixConfiguration.Spec.PrometheusMetricsEnabled != nil { return *felixConfiguration.Spec.PrometheusMetricsEnabled } diff --git a/pkg/controller/utils/imageset/imageset_test.go b/pkg/controller/utils/imageset/imageset_test.go index b749637406..566bfe7ae3 100644 --- a/pkg/controller/utils/imageset/imageset_test.go +++ b/pkg/controller/utils/imageset/imageset_test.go @@ -35,7 +35,7 @@ import ( var _ = Describe("imageset tests", func() { BeforeEach(func() { - Expect(apis.AddToScheme(kscheme.Scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(kscheme.Scheme, false)).NotTo(HaveOccurred()) }) Context("no imageset is fine", func() { diff --git a/pkg/controller/utils/utils.go b/pkg/controller/utils/utils.go index 492f1d338d..c7713f0a42 100644 --- a/pkg/controller/utils/utils.go +++ b/pkg/controller/utils/utils.go @@ -51,7 +51,6 @@ import ( v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/controller/k8sapi" "github.com/tigera/operator/pkg/ctrlruntime" @@ -831,7 +830,7 @@ func AddTigeraStatusWatch(c ctrlruntime.Controller, name string) error { // GetKubeControllerMetricsPort fetches kube controller metrics port. func GetKubeControllerMetricsPort(ctx context.Context, client client.Client) (int, error) { - kubeControllersConfig := &crdv1.KubeControllersConfiguration{} + kubeControllersConfig := &v3.KubeControllersConfiguration{} kubeControllersMetricsPort := 0 // Query the KubeControllersConfiguration object. We'll use this to help configure kube-controllers metric port. diff --git a/pkg/controller/utils/utils_test.go b/pkg/controller/utils/utils_test.go index 432c75566a..3554af325a 100644 --- a/pkg/controller/utils/utils_test.go +++ b/pkg/controller/utils/utils_test.go @@ -63,7 +63,7 @@ var _ = Describe("Utils elasticsearch license type tests", func() { BeforeEach(func() { // Create a Kubernetes client. scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(v1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -98,7 +98,6 @@ var _ = Describe("Utils elasticsearch license type tests", func() { _, err := GetElasticLicenseType(ctx, c, log) Expect(err).Should(HaveOccurred()) }) - }) var _ = Describe("Tigera License polling test", func() { @@ -144,7 +143,7 @@ var _ = Describe("Utils APIServer type tests", func() { BeforeEach(func() { // Create a Kubernetes client. scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(v1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -186,7 +185,6 @@ var _ = Describe("Utils APIServer type tests", func() { }) var _ = Describe("ValidateResourceNameIsQualified", func() { - It("returns nil for a compliant kubernetes name.", func() { qualifiedName := "proper-resource-name" @@ -239,7 +237,7 @@ var _ = Describe("PopulateK8sServiceEndPoint", func() { BeforeEach(func() { // Create a Kubernetes client. scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) Expect(v1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -274,7 +272,6 @@ var _ = Describe("PopulateK8sServiceEndPoint", func() { Expect(err).To(BeNil()) }) - }) var _ = Describe("Utils ElasticSearch test", func() { @@ -333,9 +330,7 @@ func (m *fakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*me } var _ = Describe("CreatePredicateForObject", func() { - var ( - objMeta metav1.Object - ) + var objMeta metav1.Object Context("when the name and namespace were specified with empty strings", func() { BeforeEach(func() { diff --git a/pkg/controller/whisker/controller.go b/pkg/controller/whisker/controller.go index 5099d22519..85a7f261da 100644 --- a/pkg/controller/whisker/controller.go +++ b/pkg/controller/whisker/controller.go @@ -28,8 +28,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operatorv1 "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/controller/certificatemanager" "github.com/tigera/operator/pkg/controller/options" @@ -102,7 +102,7 @@ func Add(mgr manager.Manager, opts options.AddOptions) error { return fmt.Errorf("whisker-controller failed to watch Tigerastatus: %w", err) } - if err = c.WatchObject(&crdv1.ClusterInformation{}, &handler.EnqueueRequestForObject{}); err != nil { + if err = c.WatchObject(&v3.ClusterInformation{}, &handler.EnqueueRequestForObject{}); err != nil { return fmt.Errorf("whisker-controller failed to watch ClusterInformation") } @@ -245,7 +245,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) ( ClusterDomain: r.clusterDomain, } - clusterInfo := &crdv1.ClusterInformation{} + clusterInfo := &v3.ClusterInformation{} err = r.cli.Get(ctx, utils.DefaultInstanceKey, clusterInfo) if err != nil { reqLogger.Info("Unable to retrieve ClusterInformation", "error", err) diff --git a/pkg/render/apiserver_test.go b/pkg/render/apiserver_test.go index 062c9b13e2..e08adeca51 100644 --- a/pkg/render/apiserver_test.go +++ b/pkg/render/apiserver_test.go @@ -86,7 +86,7 @@ var _ = Describe("API server rendering tests (Calico Enterprise)", func() { apiserver = &operatorv1.APIServerSpec{} dnsNames = dns.GetServiceDNSNames(render.APIServerServiceName, render.APIServerNamespace, clusterDomain) scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err = certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -1760,7 +1760,7 @@ var _ = Describe("API server rendering tests (Calico)", func() { } apiserver = &operatorv1.APIServerSpec{} scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() var err error certificateManager, err = certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/compliance_test.go b/pkg/render/compliance_test.go index 02afb87d4d..d1756ec204 100644 --- a/pkg/render/compliance_test.go +++ b/pkg/render/compliance_test.go @@ -76,7 +76,7 @@ var _ = Describe("compliance rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -312,7 +312,6 @@ var _ = Describe("compliance rendering tests", func() { container = test.GetContainer(ds.Spec.Template.Spec.Containers, "compliance-benchmarker") Expect(container).NotTo(BeNil()) Expect(container.Resources).To(Equal(complianceResources)) - }) It("should render resource requests and limits for compliance report", func() { @@ -340,7 +339,6 @@ var _ = Describe("compliance rendering tests", func() { Expect(reporter.Template.Spec.Containers).To(HaveLen(1)) container := test.GetContainer(reporter.Template.Spec.Containers, "reporter") Expect(container.Resources).To(Equal(complianceResources)) - }) Context("Standalone cluster", func() { @@ -723,7 +721,6 @@ var _ = Describe("compliance rendering tests", func() { }) Context("Certificate management enabled", func() { - It("should render init containers and volume changes", func() { ca, _ := tls.MakeCA(rmeta.DefaultOperatorCASignerName()) cert, _, _ := ca.Config.GetPEMBytes() // create a valid pem block @@ -1173,7 +1170,8 @@ var _ = Describe("compliance rendering tests", func() { render.ComplianceControllerServiceAccount, render.ComplianceReporterServiceAccount, render.ComplianceServerServiceAccount, - render.ComplianceSnapshotterServiceAccount} + render.ComplianceSnapshotterServiceAccount, + } for _, name := range expectedClusterRoleBindings { assertClusterRoleBindingHasSubjects(tenantAResources, @@ -1471,7 +1469,6 @@ var _ = Describe("compliance rendering tests", func() { }) Context("single-tenant rendering", func() { - It("should NOT render impersonation permissions as part of tigera-compliance-server ClusterRole", func() { cfg.ExternalElastic = true cfg.Tenant = &operatorv1.Tenant{ diff --git a/pkg/render/dex_test.go b/pkg/render/dex_test.go index b808bda301..bb318ce827 100644 --- a/pkg/render/dex_test.go +++ b/pkg/render/dex_test.go @@ -138,7 +138,7 @@ var _ = Describe("dex rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -554,7 +554,6 @@ var _ = Describe("dex rendering tests", func() { initContainer := test.GetContainer(deploy.Spec.Template.Spec.InitContainers, "tigera-dex-tls-key-cert-provisioner") Expect(initContainer).NotTo(BeNil()) Expect(initContainer.Resources).To(Equal(dexInitContainerResources)) - }) It("should render configuration with default Init container resource requests and limits", func() { ca, _ := tls.MakeCA(rmeta.DefaultOperatorCASignerName()) @@ -587,7 +586,6 @@ var _ = Describe("dex rendering tests", func() { "memory": resource.MustParse("50Mi"), }, })) - }) Context("allow-tigera rendering", func() { diff --git a/pkg/render/fluentd_test.go b/pkg/render/fluentd_test.go index da970ea53e..6e763cc102 100644 --- a/pkg/render/fluentd_test.go +++ b/pkg/render/fluentd_test.go @@ -64,7 +64,7 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { // Initialize a default instance to use. Each test can override this to its // desired configuration. scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -219,7 +219,6 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }) It("should render fluentd Daemonset with resources requests/limits", func() { - ca, _ := tls.MakeCA(rmeta.DefaultOperatorCASignerName()) cert, _, _ := ca.Config.GetPEMBytes() // create a valid pem block cfg.Installation.CertificateManagement = &operatorv1.CertificateManagement{CACert: cert} @@ -519,7 +518,6 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }) It("should render for Windows nodes", func() { - expectedResources := []client.Object{ &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: render.FluentdPolicyName, Namespace: render.LogCollectorNamespace}, TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}}, &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: render.FluentdMetricsServiceWindows, Namespace: render.LogCollectorNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"}}, @@ -664,7 +662,6 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }) It("should render with Syslog configuration", func() { - expectedResources := []client.Object{ &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: render.FluentdPolicyName, Namespace: render.LogCollectorNamespace}, TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}}, &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: render.FluentdMetricsService, Namespace: render.LogCollectorNamespace}, TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"}}, @@ -983,16 +980,19 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { {Name: "EKS_CLOUDWATCH_LOG_STREAM_PREFIX", Value: ""}, {Name: "EKS_CLOUDWATCH_LOG_FETCH_INTERVAL", Value: "900"}, {Name: "AWS_REGION", Value: "us-west-1", ValueFrom: nil}, - {Name: "AWS_ACCESS_KEY_ID", + { + Name: "AWS_ACCESS_KEY_ID", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "tigera-eks-log-forwarder-secret", }, Key: "aws-id", - }}, + }, + }, }, - {Name: "AWS_SECRET_ACCESS_KEY", + { + Name: "AWS_SECRET_ACCESS_KEY", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ @@ -1000,7 +1000,8 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }, Key: "aws-key", Optional: nil, - }}, + }, + }, }, {Name: "LINSEED_ENABLED", Value: "true"}, {Name: "LINSEED_ENDPOINT", Value: "https://tigera-linseed.tigera-elasticsearch.svc"}, @@ -1031,7 +1032,6 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }) It("should render with EKS Cloudwatch Log with resources", func() { - cfg.EKSConfig = setupEKSCloudwatchLogConfig() cfg.ESClusterConfig = relasticsearch.NewClusterConfig("clusterTestName", 1, 1, 1) cfg.Installation = &operatorv1.InstallationSpec{ @@ -1081,11 +1081,9 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { initContainer := test.GetContainer(deploy.Spec.Template.Spec.InitContainers, "eks-log-forwarder-startup") Expect(initContainer).NotTo(BeNil()) Expect(initContainer.Resources).To(Equal(corev1.ResourceRequirements{})) - }) It("should render with EKS Cloudwatch Log with multi tenant envvars", func() { - expectedResources := getExpectedResourcesForEKS(false) cfg.EKSConfig = setupEKSCloudwatchLogConfig() cfg.ESClusterConfig = relasticsearch.NewClusterConfig("clusterTestName", 1, 1, 1) @@ -1122,7 +1120,6 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }) It("should render with EKS Cloudwatch Log for managed cluster with linseed token volume", func() { - expectedResources := getExpectedResourcesForEKS(true) expectedResources = append(expectedResources, @@ -1311,7 +1308,6 @@ var _ = Describe("Tigera Secure Fluentd rendering tests", func() { }, })) }) - }) }) @@ -1328,8 +1324,10 @@ func setupEKSCloudwatchLogConfig() *render.EksCloudwatchLogConfig { func getExpectedResourcesForEKS(isManagedcluster bool) []client.Object { expectedResources := []client.Object{ - &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: render.FluentdPolicyName, Namespace: render.LogCollectorNamespace}, - TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}}, + &v3.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: render.FluentdPolicyName, Namespace: render.LogCollectorNamespace}, + TypeMeta: metav1.TypeMeta{Kind: "NetworkPolicy", APIVersion: "projectcalico.org/v3"}, + }, &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: render.FluentdMetricsService, Namespace: render.LogCollectorNamespace}}, &rbacv1.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: "eks-log-forwarder"}}, diff --git a/pkg/render/guardian_test.go b/pkg/render/guardian_test.go index fa52c97116..fcd8954f81 100644 --- a/pkg/render/guardian_test.go +++ b/pkg/render/guardian_test.go @@ -63,7 +63,7 @@ var _ = Describe("Rendering tests", func() { }, } scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -363,7 +363,7 @@ var _ = Describe("guardian", func() { var cfg *render.GuardianConfiguration BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/intrusion_detection.go b/pkg/render/intrusion_detection.go index a23b9b6ccf..a5e211db5a 100644 --- a/pkg/render/intrusion_detection.go +++ b/pkg/render/intrusion_detection.go @@ -269,6 +269,7 @@ func (c *intrusionDetectionComponent) intrusionDetectionClusterRole() *rbacv1.Cl }, { APIGroups: []string{ + "projectcalico.org", "crd.projectcalico.org", }, Resources: []string{ @@ -319,12 +320,12 @@ func (c *intrusionDetectionComponent) intrusionDetectionClusterRole() *rbacv1.Cl Verbs: []string{"get", "list", "watch"}, }, { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"securityeventwebhooks"}, Verbs: []string{"get", "list", "watch", "update"}, }, { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"alertexceptions"}, Verbs: []string{"get", "list"}, }, @@ -422,7 +423,6 @@ func (c *intrusionDetectionComponent) managedClustersWatchRoleBinding() client.O } else { return rcomponents.ClusterRoleBinding(IntrusionDetectionManagedClustersWatchRoleBindingName, ManagedClustersWatchClusterRoleName, IntrusionDetectionName, []string{c.cfg.Namespace}) } - } func (c *intrusionDetectionComponent) externalLinseedRoleBinding() *rbacv1.RoleBinding { diff --git a/pkg/render/intrusion_detection_test.go b/pkg/render/intrusion_detection_test.go index 69f17a32ae..5580e9d88e 100644 --- a/pkg/render/intrusion_detection_test.go +++ b/pkg/render/intrusion_detection_test.go @@ -76,7 +76,7 @@ var _ = Describe("Intrusion Detection rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -204,12 +204,12 @@ var _ = Describe("Intrusion Detection rendering tests", func() { Verbs: []string{"get", "list", "watch"}, }, rbacv1.PolicyRule{ - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"securityeventwebhooks"}, Verbs: []string{"get", "list", "watch", "update"}, }, rbacv1.PolicyRule{ - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"alertexceptions"}, Verbs: []string{"get", "list"}, }, @@ -251,7 +251,6 @@ var _ = Describe("Intrusion Detection rendering tests", func() { Namespace: render.IntrusionDetectionNamespace, }, })) - }) It("should render finalizers rbac resources in the IDS ClusterRole for an Openshift management/standalone cluster", func() { @@ -537,7 +536,6 @@ var _ = Describe("Intrusion Detection rendering tests", func() { }) It("should render container and init container with resource requests/limits when configured", func() { - intrusionDetectionResources := corev1.ResourceRequirements{ Limits: corev1.ResourceList{ "cpu": resource.MustParse("2"), @@ -632,7 +630,6 @@ var _ = Describe("Intrusion Detection rendering tests", func() { "memory": resource.MustParse("50Mi"), }, })) - }) It("should NOT render impersonation permissions as part of intrusion detection ClusterRole", func() { @@ -756,7 +753,6 @@ var _ = Describe("Intrusion Detection rendering tests", func() { Expect(envs).To(ContainElement(corev1.EnvVar{Name: "TENANT_ID", Value: "tenant-a"})) Expect(envs).To(ContainElement(corev1.EnvVar{Name: "LINSEED_URL", Value: fmt.Sprintf("https://tigera-linseed.%s.svc", tenantANamespace)})) Expect(envs).To(ContainElement(corev1.EnvVar{Name: "MULTI_CLUSTER_FORWARDING_ENDPOINT", Value: fmt.Sprintf("https://tigera-manager.%s.svc:9443", tenantANamespace)})) - }) It("should render impersonation permissions as part of tigera-intrusion-detection ClusterRole", func() { @@ -825,7 +821,6 @@ var _ = Describe("Intrusion Detection rendering tests", func() { Expect(deployment.Spec.Template.Spec.Containers).To(HaveLen(1)) Expect(deployment.Spec.Template.Spec.Containers[0].Name).To(Equal("controller")) }) - }) }) diff --git a/pkg/render/intrusiondetection/dpi/dpi.go b/pkg/render/intrusiondetection/dpi/dpi.go index f414c09705..01f5deec83 100644 --- a/pkg/render/intrusiondetection/dpi/dpi.go +++ b/pkg/render/intrusiondetection/dpi/dpi.go @@ -437,7 +437,10 @@ func (d *dpiComponent) dpiClusterRole() *rbacv1.ClusterRole { Rules: []rbacv1.PolicyRule{ { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{ + "projectcalico.org", + "crd.projectcalico.org", + }, Resources: []string{ "deeppacketinspections", }, @@ -445,7 +448,10 @@ func (d *dpiComponent) dpiClusterRole() *rbacv1.ClusterRole { }, { // Used to update the DPI resource status - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{ + "projectcalico.org", + "crd.projectcalico.org", + }, Resources: []string{ "deeppacketinspections/status", }, diff --git a/pkg/render/intrusiondetection/dpi/dpi_test.go b/pkg/render/intrusiondetection/dpi/dpi_test.go index b382f39a7f..e49d4f1764 100644 --- a/pkg/render/intrusiondetection/dpi/dpi_test.go +++ b/pkg/render/intrusiondetection/dpi/dpi_test.go @@ -72,12 +72,12 @@ var ( expectedClusterRoleRules = []rbacv1.PolicyRule{ { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"deeppacketinspections"}, Verbs: []string{"get", "list", "watch"}, }, { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"deeppacketinspections/status"}, Verbs: []string{"update"}, }, @@ -194,7 +194,7 @@ var _ = Describe("DPI rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/render/kubecontrollers/kube-controllers.go b/pkg/render/kubecontrollers/kube-controllers.go index 404e16e21c..20bdf1aab2 100644 --- a/pkg/render/kubecontrollers/kube-controllers.go +++ b/pkg/render/kubecontrollers/kube-controllers.go @@ -104,13 +104,13 @@ type KubeControllersConfiguration struct { } func NewCalicoKubeControllers(cfg *KubeControllersConfiguration) *kubeControllersComponent { - kubeControllerRolePolicyRules := kubeControllersRoleCommonRules(cfg, KubeController) + kubeControllerRolePolicyRules := kubeControllersRoleCommonRules(cfg) enabledControllers := []string{"node", "loadbalancer"} if cfg.Installation.Variant == operatorv1.TigeraSecureEnterprise { kubeControllerRolePolicyRules = append(kubeControllerRolePolicyRules, kubeControllersRoleEnterpriseCommonRules(cfg)...) kubeControllerRolePolicyRules = append(kubeControllerRolePolicyRules, rbacv1.PolicyRule{ - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"remoteclusterconfigurations"}, Verbs: []string{"watch", "list", "get"}, }, @@ -152,7 +152,7 @@ func NewCalicoKubeControllersPolicy(cfg *KubeControllersConfiguration) render.Co func NewElasticsearchKubeControllers(cfg *KubeControllersConfiguration) *kubeControllersComponent { var kubeControllerAllowTigeraPolicy *v3.NetworkPolicy - kubeControllerRolePolicyRules := kubeControllersRoleCommonRules(cfg, EsKubeController) + kubeControllerRolePolicyRules := kubeControllersRoleCommonRules(cfg) if cfg.Installation.Variant == operatorv1.TigeraSecureEnterprise { kubeControllerRolePolicyRules = append(kubeControllerRolePolicyRules, kubeControllersRoleEnterpriseCommonRules(cfg)...) @@ -286,7 +286,7 @@ func (c *kubeControllersComponent) Ready() bool { return true } -func kubeControllersRoleCommonRules(cfg *KubeControllersConfiguration, kubeControllerName string) []rbacv1.PolicyRule { +func kubeControllersRoleCommonRules(cfg *KubeControllersConfiguration) []rbacv1.PolicyRule { rules := []rbacv1.PolicyRule{ { // Nodes are watched to monitor for deletions. @@ -307,30 +307,42 @@ func kubeControllersRoleCommonRules(cfg *KubeControllersConfiguration, kubeContr }, { // IPAM resources are manipulated in response to node and block updates, as well as periodic triggers. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"ipreservations"}, Verbs: []string{"list"}, }, { - APIGroups: []string{"crd.projectcalico.org"}, - Resources: []string{"blockaffinities", "ipamblocks", "ipamhandles", "networksets", "ipamconfigs"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, + Resources: []string{"blockaffinities", "ipamblocks", "ipamhandles", "networksets", "ipamconfigurations"}, Verbs: []string{"get", "list", "create", "update", "delete", "watch"}, }, { - // Pools are watched to maintain a mapping of blocks to IP pools. - APIGroups: []string{"crd.projectcalico.org"}, - Resources: []string{"ippools"}, - Verbs: []string{"list", "watch"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, + Resources: []string{ + // Pools are watched to maintain a mapping of blocks to IP pools, and for finalization. + "ippools", + // NetworkPolicies are watched for defaulting. + "networkpolicies", + "tier.networkpolicies", + "globalnetworkpolicies", + "tier.globalnetworkpolicies", + "stagedglobalnetworkpolicies", + "tier.stagedglobalnetworkpolicies", + "stagednetworkpolicies", + "tier.stagednetworkpolicies", + "stagedkubernetesnetworkpolicies", + }, + Verbs: []string{"list", "watch", "update"}, }, { // Needs access to update clusterinformations. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"clusterinformations"}, Verbs: []string{"get", "create", "update", "list", "watch"}, }, { // Needs to manage hostendpoints. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"hostendpoints"}, Verbs: []string{"get", "list", "create", "update", "delete", "watch"}, }, @@ -338,15 +350,16 @@ func kubeControllersRoleCommonRules(cfg *KubeControllersConfiguration, kubeContr // Needs to manipulate kubecontrollersconfiguration, which contains // its config. It creates a default if none exists, and updates status // as well. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"kubecontrollersconfigurations"}, Verbs: []string{"get", "create", "list", "update", "watch"}, }, { - // calico-kube-controllers requires tiers create - APIGroups: []string{"crd.projectcalico.org"}, + // calico-kube-controllers requires tiers create to create the default tiers, + // and get permissions to access network policies in those tiers. + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"tiers"}, - Verbs: []string{"create"}, + Verbs: []string{"create", "update", "get", "list", "watch"}, }, { // Namespaces are watched for LoadBalancer IP allocation with namespace selector support @@ -384,13 +397,13 @@ func kubeControllersRoleEnterpriseCommonRules(cfg *KubeControllersConfiguration) }, { // Needed to validate the license - APIGroups: []string{"projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"licensekeys"}, Verbs: []string{"get", "watch", "list"}, }, { // Needed to validate the license - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"licensekeys"}, Verbs: []string{"get", "watch"}, }, @@ -400,12 +413,12 @@ func kubeControllersRoleEnterpriseCommonRules(cfg *KubeControllersConfiguration) Verbs: []string{"get", "watch", "list"}, }, { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"deeppacketinspections/status"}, Verbs: []string{"update"}, }, { - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"packetcaptures"}, Verbs: []string{"get", "list", "update"}, }, @@ -414,7 +427,7 @@ func kubeControllersRoleEnterpriseCommonRules(cfg *KubeControllersConfiguration) if cfg.ManagementClusterConnection != nil { rules = append(rules, rbacv1.PolicyRule{ - APIGroups: []string{"projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"licensekeys"}, Verbs: []string{"get", "create", "update", "list", "watch"}, }, diff --git a/pkg/render/kubecontrollers/kube-controllers_test.go b/pkg/render/kubecontrollers/kube-controllers_test.go index 69dd4c6fe2..c93cc8a863 100644 --- a/pkg/render/kubecontrollers/kube-controllers_test.go +++ b/pkg/render/kubecontrollers/kube-controllers_test.go @@ -107,7 +107,7 @@ var _ = Describe("kube-controllers rendering tests", func() { k8sServiceEp = k8sapi.ServiceEndpoint{} scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -450,7 +450,7 @@ var _ = Describe("kube-controllers rendering tests", func() { } scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/logstorage/dashboards/dashboards_test.go b/pkg/render/logstorage/dashboards/dashboards_test.go index dcc182ed3b..952d9027fd 100644 --- a/pkg/render/logstorage/dashboards/dashboards_test.go +++ b/pkg/render/logstorage/dashboards/dashboards_test.go @@ -341,7 +341,6 @@ var _ = Describe("Dashboards rendering tests", func() { Expect(job.Spec.Template.Spec.Containers[0].Name).To(Equal(Name)) Expect(job.Spec.Template.Spec.Containers[0].Resources).To(Equal(dashboardsJobResources)) }) - }) Context("single-tenant with external elastic rendering", func() { @@ -523,7 +522,7 @@ var _ = Describe("Dashboards rendering tests", func() { func getBundle(installation *operatorv1.InstallationSpec) certificatemanagement.TrustedBundle { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, installation, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -686,7 +685,8 @@ func expectedContainers() []corev1.Container { Key: "password", }, }, - }}, + }, + }, VolumeMounts: []corev1.VolumeMount{ { Name: "tigera-ca-bundle", diff --git a/pkg/render/logstorage/esgateway/esgateway_test.go b/pkg/render/logstorage/esgateway/esgateway_test.go index d60720e3bd..8ec04167cc 100644 --- a/pkg/render/logstorage/esgateway/esgateway_test.go +++ b/pkg/render/logstorage/esgateway/esgateway_test.go @@ -62,7 +62,7 @@ var _ = Describe("ES Gateway rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() installation = &operatorv1.InstallationSpec{ @@ -275,7 +275,6 @@ var _ = Describe("ES Gateway rendering tests", func() { initContainer := test.GetContainer(d.Spec.Template.Spec.InitContainers, "tigera-secure-elasticsearch-cert-key-cert-provisioner") Expect(initContainer).NotTo(BeNil()) Expect(initContainer.Resources).To(Equal(esGatewayResources)) - }) Context("allow-tigera rendering", func() { @@ -313,7 +312,6 @@ var _ = Describe("ES Gateway rendering tests", func() { }) func getTLS(cli client.Client, installation *operatorv1.InstallationSpec) (certificatemanagement.KeyPairInterface, certificatemanagement.TrustedBundle) { - certificateManager, err := certificatemanager.Create(cli, installation, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/render/logstorage/esmetrics/elasticsearch_metrics_test.go b/pkg/render/logstorage/esmetrics/elasticsearch_metrics_test.go index f3f5275933..e0c0963e59 100644 --- a/pkg/render/logstorage/esmetrics/elasticsearch_metrics_test.go +++ b/pkg/render/logstorage/esmetrics/elasticsearch_metrics_test.go @@ -65,7 +65,7 @@ var _ = Describe("Elasticsearch metrics", func() { esConfig = relasticsearch.NewClusterConfig("cluster", 1, 1, 1) scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, "", common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -241,7 +241,6 @@ var _ = Describe("Elasticsearch metrics", func() { }) It("should renders the Elasticsearch metrics with resource requests and limits", func() { - ca, _ := tls.MakeCA(rmeta.DefaultOperatorCASignerName()) cert, _, _ := ca.Config.GetPEMBytes() // create a valid pem block cfg.Installation.CertificateManagement = &operatorv1.CertificateManagement{CACert: cert} @@ -303,7 +302,6 @@ var _ = Describe("Elasticsearch metrics", func() { initContainer := test.GetContainer(d.Spec.Template.Spec.InitContainers, "tigera-ee-elasticsearch-metrics-tls-key-cert-provisioner") Expect(initContainer).NotTo(BeNil()) Expect(initContainer.Resources).To(Equal(esMetricsResources)) - }) It("should render toleration on GKE", func() { diff --git a/pkg/render/logstorage/kibana/kibana_test.go b/pkg/render/logstorage/kibana/kibana_test.go index 525c446778..27917edcb4 100644 --- a/pkg/render/logstorage/kibana/kibana_test.go +++ b/pkg/render/logstorage/kibana/kibana_test.go @@ -146,7 +146,6 @@ var _ = Describe("Kibana rendering tests", func() { "kibana.k8s.elastic.co", "v1", "Kibana").(*kbv1.Kibana) Expect(resultKB.Spec.Config.Data["xpack.security.session.lifespan"]).To(Equal("8h")) Expect(resultKB.Spec.Config.Data["xpack.security.session.idleTimeout"]).To(Equal("30m")) - }) It("should render toleration on GKE", func() { @@ -180,7 +179,7 @@ var _ = Describe("Kibana rendering tests", func() { }) It("should configures Kibana publicBaseUrl when BaseURL is specified", func() { - //cfg.ElasticLicenseType = render.ElasticsearchLicenseTypeBasic + // cfg.ElasticLicenseType = render.ElasticsearchLicenseTypeBasic cfg.BaseURL = "https://test.domain.com" component := kibana.Kibana(cfg) @@ -311,7 +310,6 @@ var _ = Describe("Kibana rendering tests", func() { State: "", }, } - }) It("returns Kibana CR's to delete and keeps the finalizers on the LogStorage CR", func() { @@ -320,7 +318,6 @@ var _ = Describe("Kibana rendering tests", func() { createdResources, deletedResources := component.Objects() rtest.ExpectResources(deletedResources, expectedDeletedResources) Expect(createdResources).To(BeEmpty()) - }) It("doesn't return anything to delete when Kibana have their deletion times stamps set and the LogStorage finalizers are still set", func() { @@ -426,7 +423,6 @@ var _ = Describe("Kibana rendering tests", func() { }) It("should render the kibana pod template with resource requests and limits when set", func() { - cfg.Installation.CertificateManagement = &operatorv1.CertificateManagement{ CACert: cfg.KibanaKeyPair.GetCertificatePEM(), SignerName: "my signer name", @@ -456,7 +452,8 @@ var _ = Describe("Kibana rendering tests", func() { Containers: []operatorv1.KibanaContainer{ { Name: "kibana", - Resources: &expectedResourcesRequirements}, + Resources: &expectedResourcesRequirements, + }, }, InitContainers: []operatorv1.KibanaInitContainer{ { @@ -482,16 +479,14 @@ var _ = Describe("Kibana rendering tests", func() { initcontainer := test.GetContainer(kibana.Spec.PodTemplate.Spec.InitContainers, "key-cert-provisioner") Expect(initcontainer).NotTo(BeNil()) Expect(initcontainer.Resources).To(Equal(expectedResourcesRequirements)) - }) }) - }) }) func getX509Certs(installation *operatorv1.InstallationSpec) (certificatemanagement.KeyPairInterface, certificatemanagement.TrustedBundle) { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, installation, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/logstorage/linseed/linseed_test.go b/pkg/render/logstorage/linseed/linseed_test.go index 66e2768033..0e48d21454 100644 --- a/pkg/render/logstorage/linseed/linseed_test.go +++ b/pkg/render/logstorage/linseed/linseed_test.go @@ -371,7 +371,6 @@ var _ = Describe("Linseed rendering tests", func() { initContainer = test.GetContainer(d.Spec.Template.Spec.InitContainers, "tigera-secure-linseed-cert-key-cert-provisioner") Expect(initContainer).NotTo(BeNil()) Expect(initContainer.Resources).To(Equal(linseedResources)) - }) Context("allow-tigera rendering", func() { @@ -834,7 +833,7 @@ var _ = Describe("Linseed rendering tests", func() { func getTLS(installation *operatorv1.InstallationSpec) (certificatemanagement.KeyPairInterface, certificatemanagement.KeyPairInterface, certificatemanagement.TrustedBundle) { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, installation, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/logstorage_test.go b/pkg/render/logstorage_test.go index b4edc091e6..a34ea2f059 100644 --- a/pkg/render/logstorage_test.go +++ b/pkg/render/logstorage_test.go @@ -296,7 +296,7 @@ var _ = Describe("Elasticsearch rendering tests", func() { createResources, deleteResources := component.Objects() rtest.ExpectResources(createResources, expectedCreateResources) - //compareResources(createResources, expectedCreateResources) + // compareResources(createResources, expectedCreateResources) compareResources(deleteResources, expectedDeleteResources) }) @@ -585,9 +585,11 @@ var _ = Describe("Elasticsearch rendering tests", func() { It("creates Managed cluster logstorage components", func() { expectedCreateResources := []client.Object{ &rbacv1.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: "tigera-linseed-secrets"}}, - &rbacv1.RoleBinding{ObjectMeta: metav1.ObjectMeta{Name: "tigera-linseed", Namespace: "tigera-operator"}, - RoleRef: rbacv1.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: "tigera-linseed-secrets"}, - Subjects: []rbacv1.Subject{{Kind: "ServiceAccount", Name: "guardian", Namespace: "calico-system"}}}, + &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: "tigera-linseed", Namespace: "tigera-operator"}, + RoleRef: rbacv1.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: "tigera-linseed-secrets"}, + Subjects: []rbacv1.Subject{{Kind: "ServiceAccount", Name: "guardian", Namespace: "calico-system"}}, + }, &rbacv1.Role{ObjectMeta: metav1.ObjectMeta{Name: render.CalicoKubeControllerSecret, Namespace: common.OperatorNamespace()}}, &rbacv1.RoleBinding{ObjectMeta: metav1.ObjectMeta{Name: render.CalicoKubeControllerSecret, Namespace: common.OperatorNamespace()}}, } @@ -1146,7 +1148,7 @@ var _ = Describe("Elasticsearch rendering tests", func() { func getTLS(installation *operatorv1.InstallationSpec) (certificatemanagement.KeyPairInterface, certificatemanagement.TrustedBundle) { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, installation, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/manager_test.go b/pkg/render/manager_test.go index 32ab03e98e..7d48e3cfdb 100644 --- a/pkg/render/manager_test.go +++ b/pkg/render/manager_test.go @@ -457,7 +457,8 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { APIGroups: []string{"projectcalico.org"}, Resources: []string{"managedclusters"}, Verbs: []string{"update"}, - }})) + }, + })) roleBindingUpdateManagedClusters := rtest.GetResource(resources, render.ManagerManagedClustersUpdateRBACName, "", "rbac.authorization.k8s.io", "v1", "ClusterRoleBinding").(*rbacv1.ClusterRoleBinding) Expect(roleBindingUpdateManagedClusters.RoleRef.Name).To(Equal(render.ManagerManagedClustersUpdateRBACName)) Expect(roleBindingWatchManagedClusters.Subjects).To(ConsistOf([]rbacv1.Subject{ @@ -467,7 +468,6 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { Namespace: render.ManagerNamespace, }, })) - }) It("should set OIDC Authority environment when auth-type is OIDC", func() { @@ -494,7 +494,7 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { var cfg *render.ManagerConfiguration BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, installation, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -782,7 +782,7 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { Expect(err).NotTo(HaveOccurred()) scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -1537,7 +1537,7 @@ func renderObjects(roc renderConfig) []client.Object { var voltronLinseedKP certificatemanagement.KeyPairInterface scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, roc.installation, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/monitor/monitor_test.go b/pkg/render/monitor/monitor_test.go index 7738d8e46d..07a1acc20b 100644 --- a/pkg/render/monitor/monitor_test.go +++ b/pkg/render/monitor/monitor_test.go @@ -77,7 +77,7 @@ var _ = Describe("monitor rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, dns.DefaultClusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/node.go b/pkg/render/node.go index de5399609f..469c06c9bf 100644 --- a/pkg/render/node.go +++ b/pkg/render/node.go @@ -148,6 +148,8 @@ type NodeConfiguration struct { FelixPrometheusMetricsEnabled bool FelixPrometheusMetricsPort int + + V3CRDs bool } // Node creates the node daemonset and other resources for the daemonset to operate normally. @@ -454,7 +456,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { }, { // For monitoring Calico-specific configuration. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "bgpconfigurations", "bgpfilters", @@ -480,7 +482,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { }, { // calico/node monitors for caliconodestatus objects and writes its status back into the object. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "caliconodestatuses", }, @@ -489,7 +491,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { { // For migration code in calico/node startup only. Remove when the migration // code is removed from node. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "globalbgpconfigs", "globalfelixconfigs", @@ -498,7 +500,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { }, { // Calico creates some configuration on startup. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "clusterinformations", "felixconfigurations", @@ -508,7 +510,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { }, { // Calico creates some tiers on startup. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "tiers", }, @@ -523,24 +525,24 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { { // Most IPAM resources need full CRUD permissions so we can allocate and // release IP addresses for pods. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "blockaffinities", "ipamblocks", - "ipamconfigs", + "ipamconfigurations", "ipamhandles", }, Verbs: []string{"get", "list", "create", "update", "delete"}, }, { // But, we only need to be able to query for IPAM config. - APIGroups: []string{"crd.projectcalico.org"}, - Resources: []string{"ipamconfigs"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, + Resources: []string{"ipamconfigurations"}, Verbs: []string{"get"}, }, { // confd (and in some cases, felix) watches block affinities for route aggregation. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"blockaffinities"}, Verbs: []string{"watch"}, }, @@ -550,7 +552,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { extraRules := []rbacv1.PolicyRule{ { // Calico Enterprise needs to be able to read additional resources. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "bfdconfigurations", "egressgatewaypolicies", @@ -563,7 +565,7 @@ func (c *nodeComponent) nodeRole() *rbacv1.ClusterRole { }, { // Tigera Secure updates status for packet captures. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "packetcaptures", }, @@ -612,12 +614,12 @@ func (c *nodeComponent) cniPluginRole() *rbacv1.ClusterRole { { // Most IPAM resources need full CRUD permissions so we can allocate and // release IP addresses for pods. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "blockaffinities", "ipamblocks", "ipamhandles", - "ipamconfigs", + "ipamconfigurations", "clusterinformations", "ippools", "ipreservations", @@ -661,6 +663,11 @@ func (c *nodeComponent) createCalicoPluginConfig() map[string]interface{} { if c.cfg.Installation.CalicoNetwork.LinuxPolicySetupTimeoutSeconds != nil { linuxPolicySetupTimeoutSeconds = *c.cfg.Installation.CalicoNetwork.LinuxPolicySetupTimeoutSeconds } + apiGroup := "" + if c.cfg.V3CRDs { + apiGroup = "projectcalico.org/v3" + } + // calico plugin calicoPluginConfig := map[string]interface{}{ "type": "calico", @@ -677,6 +684,7 @@ func (c *nodeComponent) createCalicoPluginConfig() map[string]interface{} { }, "policy_setup_timeout_seconds": linuxPolicySetupTimeoutSeconds, "endpoint_status_dir": filepath.Join(c.varRunCalicoVolume().VolumeSource.HostPath.Path, "endpoint-status"), + "calico_api_group": apiGroup, } // Determine logging configuration diff --git a/pkg/render/node_test.go b/pkg/render/node_test.go index a40646b155..15d5890148 100644 --- a/pkg/render/node_test.go +++ b/pkg/render/node_test.go @@ -119,7 +119,7 @@ var _ = Describe("Node rendering tests", func() { defaultInstance.CalicoNetwork.NodeAddressAutodetectionV6 = &operatorv1.NodeAddressAutodetection{FirstFound: &ff} } scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -203,6 +203,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "policy_setup_timeout_seconds": 0, "endpoint_status_dir": "/var/run/calico/endpoint-status", "datastore_type": "kubernetes", @@ -405,6 +406,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -572,6 +574,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 1450, "nodename_file_optional": false, @@ -935,6 +938,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -1337,6 +1341,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2332,6 +2337,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2404,6 +2410,7 @@ var _ = Describe("Node rendering tests", func() { "container_settings": { "allow_ip_forwarding": false }, + "calico_api_group": "", "datastore_type": "kubernetes", "ipam": { "assign_ipv4": "%t", @@ -2465,6 +2472,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2513,6 +2521,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2582,6 +2591,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2638,6 +2648,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2688,6 +2699,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "datastore_type": "kubernetes", "mtu": 0, "nodename_file_optional": false, @@ -2730,6 +2742,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "policy_setup_timeout_seconds": 0, "endpoint_status_dir": "/var/run/calico/endpoint-status", "datastore_type": "kubernetes", @@ -2868,6 +2881,7 @@ var _ = Describe("Node rendering tests", func() { "plugins": [ { "type": "calico", + "calico_api_group": "", "policy_setup_timeout_seconds": 0, "endpoint_status_dir": "/var/run/calico/endpoint-status", "datastore_type": "kubernetes", diff --git a/pkg/render/nonclusterhost/nonclusterhost.go b/pkg/render/nonclusterhost/nonclusterhost.go index bd60f386d0..ba35ce5696 100644 --- a/pkg/render/nonclusterhost/nonclusterhost.go +++ b/pkg/render/nonclusterhost/nonclusterhost.go @@ -145,7 +145,7 @@ func (c *nonClusterHostComponent) clusterRole() *rbacv1.ClusterRole { }, { // For monitoring Calico-specific configuration. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "bfdconfigurations", "bgpconfigurations", @@ -212,7 +212,7 @@ func (c *nonClusterHostComponent) clusterRole() *rbacv1.ClusterRole { // For non-cluster host init process to update labels. rules = append(rules, []rbacv1.PolicyRule{ { - APIGroups: []string{"projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"hostendpoints"}, Verbs: []string{"list", "update"}, }, diff --git a/pkg/render/nonclusterhost/nonclusterhost_test.go b/pkg/render/nonclusterhost/nonclusterhost_test.go index 5b7a1c4290..754d5d3a31 100644 --- a/pkg/render/nonclusterhost/nonclusterhost_test.go +++ b/pkg/render/nonclusterhost/nonclusterhost_test.go @@ -33,7 +33,7 @@ var _ = Describe("NonClusterHost rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cfg = &nonclusterhost.Config{ NonClusterHost: operatorv1.NonClusterHostSpec{ @@ -107,7 +107,7 @@ var _ = Describe("NonClusterHost rendering tests", func() { Verbs: []string{"get"}, }, rbacv1.PolicyRule{ - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "bfdconfigurations", "bgpconfigurations", @@ -159,7 +159,7 @@ var _ = Describe("NonClusterHost rendering tests", func() { ResourceNames: []string{"typha-server-noncluster-host"}, }, rbacv1.PolicyRule{ - APIGroups: []string{"projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"hostendpoints"}, Verbs: []string{"list", "update"}, }, diff --git a/pkg/render/packet_capture_api_test.go b/pkg/render/packet_capture_api_test.go index 93e2e3cbbf..3e3f5861f3 100644 --- a/pkg/render/packet_capture_api_test.go +++ b/pkg/render/packet_capture_api_test.go @@ -59,7 +59,7 @@ var _ = Describe("Rendering tests for PacketCapture API component", func() { var cli client.Client BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/policyrecommendation.go b/pkg/render/policyrecommendation.go index 4ebc6c733f..be5ac7c4e1 100644 --- a/pkg/render/policyrecommendation.go +++ b/pkg/render/policyrecommendation.go @@ -109,7 +109,6 @@ func (pr *policyRecommendationComponent) SupportedOSType() rmeta.OSType { } func (pr *policyRecommendationComponent) Objects() ([]client.Object, []client.Object) { - var objs []client.Object // Guardian has RBAC permissions to handle policy recommendation requests in managed clusters, @@ -443,7 +442,6 @@ func (pr *policyRecommendationComponent) allowTigeraPolicyForPolicyRecommendatio } func (pr *policyRecommendationComponent) deprecatedObjects(isManagedCluster bool) []client.Object { - var deprecatedObjs []client.Object if isManagedCluster { deprecatedObjs = append(deprecatedObjs, []client.Object{ @@ -470,5 +468,4 @@ func (pr *policyRecommendationComponent) deprecatedObjects(isManagedCluster bool } return deprecatedObjs - } diff --git a/pkg/render/policyrecommendation_test.go b/pkg/render/policyrecommendation_test.go index 6f8662e4c0..4069be9cb7 100644 --- a/pkg/render/policyrecommendation_test.go +++ b/pkg/render/policyrecommendation_test.go @@ -62,7 +62,7 @@ var _ = Describe("Policy recommendation rendering tests", func() { BeforeEach(func() { scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) @@ -180,7 +180,6 @@ var _ = Describe("Policy recommendation rendering tests", func() { Namespace: render.PolicyRecommendationNamespace, }, })) - }) It("should render toleration on GKE", func() { @@ -679,6 +678,5 @@ var _ = Describe("Policy recommendation rendering tests", func() { Expect(resources).To(BeEmpty(), "Expected no resources to be rendered in a managed cluster") rtest.ExpectResources(deleteResources, expectedDeleteResources) }) - }) }) diff --git a/pkg/render/render_test.go b/pkg/render/render_test.go index a7da4a8992..ac12094bbb 100644 --- a/pkg/render/render_test.go +++ b/pkg/render/render_test.go @@ -186,7 +186,7 @@ var _ = Describe("Rendering tests", func() { }, } scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli := ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) diff --git a/pkg/render/tierrbac/render.go b/pkg/render/tierrbac/render.go new file mode 100644 index 0000000000..1919b78130 --- /dev/null +++ b/pkg/render/tierrbac/render.go @@ -0,0 +1,237 @@ +// Copyright (c) 2019-2025 Tigera, Inc. All rights reserved. +// +// 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 tierrbac + +import ( + "fmt" + + "sigs.k8s.io/controller-runtime/pkg/client" + + operatorv1 "github.com/tigera/operator/api/v1" + "github.com/tigera/operator/pkg/ptr" + "github.com/tigera/operator/pkg/render" + rmeta "github.com/tigera/operator/pkg/render/common/meta" + "github.com/tigera/operator/pkg/render/common/secret" + "github.com/tigera/operator/pkg/tls/certificatemanagement" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// NodeConfiguration is the public API used to provide information to the render code to +// generate Kubernetes objects for installing calico/node on a cluster. +type Configuration struct { + PullSecrets []*corev1.Secret + KeyPair certificatemanagement.KeyPairInterface +} + +// Node creates the node daemonset and other resources for the daemonset to operate normally. +func RBAC(cfg *Configuration) render.Component { + return &component{cfg: cfg} +} + +type component struct { + // Input configuration from the controller. + cfg *Configuration +} + +func (c *component) ResolveImages(is *operatorv1.ImageSet) error { + return nil +} + +func (c *component) SupportedOSType() rmeta.OSType { + return rmeta.OSTypeLinux +} + +func (c *component) Objects() ([]client.Object, []client.Object) { + // Create the Deployment for the webhook. + sa := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{Kind: "ServiceAccount", APIVersion: "v1"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "tier-rbac-validator", + Namespace: "calico-system", + }, + } + + dep := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: "apps/v1"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "tier-rbac-validator", + Namespace: "calico-system", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: ptr.ToPtr(int32(1)), + Strategy: appsv1.DeploymentStrategy{ + Type: appsv1.RecreateDeploymentStrategyType, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k8s-app": "validation", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "tier-rbac-validator", + Labels: map[string]string{ + "k8s-app": "validation", + }, + }, + Spec: corev1.PodSpec{ + HostNetwork: true, + ServiceAccountName: "tier-rbac-validator", + ImagePullSecrets: secret.GetReferenceList(c.cfg.PullSecrets), + Containers: []corev1.Container{{ + Name: "tier-rbac-validator", + Image: "calico/webhook:test-build", // Placeholder image, replace with actual image. + Args: []string{ + "webhook", + fmt.Sprintf("--tls-cert-file=%s", c.cfg.KeyPair.VolumeMountCertificateFilePath()), + fmt.Sprintf("--tls-private-key-file=%s", c.cfg.KeyPair.VolumeMountKeyFilePath()), + }, + Ports: []corev1.ContainerPort{{ + ContainerPort: 6443, + Protocol: corev1.ProtocolTCP, + }}, + VolumeMounts: []corev1.VolumeMount{c.cfg.KeyPair.VolumeMount(c.SupportedOSType())}, + }}, + Volumes: []corev1.Volume{c.cfg.KeyPair.Volume()}, + }, + }, + }, + } + + svc := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "tier-rbac-validator", + Namespace: "calico-system", + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Port: 443, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(6443), + }, + }, + Type: corev1.ServiceTypeClusterIP, + Selector: map[string]string{ + "k8s-app": "validation", + }, + }, + } + + reg := &admissionregistrationv1.ValidatingWebhookConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "api.projectcalico.org", + }, + Webhooks: []admissionregistrationv1.ValidatingWebhook{ + { + Name: "api.projectcalico.org", + Rules: []admissionregistrationv1.RuleWithOperations{ + { + Operations: []admissionregistrationv1.OperationType{ + admissionregistrationv1.Create, + admissionregistrationv1.Update, + admissionregistrationv1.Delete, + }, + Rule: admissionregistrationv1.Rule{ + APIGroups: []string{"projectcalico.org"}, + APIVersions: []string{"v3"}, + Resources: []string{ + "networkpolicies", + "globalnetworkpolicies", + "stagednetworkpolicies", + "stagedglobalnetworkpolicies", + }, + Scope: &[]admissionregistrationv1.ScopeType{admissionregistrationv1.ClusterScope}[0], + }, + }, + { + Operations: []admissionregistrationv1.OperationType{ + admissionregistrationv1.Create, + admissionregistrationv1.Update, + admissionregistrationv1.Delete, + admissionregistrationv1.Connect, + }, + Rule: admissionregistrationv1.Rule{ + APIGroups: []string{"projectcalico.org"}, + APIVersions: []string{"v3"}, + Resources: []string{"networkpolicies", "globalnetworkpolicies", "stagednetworkpolicies", "stagedglobalnetworkpolicies"}, + Scope: ptr.ToPtr(admissionregistrationv1.ScopeType("*")), + }, + }, + }, + ClientConfig: admissionregistrationv1.WebhookClientConfig{ + Service: &admissionregistrationv1.ServiceReference{ + Namespace: "calico-system", + Name: "tier-rbac-validator", + }, + CABundle: c.cfg.KeyPair.GetCertificatePEM(), + }, + AdmissionReviewVersions: []string{"v1"}, + SideEffects: &[]admissionregistrationv1.SideEffectClass{admissionregistrationv1.SideEffectClassNone}[0], + TimeoutSeconds: ptr.Int32ToPtr(5), + }, + }, + } + + // Create a Cluster role binding with access to all projectcalico.org resources. + cr := &rbacv1.ClusterRole{ + TypeMeta: metav1.TypeMeta{Kind: "ClusterRole", APIVersion: "rbac.authorization.k8s.io/v1"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "tier-rbac-validator", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"projectcalico.org"}, + Resources: []string{"*"}, + Verbs: []string{"get", "list", "watch"}, + }, + { + APIGroups: []string{"authorization.k8s.io"}, + Resources: []string{"subjectaccessreviews"}, + Verbs: []string{"create"}, + }, + }, + } + + crb := &rbacv1.ClusterRoleBinding{ + TypeMeta: metav1.TypeMeta{Kind: "ClusterRoleBinding", APIVersion: "rbac.authorization.k8s.io/v1"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "tier-rbac-validator", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "tier-rbac-validator", + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: "tier-rbac-validator", + Namespace: "calico-system", + }, + }, + } + + return []client.Object{sa, dep, svc, reg, cr, crb}, nil +} + +func (c *component) Ready() bool { + return true +} diff --git a/pkg/render/typha.go b/pkg/render/typha.go index 82dc78fbdf..568dff4c96 100644 --- a/pkg/render/typha.go +++ b/pkg/render/typha.go @@ -255,7 +255,7 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { }, { // For monitoring Calico-specific configuration. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "bgpconfigurations", "bgppeers", @@ -282,7 +282,7 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { { // For migration code in calico/node startup only. Remove when the migration // code is removed from node. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "globalbgpconfigs", "globalfelixconfigs", @@ -291,7 +291,7 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { }, { // Calico creates some configuration on startup. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "clusterinformations", "felixconfigurations", @@ -301,7 +301,7 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { }, { // Calico creates some tiers on startup. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "tiers", }, @@ -316,7 +316,7 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { { // Most IPAM resources need full CRUD permissions so we can allocate and // release IP addresses for pods. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "blockaffinities", "ipamblocks", @@ -326,13 +326,13 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { }, { // But, we only need to be able to query for IPAM config. - APIGroups: []string{"crd.projectcalico.org"}, - Resources: []string{"ipamconfigs"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, + Resources: []string{"ipamconfigurations"}, Verbs: []string{"get"}, }, { // confd (and in some cases, felix) watches block affinities for route aggregation. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{"blockaffinities"}, Verbs: []string{"watch"}, }, @@ -342,7 +342,7 @@ func (c *typhaComponent) typhaRole() *rbacv1.ClusterRole { extraRules := []rbacv1.PolicyRule{ { // Tigera Secure needs to be able to read licenses, and config. - APIGroups: []string{"crd.projectcalico.org"}, + APIGroups: []string{"projectcalico.org", "crd.projectcalico.org"}, Resources: []string{ "licensekeys", "remoteclusterconfigurations", diff --git a/pkg/render/typha_test.go b/pkg/render/typha_test.go index f8e31ee083..97281363cd 100644 --- a/pkg/render/typha_test.go +++ b/pkg/render/typha_test.go @@ -69,7 +69,7 @@ var _ = Describe("Typha rendering tests", func() { }, } scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/render/windows_test.go b/pkg/render/windows_test.go index 32e48b302f..4f73c3e0ab 100644 --- a/pkg/render/windows_test.go +++ b/pkg/render/windows_test.go @@ -93,7 +93,7 @@ var _ = Describe("Windows rendering tests", func() { defaultInstance.CalicoNetwork.NodeAddressAutodetectionV4 = &operatorv1.NodeAddressAutodetection{FirstFound: &ff} defaultInstance.ServiceCIDRs = []string{"10.96.0.0/12"} scheme := runtime.NewScheme() - Expect(apis.AddToScheme(scheme)).NotTo(HaveOccurred()) + Expect(apis.AddToScheme(scheme, false)).NotTo(HaveOccurred()) cli = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() certificateManager, err := certificatemanager.Create(cli, nil, clusterDomain, common.OperatorNamespace(), certificatemanager.AllowCACreation()) Expect(err).NotTo(HaveOccurred()) diff --git a/test/crd_management_test.go b/test/crd_management_test.go index 44ccf2c7e5..53d2eff35f 100644 --- a/test/crd_management_test.go +++ b/test/crd_management_test.go @@ -48,7 +48,7 @@ var _ = Describe("CRD management tests", func() { var operatorDone chan struct{} BeforeEach(func() { scheme = runtime.NewScheme() - err := apis.AddToScheme(scheme) + err := apis.AddToScheme(scheme, false) Expect(err).NotTo(HaveOccurred()) cfg, err := config.GetConfig() Expect(err).NotTo(HaveOccurred()) @@ -61,7 +61,7 @@ var _ = Describe("CRD management tests", func() { // Save the networkpolicies CRD so we can restore it when finished npCRD = &apiextenv1.CustomResourceDefinition{ TypeMeta: metav1.TypeMeta{Kind: "CustomResourceDefinition", APIVersion: "apiextensions.k8s.io/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "networkpolicies.crd.projectcalico.org"}, + ObjectMeta: metav1.ObjectMeta{Name: "networkpolicies.projectcalico.org"}, } k := client.ObjectKey{Name: npCRD.Name} err = c.Get(context.Background(), k, npCRD) diff --git a/test/mainline_test.go b/test/mainline_test.go index 01f169dbad..8610c6a1f8 100644 --- a/test/mainline_test.go +++ b/test/mainline_test.go @@ -40,10 +40,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operator "github.com/tigera/operator/api/v1" "github.com/tigera/operator/internal/controller" "github.com/tigera/operator/pkg/apis" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/controller/options" "github.com/tigera/operator/pkg/crds" @@ -363,7 +363,7 @@ func setupManagerNoControllers(manageCRDs bool, multiTenant bool, enterpriseCRDs Expect(err).NotTo(HaveOccurred()) // Setup Scheme for all resources - err = apis.AddToScheme(mgr.GetScheme()) + err = apis.AddToScheme(mgr.GetScheme(), false) Expect(err).NotTo(HaveOccurred()) err = apiextensionsv1.AddToScheme(mgr.GetScheme()) Expect(err).NotTo(HaveOccurred()) @@ -622,7 +622,7 @@ func waitForProductTeardown(c client.Client) { func cleanupIPPools(c client.Client) { By("Cleaning up IP pools") Eventually(func() error { - ipPools := &crdv1.IPPoolList{} + ipPools := &v3.IPPoolList{} err := c.List(context.Background(), ipPools) if err != nil { return err diff --git a/test/pool_test.go b/test/pool_test.go index 429d744bab..4440460402 100644 --- a/test/pool_test.go +++ b/test/pool_test.go @@ -35,7 +35,6 @@ import ( v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" operator "github.com/tigera/operator/api/v1" - crdv1 "github.com/tigera/operator/pkg/apis/crd.projectcalico.org/v1" ) // This test suite covers the installation of IP pools. The vast majority should be covered in the pkg/controller/ippool UTs @@ -127,7 +126,7 @@ var _ = Describe("IPPool FV tests", func() { verifyCalicoHasDeployed(c) // Get IP pools installed in the cluster. - ipPools := &crdv1.IPPoolList{} + ipPools := &v3.IPPoolList{} Eventually(func() error { return c.List(context.Background(), ipPools) }, 5*time.Second, 1*time.Second).ShouldNot(HaveOccurred()) @@ -177,7 +176,7 @@ var _ = Describe("IPPool FV tests", func() { verifyCalicoHasDeployed(c) // Get IP pools installed in the cluster. - ipPools := &crdv1.IPPoolList{} + ipPools := &v3.IPPoolList{} Eventually(func() error { return c.List(context.Background(), ipPools) }, 5*time.Second, 1*time.Second).ShouldNot(HaveOccurred()) @@ -198,19 +197,19 @@ var _ = Describe("IPPool FV tests", func() { It("should assume ownership of legacy default IP pools", func() { // Create an IP pool directly - this simulates a pre-existing IP pool created by Calico prior to // the operator supporting direct IP pool management. - ipPool := crdv1.IPPool{ + ipPool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-ipv4-ippool"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/24", - IPIPMode: crdv1.IPIPModeAlways, - VXLANMode: crdv1.VXLANModeNever, + IPIPMode: v3.IPIPModeAlways, + VXLANMode: v3.VXLANModeNever, BlockSize: 26, NATOutgoing: true, NodeSelector: "all()", DisableBGPExport: false, - AllowedUses: []crdv1.IPPoolAllowedUse{ - crdv1.IPPoolAllowedUseWorkload, - crdv1.IPPoolAllowedUseTunnel, + AllowedUses: []v3.IPPoolAllowedUse{ + v3.IPPoolAllowedUseWorkload, + v3.IPPoolAllowedUseTunnel, }, AssignmentMode: operator.AssignmentModeAutomatic, }, @@ -245,7 +244,7 @@ var _ = Describe("IPPool FV tests", func() { // been controlled by the operator at this point. // Get IP pools installed in the cluster. - ipPools := &crdv1.IPPoolList{} + ipPools := &v3.IPPoolList{} Eventually(func() error { return c.List(context.Background(), ipPools) }, 5*time.Second, 1*time.Second).ShouldNot(HaveOccurred()) @@ -296,18 +295,18 @@ var _ = Describe("IPPool FV tests", func() { It("should NOT assume ownership of modified IP pools on upgrade", func() { // Create an IP pool directly - this simulates a pre-existing IP pool created by Calico prior to // the operator supporting direct IP pool management. - ipPool := crdv1.IPPool{ + ipPool := v3.IPPool{ ObjectMeta: metav1.ObjectMeta{Name: "default-ipv4-ippool"}, - Spec: crdv1.IPPoolSpec{ + Spec: v3.IPPoolSpec{ CIDR: "192.168.0.0/24", - IPIPMode: crdv1.IPIPModeAlways, - VXLANMode: crdv1.VXLANModeNever, + IPIPMode: v3.IPIPModeAlways, + VXLANMode: v3.VXLANModeNever, BlockSize: 26, NATOutgoing: true, DisableBGPExport: false, - AllowedUses: []crdv1.IPPoolAllowedUse{ - crdv1.IPPoolAllowedUseWorkload, - crdv1.IPPoolAllowedUseTunnel, + AllowedUses: []v3.IPPoolAllowedUse{ + v3.IPPoolAllowedUseWorkload, + v3.IPPoolAllowedUseTunnel, }, // Use a non-default selector. This mimics a user modifying the IP pool after it was created, // since we will use the default selector in the Installation spec. @@ -345,7 +344,7 @@ var _ = Describe("IPPool FV tests", func() { // been controlled by the operator at this point. // Get IP pools installed in the cluster. - ipPools := &crdv1.IPPoolList{} + ipPools := &v3.IPPoolList{} Eventually(func() error { return c.List(context.Background(), ipPools) }, 5*time.Second, 1*time.Second).ShouldNot(HaveOccurred())