diff --git a/Makefile b/Makefile index 89d0f72896..b524d3fd35 100644 --- a/Makefile +++ b/Makefile @@ -475,10 +475,9 @@ load-container-images: ./test/load_images_on_kind_cluster.sh $(IMAGE_TARS) deploy-crds: kubectl @export KUBECONFIG=$(KIND_KUBECONFIG) && \ $(BINDIR)/kubectl create -f pkg/crds/operator/ && \ - $(BINDIR)/kubectl apply -f pkg/crds/calico/ && \ - $(BINDIR)/kubectl apply -f pkg/crds/enterprise/ && \ - $(BINDIR)/kubectl apply -f deploy/crds/elastic/elasticsearch-crd.yaml && \ - $(BINDIR)/kubectl apply -f deploy/crds/elastic/kibana-crd.yaml && \ + $(BINDIR)/kubectl apply -f pkg/crds/calico/v1.crd.projectcalico.org/ && \ + $(BINDIR)/kubectl apply -f pkg/crds/enterprise/v1.crd.projectcalico.org/ && \ + $(BINDIR)/kubectl apply -f pkg/crds/enterprise/01-crd-eck-bundle.yaml && \ $(BINDIR)/kubectl create -f deploy/crds/prometheus create-tigera-operator-namespace: kubectl @@ -708,7 +707,8 @@ define prep_local_crds $(eval product := $(1)) rm -rf pkg/crds/$(product) rm -rf .crds/$(product) - mkdir -p pkg/crds/$(product) + mkdir -p pkg/crds/$(product)/v1.crd.projectcalico.org/ + mkdir -p pkg/crds/$(product)/v3.projectcalico.org/ mkdir -p .crds/$(product) endef @@ -722,15 +722,20 @@ define fetch_crds @echo "Fetching $(dir) CRDs from $(project) branch $(branch)" git -C .crds/$(dir) clone --depth 1 --branch $(branch) --single-branch git@github.com:$(project).git ./ endef -define copy_crds +define copy_v1_crds $(eval dir := $(1)) $(eval product := $(2)) - @cp $(dir)/libcalico-go/config/crd/* pkg/crds/$(product)/ && echo "Copied $(product) CRDs" + @cp $(dir)/libcalico-go/config/crd/* pkg/crds/$(product)/v1.crd.projectcalico.org/ && echo "Copied $(product) CRDs" +endef +define copy_v3_crds + $(eval dir := $(1)) + $(eval product := $(2)) + @cp $(dir)/api/config/crd/* pkg/crds/$(product)/v3.projectcalico.org/ && echo "Copied $(product) CRDs" endef define copy_eck_crds $(eval dir := $(1)) $(eval product := $(2)) - @cp $(dir)/charts/tigera-operator/crds/eck/* pkg/crds/$(product)/ && echo "Copied $(product) ECK CRDs" + @cp $(dir)/charts/crd.projectcalico.org.v1/templates/eck/* pkg/crds/$(product)/ && echo "Copied $(product) ECK CRDs" endef .PHONY: read-libcalico-version read-libcalico-enterprise-version @@ -748,7 +753,8 @@ read-libcalico-calico-version: if [ -z "$(CALICO_BRANCH)" ]; then echo "libcalico branch not defined"; exit 1; fi update-calico-crds: fetch-calico-crds - $(call copy_crds, $(CALICO_CRDS_DIR),"calico") + $(call copy_v1_crds, $(CALICO_CRDS_DIR),"calico") + $(call copy_v3_crds, $(CALICO_CRDS_DIR),"calico") prepare-for-calico-crds: $(call prep_local_crds,"calico") @@ -766,7 +772,7 @@ read-libcalico-enterprise-version: if [ -z "$(CALICO_ENTERPRISE_BRANCH)" ]; then echo "libcalico enterprise branch not defined"; exit 1; fi update-enterprise-crds: fetch-enterprise-crds - $(call copy_crds,$(ENTERPRISE_CRDS_DIR),"enterprise") + $(call copy_v1_crds,$(ENTERPRISE_CRDS_DIR),"enterprise") $(call copy_eck_crds,$(ENTERPRISE_CRDS_DIR),"enterprise") prepare-for-enterprise-crds: diff --git a/cmd/main.go b/cmd/main.go index 10891bcb8f..684eabdea5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -81,15 +81,12 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(apiextensions.AddToScheme(scheme)) utilruntime.Must(operatortigeraiov1.AddToScheme(scheme)) - utilruntime.Must(apis.AddToScheme(scheme)) } 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() { @@ -146,6 +143,7 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe fmt.Println("Enterprise:", components.EnterpriseRelease) os.Exit(0) } + if printImages != "" { var cmpnts []components.Component if strings.ToLower(printImages) == "list" { @@ -166,6 +164,7 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe } os.Exit(0) } + if printCalicoCRDs != "" { if err := showCRDs(operatortigeraiov1.Calico, printCalicoCRDs); err != nil { fmt.Println(err) @@ -211,6 +210,15 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe os.Exit(1) } + v3CRDs, err := apis.UseV3CRDS(cs) + if err != nil { + log.Error(err, "Failed to determine CRD version to use") + os.Exit(1) + } + + // Add the Calico API to the scheme, now that we know which backing CRD version to use. + utilruntime.Must(apis.AddToScheme(scheme, v3CRDs)) + // Because we only run this as a job that is set up by the operator, it should not be // launched except by an operator that is the active operator. So we do not need to // check that we're the active operator before running the AWS SG setup. @@ -280,7 +288,9 @@ If a value other than 'all' is specified, the first CRD with a prefix of the spe // If configured to manage CRDs, do a preliminary install of them here. The Installation controller // will reconcile them as well, but we need to make sure they are installed before we start the rest of the controllers. if bootstrapCRDs || manageCRDs { - if err := crds.Ensure(mgr.GetClient(), variant); err != nil { + setupLog.WithValues("v3", v3CRDs).Info("Ensuring CRDs are installed") + + if err := crds.Ensure(mgr.GetClient(), variant, v3CRDs, setupLog); err != nil { setupLog.Error(err, "Failed to ensure CRDs are created") os.Exit(1) } @@ -443,6 +453,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: v3CRDs, } // Before we start any controllers, make sure our options are valid. @@ -520,7 +531,7 @@ func metricsAddr() string { func showCRDs(variant operatortigeraiov1.ProductVariant, outputType string) error { first := true - for _, v := range crds.GetCRDs(variant) { + for _, v := range crds.GetCRDs(variant, os.Getenv("CALICO_API_GROUP") == "projectcalico.org/v3") { if outputType != "all" { if !strings.HasPrefix(v.Name, outputType) { continue diff --git a/config/calico_versions.yml b/config/calico_versions.yml index 239e4998e2..c32299d76b 100644 --- a/config/calico_versions.yml +++ b/config/calico_versions.yml @@ -2,7 +2,7 @@ title: master components: libcalico-go: - version: master + version: casey-v3-crds typha: version: master node: 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 24e8a6913f..c4c4147e7b 100644 --- a/go.mod +++ b/go.mod @@ -22,13 +22,12 @@ require ( github.com/openshift/api v0.0.0-20260122154241-80c3fbc164d6 github.com/openshift/library-go v0.0.0-20260121132910-dc3a1c884c04 github.com/pkg/errors v0.9.1 - github.com/projectcalico/api v0.0.0-20250916150628-d4009e4d7c50 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.88.0 github.com/r3labs/diff/v2 v2.15.1 github.com/sirupsen/logrus v1.9.4 github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d github.com/stretchr/testify v1.11.1 - github.com/tigera/api v0.0.0-20260115201458-bce624761bbd + github.com/tigera/api v0.0.0-20260131232301-9cd5ef33622f github.com/tigera/operator/api v0.0.0-20260120220012-4a3f8a7d8399 github.com/urfave/cli/v3 v3.6.2 go.uber.org/zap v1.27.1 diff --git a/go.sum b/go.sum index c1ef9c896b..2fa29d1875 100644 --- a/go.sum +++ b/go.sum @@ -352,8 +352,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/projectcalico/api v0.0.0-20250916150628-d4009e4d7c50 h1:uawQ+eFENhBbwlOy0ooDwnzVWN2KP6X//GuJMXauyew= -github.com/projectcalico/api v0.0.0-20250916150628-d4009e4d7c50/go.mod h1:bUD5LQaKzGNl93fq+RcBH4CyzfIGoeq/xIRH/IxaGwI= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.88.0 h1:eKVckm/elKIvnNKQAO9WXxBOudphxpkZmT9+bevtvDo= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.88.0/go.mod h1:IJwk1oNs212afqGbNnE84GAB95OHtJR/BuI1rKESiYk= github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= @@ -419,8 +417,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tigera/api v0.0.0-20260115201458-bce624761bbd h1:F0fbust3k5972J78YBz9xvsifP8WIsG/+aC8RBAHT6I= -github.com/tigera/api v0.0.0-20260115201458-bce624761bbd/go.mod h1:iwTu4rNSqc5QhfZJovB4d/zC3YIf7v55BO01Q0JBf2Q= +github.com/tigera/api v0.0.0-20260131232301-9cd5ef33622f h1:kvsv9htGZBL8L4j+SRjy4iwCM4iVcEEo9RuMQ+o1CgA= +github.com/tigera/api v0.0.0-20260131232301-9cd5ef33622f/go.mod h1:bxcXRBfeRHbx80vBXAg8ivbN/y6seqMm2MPhgbWoShc= github.com/urfave/cli/v3 v3.6.2 h1:lQuqiPrZ1cIz8hz+HcrG0TNZFxU70dPZ3Yl+pSrH9A8= github.com/urfave/cli/v3 v3.6.2/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= diff --git a/hack/release/github_test.go b/hack/release/github_test.go index 6ed8b1c52c..9448606673 100644 --- a/hack/release/github_test.go +++ b/hack/release/github_test.go @@ -107,7 +107,7 @@ func TestGenerateReleaseNotes(t *testing.T) { cmpNormalizeDateOpt := cmp.Transformer("NormalizeDates", func(s string) string { return dateRegex.ReplaceAllString(s, "DD MMM YYYY") }) - want := `27 Nov 2025 + want := `27 Nov 2026 #### Included Calico versions diff --git a/pkg/active/active_test.go b/pkg/active/active_test.go index f0988d5820..e2678c315b 100644 --- a/pkg/active/active_test.go +++ b/pkg/active/active_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2026 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. @@ -37,13 +37,12 @@ var _ = Describe("test active pkg", func() { c client.Client ctx context.Context scheme *runtime.Scheme - //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,14 +51,15 @@ var _ = Describe("test active pkg", func() { c = ctrlrfake.DefaultFakeClientBuilder(scheme).Build() ctx = context.Background() - //log = logf.Log.WithName("active-test-logger") }) + Context("GetActiveConfigMap", func() { It("should not error with no ConfigMap", func() { cm, err := GetActiveConfigMap(c) Expect(err).To(BeNil()) Expect(cm).To(BeNil()) }) + It("should retrieve ConfigMap", func() { dataMap := map[string]string{"test-key": "test-data"} Expect(c.Create(ctx, &corev1.ConfigMap{ diff --git a/pkg/apis/addtoscheme_operator_v1.go b/pkg/apis/addtoscheme_operator_v1.go deleted file mode 100644 index 66cb9a4206..0000000000 --- a/pkg/apis/addtoscheme_operator_v1.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2020-2026 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" - admregv1 "k8s.io/api/admissionregistration/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" - 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) - AddToSchemes = append(AddToSchemes, admregv1.SchemeBuilder.AddToScheme) - AddToSchemes = append(AddToSchemes, autoscalingv2.SchemeBuilder.AddToScheme) -} diff --git a/pkg/apis/apis.go b/pkg/apis/apis.go deleted file mode 100644 index 8120ff5dc4..0000000000 --- a/pkg/apis/apis.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2019-2026 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 7fd416c92b..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/clusterinfo.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2017, 2020-2026 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 afe40f0400..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/felixconfig.go +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright (c) 2017-2026 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" - NFTablesModeAuto NFTablesMode = "Auto" -) - -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"` - - // IstioAmbientMode configures Felix to work together with Tigera's Istio distribution. - // [Default: Disabled] - IstioAmbientMode *string `json:"istioAmbientMode,omitempty"` - - // IstioDSCPMark sets the value to use when directing traffic to Istio ZTunnel, when Istio is enabled. The mark is set only on - // SYN packets at the final hop to avoid interference with other protocols. This value is reserved by Calico and must not be - // used with other Istio intallation - // elsewhere. [Default: 23] - IstioDSCPMark *numorstring.DSCP `json:"istioDSCPMark,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 a41ee0ee5c..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/ippool.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2020-2026 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 1a289bad84..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/register.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2023-2026 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 c309614e16..0000000000 --- a/pkg/apis/crd.projectcalico.org/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,1069 +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.IstioAmbientMode != nil { - in, out := &in.IstioAmbientMode, &out.IstioAmbientMode - *out = new(string) - **out = **in - } - if in.IstioDSCPMark != nil { - in, out := &in.IstioDSCPMark, &out.IstioDSCPMark - *out = new(libnumorstring.DSCP) - **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..bbb26acd6f --- /dev/null +++ b/pkg/apis/register.go @@ -0,0 +1,154 @@ +// Copyright (c) 2019-2026 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" + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" + certificatesv1 "k8s.io/api/certificates/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + rbacv1 "k8s.io/api/rbac/v1" + storagev1 "k8s.io/api/storage/v1" + 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() { + 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) + AddToSchemes = append(AddToSchemes, corev1.AddToScheme) + AddToSchemes = append(AddToSchemes, rbacv1.AddToScheme) + AddToSchemes = append(AddToSchemes, appsv1.AddToScheme) + AddToSchemes = append(AddToSchemes, batchv1.AddToScheme) + AddToSchemes = append(AddToSchemes, storagev1.AddToScheme) + AddToSchemes = append(AddToSchemes, certificatesv1.AddToScheme) + AddToSchemes = append(AddToSchemes, networkingv1.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 { + log.Info("Registering Calico CRD types with projectcalico.org/v3 API group") + v3Types = append(v3Types, variableTypes...) + } else { + log.Info("Registering Calico CRD types with crd.projectcalico.org/v1 API group") + 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...) + metav1.AddToGroupVersion(scheme, v1GV) + + // 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/apis/version.go b/pkg/apis/version.go new file mode 100644 index 0000000000..72cffb2a87 --- /dev/null +++ b/pkg/apis/version.go @@ -0,0 +1,52 @@ +// Copyright (c) 2026 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 ( + "os" + + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" + "k8s.io/client-go/kubernetes" + ctrl "sigs.k8s.io/controller-runtime" +) + +var log = ctrl.Log.WithName("apis") + +// UseV3CRDS detects whether we should use the crd.projectcalic.org/v1 or +// projectcalico.org/v3 API group for Calico CRDs. +func UseV3CRDS(cs kubernetes.Interface) (bool, error) { + if os.Getenv("CALICO_API_GROUP") != "" { + log.Info("CALICO_API_GROUP environment variable is set, using its value to determine API group", "CALICO_API_GROUP", os.Getenv("CALICO_API_GROUP")) + return os.Getenv("CALICO_API_GROUP") == "projectcalico.org/v3", nil + } + + apiGroups, err := cs.Discovery().ServerGroups() + if err != nil { + return false, err + } + + v3present, v1present := false, false + for _, g := range apiGroups.Groups { + if g.Name == v3.GroupName { + v3present = true + } + if g.Name == "crd.projectcalico.org" { + v1present = true + } + } + + log.Info("Detected API groups from API server", "v3present", v3present, "v1present", v1present) + return v3present && !v1present, nil +} diff --git a/pkg/awssgsetup/aws_security_group_setup.go b/pkg/awssgsetup/aws_security_group_setup.go index 32806ae1c7..82c54c1193 100644 --- a/pkg/awssgsetup/aws_security_group_setup.go +++ b/pkg/awssgsetup/aws_security_group_setup.go @@ -37,9 +37,11 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" ) -var log = logf.Log.WithName("AWS_SG_Setup") -var TRACE = 7 -var DEBUG = 5 +var ( + log = logf.Log.WithName("AWS_SG_Setup") + TRACE = 7 + DEBUG = 5 +) type errorSecurityGroupNotFound struct { FilterKey string @@ -312,7 +314,7 @@ func allowIngressToSG(cli *ec2.EC2, toSG *ec2.SecurityGroup, sources []ingressSr if skip { continue } - in.SetIpPermissions([]*ec2.IpPermission{&ec2.IpPermission{ + in.SetIpPermissions([]*ec2.IpPermission{{ UserIdGroupPairs: []*ec2.UserIdGroupPair{{ GroupId: aws.String(s.srcSGId), }}, diff --git a/pkg/controller/apiserver/apiserver_controller.go b/pkg/controller/apiserver/apiserver_controller.go index b5a0f11b15..c8bf445319 100644 --- a/pkg/controller/apiserver/apiserver_controller.go +++ b/pkg/controller/apiserver/apiserver_controller.go @@ -224,7 +224,7 @@ func (r *ReconcileAPIServer) Reconcile(ctx context.Context, request reconcile.Re instance, msg, err := utils.GetAPIServer(ctx, r.client) if err != nil { if errors.IsNotFound(err) { - reqLogger.Info("APIServer config not found") + reqLogger.V(1).Info("APIServer not found") r.status.OnCRNotFound() f, err := r.maintainFinalizer(ctx, nil) // If the finalizer is still set, then requeue so we aren't dependent on the periodic reconcile to check and remove the finalizer diff --git a/pkg/controller/apiserver/apiserver_controller_test.go b/pkg/controller/apiserver/apiserver_controller_test.go index 806b91c5ed..84e53603c2 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 75bca2606a..c4e6fe292f 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" @@ -136,7 +136,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) } @@ -475,7 +475,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 @@ -497,31 +497,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. @@ -535,12 +535,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 @@ -550,7 +550,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 8815b04aa8..2d49d4629c 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 5681de3c0c..277d832afb 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 e7878f3f72..34e3a94539 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 80a70e6d44..142793bad1 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 b48ee826b1..d7936722d0 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 aa7cf88f20..4b54e09e85 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 07a5fd5005..2f0d1514be 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" @@ -112,7 +112,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) } @@ -296,7 +296,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 } @@ -341,7 +341,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()) @@ -582,7 +582,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 { @@ -595,7 +595,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 { @@ -612,7 +612,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 8c7d0bf45a..8246b48318 100644 --- a/pkg/controller/egressgateway/egressgateway_controller_test.go +++ b/pkg/controller/egressgateway/egressgateway_controller_test.go @@ -40,9 +40,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" @@ -63,7 +63,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()) @@ -96,11 +96,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, @@ -108,11 +108,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, @@ -120,32 +120,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()) @@ -267,7 +267,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")) @@ -324,7 +324,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 e62001bf13..35a0287191 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 529197618c..e05e3f114d 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 eb9ddc787d..795d8fcf97 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..1ac744bddc 100644 --- a/pkg/controller/installation/bpf_test.go +++ b/pkg/controller/installation/bpf_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2026 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. @@ -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 39fdcfa281..d232127247 100644 --- a/pkg/controller/installation/core_controller.go +++ b/pkg/controller/installation/core_controller.go @@ -60,7 +60,6 @@ import ( calicoclient "github.com/tigera/api/pkg/client/clientset_generated/clientset" 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/components" "github.com/tigera/operator/pkg/controller/certificatemanager" @@ -155,54 +154,8 @@ func Add(mgr manager.Manager, opts options.AddOptions) error { ) } - return add(c, ri) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager, opts options.AddOptions) (*ReconcileInstallation, error) { - nm, err := migration.NewCoreNamespaceMigration(opts.K8sClientset) - if err != nil { - return nil, fmt.Errorf("failed to initialize Namespace migration: %w", err) - } - - statusManager := status.New(mgr.GetClient(), "calico", opts.KubernetesVersion) - - // Create the SharedIndexInformer used by the typhaAutoscaler - nodeListWatch := cache.NewListWatchFromClient(opts.K8sClientset.CoreV1().RESTClient(), "nodes", "", fields.Everything()) - nodeIndexInformer := cache.NewSharedIndexInformer(nodeListWatch, &corev1.Node{}, 0, cache.Indexers{}) - go nodeIndexInformer.Run(opts.ShutdownContext.Done()) - - // Create a Typha autoscaler. - typhaListWatch := cache.NewListWatchFromClient(opts.K8sClientset.AppsV1().RESTClient(), "deployments", "calico-system", fields.OneTermEqualSelector("metadata.name", "calico-typha")) - typhaScaler := newTyphaAutoscaler(opts.K8sClientset, nodeIndexInformer, typhaListWatch, statusManager) - - r := &ReconcileInstallation{ - config: mgr.GetConfig(), - client: mgr.GetClient(), - clientset: opts.K8sClientset, - scheme: mgr.GetScheme(), - shutdownContext: opts.ShutdownContext, - watches: make(map[runtime.Object]struct{}), - autoDetectedProvider: opts.DetectedProvider, - status: statusManager, - typhaAutoscaler: typhaScaler, - namespaceMigration: nm, - enterpriseCRDsExist: opts.EnterpriseCRDExists, - clusterDomain: opts.ClusterDomain, - manageCRDs: opts.ManageCRDs, - tierWatchReady: &utils.ReadyFlag{}, - newComponentHandler: utils.NewComponentHandler, - } - r.status.Run(opts.ShutdownContext) - r.typhaAutoscaler.start(opts.ShutdownContext) - - return r, nil -} - -// add adds watches for resources that are available at startup -func add(c ctrlruntime.Controller, r *ReconcileInstallation) error { // Watch for changes to primary resource Installation - err := c.WatchObject(&operatorv1.Installation{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&operatorv1.Installation{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("tigera-installation-controller failed to watch primary resource: %w", err) } @@ -212,7 +165,7 @@ func add(c ctrlruntime.Controller, r *ReconcileInstallation) error { return fmt.Errorf("tigera-installation-controller failed to watch calico Tigerastatus: %w", err) } - if r.autoDetectedProvider.IsOpenShift() { + if opts.DetectedProvider.IsOpenShift() { // Watch for OpenShift network configuration as well. If we're running in OpenShift, we need to // merge this configuration with our own and the write back the status object. err = c.WatchObject(&configv1.Network{}, &handler.EnqueueRequestForObject{}) @@ -260,24 +213,24 @@ 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) } - if r.enterpriseCRDsExist { + if opts.EnterpriseCRDExists { // Watch for changes to primary resource ManagementCluster err = c.WatchObject(&operatorv1.ManagementCluster{}, &handler.EnqueueRequestForObject{}) if err != nil { @@ -301,21 +254,21 @@ func add(c ctrlruntime.Controller, r *ReconcileInstallation) error { return fmt.Errorf("tigera-installation-controller failed to watch secret: %v", err) } - if r.manageCRDs { - if err = addCRDWatches(c, operatorv1.TigeraSecureEnterprise); err != nil { + if opts.ManageCRDs { + if err = addCRDWatches(c, operatorv1.TigeraSecureEnterprise, opts.UseV3CRDs); err != nil { return fmt.Errorf("tigera-installation-controller failed to watch CRD resource: %v", err) } } } else { - if r.manageCRDs { - if err = addCRDWatches(c, operatorv1.Calico); err != nil { + if opts.ManageCRDs { + if err = addCRDWatches(c, operatorv1.Calico, opts.UseV3CRDs); err != nil { return fmt.Errorf("tigera-installation-controller failed to watch CRD resource: %v", err) } } } // 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) } @@ -330,6 +283,63 @@ func add(c ctrlruntime.Controller, r *ReconcileInstallation) error { return nil } +func addCRDWatches(c ctrlruntime.Controller, v operatorv1.ProductVariant, useV3 bool) error { + pred := predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + // Create occurs because we've created it, so we can safely ignore it. + return false + }, + } + for _, x := range crds.GetCRDs(v, useV3) { + if err := c.WatchObject(x, &handler.EnqueueRequestForObject{}, pred); err != nil { + return err + } + } + return nil +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager, opts options.AddOptions) (*ReconcileInstallation, error) { + nm, err := migration.NewCoreNamespaceMigration(opts.K8sClientset) + if err != nil { + return nil, fmt.Errorf("failed to initialize Namespace migration: %w", err) + } + + statusManager := status.New(mgr.GetClient(), "calico", opts.KubernetesVersion) + + // Create the SharedIndexInformer used by the typhaAutoscaler + nodeListWatch := cache.NewListWatchFromClient(opts.K8sClientset.CoreV1().RESTClient(), "nodes", "", fields.Everything()) + nodeIndexInformer := cache.NewSharedIndexInformer(nodeListWatch, &corev1.Node{}, 0, cache.Indexers{}) + go nodeIndexInformer.Run(opts.ShutdownContext.Done()) + + // Create a Typha autoscaler. + typhaListWatch := cache.NewListWatchFromClient(opts.K8sClientset.AppsV1().RESTClient(), "deployments", "calico-system", fields.OneTermEqualSelector("metadata.name", "calico-typha")) + typhaScaler := newTyphaAutoscaler(opts.K8sClientset, nodeIndexInformer, typhaListWatch, statusManager) + + r := &ReconcileInstallation{ + config: mgr.GetConfig(), + client: mgr.GetClient(), + clientset: opts.K8sClientset, + scheme: mgr.GetScheme(), + shutdownContext: opts.ShutdownContext, + watches: make(map[runtime.Object]struct{}), + autoDetectedProvider: opts.DetectedProvider, + status: statusManager, + typhaAutoscaler: typhaScaler, + namespaceMigration: nm, + enterpriseCRDsExist: opts.EnterpriseCRDExists, + clusterDomain: opts.ClusterDomain, + manageCRDs: opts.ManageCRDs, + tierWatchReady: &utils.ReadyFlag{}, + newComponentHandler: utils.NewComponentHandler, + v3CRDs: opts.UseV3CRDs, + } + r.status.Run(opts.ShutdownContext) + r.typhaAutoscaler.start(opts.ShutdownContext) + + return r, nil +} + // secondaryResources returns a list of the secondary resources that this controller // monitors for changes. Add resources here which correspond to the resources created by // this controller. @@ -377,17 +387,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 @@ -430,7 +442,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 *operatorv1.Installation, awsNode *appsv1.DaemonSet, currentPools *crdv1.IPPoolList) error { +func MergeAndFillDefaults(i *operatorv1.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()) @@ -441,7 +453,7 @@ func MergeAndFillDefaults(i *operatorv1.Installation, awsNode *appsv1.DaemonSet, } // fillDefaults populates the default values onto an Installation object. -func fillDefaults(instance *operatorv1.Installation, currentPools *crdv1.IPPoolList) error { +func fillDefaults(instance *operatorv1.Installation, currentPools *v3.IPPoolList) error { if len(instance.Spec.Variant) == 0 { // Default to installing Calico. instance.Spec.Variant = operatorv1.Calico @@ -1121,7 +1133,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 { @@ -1410,7 +1422,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(operatorv1.ResourceReadError, "Unable to read BGPConfiguration", err, reqLogger) @@ -1489,10 +1501,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 { @@ -1604,7 +1621,7 @@ func (r *ReconcileInstallation) Reconcile(ctx context.Context, request reconcile certificateManager.AddToStatusManager(r.status, common.CalicoNamespace) // 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 { @@ -1807,24 +1824,24 @@ func getOrCreateTyphaNodeTLSConfig(cli client.Client, certificateManager certifi }, nil } -func (r *ReconcileInstallation) setNftablesMode(_ context.Context, install *operatorv1.Installation, fc *crdv1.FelixConfiguration, reqLogger logr.Logger) (bool, error) { +func (r *ReconcileInstallation) setNftablesMode(_ context.Context, install *operatorv1.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 // we don't need to handle upgrades from versions that were previously FelixConfiguration only - nftables mode has always // been controlled by the operator. if install.Spec.CalicoNetwork.LinuxDataplane != nil { - nftablesMode := crdv1.NFTablesModeDisabled + nftablesMode := v3.NFTablesModeDisabled if install.Spec.IsNftables() { // The operator is configured to use the nftables dataplane. if install.Spec.BPFEnabled() { // For BPF mode, we always use nftables, as we don't use the upstream kube-proxy and so don't need to // worry about compatibility with its mode of operation. - nftablesMode = crdv1.NFTablesModeEnabled + nftablesMode = v3.NFTablesModeEnabled } else { // Otherwise, kube-proxy is running - configure Felix to auto-detect whether it should use nftables or iptables on // a per-node basis, allowing for smoother upgrades. - nftablesMode = crdv1.NFTablesModeAuto + nftablesMode = v3.NFTablesModeAuto } } updated = fc.Spec.NFTablesMode == nil || *fc.Spec.NFTablesMode != nftablesMode @@ -1838,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 *operatorv1.Installation, fc *crdv1.FelixConfiguration, reqLogger logr.Logger, needNsMigration bool) (bool, error) { +func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Context, install *operatorv1.Installation, fc *v3.FelixConfiguration, reqLogger logr.Logger, needNsMigration bool) (bool, error) { updated := false switch install.Spec.CNI.Type { @@ -1854,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, } @@ -1863,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, } @@ -1989,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 *operatorv1.Installation, fc *crdv1.FelixConfiguration, reqLogger logr.Logger) (bool, error) { +func (r *ReconcileInstallation) setBPFUpdatesOnFelixConfiguration(ctx context.Context, install *operatorv1.Installation, fc *v3.FelixConfiguration, reqLogger logr.Logger) (bool, error) { updated := false bpfEnabledOnInstall := install.Spec.BPFEnabled() @@ -2110,7 +2127,7 @@ func (r *ReconcileInstallation) updateCRDs(ctx context.Context, variant operator if !r.manageCRDs { return nil } - crdComponent := render.NewPassthrough(crds.ToRuntimeObjects(crds.GetCRDs(variant)...)...) + crdComponent := render.NewPassthrough(crds.ToRuntimeObjects(crds.GetCRDs(variant, r.v3CRDs)...)...) // Specify nil for the CR so no ownership is put on the CRDs. We do this so removing the // Installation CR will not remove the CRDs. handler := r.newComponentHandler(log, r.client, r.scheme, nil) @@ -2187,26 +2204,11 @@ func updateInstallationForAWSNode(i *operatorv1.Installation, ds *appsv1.DaemonS return nil } -func addCRDWatches(c ctrlruntime.Controller, v operatorv1.ProductVariant) error { - pred := predicate.Funcs{ - CreateFunc: func(e event.CreateEvent) bool { - // Create occurs because we've created it, so we can safely ignore it. - return false - }, - } - for _, x := range crds.GetCRDs(v) { - if err := c.WatchObject(x, &handler.EnqueueRequestForObject{}, pred); err != nil { - return err - } - } - return nil -} - -func crdPoolsToOperator(crds []crdv1.IPPool) []operatorv1.IPPool { +func crdPoolsToOperator(crds []v3.IPPool) []operatorv1.IPPool { pools := []operatorv1.IPPool{} for _, p := range crds { op := operatorv1.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 0db859634d..1cd3fef377 100644 --- a/pkg/controller/installation/core_controller_test.go +++ b/pkg/controller/installation/core_controller_test.go @@ -48,7 +48,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" @@ -129,7 +128,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()) @@ -230,14 +229,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()) @@ -681,15 +680,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()) @@ -744,7 +743,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()) @@ -836,14 +835,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()) @@ -950,7 +949,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()) @@ -1040,14 +1039,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()) @@ -1095,11 +1094,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.NFTablesModeAuto)) + Expect(*fc.Spec.NFTablesMode).To(Equal(v3.NFTablesModeAuto)) }) It("should set NFTablesMode to Disabled if nftables mode is changed", func() { @@ -1119,11 +1118,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))) }) }) @@ -1234,11 +1233,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() { @@ -1259,7 +1258,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()) @@ -1332,11 +1331,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, }, } @@ -1365,7 +1364,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()) @@ -1427,7 +1426,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()) @@ -1442,13 +1441,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() { @@ -1459,7 +1458,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()) @@ -1476,7 +1475,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()) @@ -1494,7 +1493,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()) @@ -1515,7 +1514,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()) @@ -1534,7 +1533,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()) @@ -1564,7 +1563,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()) @@ -1582,7 +1581,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()) @@ -1596,11 +1595,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() { @@ -1610,20 +1609,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", }, } @@ -1635,20 +1634,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", }, } @@ -1660,20 +1659,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}, }, } @@ -1685,7 +1684,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()) @@ -2098,7 +2097,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()) @@ -2234,7 +2233,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()) @@ -2337,14 +2336,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 89f364b998..c55d5f50e8 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/validation.go b/pkg/controller/installation/validation.go index 57f1720f5a..8712bb5144 100644 --- a/pkg/controller/installation/validation.go +++ b/pkg/controller/installation/validation.go @@ -15,13 +15,12 @@ package installation import ( + "errors" "fmt" "net" "path" "strings" - "errors" - operatorv1 "github.com/tigera/operator/api/v1" "github.com/tigera/operator/pkg/common" "github.com/tigera/operator/pkg/common/validation" diff --git a/pkg/controller/installation/version.go b/pkg/controller/installation/version.go index d16253a673..e84ce2d77b 100644 --- a/pkg/controller/installation/version.go +++ b/pkg/controller/installation/version.go @@ -22,9 +22,11 @@ import ( "github.com/tigera/operator/version" ) -var buildVersion *gv.Version -var gitDescribeSuffixRegexp = regexp.MustCompile(`-\d+-\w+$`) -var versionRegexp = regexp.MustCompile("^" + gv.VersionRegexpRaw + "$") +var ( + buildVersion *gv.Version + gitDescribeSuffixRegexp = regexp.MustCompile(`-\d+-\w+$`) + versionRegexp = regexp.MustCompile("^" + gv.VersionRegexpRaw + "$") +) func init() { bv, err := versionFromBuildVersion(version.VERSION) diff --git a/pkg/controller/installation/windows_controller.go b/pkg/controller/installation/windows_controller.go index 8f5a83a0ce..73e6b83c13 100644 --- a/pkg/controller/installation/windows_controller.go +++ b/pkg/controller/installation/windows_controller.go @@ -38,11 +38,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,13 +142,13 @@ 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) } // Watch for changes to IPAMConfiguration. - go utils.WaitToAddResourceWatch(c, opts.K8sClientset, logw, ri.ipamConfigWatchReady, []client.Object{&apiv3.IPAMConfiguration{TypeMeta: metav1.TypeMeta{Kind: apiv3.KindIPAMConfiguration}}}) + go utils.WaitToAddResourceWatch(c, opts.K8sClientset, logw, ri.ipamConfigWatchReady, []client.Object{&v3.IPAMConfiguration{TypeMeta: metav1.TypeMeta{Kind: v3.KindIPAMConfiguration}}}) if ri.enterpriseCRDsExist { for _, ns := range []string{common.CalicoNamespace, common.OperatorNamespace()} { @@ -303,7 +302,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) @@ -316,7 +315,7 @@ func (r *ReconcileWindows) Reconcile(ctx context.Context, request reconcile.Requ r.status.SetDegraded(operatorv1.ResourceNotReady, "Waiting for IPAMConfiguration watch to be established", nil, logw) return reconcile.Result{RequeueAfter: utils.StandardRetry}, nil } - ipamConfiguration := &apiv3.IPAMConfiguration{} + ipamConfiguration := &v3.IPAMConfiguration{} err = r.client.Get(ctx, types.NamespacedName{Name: "default"}, ipamConfiguration) if err != nil && !apierrors.IsNotFound(err) { r.status.SetDegraded(operatorv1.ResourceReadError, "Unable to read IPAMConfiguration", err, reqLogger) diff --git a/pkg/controller/installation/windows_controller_test.go b/pkg/controller/installation/windows_controller_test.go index 5cb0eb0627..21ac22796f 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 f0a7e1e0eb..310bd4e8d6 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 21747ffaa9..708fb257ca 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 834e47ad50..6eb454af7c 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 true 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 } @@ -496,20 +496,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 diff --git a/pkg/controller/ippool/pool_controller_test.go b/pkg/controller/ippool/pool_controller_test.go index 2186997fcb..f393830ce2 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" @@ -47,9 +47,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 @@ -59,7 +56,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()) @@ -152,7 +149,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)) @@ -177,9 +174,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()) @@ -203,7 +200,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)) @@ -246,13 +243,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 } @@ -354,7 +351,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)) @@ -386,7 +383,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()) @@ -396,7 +393,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. @@ -591,13 +588,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 237c12214d..4d90854dc8 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/istio/istio_controller.go b/pkg/controller/istio/istio_controller.go index d5b3f171cc..2412e85811 100644 --- a/pkg/controller/istio/istio_controller.go +++ b/pkg/controller/istio/istio_controller.go @@ -31,9 +31,9 @@ import ( "github.com/elastic/cloud-on-k8s/v2/pkg/utils/stringsutil" "github.com/go-logr/logr" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/api/pkg/lib/numorstring" 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" @@ -86,7 +86,7 @@ func Add(mgr manager.Manager, opts options.AddOptions) error { return fmt.Errorf("istio-controller failed to watch Installation resource: %v", err) } - err = c.WatchObject(&crdv1.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) + err = c.WatchObject(&v3.FelixConfiguration{}, &handler.EnqueueRequestForObject{}) if err != nil { return fmt.Errorf("istio-controller failed to watch FelixConfiguration resource: %w", err) } @@ -128,7 +128,7 @@ func (r *ReconcileIstio) Reconcile(ctx context.Context, request reconcile.Reques err := r.Get(ctx, utils.DefaultInstanceKey, instance) if err != nil { if errors.IsNotFound(err) { - reqLogger.Info("Istio object not found") + reqLogger.V(1).Info("Istio object not found") r.status.OnCRNotFound() return reconcile.Result{}, nil } @@ -243,7 +243,7 @@ func (r *ReconcileIstio) Reconcile(ctx context.Context, request reconcile.Reques return reconcile.Result{}, err } - _, 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.setIstioFelixConfiguration(ctx, instance, fc, false) }) if err != nil { @@ -264,7 +264,7 @@ func updateDefaults(istio *operatorv1.Istio) { } } -func (r *ReconcileIstio) setIstioFelixConfiguration(ctx context.Context, instance *operatorv1.Istio, fc *crdv1.FelixConfiguration, remove bool) (bool, error) { +func (r *ReconcileIstio) setIstioFelixConfiguration(ctx context.Context, instance *operatorv1.Istio, fc *v3.FelixConfiguration, remove bool) (bool, error) { // Handle Istio Ambient Mode configuration if err := r.configureIstioAmbientMode(fc, remove); err != nil { return false, err @@ -278,7 +278,7 @@ func (r *ReconcileIstio) setIstioFelixConfiguration(ctx context.Context, instanc return true, nil } -func (r *ReconcileIstio) configureIstioAmbientMode(fc *crdv1.FelixConfiguration, remove bool) error { +func (r *ReconcileIstio) configureIstioAmbientMode(fc *v3.FelixConfiguration, remove bool) error { var annotationMode *string if fc.Annotations[istio.IstioOperatorAnnotationMode] != "" { value := fc.Annotations[istio.IstioOperatorAnnotationMode] @@ -287,7 +287,7 @@ func (r *ReconcileIstio) configureIstioAmbientMode(fc *crdv1.FelixConfiguration, // If the annotation does not match the spec value (ignoring both nil), it indicates a misconfiguration. match := annotationMode == nil && fc.Spec.IstioAmbientMode == nil || - annotationMode != nil && fc.Spec.IstioAmbientMode != nil && *annotationMode == *fc.Spec.IstioAmbientMode + annotationMode != nil && fc.Spec.IstioAmbientMode != nil && *annotationMode == string(*fc.Spec.IstioAmbientMode) if !match { return fmt.Errorf("felixconfig IstioAmbientMode modified by user") @@ -297,18 +297,18 @@ func (r *ReconcileIstio) configureIstioAmbientMode(fc *crdv1.FelixConfiguration, delete(fc.Annotations, istio.IstioOperatorAnnotationMode) fc.Spec.IstioAmbientMode = nil } else { - istioModeDesired := "Enabled" + istioModeDesired := v3.IstioAmbientModeEnabled fc.Spec.IstioAmbientMode = &istioModeDesired if fc.Annotations == nil { fc.Annotations = make(map[string]string) } - fc.Annotations[istio.IstioOperatorAnnotationMode] = istioModeDesired + fc.Annotations[istio.IstioOperatorAnnotationMode] = string(istioModeDesired) } return nil } -func (r *ReconcileIstio) configureIstioDSCPMark(instance *operatorv1.Istio, fc *crdv1.FelixConfiguration, remove bool) error { +func (r *ReconcileIstio) configureIstioDSCPMark(instance *operatorv1.Istio, fc *v3.FelixConfiguration, remove bool) error { var annotationDSCP *numorstring.DSCP if fc.Annotations[istio.IstioOperatorAnnotationDSCP] != "" { value, err := strconv.ParseUint(fc.Annotations[istio.IstioOperatorAnnotationDSCP], 10, 6) @@ -342,7 +342,7 @@ func (r *ReconcileIstio) configureIstioDSCPMark(instance *operatorv1.Istio, fc * func (r *ReconcileIstio) maintainFinalizer(ctx context.Context, instance *operatorv1.Istio, reqLogger logr.Logger) (res reconcile.Result, err error, finalized bool) { // Executing clean up on finalizing if !instance.DeletionTimestamp.IsZero() { - if _, err = utils.PatchFelixConfiguration(ctx, r.Client, func(fc *crdv1.FelixConfiguration) (bool, error) { + if _, err = utils.PatchFelixConfiguration(ctx, r.Client, func(fc *v3.FelixConfiguration) (bool, error) { return r.setIstioFelixConfiguration(ctx, instance, fc, true) }); err != nil { r.status.SetDegraded(operatorv1.ResourceReadError, "Error cleaning up felix configuration", err, reqLogger) diff --git a/pkg/controller/istio/istio_controller_test.go b/pkg/controller/istio/istio_controller_test.go index 0641efdb90..e6d11405af 100644 --- a/pkg/controller/istio/istio_controller_test.go +++ b/pkg/controller/istio/istio_controller_test.go @@ -35,10 +35,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + v3 "github.com/tigera/api/pkg/apis/projectcalico/v3" "github.com/tigera/api/pkg/lib/numorstring" 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/controller/certificatemanager" "github.com/tigera/operator/pkg/controller/status" @@ -62,12 +62,11 @@ var _ = Describe("Istio 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()) Expect(autoscalingv2.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) - Expect(crdv1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) ctx = context.Background() objTrackerWithCalls = test.NewObjectTrackerWithCalls(scheme) @@ -268,12 +267,10 @@ var _ = Describe("Istio controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) mockStatus.AssertCalled(GinkgoT(), "OnCRFound") - //mockStatus.AssertCalled(GinkgoT(), "ClearDegraded") mockStatus.AssertCalled(GinkgoT(), "ReadyToMonitor") }) It("should handle reconciliation without errors", func() { - r := &ReconcileIstio{ Client: cli, scheme: scheme, @@ -318,7 +315,7 @@ var _ = Describe("Istio controller tests", func() { It("should handle deletion and remove finalizer", func() { // Create FelixConfiguration for cleanup test - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, @@ -385,10 +382,10 @@ var _ = Describe("Istio controller tests", func() { Expect(updatedIstio.Spec.DSCPMark.ToUint8()).To(Equal(uint8(23))) // Verify FelixConfiguration was patched - updatedFC := &crdv1.FelixConfiguration{} + updatedFC := &v3.FelixConfiguration{} Expect(cli.Get(ctx, types.NamespacedName{Name: "default"}, updatedFC)).NotTo(HaveOccurred()) Expect(updatedFC.Spec.IstioAmbientMode).NotTo(BeNil()) - Expect(*updatedFC.Spec.IstioAmbientMode).To(Equal("Enabled")) + Expect(*updatedFC.Spec.IstioAmbientMode).To(Equal(v3.IstioAmbientModeEnabled)) Expect(updatedFC.Annotations).To(HaveKey(istio.IstioOperatorAnnotationMode)) Expect(updatedFC.Annotations[istio.IstioOperatorAnnotationMode]).To(Equal("Enabled")) Expect(updatedFC.Spec.IstioDSCPMark).NotTo(BeNil()) @@ -428,10 +425,10 @@ var _ = Describe("Istio controller tests", func() { Expect(updatedIstio.Spec.DSCPMark.ToUint8()).To(Equal(uint8(10))) // Verify FelixConfiguration was patched - updatedFC := &crdv1.FelixConfiguration{} + updatedFC := &v3.FelixConfiguration{} Expect(cli.Get(ctx, types.NamespacedName{Name: "default"}, updatedFC)).NotTo(HaveOccurred()) Expect(updatedFC.Spec.IstioAmbientMode).NotTo(BeNil()) - Expect(*updatedFC.Spec.IstioAmbientMode).To(Equal("Enabled")) + Expect(*updatedFC.Spec.IstioAmbientMode).To(Equal(v3.IstioAmbientModeEnabled)) Expect(updatedFC.Annotations).To(HaveKey(istio.IstioOperatorAnnotationMode)) Expect(updatedFC.Annotations[istio.IstioOperatorAnnotationMode]).To(Equal("Enabled")) Expect(updatedFC.Spec.IstioDSCPMark).NotTo(BeNil()) @@ -448,15 +445,15 @@ var _ = Describe("Istio controller tests", func() { It("should detect user modification of IstioAmbientMode in FelixConfiguration", func() { // Create FelixConfiguration with mismatched annotation and spec - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Annotations: map[string]string{ istio.IstioOperatorAnnotationMode: "Enabled", }, }, - Spec: crdv1.FelixConfigurationSpec{ - IstioAmbientMode: ptr.To("Disabled"), + Spec: v3.FelixConfigurationSpec{ + IstioAmbientMode: ptr.To[v3.IstioAmbientMode]("Disabled"), }, } Expect(cli.Create(ctx, fc)).NotTo(HaveOccurred()) @@ -476,14 +473,14 @@ var _ = Describe("Istio controller tests", func() { It("should detect user modification of IstioDSCPMark in FelixConfiguration", func() { // Create FelixConfiguration with mismatched annotation and spec userModifiedDSCP := numorstring.DSCPFromInt(50) - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Annotations: map[string]string{ istio.IstioOperatorAnnotationDSCP: "23", }, }, - Spec: crdv1.FelixConfigurationSpec{ + Spec: v3.FelixConfigurationSpec{ IstioDSCPMark: &userModifiedDSCP, }, } @@ -503,7 +500,7 @@ var _ = Describe("Istio controller tests", func() { It("should clear FelixConfiguration on deletion", func() { // Create empty FelixConfiguration - fc := &crdv1.FelixConfiguration{ + fc := &v3.FelixConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "default", }, @@ -522,10 +519,10 @@ var _ = Describe("Istio controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) // Verify FelixConfiguration was patched with Istio settings - patchedFC := &crdv1.FelixConfiguration{} + patchedFC := &v3.FelixConfiguration{} Expect(cli.Get(ctx, types.NamespacedName{Name: "default"}, patchedFC)).NotTo(HaveOccurred()) Expect(patchedFC.Spec.IstioAmbientMode).NotTo(BeNil()) - Expect(*patchedFC.Spec.IstioAmbientMode).To(Equal("Enabled")) + Expect(*patchedFC.Spec.IstioAmbientMode).To(Equal(v3.IstioAmbientModeEnabled)) Expect(patchedFC.Spec.IstioDSCPMark).NotTo(BeNil()) Expect(patchedFC.Spec.IstioDSCPMark.ToUint8()).To(Equal(uint8(23))) Expect(patchedFC.Annotations).To(HaveKey(istio.IstioOperatorAnnotationMode)) @@ -545,7 +542,7 @@ var _ = Describe("Istio controller tests", func() { Expect(err).ShouldNot(HaveOccurred()) // Verify FelixConfiguration was cleared - clearedFC := &crdv1.FelixConfiguration{} + clearedFC := &v3.FelixConfiguration{} Expect(cli.Get(ctx, types.NamespacedName{Name: "default"}, clearedFC)).NotTo(HaveOccurred()) Expect(clearedFC.Spec.IstioAmbientMode).To(BeNil()) Expect(clearedFC.Spec.IstioDSCPMark).To(BeNil()) diff --git a/pkg/controller/kubeproxy/controller.go b/pkg/controller/kubeproxy/controller.go index 48aaec9603..0b8d96dac0 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 fa74f010e3..c06a30e778 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 21bcfeddfe..317826ae88 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 c76b14575d..c2faf42013 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 7ed0e0ade9..233f1accc8 100644 --- a/pkg/controller/logstorage/elastic/elastic_controller_test.go +++ b/pkg/controller/logstorage/elastic/elastic_controller_test.go @@ -122,7 +122,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 bd11a6b370..f433d93c2b 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..23e23eb39e 100644 --- a/pkg/controller/logstorage/esmetrics/esmetrics_controller_test.go +++ b/pkg/controller/logstorage/esmetrics/esmetrics_controller_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2023-2026 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. @@ -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..2acd70b252 100644 --- a/pkg/controller/logstorage/initializer/conditions_controller_test.go +++ b/pkg/controller/logstorage/initializer/conditions_controller_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2026 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. @@ -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 00ba8b6970..3452a8cbc4 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 460d4ff092..eb03296f0e 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 aa8106390c..97d5454d4c 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 d167e23a63..45b2c01f67 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..e1f010b813 100644 --- a/pkg/controller/logstorage/secrets/secret_controller_test.go +++ b/pkg/controller/logstorage/secrets/secret_controller_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2023-2026 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. @@ -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 eefb4a566c..e3e4f64b17 100644 --- a/pkg/controller/manager/manager_controller_test.go +++ b/pkg/controller/manager/manager_controller_test.go @@ -69,7 +69,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 5aa3498bd4..31e1c795cf 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 cbb633399b..4564d59fd7 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" @@ -34,8 +34,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, @@ -62,7 +64,7 @@ var _ = Describe("convert bpf config", func() { var ( comps = emptyComponents() i = &operatorv1.Installation{} - f = &crdv1.FelixConfiguration{} + f = &v3.FelixConfiguration{} scheme = kscheme.Scheme ) @@ -70,7 +72,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..a346a34913 100644 --- a/pkg/controller/migration/convert/convert_test.go +++ b/pkg/controller/migration/convert/convert_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2026 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. @@ -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/core.go b/pkg/controller/migration/convert/core.go index 83b4bae7e2..f56f46c26e 100644 --- a/pkg/controller/migration/convert/core.go +++ b/pkg/controller/migration/convert/core.go @@ -373,7 +373,6 @@ func handleNodeSelectors(c *components, install *operatorv1.Installation) error component: ComponentCalicoNode, fix: "remove the nodeSelector", } - } // check typha nodeSelectors @@ -436,7 +435,7 @@ func handleNodeSelectors(c *components, install *operatorv1.Installation) error // removeOSNodeSelectors returns the given nodeSelectors with [beta.]kubernetes.io/os=linux nodeSelectors removed. func removeOSNodeSelectors(existing map[string]string) map[string]string { - var nodeSel = map[string]string{} + nodeSel := map[string]string{} for key, val := range existing { if (key == "kubernetes.io/os" || key == "beta.kubernetes.io/os") && val == "linux" { continue diff --git a/pkg/controller/migration/convert/core_test.go b/pkg/controller/migration/convert/core_test.go index 2be5c26158..1b6e96df37 100644 --- a/pkg/controller/migration/convert/core_test.go +++ b/pkg/controller/migration/convert/core_test.go @@ -46,7 +46,7 @@ var _ = Describe("core handler", func() { Expect(i.Spec.ComponentResources).To(BeEmpty()) }) - var rqs = v1.ResourceRequirements{ + rqs := v1.ResourceRequirements{ Limits: v1.ResourceList{ v1.ResourceCPU: resource.MustParse("500m"), v1.ResourceMemory: resource.MustParse("500Mi"), @@ -89,7 +89,7 @@ var _ = Describe("core handler", func() { v1.ResourceCPU: resource.MustParse("500m"), }, } - expectedCompRsrc := []operatorv1.ComponentResource{operatorv1.ComponentResource{ + expectedCompRsrc := []operatorv1.ComponentResource{{ ComponentName: operatorv1.ComponentNameNode, ResourceRequirements: rqs.DeepCopy(), }} @@ -631,7 +631,6 @@ var _ = Describe("core handler", func() { Expect(*i.Spec.NodeMetricsPort).To(Equal(int32(9091))) }) It("defaults prometheus off when no prometheus environment variables set", func() { - Expect(handleFelixNodeMetrics(&comps, i)).ToNot(HaveOccurred()) Expect(i.Spec.NodeMetricsPort).To(BeNil()) }) diff --git a/pkg/controller/migration/convert/felix_vars.go b/pkg/controller/migration/convert/felix_vars.go index fc56901053..bf0e3ea2b0 100644 --- a/pkg/controller/migration/convert/felix_vars.go +++ b/pkg/controller/migration/convert/felix_vars.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2026 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. @@ -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..b6ef9277c7 100644 --- a/pkg/controller/migration/convert/felix_vars_test.go +++ b/pkg/controller/migration/convert/felix_vars_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2026 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. @@ -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..060d3c5749 100644 --- a/pkg/controller/migration/convert/ippools.go +++ b/pkg/controller/migration/convert/ippools.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2026 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. @@ -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..24be8cd0d5 100644 --- a/pkg/controller/migration/convert/ippools_test.go +++ b/pkg/controller/migration/convert/ippools_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2026 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. @@ -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.go b/pkg/controller/migration/convert/network.go index 87083f40c2..f5b4a5727b 100644 --- a/pkg/controller/migration/convert/network.go +++ b/pkg/controller/migration/convert/network.go @@ -210,7 +210,6 @@ func handleCalicoCNI(c *components, install *operatorv1.Installation) error { // parse JSON data var tuningSpecData TuningSpec if err := json.Unmarshal([]byte(pluginData.Bytes), &tuningSpecData); err != nil { - return ErrIncompatibleCluster{ err: "error parsing CNI config plugin type 'tuning'", component: ComponentCNIConfig, @@ -506,7 +505,7 @@ func getAutoDetectionMethod(method *string) (*operatorv1.NodeAddressAutodetectio // first-found if *method == "" || *method == AutodetectionMethodFirst { - var t = true + t := true return &operatorv1.NodeAddressAutodetection{FirstFound: &t}, nil } @@ -537,7 +536,7 @@ func getAutoDetectionMethod(method *string) (*operatorv1.NodeAddressAutodetectio // kubernetes-internal-ip if *method == "" || *method == AutodetectionMethodNodeIP { - var k = operatorv1.NodeInternalIP + k := operatorv1.NodeInternalIP return &operatorv1.NodeAddressAutodetection{Kubernetes: &k}, nil } diff --git a/pkg/controller/migration/convert/network_test.go b/pkg/controller/migration/convert/network_test.go index 924b16892a..76c32353d3 100644 --- a/pkg/controller/migration/convert/network_test.go +++ b/pkg/controller/migration/convert/network_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2023-2026 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. @@ -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 e149fe1e6a..d9a80011e0 100644 --- a/pkg/controller/migration/convert/nftables.go +++ b/pkg/controller/migration/convert/nftables.go @@ -17,14 +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" "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) @@ -35,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 == crdv1.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 295b47a9e0..211af76453 100644 --- a/pkg/controller/migration/convert/nftables_test.go +++ b/pkg/controller/migration/convert/nftables_test.go @@ -17,9 +17,9 @@ 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" ctrlrfake "github.com/tigera/operator/pkg/ctrlruntime/client/fake" v1 "k8s.io/api/core/v1" @@ -31,7 +31,7 @@ var _ = Describe("convert nftables mode", func() { var ( comps = emptyComponents() i = &operatorv1.Installation{} - f = &crdv1.FelixConfiguration{} + f = &v3.FelixConfiguration{} scheme = kscheme.Scheme ) @@ -39,11 +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() { - f.Spec.NFTablesMode = ptr.To(crdv1.NFTablesModeEnabled) + f.Spec.NFTablesMode = ptr.To(v3.NFTablesMode(v3.NFTablesModeEnabled)) comps.client = ctrlrfake.DefaultFakeClientBuilder(scheme).WithObjects(endPointCM, f).Build() err := handleNftables(&comps, i) @@ -53,7 +53,7 @@ var _ = Describe("convert nftables mode", func() { }) It("converts nftables mode from FelixConfiguration Disabled", func() { - f.Spec.NFTablesMode = ptr.To(crdv1.NFTablesModeDisabled) + 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()) @@ -61,7 +61,7 @@ var _ = Describe("convert nftables mode", func() { }) It("rejects migration if another dataplane is already set", func() { - f.Spec.NFTablesMode = ptr.To(crdv1.NFTablesModeEnabled) + 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..dae35b352b 100644 --- a/pkg/controller/migration/convert/testutils_test.go +++ b/pkg/controller/migration/convert/testutils_test.go @@ -1,8 +1,21 @@ +// Copyright (c) 2026 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 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 +173,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..aa73416ddb 100644 --- a/pkg/controller/migration/convert/typha_test.go +++ b/pkg/controller/migration/convert/typha_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2026 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. @@ -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/migration/namespace_migration.go b/pkg/controller/migration/namespace_migration.go index aaef60bdc3..632ad64c16 100644 --- a/pkg/controller/migration/namespace_migration.go +++ b/pkg/controller/migration/namespace_migration.go @@ -63,9 +63,7 @@ const ( defaultMaxUnavailable int32 = 1 ) -var ( - migratedNodeLabel = map[string]string{nodeSelectorKey: nodeSelectorValuePost} -) +var migratedNodeLabel = map[string]string{nodeSelectorKey: nodeSelectorValuePost} type NamespaceMigration interface { NeedsCoreNamespaceMigration(ctx context.Context) (bool, error) diff --git a/pkg/controller/monitor/monitor_controller.go b/pkg/controller/monitor/monitor_controller.go index cf63f241c4..2165b18eee 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 912e65875b..650e318af5 100644 --- a/pkg/controller/monitor/monitor_controller_test.go +++ b/pkg/controller/monitor/monitor_controller_test.go @@ -66,7 +66,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 e85a058a50..89f705d216 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 a5f3927bb2..4a768075c6 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 dd6e65b8b0..d1d33fa0be 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 a98d7efeed..2ac60994ac 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 c2436277f8..7fc4522ac5 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 49c3aa2deb..80f24abcac 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..632b2e3005 100644 --- a/pkg/controller/status/status_test.go +++ b/pkg/controller/status/status_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2026 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. @@ -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..517c044cdd 100644 --- a/pkg/controller/tiers/tiers_controller_test.go +++ b/pkg/controller/tiers/tiers_controller_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2026 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. @@ -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..b5d2bb6ed2 100644 --- a/pkg/controller/utils/auth_test.go +++ b/pkg/controller/utils/auth_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2024-2026 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. @@ -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_test.go b/pkg/controller/utils/component_test.go index 0e1ca3850c..3643f94e78 100644 --- a/pkg/controller/utils/component_test.go +++ b/pkg/controller/utils/component_test.go @@ -70,7 +70,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 7886738ea0..c00c67d6e4 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 fb1ff0f981..af1d098c9e 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) @@ -61,8 +61,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) @@ -70,7 +70,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..dbfa7b767a 100644 --- a/pkg/controller/utils/imageset/imageset_test.go +++ b/pkg/controller/utils/imageset/imageset_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2026 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. @@ -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 563bae5191..c894ed251a 100644 --- a/pkg/controller/utils/utils.go +++ b/pkg/controller/utils/utils.go @@ -52,7 +52,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" @@ -832,7 +831,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 9e7a4a0773..eed1d081b3 100644 --- a/pkg/controller/utils/utils_test.go +++ b/pkg/controller/utils/utils_test.go @@ -62,7 +62,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(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -97,7 +97,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() { @@ -143,7 +142,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(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -185,7 +184,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" @@ -238,7 +236,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(corev1.SchemeBuilder.AddToScheme(scheme)).ShouldNot(HaveOccurred()) @@ -273,7 +271,6 @@ var _ = Describe("PopulateK8sServiceEndPoint", func() { Expect(err).To(BeNil()) }) - }) var _ = Describe("Utils ElasticSearch test", func() { @@ -332,9 +329,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() { @@ -349,10 +344,12 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{})).To(BeTrue()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "", Generation: 0}}})).To(BeTrue()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "", Generation: 0}}, + })).To(BeTrue()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "", Generation: 1}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "", Generation: 2}}})).To(BeTrue()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "", Generation: 2}}, + })).To(BeTrue()) Expect(p.Delete(event.DeleteEvent{})).To(BeTrue()) }) }) @@ -370,10 +367,12 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: ""}}})).To(BeTrue()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 0}}})).To(BeTrue()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 0}}, + })).To(BeTrue()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 3}}})).To(BeTrue()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 3}}, + })).To(BeTrue()) Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: ""}}})).To(BeTrue()) }) @@ -382,13 +381,16 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: ""}}})).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "", Generation: 0}}})).To(BeFalse()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "", Generation: 0}}, + })).To(BeFalse()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "", Generation: 3}}})).To(BeFalse()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "", Generation: 3}}, + })).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 2}}})).To(BeFalse()) // Generation didn't change. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "", Generation: 2}}, + })).To(BeFalse()) // Generation didn't change. Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: ""}}})).To(BeFalse()) }) }) @@ -406,10 +408,12 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace"}}})).To(BeTrue()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 0}}})).To(BeTrue()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 0}}, + })).To(BeTrue()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 3}}})).To(BeTrue()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 3}}, + })).To(BeTrue()) Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace"}}})).To(BeTrue()) }) @@ -418,13 +422,16 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace"}}})).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace", Generation: 0}}})).To(BeFalse()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace", Generation: 0}}, + })).To(BeFalse()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace", Generation: 3}}})).To(BeFalse()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace", Generation: 3}}, + })).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 2}}})).To(BeFalse()) // Generation didn't change. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "test-namespace", Generation: 2}}, + })).To(BeFalse()) // Generation didn't change. Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: "other-namespace"}}})).To(BeFalse()) }) }) @@ -442,10 +449,12 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace"}}})).To(BeTrue()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 0}}})).To(BeTrue()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 0}}, + })).To(BeTrue()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 3}}})).To(BeTrue()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 3}}, + })).To(BeTrue()) Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace"}}})).To(BeTrue()) }) @@ -454,24 +463,30 @@ var _ = Describe("CreatePredicateForObject", func() { Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace"}}})).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 0}}})).To(BeFalse()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 0}}, + })).To(BeFalse()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 3}}})).To(BeFalse()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 3}}, + })).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 2}}})).To(BeFalse()) // Generation didn't change. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "test-namespace", Generation: 2}}, + })).To(BeFalse()) // Generation didn't change. Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-object", Namespace: "other-namespace"}}})).To(BeFalse()) Expect(p.Create(event.CreateEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace"}}})).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 0}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 0}}})).To(BeFalse()) // Generation was not specified. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 0}}, + })).To(BeFalse()) // Generation was not specified. Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 3}}})).To(BeFalse()) + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 3}}, + })).To(BeFalse()) Expect(p.Update(event.UpdateEvent{ ObjectOld: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 2}}, - ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 2}}})).To(BeFalse()) // Generation didn't change. + ObjectNew: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace", Generation: 2}}, + })).To(BeFalse()) // Generation didn't change. Expect(p.Delete(event.DeleteEvent{Object: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "other-object", Namespace: "test-namespace"}}})).To(BeFalse()) }) }) diff --git a/pkg/controller/whisker/controller.go b/pkg/controller/whisker/controller.go index 8b808702f2..c59e417c76 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/crds/calico/crd.projectcalico.org_bgpconfigurations.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgpconfigurations.yaml similarity index 93% rename from pkg/crds/calico/crd.projectcalico.org_bgpconfigurations.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgpconfigurations.yaml index 1d10c04c90..9b5a0d30c5 100644 --- a/pkg/crds/calico/crd.projectcalico.org_bgpconfigurations.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgpconfigurations.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: bgpconfigurations.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -100,12 +100,6 @@ spec: type: string type: object type: array - serviceLoadBalancerAggregation: - default: Enabled - enum: - - Enabled - - Disabled - type: string serviceLoadBalancerIPs: items: properties: diff --git a/pkg/crds/enterprise/crd.projectcalico.org_bgpfilters.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgpfilters.yaml similarity index 98% rename from pkg/crds/enterprise/crd.projectcalico.org_bgpfilters.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgpfilters.yaml index 826d3f2c4f..17d5fe3c1a 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_bgpfilters.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgpfilters.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: bgpfilters.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_bgppeers.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgppeers.yaml similarity index 87% rename from pkg/crds/calico/crd.projectcalico.org_bgppeers.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgppeers.yaml index 8e05dbc193..10402f4682 100644 --- a/pkg/crds/calico/crd.projectcalico.org_bgppeers.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_bgppeers.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: bgppeers.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -35,11 +35,6 @@ spec: type: array keepOriginalNextHop: type: boolean - keepaliveTime: - type: string - localASNumber: - format: int32 - type: integer localWorkloadSelector: type: string maxRestartTime: @@ -84,11 +79,6 @@ spec: type: string reachableBy: type: string - reversePeering: - enum: - - Auto - - Manual - type: string sourceAddress: type: string ttlSecurity: diff --git a/pkg/crds/enterprise/crd.projectcalico.org_blockaffinities.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_blockaffinities.yaml similarity index 95% rename from pkg/crds/enterprise/crd.projectcalico.org_blockaffinities.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_blockaffinities.yaml index c18b570977..635f6b6d69 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_blockaffinities.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_blockaffinities.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: blockaffinities.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/enterprise/crd.projectcalico.org_caliconodestatuses.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_caliconodestatuses.yaml similarity index 99% rename from pkg/crds/enterprise/crd.projectcalico.org_caliconodestatuses.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_caliconodestatuses.yaml index 166fa6d545..55ef1ef509 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_caliconodestatuses.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_caliconodestatuses.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: caliconodestatuses.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_clusterinformations.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_clusterinformations.yaml similarity index 95% rename from pkg/crds/calico/crd.projectcalico.org_clusterinformations.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_clusterinformations.yaml index 9f802f1320..4a028495d2 100644 --- a/pkg/crds/calico/crd.projectcalico.org_clusterinformations.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_clusterinformations.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: clusterinformations.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_felixconfigurations.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml similarity index 92% rename from pkg/crds/calico/crd.projectcalico.org_felixconfigurations.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml index 89d9263ad3..8ff273b908 100644 --- a/pkg/crds/calico/crd.projectcalico.org_felixconfigurations.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: felixconfigurations.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -60,16 +60,6 @@ spec: - Enable - Disable type: string - bpfAttachType: - description: |- - BPFAttachType controls how are the BPF programs at the network interfaces attached. - By default `TCX` is used where available to enable easier coexistence with 3rd party programs. - `TC` can force the legacy method of attaching via a qdisc. `TCX` falls back to `TC` if `TCX` is not available. - [Default: TCX] - enum: - - TC - - TCX - type: string bpfCTLBLogFilter: description: |- BPFCTLBLogFilter specifies, what is logged by connect time load balancer when BPFLogLevel is @@ -284,24 +274,12 @@ spec: - Enabled - Disabled type: string - bpfJITHardening: - allOf: - - enum: - - Auto - - Strict - - enum: - - Auto - - Strict - description: |- - BPFJITHardening controls BPF JIT hardening. When set to "Auto", Felix will set JIT hardening to 1 - if it detects the current value is 2 (strict mode that hurts performance). When set to "Strict", - Felix will not modify the JIT hardening setting. [Default: Auto] - type: string - bpfKubeProxyHealthzPort: + bpfKubeProxyEndpointSlicesEnabled: description: |- - BPFKubeProxyHealthzPort, in BPF mode, controls the port that Felix's embedded kube-proxy health check server binds to. - The health check server is used by external load balancers to determine if this node should receive traffic. [Default: 10256] - type: integer + BPFKubeProxyEndpointSlicesEnabled is deprecated and has no effect. BPF + kube-proxy always accepts endpoint slices. This option will be removed in + the next release. + type: boolean bpfKubeProxyIptablesCleanupEnabled: description: |- BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF mode, Felix will proactively clean up the upstream @@ -340,23 +318,6 @@ spec: [Default: Off]. pattern: ^(?i)(Off|Info|Debug)?$ type: string - bpfMaglevMaxEndpointsPerService: - description: |- - BPFMaglevMaxEndpointsPerService is the maximum number of endpoints - expected to be part of a single Maglev-enabled service. - - Influences the size of the per-service Maglev lookup-tables generated by Felix - and thus the amount of memory reserved. - - [Default: 100] - type: integer - bpfMaglevMaxServices: - description: |- - BPFMaglevMaxServices is the maximum number of expected Maglev-enabled - services that Felix will allocate lookup-tables for. - - [Default: 100] - type: integer bpfMapSizeConntrack: description: |- BPFMapSizeConntrack sets the size for the conntrack map. This map must be large enough to hold @@ -445,19 +406,17 @@ spec: type: string bpfRedirectToPeer: description: |- - BPFRedirectToPeer controls whether traffic may be forwarded directly to the peer side of a workload’s device. - Note that the legacy "L2Only" option is now deprecated and if set it is treated like "Enabled. - Setting this option to "Enabled" allows direct redirection (including from L3 host devices such as IPIP tunnels or WireGuard), - which can improve redirection performance but causes the redirected packets to bypass the host‑side ingress path. - As a result, packet‑capture tools on the host side of the workload device (for example, tcpdump) will not see that traffic. [Default: Enabled] + BPFRedirectToPeer controls which whether it is allowed to forward straight to the + peer side of the workload devices. It is allowed for any host L2 devices by default + (L2Only), but it breaks TCP dump on the host side of workload device as it bypasses + it on ingress. Value of Enabled also allows redirection from L3 host devices like + IPIP tunnel or Wireguard directly to the peer side of the workload's device. This + makes redirection faster, however, it breaks tools like tcpdump on the peer side. + Use Enabled with caution. [Default: L2Only] enum: - Enabled - Disabled - type: string - cgroupV2Path: - description: - CgroupV2Path overrides the default location where to - find the cgroup hierarchy. + - L2Only type: string chainInsertMode: description: |- @@ -818,10 +777,26 @@ spec: with an iptables "DROP" action. If you want to use "REJECT" action instead you can configure it in here. pattern: ^(?i)(Drop|Reject)?$ type: string + iptablesLockFilePath: + description: |- + 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] + type: string iptablesLockProbeInterval: description: |- - IptablesLockProbeInterval configures the interval between attempts to claim - the xtables lock. Shorter intervals are more responsive but use more CPU. [Default: 50ms] + IptablesLockProbeInterval when IptablesLockTimeout is enabled: 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] + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + iptablesLockTimeout: + description: |- + IptablesLockTimeout is the time that Felix itself will wait for the iptables lock (rather than delegating the + lock handling to the `iptables` command). + + Deprecated: `iptables-restore` v1.8+ always takes the lock, so enabling this feature results in deadlock. + [Default: 0s disabled] pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string iptablesMangleAllowAction: @@ -881,19 +856,6 @@ spec: pattern: ^.* x-kubernetes-int-or-string: true type: array - logActionRateLimit: - description: |- - LogActionRateLimit sets the rate of hitting a Log action. The value must be in the format "N/unit", - where N is a number and unit is one of: second, minute, hour, or day. For example: "10/second" or "100/hour". - pattern: ^[1-9]\d{0,3}/(?:second|minute|hour|day)$ - type: string - logActionRateLimitBurst: - description: - LogActionRateLimitBurst sets the rate limit burst of - hitting a Log action when LogActionRateLimit is enabled. - maximum: 9999 - minimum: 0 - type: integer logDebugFilenameRegex: description: |- LogDebugFilenameRegex controls which source code files have their Debug log output included in the logs. @@ -906,17 +868,9 @@ spec: none to disable file logging. [Default: /var/log/calico/felix.log]" type: string logPrefix: - description: |- - LogPrefix is the log prefix that Felix uses when rendering LOG rules. It is possible to use the following specifiers - to include extra information in the log prefix. - - %t: Tier name. - - %k: Kind (short names). - - %n: Policy or profile name. - - %p: Policy or profile name (namespace/name for namespaced kinds or just name for non namespaced kinds). - Calico includes ": " characters at the end of the generated log prefix. - Note that iptables shows up to 29 characters for the log prefix and nftables up to 127 characters. Extra characters are truncated. - [Default: calico-packet] - pattern: "^([a-zA-Z0-9%: /_-])*$" + description: + "LogPrefix is the log prefix that Felix uses when rendering + LOG rules. [Default: calico-packet]" type: string logSeverityFile: description: @@ -1020,10 +974,9 @@ spec: format: int32 type: integer nftablesMode: - default: Auto description: "NFTablesMode configures nftables support in Felix. [Default: - Auto]" + Disabled]" enum: - Disabled - Enabled @@ -1059,21 +1012,6 @@ spec: 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] type: boolean - prometheusMetricsCAFile: - description: |- - PrometheusMetricsCAFile defines the absolute path to the TLS CA certificate file used for securing the /metrics endpoint. - This certificate must be valid and accessible by the calico-node process. - type: string - prometheusMetricsCertFile: - description: |- - PrometheusMetricsCertFile defines the absolute path to the TLS certificate file used for securing the /metrics endpoint. - This certificate must be valid and accessible by the calico-node process. - type: string - prometheusMetricsClientAuth: - description: |- - PrometheusMetricsClientAuth specifies the client authentication type for the /metrics endpoint. - This determines how the server validates client certificates. Default is "RequireAndVerifyClientCert". - type: string prometheusMetricsEnabled: description: "PrometheusMetricsEnabled enables the Prometheus metrics @@ -1084,11 +1022,6 @@ spec: "PrometheusMetricsHost is the host that the Prometheus metrics server should bind to. [Default: empty]" type: string - prometheusMetricsKeyFile: - description: |- - PrometheusMetricsKeyFile defines the absolute path to the private key file corresponding to the TLS certificate - used for securing the /metrics endpoint. The private key must be valid and accessible by the calico-node process. - type: string prometheusMetricsPort: description: "PrometheusMetricsPort is the TCP port that the Prometheus diff --git a/pkg/crds/calico/crd.projectcalico.org_globalnetworkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworkpolicies.yaml similarity index 99% rename from pkg/crds/calico/crd.projectcalico.org_globalnetworkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworkpolicies.yaml index a9035d842f..c84f2b4ac6 100644 --- a/pkg/crds/calico/crd.projectcalico.org_globalnetworkpolicies.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworkpolicies.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: globalnetworkpolicies.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -361,7 +361,6 @@ spec: serviceAccountSelector: type: string tier: - default: default type: string types: items: diff --git a/pkg/crds/calico/crd.projectcalico.org_globalnetworksets.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworksets.yaml similarity index 94% rename from pkg/crds/calico/crd.projectcalico.org_globalnetworksets.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworksets.yaml index 11c0576057..c44ce162a1 100644 --- a/pkg/crds/calico/crd.projectcalico.org_globalnetworksets.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworksets.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: globalnetworksets.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/enterprise/crd.projectcalico.org_hostendpoints.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_hostendpoints.yaml similarity index 97% rename from pkg/crds/enterprise/crd.projectcalico.org_hostendpoints.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_hostendpoints.yaml index d9b542930e..e2bd246fc6 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_hostendpoints.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_hostendpoints.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: hostendpoints.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/enterprise/crd.projectcalico.org_ipamblocks.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamblocks.yaml similarity index 93% rename from pkg/crds/enterprise/crd.projectcalico.org_ipamblocks.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamblocks.yaml index 051bc67cfc..3c3a54b4a3 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_ipamblocks.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamblocks.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: ipamblocks.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -28,9 +28,6 @@ spec: properties: affinity: type: string - affinityClaimTime: - format: date-time - type: string allocations: items: type: integer diff --git a/pkg/crds/enterprise/crd.projectcalico.org_ipamconfigs.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamconfigs.yaml similarity index 95% rename from pkg/crds/enterprise/crd.projectcalico.org_ipamconfigs.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamconfigs.yaml index b7e9260b9c..beabfe805a 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_ipamconfigs.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamconfigs.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: ipamconfigs.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/enterprise/crd.projectcalico.org_ipamhandles.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamhandles.yaml similarity index 95% rename from pkg/crds/enterprise/crd.projectcalico.org_ipamhandles.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamhandles.yaml index d2305fe418..a1b7853a86 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_ipamhandles.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipamhandles.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: ipamhandles.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_ippools.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml similarity index 91% rename from pkg/crds/calico/crd.projectcalico.org_ippools.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml index 3e029cd922..299d136368 100644 --- a/pkg/crds/calico/crd.projectcalico.org_ippools.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: ippools.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -31,7 +31,6 @@ spec: type: string type: array assignmentMode: - default: Automatic enum: - Automatic - Manual @@ -53,8 +52,6 @@ spec: type: object ipipMode: type: string - namespaceSelector: - type: string nat-outgoing: type: boolean natOutgoing: diff --git a/pkg/crds/enterprise/crd.projectcalico.org_ipreservations.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipreservations.yaml similarity index 94% rename from pkg/crds/enterprise/crd.projectcalico.org_ipreservations.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipreservations.yaml index 61ddf451f1..213a92be5b 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_ipreservations.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ipreservations.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: ipreservations.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_kubecontrollersconfigurations.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_kubecontrollersconfigurations.yaml similarity index 87% rename from pkg/crds/calico/crd.projectcalico.org_kubecontrollersconfigurations.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_kubecontrollersconfigurations.yaml index 80848a80b2..8853f9550e 100644 --- a/pkg/crds/calico/crd.projectcalico.org_kubecontrollersconfigurations.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_kubecontrollersconfigurations.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: kubecontrollersconfigurations.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -31,7 +31,6 @@ spec: loadBalancer: properties: assignIPs: - default: AllServices type: string type: object namespace: @@ -57,8 +56,6 @@ spec: items: type: string type: array - interfacePattern: - type: string labels: additionalProperties: type: string @@ -80,15 +77,6 @@ spec: reconcilerPeriod: type: string type: object - policyMigration: - properties: - enabled: - default: Enabled - enum: - - Disabled - - Enabled - type: string - type: object serviceAccount: properties: reconcilerPeriod: @@ -127,7 +115,6 @@ spec: loadBalancer: properties: assignIPs: - default: AllServices type: string type: object namespace: @@ -153,8 +140,6 @@ spec: items: type: string type: array - interfacePattern: - type: string labels: additionalProperties: type: string @@ -176,15 +161,6 @@ spec: reconcilerPeriod: type: string type: object - policyMigration: - properties: - enabled: - default: Enabled - enum: - - Disabled - - Enabled - type: string - type: object serviceAccount: properties: reconcilerPeriod: diff --git a/pkg/crds/calico/crd.projectcalico.org_networkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_networkpolicies.yaml similarity index 99% rename from pkg/crds/calico/crd.projectcalico.org_networkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_networkpolicies.yaml index e18c0014ed..31ebbac74d 100644 --- a/pkg/crds/calico/crd.projectcalico.org_networkpolicies.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_networkpolicies.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: networkpolicies.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -353,7 +353,6 @@ spec: serviceAccountSelector: type: string tier: - default: default type: string types: items: diff --git a/pkg/crds/calico/crd.projectcalico.org_networksets.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_networksets.yaml similarity index 94% rename from pkg/crds/calico/crd.projectcalico.org_networksets.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_networksets.yaml index 26b2f55e47..60553b9d42 100644 --- a/pkg/crds/calico/crd.projectcalico.org_networksets.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_networksets.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: networksets.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml similarity index 99% rename from pkg/crds/calico/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml index 50027b986e..fc9e5a2503 100644 --- a/pkg/crds/calico/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: stagedglobalnetworkpolicies.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -363,7 +363,6 @@ spec: stagedAction: type: string tier: - default: default type: string types: items: diff --git a/pkg/crds/enterprise/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml similarity index 99% rename from pkg/crds/enterprise/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml index 094fc67791..d76c0b2c98 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: stagedkubernetesnetworkpolicies.crd.projectcalico.org spec: group: crd.projectcalico.org diff --git a/pkg/crds/calico/crd.projectcalico.org_stagednetworkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagednetworkpolicies.yaml similarity index 99% rename from pkg/crds/calico/crd.projectcalico.org_stagednetworkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagednetworkpolicies.yaml index a2892ac3f8..5ea0b6dff7 100644 --- a/pkg/crds/calico/crd.projectcalico.org_stagednetworkpolicies.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_stagednetworkpolicies.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: stagednetworkpolicies.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -355,7 +355,6 @@ spec: stagedAction: type: string tier: - default: default type: string types: items: diff --git a/pkg/crds/enterprise/crd.projectcalico.org_tiers.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_tiers.yaml similarity index 52% rename from pkg/crds/enterprise/crd.projectcalico.org_tiers.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_tiers.yaml index 430a51625f..dfd5324798 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_tiers.yaml +++ b/pkg/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_tiers.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.17.3 name: tiers.crd.projectcalico.org spec: group: crd.projectcalico.org @@ -34,22 +34,6 @@ spec: order: type: number type: object - required: - - metadata - - spec type: object - x-kubernetes-validations: - - message: The 'kube-admin' tier must have default action 'Pass' - rule: - "self.metadata.name == 'kube-admin' ? self.spec.defaultAction == - 'Pass' : true" - - message: The 'kube-baseline' tier must have default action 'Pass' - rule: - "self.metadata.name == 'kube-baseline' ? self.spec.defaultAction - == 'Pass' : true" - - message: The 'default' tier must have default action 'Deny' - rule: - "self.metadata.name == 'default' ? self.spec.defaultAction == 'Deny' - : true" served: true storage: true diff --git a/pkg/crds/enterprise/policy.networking.k8s.io_adminnetworkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/policy.networking.k8s.io_adminnetworkpolicies.yaml similarity index 100% rename from pkg/crds/enterprise/policy.networking.k8s.io_adminnetworkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/policy.networking.k8s.io_adminnetworkpolicies.yaml diff --git a/pkg/crds/enterprise/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml b/pkg/crds/calico/v1.crd.projectcalico.org/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml similarity index 100% rename from pkg/crds/enterprise/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml rename to pkg/crds/calico/v1.crd.projectcalico.org/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgpconfigurations.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgpconfigurations.yaml new file mode 100644 index 0000000000..f87b46617c --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgpconfigurations.yaml @@ -0,0 +1,113 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: bgpconfigurations.projectcalico.org +spec: + group: projectcalico.org + names: + kind: BGPConfiguration + listKind: BGPConfigurationList + plural: bgpconfigurations + singular: bgpconfiguration + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + asNumber: + format: int32 + type: integer + bindMode: + type: string + communities: + items: + properties: + name: + type: string + value: + pattern: ^(\d+):(\d+)$|^(\d+):(\d+):(\d+)$ + type: string + type: object + type: array + ignoredInterfaces: + items: + type: string + type: array + listenPort: + maximum: 65535 + minimum: 1 + type: integer + localWorkloadPeeringIPV4: + type: string + localWorkloadPeeringIPV6: + type: string + logSeverityScreen: + type: string + nodeMeshMaxRestartTime: + type: string + nodeMeshPassword: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + nodeToNodeMeshEnabled: + type: boolean + prefixAdvertisements: + items: + properties: + cidr: + type: string + communities: + items: + type: string + type: array + type: object + type: array + serviceClusterIPs: + items: + properties: + cidr: + type: string + type: object + type: array + serviceExternalIPs: + items: + properties: + cidr: + type: string + type: object + type: array + serviceLoadBalancerIPs: + items: + properties: + cidr: + type: string + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgpfilters.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgpfilters.yaml new file mode 100644 index 0000000000..e439f0ed99 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgpfilters.yaml @@ -0,0 +1,152 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: bgpfilters.projectcalico.org +spec: + group: projectcalico.org + names: + kind: BGPFilter + listKind: BGPFilterList + plural: bgpfilters + singular: bgpfilter + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + exportV4: + items: + properties: + action: + type: string + cidr: + type: string + interface: + type: string + matchOperator: + type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object + source: + type: string + required: + - action + type: object + type: array + exportV6: + items: + properties: + action: + type: string + cidr: + type: string + interface: + type: string + matchOperator: + type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object + source: + type: string + required: + - action + type: object + type: array + importV4: + items: + properties: + action: + type: string + cidr: + type: string + interface: + type: string + matchOperator: + type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object + source: + type: string + required: + - action + type: object + type: array + importV6: + items: + properties: + action: + type: string + cidr: + type: string + interface: + type: string + matchOperator: + type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object + source: + type: string + required: + - action + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgppeers.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgppeers.yaml new file mode 100644 index 0000000000..7539f5c468 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_bgppeers.yaml @@ -0,0 +1,78 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: bgppeers.projectcalico.org +spec: + group: projectcalico.org + names: + kind: BGPPeer + listKind: BGPPeerList + plural: bgppeers + singular: bgppeer + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + asNumber: + format: int32 + type: integer + filters: + items: + type: string + type: array + keepOriginalNextHop: + type: boolean + localWorkloadSelector: + type: string + maxRestartTime: + type: string + node: + type: string + nodeSelector: + type: string + numAllowedLocalASNumbers: + format: int32 + type: integer + password: + properties: + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + peerIP: + type: string + peerSelector: + type: string + reachableBy: + type: string + sourceAddress: + type: string + ttlSecurity: + type: integer + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_blockaffinities.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_blockaffinities.yaml new file mode 100644 index 0000000000..67c6f508e7 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_blockaffinities.yaml @@ -0,0 +1,46 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: blockaffinities.projectcalico.org +spec: + group: projectcalico.org + names: + kind: BlockAffinity + listKind: BlockAffinityList + plural: blockaffinities + singular: blockaffinity + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + cidr: + type: string + deleted: + type: boolean + node: + type: string + state: + type: string + type: + type: string + required: + - cidr + - node + - state + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_caliconodestatuses.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_caliconodestatuses.yaml new file mode 100644 index 0000000000..dd96e37720 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_caliconodestatuses.yaml @@ -0,0 +1,162 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: caliconodestatuses.projectcalico.org +spec: + group: projectcalico.org + names: + kind: CalicoNodeStatus + listKind: CalicoNodeStatusList + plural: caliconodestatuses + singular: caliconodestatus + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + classes: + items: + type: string + type: array + node: + type: string + updatePeriodSeconds: + format: int32 + type: integer + type: object + status: + properties: + agent: + properties: + birdV4: + properties: + lastBootTime: + type: string + lastReconfigurationTime: + type: string + routerID: + type: string + state: + type: string + version: + type: string + type: object + birdV6: + properties: + lastBootTime: + type: string + lastReconfigurationTime: + type: string + routerID: + type: string + state: + type: string + version: + type: string + type: object + type: object + bgp: + properties: + numberEstablishedV4: + type: integer + numberEstablishedV6: + type: integer + numberNotEstablishedV4: + type: integer + numberNotEstablishedV6: + type: integer + peersV4: + items: + properties: + peerIP: + type: string + since: + type: string + state: + type: string + type: + type: string + type: object + type: array + peersV6: + items: + properties: + peerIP: + type: string + since: + type: string + state: + type: string + type: + type: string + type: object + type: array + required: + - numberEstablishedV4 + - numberEstablishedV6 + - numberNotEstablishedV4 + - numberNotEstablishedV6 + type: object + lastUpdated: + format: date-time + nullable: true + type: string + routes: + properties: + routesV4: + items: + properties: + destination: + type: string + gateway: + type: string + interface: + type: string + learnedFrom: + properties: + peerIP: + type: string + sourceType: + type: string + type: object + type: + type: string + type: object + type: array + routesV6: + items: + properties: + destination: + type: string + gateway: + type: string + interface: + type: string + learnedFrom: + properties: + peerIP: + type: string + sourceType: + type: string + type: object + type: + type: string + type: object + type: array + type: object + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_clusterinformations.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_clusterinformations.yaml new file mode 100644 index 0000000000..c9545db956 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_clusterinformations.yaml @@ -0,0 +1,42 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: clusterinformations.projectcalico.org +spec: + group: projectcalico.org + names: + kind: ClusterInformation + listKind: ClusterInformationList + plural: clusterinformations + singular: clusterinformation + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + calicoVersion: + type: string + clusterGUID: + type: string + clusterType: + type: string + datastoreReady: + type: boolean + variant: + type: string + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_felixconfigurations.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_felixconfigurations.yaml new file mode 100644 index 0000000000..d7c750147f --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_felixconfigurations.yaml @@ -0,0 +1,551 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: felixconfigurations.projectcalico.org +spec: + group: projectcalico.org + names: + kind: FelixConfiguration + listKind: FelixConfigurationList + plural: felixconfigurations + singular: felixconfiguration + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + allowIPIPPacketsFromWorkloads: + type: boolean + allowVXLANPacketsFromWorkloads: + type: boolean + awsSrcDstCheck: + enum: + - DoNothing + - Enable + - Disable + type: string + bpfCTLBLogFilter: + type: string + bpfConnectTimeLoadBalancing: + enum: + - TCP + - Enabled + - Disabled + type: string + bpfConnectTimeLoadBalancingEnabled: + type: boolean + bpfConntrackLogLevel: + enum: + - "Off" + - Debug + type: string + bpfConntrackMode: + enum: + - Auto + - Userspace + - BPFProgram + type: string + bpfConntrackTimeouts: + properties: + creationGracePeriod: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + genericTimeout: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + icmpTimeout: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + tcpEstablished: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + tcpFinsSeen: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + tcpResetSeen: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + tcpSynSent: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + udpTimeout: + pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$ + type: string + type: object + bpfDSROptoutCIDRs: + items: + type: string + type: array + bpfDataIfacePattern: + type: string + bpfDisableGROForIfaces: + type: string + bpfDisableUnprivileged: + type: boolean + bpfEnabled: + type: boolean + bpfEnforceRPF: + pattern: ^(?i)(Disabled|Strict|Loose)?$ + type: string + bpfExcludeCIDRsFromNAT: + items: + type: string + type: array + bpfExportBufferSizeMB: + type: integer + bpfExtToServiceConnmark: + type: integer + bpfExternalServiceMode: + pattern: ^(?i)(Tunnel|DSR)?$ + type: string + bpfForceTrackPacketsFromIfaces: + items: + type: string + type: array + bpfHostConntrackBypass: + type: boolean + bpfHostNetworkedNATWithoutCTLB: + enum: + - Enabled + - Disabled + type: string + bpfKubeProxyEndpointSlicesEnabled: + type: boolean + bpfKubeProxyIptablesCleanupEnabled: + type: boolean + bpfKubeProxyMinSyncPeriod: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + bpfL3IfacePattern: + type: string + bpfLogFilters: + additionalProperties: + type: string + type: object + bpfLogLevel: + pattern: ^(?i)(Off|Info|Debug)?$ + type: string + bpfMapSizeConntrack: + type: integer + bpfMapSizeConntrackCleanupQueue: + minimum: 1 + type: integer + bpfMapSizeConntrackScaling: + pattern: ^(?i)(Disabled|DoubleIfFull)?$ + type: string + bpfMapSizeIPSets: + type: integer + bpfMapSizeIfState: + type: integer + bpfMapSizeNATAffinity: + type: integer + bpfMapSizeNATBackend: + type: integer + bpfMapSizeNATFrontend: + type: integer + bpfMapSizePerCpuConntrack: + type: integer + bpfMapSizeRoute: + type: integer + bpfPSNATPorts: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + bpfPolicyDebugEnabled: + type: boolean + bpfProfiling: + enum: + - Enabled + - Disabled + type: string + bpfRedirectToPeer: + enum: + - Enabled + - Disabled + - L2Only + type: string + chainInsertMode: + pattern: ^(?i)(Insert|Append)?$ + type: string + dataplaneDriver: + type: string + dataplaneWatchdogTimeout: + type: string + debugDisableLogDropping: + type: boolean + debugHost: + type: string + debugMemoryProfilePath: + type: string + debugPort: + type: integer + debugSimulateCalcGraphHangAfter: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + debugSimulateDataplaneApplyDelay: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + debugSimulateDataplaneHangAfter: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + defaultEndpointToHostAction: + pattern: ^(?i)(Drop|Accept|Return)?$ + type: string + deviceRouteProtocol: + type: integer + deviceRouteSourceAddress: + type: string + deviceRouteSourceAddressIPv6: + type: string + disableConntrackInvalidCheck: + type: boolean + endpointReportingDelay: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + endpointReportingEnabled: + type: boolean + endpointStatusPathPrefix: + type: string + externalNodesList: + items: + type: string + type: array + failsafeInboundHostPorts: + items: + properties: + net: + type: string + port: + type: integer + protocol: + type: string + required: + - port + type: object + type: array + failsafeOutboundHostPorts: + items: + properties: + net: + type: string + port: + type: integer + protocol: + type: string + required: + - port + type: object + type: array + featureDetectOverride: + pattern: ^([a-zA-Z0-9-_]+=(true|false|),)*([a-zA-Z0-9-_]+=(true|false|))?$ + type: string + featureGates: + pattern: ^([a-zA-Z0-9-_]+=([^=]+),)*([a-zA-Z0-9-_]+=([^=]+))?$ + type: string + floatingIPs: + enum: + - Enabled + - Disabled + type: string + flowLogsCollectorDebugTrace: + type: boolean + flowLogsFlushInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + flowLogsGoldmaneServer: + type: string + flowLogsLocalReporter: + enum: + - Disabled + - Enabled + type: string + flowLogsPolicyEvaluationMode: + enum: + - None + - Continuous + type: string + genericXDPEnabled: + type: boolean + goGCThreshold: + type: integer + goMaxProcs: + type: integer + goMemoryLimitMB: + type: integer + healthEnabled: + type: boolean + healthHost: + type: string + healthPort: + type: integer + healthTimeoutOverrides: + items: + properties: + name: + type: string + timeout: + type: string + required: + - name + - timeout + type: object + type: array + interfaceExclude: + type: string + interfacePrefix: + type: string + interfaceRefreshInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + ipForwarding: + enum: + - Enabled + - Disabled + type: string + ipipEnabled: + type: boolean + ipipMTU: + type: integer + ipsetsRefreshInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + iptablesBackend: + pattern: ^(?i)(Auto|Legacy|NFT)?$ + type: string + iptablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + iptablesFilterDenyAction: + pattern: ^(?i)(Drop|Reject)?$ + type: string + iptablesLockFilePath: + type: string + iptablesLockProbeInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + iptablesLockTimeout: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + iptablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + iptablesMarkMask: + format: int32 + type: integer + iptablesNATOutgoingInterfaceFilter: + type: string + iptablesPostWriteCheckInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + iptablesRefreshInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + ipv6Support: + type: boolean + kubeNodePortRanges: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + logDebugFilenameRegex: + type: string + logFilePath: + type: string + logPrefix: + type: string + logSeverityFile: + pattern: ^(?i)(Trace|Debug|Info|Warning|Error|Fatal)?$ + type: string + logSeverityScreen: + pattern: ^(?i)(Trace|Debug|Info|Warning|Error|Fatal)?$ + type: string + logSeveritySys: + pattern: ^(?i)(Trace|Debug|Info|Warning|Error|Fatal)?$ + type: string + maxIpsetSize: + type: integer + metadataAddr: + type: string + metadataPort: + type: integer + mtuIfacePattern: + type: string + natOutgoingAddress: + type: string + natOutgoingExclusions: + enum: + - IPPoolsOnly + - IPPoolsAndHostIPs + type: string + natPortRange: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + netlinkTimeout: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + format: int32 + type: integer + nftablesMode: + enum: + - Disabled + - Enabled + - Auto + type: string + nftablesRefreshInterval: + type: string + openstackRegion: + type: string + policySyncPathPrefix: + type: string + programRoutes: + enum: + - Enabled + - Disabled + type: string + prometheusGoMetricsEnabled: + type: boolean + prometheusMetricsEnabled: + type: boolean + prometheusMetricsHost: + type: string + prometheusMetricsPort: + type: integer + prometheusProcessMetricsEnabled: + type: boolean + prometheusWireGuardMetricsEnabled: + type: boolean + removeExternalRoutes: + type: boolean + reportingInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + reportingTTL: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + routeRefreshInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + routeSource: + pattern: ^(?i)(WorkloadIPs|CalicoIPAM)?$ + type: string + routeSyncDisabled: + type: boolean + routeTableRange: + properties: + max: + type: integer + min: + type: integer + required: + - max + - min + type: object + routeTableRanges: + items: + properties: + max: + type: integer + min: + type: integer + required: + - max + - min + type: object + type: array + serviceLoopPrevention: + pattern: ^(?i)(Drop|Reject|Disabled)?$ + type: string + sidecarAccelerationEnabled: + type: boolean + usageReportingEnabled: + type: boolean + usageReportingInitialDelay: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + usageReportingInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + useInternalDataplaneDriver: + type: boolean + vxlanEnabled: + type: boolean + vxlanMTU: + type: integer + vxlanMTUV6: + type: integer + vxlanPort: + type: integer + vxlanVNI: + type: integer + windowsManageFirewallRules: + enum: + - Enabled + - Disabled + type: string + wireguardEnabled: + type: boolean + wireguardEnabledV6: + type: boolean + wireguardHostEncryptionEnabled: + type: boolean + wireguardInterfaceName: + type: string + wireguardInterfaceNameV6: + type: string + wireguardKeepAlive: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + wireguardListeningPort: + type: integer + wireguardListeningPortV6: + type: integer + wireguardMTU: + type: integer + wireguardMTUV6: + type: integer + wireguardRoutingRulePriority: + type: integer + wireguardThreadingEnabled: + type: boolean + workloadSourceSpoofing: + pattern: ^(?i)(Disabled|Any)?$ + type: string + xdpEnabled: + type: boolean + xdpRefreshInterval: + pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ + type: string + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_globalnetworkpolicies.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_globalnetworkpolicies.yaml new file mode 100644 index 0000000000..afa910fb7f --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_globalnetworkpolicies.yaml @@ -0,0 +1,372 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: globalnetworkpolicies.projectcalico.org +spec: + group: projectcalico.org + names: + kind: GlobalNetworkPolicy + listKind: GlobalNetworkPolicyList + plural: globalnetworkpolicies + singular: globalnetworkpolicy + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + applyOnForward: + type: boolean + doNotTrack: + type: boolean + egress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + ingress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + namespaceSelector: + type: string + order: + type: number + performanceHints: + items: + type: string + type: array + preDNAT: + type: boolean + selector: + type: string + serviceAccountSelector: + type: string + tier: + type: string + types: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_globalnetworksets.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_globalnetworksets.yaml new file mode 100644 index 0000000000..61cd19b10f --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_globalnetworksets.yaml @@ -0,0 +1,36 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: globalnetworksets.projectcalico.org +spec: + group: projectcalico.org + names: + kind: GlobalNetworkSet + listKind: GlobalNetworkSetList + plural: globalnetworksets + singular: globalnetworkset + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + nets: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_hostendpoints.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_hostendpoints.yaml new file mode 100644 index 0000000000..126cef6ef0 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_hostendpoints.yaml @@ -0,0 +1,63 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: hostendpoints.projectcalico.org +spec: + group: projectcalico.org + names: + kind: HostEndpoint + listKind: HostEndpointList + plural: hostendpoints + singular: hostendpoint + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + expectedIPs: + items: + type: string + type: array + interfaceName: + type: string + node: + type: string + ports: + items: + properties: + name: + type: string + port: + type: integer + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + required: + - name + - port + - protocol + type: object + type: array + profiles: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamblocks.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamblocks.yaml new file mode 100644 index 0000000000..60b4031e34 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamblocks.yaml @@ -0,0 +1,77 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: ipamblocks.projectcalico.org +spec: + group: projectcalico.org + names: + kind: IPAMBlock + listKind: IPAMBlockList + plural: ipamblocks + singular: ipamblock + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + type: string + allocations: + items: + type: integer + # TODO: This nullable is manually added in. We should update controller-gen + # to handle []*int properly itself. + nullable: true + type: array + attributes: + items: + properties: + handle_id: + type: string + secondary: + additionalProperties: + type: string + type: object + type: object + type: array + cidr: + type: string + deleted: + type: boolean + sequenceNumber: + default: 0 + format: int64 + type: integer + sequenceNumberForAllocation: + additionalProperties: + format: int64 + type: integer + type: object + strictAffinity: + type: boolean + unallocated: + items: + type: integer + type: array + required: + - allocations + - attributes + - cidr + - strictAffinity + - unallocated + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamconfigurations.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamconfigurations.yaml new file mode 100644 index 0000000000..2c98a2675d --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamconfigurations.yaml @@ -0,0 +1,42 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: ipamconfigurations.projectcalico.org +spec: + group: projectcalico.org + names: + kind: IPAMConfiguration + listKind: IPAMConfigurationList + plural: ipamconfigurations + singular: ipamconfiguration + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + autoAllocateBlocks: + type: boolean + maxBlocksPerHost: + format: int32 + type: integer + strictAffinity: + type: boolean + required: + - autoAllocateBlocks + - strictAffinity + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamhandles.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamhandles.yaml new file mode 100644 index 0000000000..9a32490b04 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipamhandles.yaml @@ -0,0 +1,43 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: ipamhandles.projectcalico.org +spec: + group: projectcalico.org + names: + kind: IPAMHandle + listKind: IPAMHandleList + plural: ipamhandles + singular: ipamhandle + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + block: + additionalProperties: + type: integer + type: object + deleted: + type: boolean + handleID: + type: string + required: + - block + - handleID + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ippools.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ippools.yaml new file mode 100644 index 0000000000..e7b6506870 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ippools.yaml @@ -0,0 +1,68 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: ippools.projectcalico.org +spec: + group: projectcalico.org + names: + kind: IPPool + listKind: IPPoolList + plural: ippools + singular: ippool + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + allowedUses: + items: + type: string + type: array + assignmentMode: + enum: + - Automatic + - Manual + type: string + blockSize: + type: integer + cidr: + type: string + disableBGPExport: + type: boolean + disabled: + type: boolean + ipip: + properties: + enabled: + type: boolean + mode: + type: string + type: object + ipipMode: + type: string + nat-outgoing: + type: boolean + natOutgoing: + type: boolean + nodeSelector: + type: string + vxlanMode: + type: string + required: + - cidr + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipreservations.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipreservations.yaml new file mode 100644 index 0000000000..4ff84bf6f6 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_ipreservations.yaml @@ -0,0 +1,36 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: ipreservations.projectcalico.org +spec: + group: projectcalico.org + names: + kind: IPReservation + listKind: IPReservationList + plural: ipreservations + singular: ipreservation + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + reservedCIDRs: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_kubecontrollersconfigurations.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_kubecontrollersconfigurations.yaml new file mode 100644 index 0000000000..78f3dac831 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_kubecontrollersconfigurations.yaml @@ -0,0 +1,192 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: kubecontrollersconfigurations.projectcalico.org +spec: + group: projectcalico.org + names: + kind: KubeControllersConfiguration + listKind: KubeControllersConfigurationList + plural: kubecontrollersconfigurations + singular: kubecontrollersconfiguration + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + controllers: + properties: + loadBalancer: + properties: + assignIPs: + type: string + type: object + namespace: + properties: + reconcilerPeriod: + type: string + type: object + node: + properties: + hostEndpoint: + properties: + autoCreate: + type: string + createDefaultHostEndpoint: + type: string + templates: + items: + properties: + generateName: + maxLength: 253 + type: string + interfaceCIDRs: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + nodeSelector: + type: string + type: object + type: array + type: object + leakGracePeriod: + type: string + reconcilerPeriod: + type: string + syncLabels: + type: string + type: object + policy: + properties: + reconcilerPeriod: + type: string + type: object + serviceAccount: + properties: + reconcilerPeriod: + type: string + type: object + workloadEndpoint: + properties: + reconcilerPeriod: + type: string + type: object + type: object + debugProfilePort: + format: int32 + type: integer + etcdV3CompactionPeriod: + type: string + healthChecks: + type: string + logSeverityScreen: + type: string + prometheusMetricsPort: + type: integer + required: + - controllers + type: object + status: + properties: + environmentVars: + additionalProperties: + type: string + type: object + runningConfig: + properties: + controllers: + properties: + loadBalancer: + properties: + assignIPs: + type: string + type: object + namespace: + properties: + reconcilerPeriod: + type: string + type: object + node: + properties: + hostEndpoint: + properties: + autoCreate: + type: string + createDefaultHostEndpoint: + type: string + templates: + items: + properties: + generateName: + maxLength: 253 + type: string + interfaceCIDRs: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + nodeSelector: + type: string + type: object + type: array + type: object + leakGracePeriod: + type: string + reconcilerPeriod: + type: string + syncLabels: + type: string + type: object + policy: + properties: + reconcilerPeriod: + type: string + type: object + serviceAccount: + properties: + reconcilerPeriod: + type: string + type: object + workloadEndpoint: + properties: + reconcilerPeriod: + type: string + type: object + type: object + debugProfilePort: + format: int32 + type: integer + etcdV3CompactionPeriod: + type: string + healthChecks: + type: string + logSeverityScreen: + type: string + prometheusMetricsPort: + type: integer + required: + - controllers + type: object + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_networkpolicies.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_networkpolicies.yaml new file mode 100644 index 0000000000..6f89bb2cb4 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_networkpolicies.yaml @@ -0,0 +1,364 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: networkpolicies.projectcalico.org +spec: + group: projectcalico.org + names: + kind: NetworkPolicy + listKind: NetworkPolicyList + plural: networkpolicies + singular: networkpolicy + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + egress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + ingress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + order: + type: number + performanceHints: + items: + type: string + type: array + selector: + type: string + serviceAccountSelector: + type: string + tier: + type: string + types: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_networksets.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_networksets.yaml new file mode 100644 index 0000000000..e9ccc9d04a --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_networksets.yaml @@ -0,0 +1,36 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: networksets.projectcalico.org +spec: + group: projectcalico.org + names: + kind: NetworkSet + listKind: NetworkSetList + plural: networksets + singular: networkset + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + nets: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_profiles.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_profiles.yaml new file mode 100644 index 0000000000..199649b952 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_profiles.yaml @@ -0,0 +1,352 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: profiles.projectcalico.org +spec: + group: projectcalico.org + names: + kind: Profile + listKind: ProfileList + plural: profiles + singular: profile + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + egress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + ingress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + labelsToApply: + additionalProperties: + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagedglobalnetworkpolicies.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagedglobalnetworkpolicies.yaml new file mode 100644 index 0000000000..a957087df8 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagedglobalnetworkpolicies.yaml @@ -0,0 +1,374 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: stagedglobalnetworkpolicies.projectcalico.org +spec: + group: projectcalico.org + names: + kind: StagedGlobalNetworkPolicy + listKind: StagedGlobalNetworkPolicyList + plural: stagedglobalnetworkpolicies + singular: stagedglobalnetworkpolicy + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + applyOnForward: + type: boolean + doNotTrack: + type: boolean + egress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + ingress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + namespaceSelector: + type: string + order: + type: number + performanceHints: + items: + type: string + type: array + preDNAT: + type: boolean + selector: + type: string + serviceAccountSelector: + type: string + stagedAction: + type: string + tier: + type: string + types: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagedkubernetesnetworkpolicies.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagedkubernetesnetworkpolicies.yaml new file mode 100644 index 0000000000..9883bf1e71 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagedkubernetesnetworkpolicies.yaml @@ -0,0 +1,246 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: stagedkubernetesnetworkpolicies.projectcalico.org +spec: + group: projectcalico.org + names: + kind: StagedKubernetesNetworkPolicy + listKind: StagedKubernetesNetworkPolicyList + plural: stagedkubernetesnetworkpolicies + singular: stagedkubernetesnetworkpolicy + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + egress: + items: + properties: + ports: + items: + properties: + endPort: + format: int32 + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + protocol: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + to: + items: + properties: + ipBlock: + properties: + cidr: + type: string + except: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - cidr + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + ingress: + items: + properties: + from: + items: + properties: + ipBlock: + properties: + cidr: + type: string + except: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - cidr + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + endPort: + format: int32 + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + protocol: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + policyTypes: + items: + type: string + type: array + stagedAction: + type: string + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagednetworkpolicies.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagednetworkpolicies.yaml new file mode 100644 index 0000000000..1e30ad0c76 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_stagednetworkpolicies.yaml @@ -0,0 +1,366 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: stagednetworkpolicies.projectcalico.org +spec: + group: projectcalico.org + names: + kind: StagedNetworkPolicy + listKind: StagedNetworkPolicyList + plural: stagednetworkpolicies + singular: stagednetworkpolicy + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + egress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + ingress: + items: + properties: + action: + type: string + destination: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + http: + properties: + methods: + items: + type: string + type: array + paths: + items: + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + properties: + code: + type: integer + type: + type: integer + type: object + ipVersion: + type: integer + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + type: object + notICMP: + properties: + code: + type: integer + type: + type: integer + type: object + notProtocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + protocol: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + source: + properties: + namespaceSelector: + type: string + nets: + items: + type: string + type: array + notNets: + items: + type: string + type: array + notPorts: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + type: string + ports: + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + type: string + serviceAccounts: + properties: + names: + items: + type: string + type: array + selector: + type: string + type: object + services: + properties: + name: + type: string + namespace: + type: string + type: object + type: object + required: + - action + type: object + type: array + order: + type: number + performanceHints: + items: + type: string + type: array + selector: + type: string + serviceAccountSelector: + type: string + stagedAction: + type: string + tier: + type: string + types: + items: + type: string + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_tiers.yaml b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_tiers.yaml new file mode 100644 index 0000000000..8925689f78 --- /dev/null +++ b/pkg/crds/calico/v3.projectcalico.org/projectcalico.org_tiers.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: tiers.projectcalico.org +spec: + group: projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + preserveUnknownFields: false + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + defaultAction: + enum: + - Pass + - Deny + type: string + order: + type: number + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/crds.go b/pkg/crds/crds.go index b8ce235e5e..ad48a102ce 100644 --- a/pkg/crds/crds.go +++ b/pkg/crds/crds.go @@ -30,10 +30,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" // gopkg.in/yaml.v2 didn't parse all the fields but this package did + "github.com/go-logr/logr" opv1 "github.com/tigera/operator/api/v1" ) var ( + //go:embed calico calicoCRDFiles embed.FS //go:embed enterprise @@ -55,15 +57,19 @@ func init() { calicoOprtrCRDsRe = regexp.MustCompile(fmt.Sprintf("(%s)", strings.Join(calicoCRDNames, "|"))) } -func getCalicoCRDSource() map[string][]byte { +func getCalicoCRDSource(v3 bool) map[string][]byte { ret := map[string][]byte{} - entries, err := calicoCRDFiles.ReadDir("calico") + dir := "calico/v1.crd.projectcalico.org" + if v3 { + dir = "calico/v3.projectcalico.org" + } + entries, err := calicoCRDFiles.ReadDir(dir) if err != nil { panic(fmt.Sprintf("Failed to read Calico CRDs: %v", err)) } for _, entry := range entries { - b, err := calicoCRDFiles.ReadFile(path.Join("calico", entry.Name())) + b, err := calicoCRDFiles.ReadFile(path.Join(dir, entry.Name())) if err != nil { panic(fmt.Sprintf("Failed to read Calico CRD %s: %v", entry.Name(), err)) } @@ -79,23 +85,31 @@ func getCalicoCRDSource() map[string][]byte { func getEnterpriseCRDSource() map[string][]byte { ret := map[string][]byte{} - entries, err := enterpriseCRDFiles.ReadDir("enterprise") + dir := "enterprise/v1.crd.projectcalico.org" + entries, err := enterpriseCRDFiles.ReadDir(dir) if err != nil { panic(fmt.Sprintf("Failed to read Enterprise CRDs: %v", err)) } + // Determine paths of each file to parse, loading all of the files discovered in + // the Calico CRD directory plus the ECK CRD bundle file. + files := map[string]string{} for _, entry := range entries { - b, err := enterpriseCRDFiles.ReadFile(path.Join("enterprise", entry.Name())) + files[entry.Name()] = path.Join(dir, entry.Name()) + } + files["01-crd-eck-bundle.yaml"] = "enterprise/01-crd-eck-bundle.yaml" + + for name, path := range files { + b, err := enterpriseCRDFiles.ReadFile(path) if err != nil { - panic(fmt.Sprintf("Failed to read Enterprise CRD %s: %v", entry.Name(), err)) + panic(fmt.Sprintf("Failed to read Enterprise CRD %s: %v", name, err)) } crds := bytes.Split(b, []byte("\n---")) for i, crd := range crds { - ret[fmt.Sprintf("%s_%d", entry.Name(), i)] = crd + ret[fmt.Sprintf("%s_%d", name, i)] = crd } } - return ret } @@ -144,14 +158,14 @@ func convertYamlsToCRDs(yamls ...map[string][]byte) []*apiextenv1.CustomResource return crds } -func GetCRDs(variant opv1.ProductVariant) []*apiextenv1.CustomResourceDefinition { +func GetCRDs(variant opv1.ProductVariant, v3 bool) []*apiextenv1.CustomResourceDefinition { lock.Lock() defer lock.Unlock() var crds []*apiextenv1.CustomResourceDefinition if variant == opv1.Calico { if len(calicoCRDs) == 0 { - calicoCRDs = convertYamlsToCRDs(getCalicoCRDSource(), getOperatorCRDSource(variant)) + calicoCRDs = convertYamlsToCRDs(getCalicoCRDSource(v3), getOperatorCRDSource(variant)) } crds = calicoCRDs } else { @@ -161,18 +175,18 @@ func GetCRDs(variant opv1.ProductVariant) []*apiextenv1.CustomResourceDefinition crds = enterpriseCRDs } - // Make a copy of the slice so that when we use the resource to Create or Update - // our original copy of the definitions are not tainted with a ResourceVersion - copy := []*apiextenv1.CustomResourceDefinition{} + // Make a cp of the slice so that when we use the resource to Create or Update + // our original cp of the definitions are not tainted with a ResourceVersion + cp := []*apiextenv1.CustomResourceDefinition{} for _, crd := range crds { // Skip the Tenant CRD - this is only used in Calico Cloud. if crd.Name == "tenants.operator.tigera.io" { continue } - copy = append(copy, crd.DeepCopy()) + cp = append(cp, crd.DeepCopy()) } - return copy + return cp } // ToRuntimeObjects converts the given list of CRDs to a list of client.Objects @@ -189,9 +203,11 @@ func ToRuntimeObjects(crds ...*apiextenv1.CustomResourceDefinition) []client.Obj // Ensure ensures that the CRDs necessary for bootstrapping exist in the cluster. // Further reconciliation of the CRDs is handled by the core controller. -func Ensure(c client.Client, variant string) error { +func Ensure(c client.Client, variant string, v3 bool, log logr.Logger) error { // Ensure Calico CRDs exist, which will allow us to bootstrap. - for _, crd := range GetCRDs(opv1.ProductVariant(variant)) { + for _, crd := range GetCRDs(opv1.ProductVariant(variant), v3) { + + log.Info("ensuring CustomResourceDefinition exists", "name", crd.Name) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) if err := c.Create(ctx, crd); err != nil { diff --git a/pkg/crds/crds_test.go b/pkg/crds/crds_test.go index d414b84a78..8b1937f125 100644 --- a/pkg/crds/crds_test.go +++ b/pkg/crds/crds_test.go @@ -15,6 +15,8 @@ package crds import ( + "fmt" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -24,24 +26,32 @@ import ( // The real test here is simply calling these functions will result in a panic if any of the CRDs cannot be parsed var _ = Describe("test crds pkg", func() { - It("can parse Calico CRDs", func() { - Expect(func() { Expect(getCalicoCRDSource()).ToNot(BeEmpty()) }).ToNot(Panic()) + for _, v3 := range []bool{true, false} { + It(fmt.Sprintf("can parse Calico CRDs (v3=%t)", v3), func() { + Expect(func() { Expect(getCalicoCRDSource(v3)).ToNot(BeEmpty()) }).ToNot(Panic()) + }) + + It(fmt.Sprintf("can get all CRDS used with Calico (v3=%t)", v3), func() { + Expect(func() { Expect(GetCRDs(opv1.Calico, v3)).ToNot(BeEmpty()) }).ToNot(Panic()) + }) + } + + It("can get all CRDS used with Enterprise", func() { + Expect(func() { Expect(GetCRDs(opv1.TigeraSecureEnterprise, false)).ToNot(BeEmpty()) }).ToNot(Panic()) }) + It("can parse Enterprise CRDs", func() { Expect(func() { Expect(getEnterpriseCRDSource()).ToNot(BeEmpty()) }).ToNot(Panic()) }) + It("can parse Operator CRDs used with calico", func() { Expect(func() { Expect(getOperatorCRDSource(opv1.Calico)).ToNot(BeEmpty()) }).ToNot(Panic()) }) + It("can parse Operator CRDs used with Enterprise", func() { Expect(func() { Expect(getOperatorCRDSource(opv1.TigeraSecureEnterprise)).ToNot(BeEmpty()) }).ToNot(Panic()) }) - It("can get all CRDS used with Calico", func() { - Expect(func() { Expect(GetCRDs(opv1.Calico)).ToNot(BeEmpty()) }).ToNot(Panic()) - }) - It("can get all CRDS used with Enterprise", func() { - Expect(func() { Expect(GetCRDs(opv1.TigeraSecureEnterprise)).ToNot(BeEmpty()) }).ToNot(Panic()) - }) + It("installs GatewayAPI CRD with Calico OSS", func() { Expect(getOperatorCRDSource(opv1.Calico)).To(HaveKey(ContainSubstring("gatewayapis"))) }) diff --git a/pkg/crds/enterprise/crd.projectcalico.org_alertexceptions.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_alertexceptions.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_alertexceptions.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_alertexceptions.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_bfdconfigurations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bfdconfigurations.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_bfdconfigurations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bfdconfigurations.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_bgpconfigurations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgpconfigurations.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_bgpconfigurations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgpconfigurations.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_bgpfilters.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgpfilters.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_bgpfilters.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgpfilters.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_bgppeers.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgppeers.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_bgppeers.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgppeers.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_blockaffinities.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_blockaffinities.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_blockaffinities.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_blockaffinities.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_caliconodestatuses.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_caliconodestatuses.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_caliconodestatuses.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_caliconodestatuses.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_clusterinformations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_clusterinformations.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_clusterinformations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_clusterinformations.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_deeppacketinspections.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_deeppacketinspections.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_deeppacketinspections.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_deeppacketinspections.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_egressgatewaypolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_egressgatewaypolicies.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_egressgatewaypolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_egressgatewaypolicies.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_externalnetworks.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_externalnetworks.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_externalnetworks.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_externalnetworks.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_felixconfigurations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml similarity index 99% rename from pkg/crds/enterprise/crd.projectcalico.org_felixconfigurations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml index 248ee47098..844f714351 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_felixconfigurations.yaml +++ b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml @@ -1642,12 +1642,14 @@ spec: format: int32 type: integer nftablesMode: + default: Auto description: "NFTablesMode configures nftables support in Felix. [Default: - Disabled]" + Auto]" enum: - Disabled - Enabled + - Auto type: string nftablesRefreshInterval: description: diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalalerts.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalalerts.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalalerts.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalalerts.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalalerttemplates.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalalerttemplates.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalalerttemplates.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalalerttemplates.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalnetworkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworkpolicies.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalnetworkpolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworkpolicies.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalnetworksets.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworksets.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalnetworksets.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalnetworksets.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalreports.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalreports.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalreports.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalreports.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalreporttypes.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalreporttypes.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalreporttypes.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalreporttypes.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_globalthreatfeeds.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalthreatfeeds.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_globalthreatfeeds.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_globalthreatfeeds.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_hostendpoints.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_hostendpoints.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_hostendpoints.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_hostendpoints.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_ipamblocks.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipamblocks.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_ipamblocks.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipamblocks.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_ipamconfigs.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipamconfigs.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_ipamconfigs.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipamconfigs.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_ipamhandles.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipamhandles.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_ipamhandles.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipamhandles.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_ippools.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_ippools.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_ipreservations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipreservations.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_ipreservations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_ipreservations.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_kubecontrollersconfigurations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_kubecontrollersconfigurations.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_kubecontrollersconfigurations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_kubecontrollersconfigurations.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_licensekeys.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_licensekeys.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_licensekeys.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_licensekeys.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_managedclusters.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_managedclusters.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_managedclusters.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_managedclusters.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_networkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_networkpolicies.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_networkpolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_networkpolicies.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_networksets.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_networksets.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_networksets.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_networksets.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_packetcaptures.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_packetcaptures.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_packetcaptures.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_packetcaptures.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_policyrecommendationscopes.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_policyrecommendationscopes.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_policyrecommendationscopes.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_policyrecommendationscopes.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_remoteclusterconfigurations.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_remoteclusterconfigurations.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_remoteclusterconfigurations.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_remoteclusterconfigurations.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_securityeventwebhooks.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_securityeventwebhooks.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_securityeventwebhooks.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_securityeventwebhooks.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_stagedglobalnetworkpolicies.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_stagedkubernetesnetworkpolicies.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_stagednetworkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_stagednetworkpolicies.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_stagednetworkpolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_stagednetworkpolicies.yaml diff --git a/pkg/crds/calico/crd.projectcalico.org_tiers.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_tiers.yaml similarity index 100% rename from pkg/crds/calico/crd.projectcalico.org_tiers.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_tiers.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_uisettings.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_uisettings.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_uisettings.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_uisettings.yaml diff --git a/pkg/crds/enterprise/crd.projectcalico.org_uisettingsgroups.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_uisettingsgroups.yaml similarity index 100% rename from pkg/crds/enterprise/crd.projectcalico.org_uisettingsgroups.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_uisettingsgroups.yaml diff --git a/pkg/crds/enterprise/v1.crd.projectcalico.org/policy.networking.k8s.io_adminnetworkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/policy.networking.k8s.io_adminnetworkpolicies.yaml new file mode 100644 index 0000000000..3fd0b0f5a9 --- /dev/null +++ b/pkg/crds/enterprise/v1.crd.projectcalico.org/policy.networking.k8s.io_adminnetworkpolicies.yaml @@ -0,0 +1,1107 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: experimental + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + + Support: Extended + + + + type: string + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + networks: + description: |- + Networks defines a way to select peers via CIDR blocks. + This is intended for representing entities that live outside the cluster, + which can't be selected by pods, namespaces and nodes peers, but note + that cluster-internal traffic will be checked against the rule as + well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow + or deny all IPv4 pod-to-pod traffic as well. If you don't want that, + add a rule that Passes all pod traffic before the Networks rule. + + + Each item in Networks should be provided in the CIDR format and should be + IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8". + + + Networks can have upto 25 CIDRs specified. + + + Support: Extended + + + + items: + description: |- + CIDR is an IP address range in CIDR notation (for example, "10.0.0.0/8" or "fd00::/8"). + This string must be validated by implementations using net.ParseCIDR + TODO: Introduce CEL CIDR validation regex isCIDR() in Kube 1.31 when it is available. + maxLength: 43 + type: string + x-kubernetes-validations: + - message: + CIDR must be either an IPv4 or IPv6 address. + IPv4 address embedded in IPv6 addresses are not + supported + rule: self.contains(':') != self.contains('.') + maxItems: 25 + minItems: 1 + type: array + x-kubernetes-list-type: set + nodes: + description: |- + Nodes defines a way to select a set of nodes in + the cluster. This field follows standard label selector + semantics; if present but empty, it selects all Nodes. + + + Support: Extended + + + + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: + matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: + matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + x-kubernetes-validations: + - message: + networks/nodes peer cannot be set with namedPorts since + there are no namedPorts for networks/nodes + rule: + "!(self.to.exists(peer, has(peer.networks) || has(peer.nodes)) + && has(self.ports) && self.ports.exists(port, has(port.namedPort)))" + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: + matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: + matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + + Support: Extended + + + + type: string + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: + Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: + "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/pkg/crds/calico/policy.networking.k8s.io_clusternetworkpolicies.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml similarity index 76% rename from pkg/crds/calico/policy.networking.k8s.io_clusternetworkpolicies.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml index 43f86d4321..fddc29a85f 100644 --- a/pkg/crds/calico/policy.networking.k8s.io_clusternetworkpolicies.yaml +++ b/pkg/crds/enterprise/v1.crd.projectcalico.org/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml @@ -2,35 +2,32 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/300 - policy.networking.k8s.io/bundle-version: v0.1.7 - policy.networking.k8s.io/channel: standard - name: clusternetworkpolicies.policy.networking.k8s.io + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: experimental + creationTimestamp: null + name: baselineadminnetworkpolicies.policy.networking.k8s.io spec: group: policy.networking.k8s.io names: - kind: ClusterNetworkPolicy - listKind: ClusterNetworkPolicyList - plural: clusternetworkpolicies + kind: BaselineAdminNetworkPolicy + listKind: BaselineAdminNetworkPolicyList + plural: baselineadminnetworkpolicies shortNames: - - cnp - singular: clusternetworkpolicy + - banp + singular: baselineadminnetworkpolicy scope: Cluster versions: - additionalPrinterColumns: - - jsonPath: .spec.tier - name: Tier - type: string - - jsonPath: .spec.priority - name: Priority - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha2 + name: v1alpha1 schema: openAPIV3Schema: - description: ClusterNetworkPolicy is a cluster-wide network policy resource. + description: |- + BaselineAdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. properties: apiVersion: description: |- @@ -50,54 +47,50 @@ spec: metadata: type: object spec: - description: Spec defines the desired behavior of ClusterNetworkPolicy. + description: Specification of the desired behavior of BaselineAdminNetworkPolicy. properties: egress: description: |- - Egress is the list of Egress rules to be applied to the selected pods. - - A maximum of 25 rules is allowed in this block. - - The relative precedence of egress rules within a single CNP object - (all of which share the priority) will be determined by the order - in which the rule is written. + Egress is the list of Egress rules to be applied to the selected pods if + they are not matched by any AdminNetworkPolicy or NetworkPolicy rules. + A total of 100 Egress rules will be allowed in each BANP instance. + The relative precedence of egress rules within a single BANP object + will be determined by the order in which the rule is written. Thus, a rule that appears at the top of the egress rules would take the highest precedence. - CNPs with no egress rules do not affect egress traffic. + BANPs with no egress rules do not affect egress traffic. + + + Support: Core items: description: |- - ClusterNetworkPolicyEgressRule describes an action to take on a particular - set of traffic originating from pods selected by a ClusterNetworkPolicy's + BaselineAdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a BaselineAdminNetworkPolicy's Subject field. properties: action: description: |- - Action specifies the effect this rule will have on matching - traffic. Currently the following actions are supported: - - - Accept: Accepts the selected traffic, allowing it to - egress. No further ClusterNetworkPolicy or NetworkPolicy - rules will be processed. + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic + Deny: denies the selected traffic - - Deny: Drops the selected traffic. No further - ClusterNetworkPolicy or NetworkPolicy rules will be - processed. - - Pass: Skips all further ClusterNetworkPolicy rules in the - current tier for the selected traffic, and passes - evaluation to the next tier. + Support: Core enum: - - Accept + - Allow - Deny - - Pass type: string name: description: |- - Name is an identifier for this rule, that may be no more than - 100 characters in length. This field should be used by the implementation - to help improve observability, readability and error-reporting - for any applied AdminNetworkPolicies. + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + BaselineAdminNetworkPolicies. + + + Support: Core maxLength: 100 type: string ports: @@ -107,18 +100,34 @@ spec: If Ports is not set then the rule does not filter traffic via port. items: description: |- - ClusterNetworkPolicyPort describes how to select destination network ports. + AdminNetworkPolicyPort describes how to select network ports on pod(s). Exactly one field must be set. maxProperties: 1 minProperties: 1 properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + + Support: Extended + + + + type: string portNumber: - description: - Port selects a destination port based on - protocol and port number. + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core properties: port: - description: Number defines a network port value. + description: |- + Number defines a network port value. + + + Support: Core format: int32 maximum: 65535 minimum: 1 @@ -128,6 +137,9 @@ spec: description: |- Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP. + + + Support: Core type: string required: - port @@ -135,13 +147,19 @@ spec: type: object portRange: description: |- - PortRange selects a destination port range based on protocol and - start and end port numbers. + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core properties: end: description: |- End defines a network port that is the end of a port range, the End value must be greater than Start. + + + Support: Core format: int32 maximum: 65535 minimum: 1 @@ -151,11 +169,17 @@ spec: description: |- Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP. + + + Support: Core type: string start: description: |- Start defines a network port that is the start of a port range, the Start value must be less than End. + + + Support: Core format: int32 maximum: 65535 minimum: 1 @@ -164,31 +188,24 @@ spec: - end - start type: object - x-kubernetes-validations: - - message: Start port must be less than End port - rule: self.start < self.end type: object - maxItems: 25 - minItems: 1 + maxItems: 100 type: array to: description: |- - To is the List of destinations whose traffic this rule applies to. - If any element matches the destination of outgoing + To is the list of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing traffic then the specified action is applied. This field must be defined and contain at least one item. - items: - description: |- - ClusterNetworkPolicyEgressPeer defines a peer to allow traffic to. - Exactly one of the fields must be set for a given peer and this is enforced - by the validation rules on the CRD. If an implementation sees no fields are - set then it can infer that the deployed CRD is of an incompatible version - with an unknown field. In that case it should fail closed. - For "Accept" rules, "fail closed" means: "treat the rule as matching no - traffic". For "Deny" and "Pass" rules, "fail closed" means: "treat the rule - as a 'Deny all' rule". + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. maxProperties: 1 minProperties: 1 properties: @@ -196,6 +213,9 @@ spec: description: |- Namespaces defines a way to select all pods within a set of Namespaces. Note that host-networked pods are not included in this type of peer. + + + Support: Core properties: matchExpressions: description: @@ -225,13 +245,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -248,32 +266,102 @@ spec: This is intended for representing entities that live outside the cluster, which can't be selected by pods, namespaces and nodes peers, but note that cluster-internal traffic will be checked against the rule as - well. So if you Accept or Deny traffic to `"0.0.0.0/0"`, that will allow + well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow or deny all IPv4 pod-to-pod traffic as well. If you don't want that, add a rule that Passes all pod traffic before the Networks rule. + Each item in Networks should be provided in the CIDR format and should be IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8". + Networks can have upto 25 CIDRs specified. + + + Support: Extended + + + items: description: |- - CIDR is an IP address range in CIDR notation - (for example, "10.0.0.0/8" or "fd00::/8"). + CIDR is an IP address range in CIDR notation (for example, "10.0.0.0/8" or "fd00::/8"). + This string must be validated by implementations using net.ParseCIDR + TODO: Introduce CEL CIDR validation regex isCIDR() in Kube 1.31 when it is available. maxLength: 43 type: string x-kubernetes-validations: - - message: Invalid CIDR format provided - rule: isCIDR(self) + - message: + CIDR must be either an IPv4 or IPv6 address. + IPv4 address embedded in IPv6 addresses are not + supported + rule: self.contains(':') != self.contains('.') maxItems: 25 minItems: 1 type: array x-kubernetes-list-type: set + nodes: + description: |- + Nodes defines a way to select a set of nodes in + the cluster. This field follows standard label selector + semantics; if present but empty, it selects all Nodes. + + + Support: Extended + + + + properties: + matchExpressions: + description: + matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: + key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic pods: description: |- Pods defines a way to select a set of pods in a set of namespaces. Note that host-networked pods are not included in this type of peer. + + + Support: Core properties: namespaceSelector: description: |- @@ -309,13 +397,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -328,8 +414,8 @@ spec: x-kubernetes-map-type: atomic podSelector: description: |- - PodSelector is used to explicitly select pods within a namespace; - if empty, it selects all Pods. + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. properties: matchExpressions: description: @@ -360,13 +446,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -382,77 +466,69 @@ spec: - podSelector type: object type: object - maxItems: 25 + maxItems: 100 minItems: 1 type: array required: - action - to type: object - maxItems: 25 + x-kubernetes-validations: + - message: + networks/nodes peer cannot be set with namedPorts since + there are no namedPorts for networks/nodes + rule: + "!(self.to.exists(peer, has(peer.networks) || has(peer.nodes)) + && has(self.ports) && self.ports.exists(port, has(port.namedPort)))" + maxItems: 100 type: array ingress: description: |- - Ingress is the list of Ingress rules to be applied to the selected pods. - - A maximum of 25 rules is allowed in this block. - - The relative precedence of ingress rules within a single CNP object - (all of which share the priority) will be determined by the order - in which the rule is written. + Ingress is the list of Ingress rules to be applied to the selected pods + if they are not matched by any AdminNetworkPolicy or NetworkPolicy rules. + A total of 100 Ingress rules will be allowed in each BANP instance. + The relative precedence of ingress rules within a single BANP object + will be determined by the order in which the rule is written. Thus, a rule that appears at the top of the ingress rules would take the highest precedence. - CNPs with no ingress rules do not affect ingress traffic. + BANPs with no ingress rules do not affect ingress traffic. + + + Support: Core items: description: |- - ClusterNetworkPolicyIngressRule describes an action to take on a particular - set of traffic destined for pods selected by a ClusterNetworkPolicy's + BaselineAdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by a BaselineAdminNetworkPolicy's Subject field. properties: action: description: |- - Action specifies the effect this rule will have on matching - traffic. Currently the following actions are supported: + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic + Deny: denies the selected traffic - - Accept: Accepts the selected traffic, allowing it into - the destination. No further ClusterNetworkPolicy or - NetworkPolicy rules will be processed. - Note: while Accept ensures traffic is accepted by - Kubernetes network policy, it is still possible that the - packet is blocked in other ways: custom nftable rules, - high-layers e.g. service mesh. - - - Deny: Drops the selected traffic. No further - ClusterNetworkPolicy or NetworkPolicy rules will be - processed. - - - Pass: Skips all further ClusterNetworkPolicy rules in the - current tier for the selected traffic, and passes - evaluation to the next tier. + Support: Core enum: - - Accept + - Allow - Deny - - Pass type: string from: description: |- From is the list of sources whose traffic this rule applies to. - If any element matches the source of incoming + If any AdminNetworkPolicyIngressPeer matches the source of incoming traffic then the specified action is applied. This field must be defined and contain at least one item. - items: - description: |- - ClusterNetworkPolicyIngressPeer defines a peer to allow traffic from. - Exactly one of the fields must be set for a given peer and this is enforced - by the validation rules on the CRD. If an implementation sees no fields are - set then it can infer that the deployed CRD is of an incompatible version - with an unknown field. In that case it should fail closed. - For "Accept" rules, "fail closed" means: "treat the rule as matching no - traffic". For "Deny" and "Pass" rules, "fail closed" means: "treat the rule - as a 'Deny all' rule". + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. maxProperties: 1 minProperties: 1 properties: @@ -460,6 +536,9 @@ spec: description: |- Namespaces defines a way to select all pods within a set of Namespaces. Note that host-networked pods are not included in this type of peer. + + + Support: Core properties: matchExpressions: description: @@ -489,13 +568,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -511,6 +588,9 @@ spec: Pods defines a way to select a set of pods in a set of namespaces. Note that host-networked pods are not included in this type of peer. + + + Support: Core properties: namespaceSelector: description: |- @@ -546,13 +626,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -565,8 +643,8 @@ spec: x-kubernetes-map-type: atomic podSelector: description: |- - PodSelector is used to explicitly select pods within a namespace; - if empty, it selects all Pods. + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. properties: matchExpressions: description: @@ -597,13 +675,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -619,15 +695,18 @@ spec: - podSelector type: object type: object - maxItems: 25 + maxItems: 100 minItems: 1 type: array name: description: |- - Name is an identifier for this rule, that may be no more than - 100 characters in length. This field should be used by the implementation - to help improve observability, readability and error-reporting - for any applied AdminNetworkPolicies. + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + BaselineAdminNetworkPolicies. + + + Support: Core maxLength: 100 type: string ports: @@ -637,20 +716,39 @@ spec: the pods selected for this policy i.e the subject of the policy. So it matches on the destination port for the ingress traffic. If Ports is not set then the rule does not filter traffic via port. + + + Support: Core items: description: |- - ClusterNetworkPolicyPort describes how to select destination network ports. + AdminNetworkPolicyPort describes how to select network ports on pod(s). Exactly one field must be set. maxProperties: 1 minProperties: 1 properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + + Support: Extended + + + + type: string portNumber: - description: - Port selects a destination port based on - protocol and port number. + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core properties: port: - description: Number defines a network port value. + description: |- + Number defines a network port value. + + + Support: Core format: int32 maximum: 65535 minimum: 1 @@ -660,6 +758,9 @@ spec: description: |- Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP. + + + Support: Core type: string required: - port @@ -667,13 +768,19 @@ spec: type: object portRange: description: |- - PortRange selects a destination port range based on protocol and - start and end port numbers. + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core properties: end: description: |- End defines a network port that is the end of a port range, the End value must be greater than Start. + + + Support: Core format: int32 maximum: 65535 minimum: 1 @@ -683,11 +790,17 @@ spec: description: |- Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP. + + + Support: Core type: string start: description: |- Start defines a network port that is the start of a port range, the Start value must be less than End. + + + Support: Core format: int32 maximum: 65535 minimum: 1 @@ -696,41 +809,22 @@ spec: - end - start type: object - x-kubernetes-validations: - - message: Start port must be less than End port - rule: self.start < self.end type: object - maxItems: 25 - minItems: 1 + maxItems: 100 type: array required: - action - from type: object - maxItems: 25 + maxItems: 100 type: array - priority: - description: |- - Priority is a value from 0 to 1000 indicating the precedence of - the policy within its tier. Policies with lower priority values have - higher precedence, and are checked before policies with higher priority - values in the same tier. All Admin tier rules have higher precedence than - NetworkPolicy or Baseline tier rules. - If two (or more) policies in the same tier with the same priority - could match a connection, then the implementation can apply any of the - matching policies to the connection, and there is no way for the user to - reliably determine which one it will choose. Administrators must be - careful about assigning the priorities for policies with rules that will - match many connections, and ensure that policies have unique priority - values in cases where ambiguity would be unacceptable. - format: int32 - maximum: 1000 - minimum: 0 - type: integer subject: - description: - Subject defines the pods to which this ClusterNetworkPolicy - applies. + description: |- + Subject defines the pods to which this BaselineAdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core maxProperties: 1 minProperties: 1 properties: @@ -765,13 +859,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -820,13 +912,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -839,8 +929,8 @@ spec: x-kubernetes-map-type: atomic podSelector: description: |- - PodSelector is used to explicitly select pods within a namespace; - if empty, it selects all Pods. + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. properties: matchExpressions: description: @@ -870,13 +960,11 @@ spec: items: type: string type: array - x-kubernetes-list-type: atomic required: - key - operator type: object type: array - x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -892,45 +980,8 @@ spec: - podSelector type: object type: object - tier: - description: |- - Tier is used as the top-level grouping for network policy prioritization. - - Policy tiers are evaluated in the following order: - * Admin tier - * NetworkPolicy tier - * Baseline tier - - ClusterNetworkPolicy can use 2 of these tiers: Admin and Baseline. - - The Admin tier takes precedence over all other policies. Policies - defined in this tier are used to set cluster-wide security rules - that cannot be overridden in the other tiers. If Admin tier has - made a final decision (Accept or Deny) on a connection, then no - further evaluation is done. - - NetworkPolicy tier is the tier for the namespaced v1.NetworkPolicy. - These policies are intended for the application developer to describe - the security policy associated with their deployments inside their - namespace. v1.NetworkPolicy always makes a final decision for selected - pods. Further evaluation only happens for Pods not selected by a - v1.NetworkPolicy. - - Baseline tier is a cluster-wide policy that can be overridden by the - v1.NetworkPolicy. If Baseline tier has made a final decision (Accept or - Deny) on a connection, then no further evaluation is done. - - If a given connection wasn't allowed or denied by any of the tiers, - the default kubernetes policy is applied, which says that - all pods can communicate with each other. - enum: - - Admin - - Baseline - type: string required: - - priority - subject - - tier type: object status: description: Status is the status to be reported by the implementation. @@ -938,8 +989,16 @@ spec: conditions: items: description: - Condition contains details for one aspect of the current - state of this API Resource. + "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: description: |- @@ -980,7 +1039,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -1002,6 +1066,11 @@ spec: - metadata - spec type: object + x-kubernetes-validations: + - message: + Only one baseline admin network policy with metadata.name="default" + can be created in the cluster + rule: self.metadata.name == 'default' served: true storage: true subresources: diff --git a/pkg/crds/enterprise/usage.tigera.io_licenseusagereports.yaml b/pkg/crds/enterprise/v1.crd.projectcalico.org/usage.tigera.io_licenseusagereports.yaml similarity index 100% rename from pkg/crds/enterprise/usage.tigera.io_licenseusagereports.yaml rename to pkg/crds/enterprise/v1.crd.projectcalico.org/usage.tigera.io_licenseusagereports.yaml diff --git a/pkg/render/apiserver_test.go b/pkg/render/apiserver_test.go index 6c5821fade..cc4f13c117 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()) @@ -1770,7 +1770,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 e9e2cb4fcc..34ade2d345 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 @@ -1175,7 +1172,8 @@ var _ = Describe("compliance rendering tests", func() { render.ComplianceControllerServiceAccount, render.ComplianceReporterServiceAccount, render.ComplianceServerServiceAccount, - render.ComplianceSnapshotterServiceAccount} + render.ComplianceSnapshotterServiceAccount, + } for _, name := range expectedClusterRoleBindings { assertClusterRoleBindingHasSubjects(tenantAResources, @@ -1473,7 +1471,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 f00ce3baec..4940880b4d 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.go b/pkg/render/fluentd.go index aa8978c3dd..f44b7f7d23 100644 --- a/pkg/render/fluentd.go +++ b/pkg/render/fluentd.go @@ -451,7 +451,7 @@ func (c *fluentdComponent) splunkCredentialSecret() []*corev1.Secret { return nil } return []*corev1.Secret{ - &corev1.Secret{ + { TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}, ObjectMeta: metav1.ObjectMeta{ Name: SplunkFluentdTokenSecretName, @@ -1156,7 +1156,6 @@ func trustedBundleVolume(bundle certificatemanagement.TrustedBundle) corev1.Volu } func (c *fluentdComponent) eksLogForwarderVolumeMounts() []corev1.VolumeMount { - volumeMounts := []corev1.VolumeMount{ { Name: "plugin-statefile-dir", @@ -1183,7 +1182,6 @@ func (c *fluentdComponent) eksLogForwarderVolumeMounts() []corev1.VolumeMount { } func (c *fluentdComponent) eksLogForwarderVolumes() []corev1.Volume { - volumes := []corev1.Volume{ trustedBundleVolume(c.cfg.TrustedBundle), { diff --git a/pkg/render/fluentd_test.go b/pkg/render/fluentd_test.go index bab49b7885..6797bc0aa5 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/gatewayapi/gateway_api.go b/pkg/render/gatewayapi/gateway_api.go index 5e0bd90697..d97378b423 100644 --- a/pkg/render/gatewayapi/gateway_api.go +++ b/pkg/render/gatewayapi/gateway_api.go @@ -135,7 +135,7 @@ var ( func GatewayAPIResourcesGetter() func() *gatewayAPIResources { var lock sync.Mutex - var resources = &gatewayAPIResources{} + resources := &gatewayAPIResources{} const yamlDelimiter = "\n---\n" return func() *gatewayAPIResources { lock.Lock() @@ -862,7 +862,6 @@ func (pr *gatewayAPIImplementationComponent) envoyProxyConfig(className string, accessLogsName := "access-logs" // Add or update Container volume mount wafSocketVolumeMount := corev1.VolumeMount{ - Name: wafFilterName, MountPath: "/var/run/waf-http-filter", } @@ -876,7 +875,6 @@ func (pr *gatewayAPIImplementationComponent) envoyProxyConfig(className string, hasAccessLogsVolumeMount := false for i, volumeMount := range envoyProxy.Spec.Provider.Kubernetes.EnvoyDeployment.Container.VolumeMounts { - switch volumeMount.Name { case wafSocketVolumeMount.Name: hasWAFFilterSocketVolumeMount = true diff --git a/pkg/render/gatewayapi/gateway_api_test.go b/pkg/render/gatewayapi/gateway_api_test.go index 5fe99c538f..55c6d2e099 100644 --- a/pkg/render/gatewayapi/gateway_api_test.go +++ b/pkg/render/gatewayapi/gateway_api_test.go @@ -43,6 +43,7 @@ type matchObject struct { func (m *matchObject) Match(actual any) (success bool, err error) { return actual.(client.Object).GetName() == m.name, nil } + func (m *matchObject) FailureMessage(actual any) (message string) { return "" // not used within ContainElement } @@ -52,8 +53,7 @@ func (m *matchObject) NegatedFailureMessage(actual any) (message string) { } var _ = Describe("Gateway API rendering tests", func() { - - var AccessLogSettings = []envoyapi.ProxyAccessLogSetting{ + AccessLogSettings := []envoyapi.ProxyAccessLogSetting{ { Sinks: []envoyapi.ProxyAccessLogSink{ { diff --git a/pkg/render/guardian.go b/pkg/render/guardian.go index 36dea665d1..f33b23a276 100644 --- a/pkg/render/guardian.go +++ b/pkg/render/guardian.go @@ -145,7 +145,6 @@ func (c *GuardianComponent) SupportedOSType() rmeta.OSType { } func (c *GuardianComponent) Objects() ([]client.Object, []client.Object) { - objs := []client.Object{ // common RBAC for EE and OSS c.serviceAccount(), @@ -772,7 +771,6 @@ func GuardianService(clusterDomain string) string { // rulesForManagementClusterRequests returns the set of RBAC rules needed by Guardian in order to // satisfy requests from the management cluster over the tunnel. func rulesForManagementClusterRequests(isOpenShift bool) []rbacv1.PolicyRule { - rules := []rbacv1.PolicyRule{ // Common rules required to handle requests from multiple components in the management cluster. { diff --git a/pkg/render/guardian_test.go b/pkg/render/guardian_test.go index e737aee657..70283d7986 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 4896cb407e..041fabc0a5 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 61bd6b45f6..2b7b9cdc71 100644 --- a/pkg/render/intrusion_detection_test.go +++ b/pkg/render/intrusion_detection_test.go @@ -84,7 +84,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()) @@ -212,12 +212,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"}, }, @@ -259,7 +259,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() { @@ -552,7 +551,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"), @@ -647,7 +645,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() { @@ -771,7 +768,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: render.ManagerService(tenantA)})) - }) It("should render impersonation permissions as part of tigera-intrusion-detection ClusterRole", func() { @@ -840,7 +836,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 e93bb732b6..660cf09bf7 100644 --- a/pkg/render/intrusiondetection/dpi/dpi.go +++ b/pkg/render/intrusiondetection/dpi/dpi.go @@ -438,7 +438,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", }, @@ -446,7 +449,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 2239f232b2..63637db33b 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"}, }, @@ -199,7 +199,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/istio/istio.go b/pkg/render/istio/istio.go index 1472f820c9..c698ae610d 100644 --- a/pkg/render/istio/istio.go +++ b/pkg/render/istio/istio.go @@ -132,7 +132,6 @@ func Istio(cfg *Configuration) (*IstioComponentCRDs, *IstioComponent, error) { crds := &IstioComponentCRDs{resources: resources} istio := &IstioComponent{cfg: cfg, resources: resources} return crds, istio, nil - } func (c *IstioComponent) patchImages() (err error) { diff --git a/pkg/render/istio/istio_test.go b/pkg/render/istio/istio_test.go index 1b1ce8a261..9431fcab4e 100644 --- a/pkg/render/istio/istio_test.go +++ b/pkg/render/istio/istio_test.go @@ -705,9 +705,7 @@ var _ = Describe("Istio Component Rendering", func() { }) Describe("GKE Platform Configuration", func() { - var ( - component *istio.IstioComponent - ) + var component *istio.IstioComponent BeforeEach(func() { cfg.Installation.KubernetesProvider = operatorv1.ProviderGKE diff --git a/pkg/render/kubecontrollers/kube-controllers.go b/pkg/render/kubecontrollers/kube-controllers.go index 61c72e8f6e..d62f411027 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 @@ -402,13 +415,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"}, }, @@ -418,12 +431,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"}, }, @@ -432,7 +445,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 0ed1fc0b64..4095bb7b43 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..9f078f2035 100644 --- a/pkg/render/logstorage/dashboards/dashboards_test.go +++ b/pkg/render/logstorage/dashboards/dashboards_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2024-2026 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. @@ -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 fc760e6c74..c485a85e05 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..82df1b4a57 100644 --- a/pkg/render/logstorage/esmetrics/elasticsearch_metrics_test.go +++ b/pkg/render/logstorage/esmetrics/elasticsearch_metrics_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2026 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. @@ -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.go b/pkg/render/logstorage/kibana/kibana.go index 2ae439356b..01ff818796 100644 --- a/pkg/render/logstorage/kibana/kibana.go +++ b/pkg/render/logstorage/kibana/kibana.go @@ -64,9 +64,7 @@ const ( FlowsDashboardName = "Calico Flow Logs" ) -var ( - EntityRule = networkpolicy.CreateEntityRule(Namespace, CRName, Port) -) +var EntityRule = networkpolicy.CreateEntityRule(Namespace, CRName, Port) // Kibana renders the components necessary for kibana and elasticsearch func Kibana(cfg *Configuration) render.Component { diff --git a/pkg/render/logstorage/kibana/kibana_test.go b/pkg/render/logstorage/kibana/kibana_test.go index 0a1e25cfbf..9a5c2f5041 100644 --- a/pkg/render/logstorage/kibana/kibana_test.go +++ b/pkg/render/logstorage/kibana/kibana_test.go @@ -142,8 +142,7 @@ var _ = Describe("Kibana rendering tests", func() { &corev1.SeccompProfile{ Type: corev1.SeccompProfileTypeRuntimeDefault, })) - resultKB := rtest.GetResource(createResources, kibana.CRName, kibana.Namespace, - "kibana.k8s.elastic.co", "v1", "Kibana").(*kbv1.Kibana) + resultKB := rtest.GetResource(createResources, kibana.CRName, kibana.Namespace, "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")) Expect(resultKB.Spec.Config.Data["xpack.fleet.enabled"]).To(BeFalse()) @@ -186,7 +185,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) @@ -317,7 +316,6 @@ var _ = Describe("Kibana rendering tests", func() { State: "", }, } - }) It("returns Kibana CR's to delete and keeps the finalizers on the LogStorage CR", func() { @@ -326,7 +324,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() { @@ -432,7 +429,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", @@ -462,7 +458,8 @@ var _ = Describe("Kibana rendering tests", func() { Containers: []operatorv1.KibanaContainer{ { Name: "kibana", - Resources: &expectedResourcesRequirements}, + Resources: &expectedResourcesRequirements, + }, }, InitContainers: []operatorv1.KibanaInitContainer{ { @@ -488,16 +485,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 c49e5f499c..666557a4d4 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() { @@ -839,7 +838,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 a19f819b14..aee9fc0de9 100644 --- a/pkg/render/logstorage_test.go +++ b/pkg/render/logstorage_test.go @@ -297,7 +297,7 @@ var _ = Describe("Elasticsearch rendering tests", func() { createResources, deleteResources := component.Objects() rtest.ExpectResources(createResources, expectedCreateResources) - //compareResources(createResources, expectedCreateResources) + // compareResources(createResources, expectedCreateResources) compareResources(deleteResources, expectedDeleteResources) }) @@ -601,9 +601,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()}}, } @@ -1162,7 +1164,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.go b/pkg/render/manager.go index c609c33a1f..db6a4e95d1 100644 --- a/pkg/render/manager.go +++ b/pkg/render/manager.go @@ -227,7 +227,6 @@ func (c *managerComponent) ResolveImages(is *operatorv1.ImageSet) error { } c.uiAPIsImage, err = components.GetReference(components.ComponentUIAPIs, reg, path, prefix, is) - if err != nil { errMsgs = append(errMsgs, err.Error()) } @@ -1394,7 +1393,6 @@ func managerClusterWideDefaultView() *v3.UISettings { // can be removed for Calico Enterprise v3.26 which corresponds to operator version when the legacy names will no // longer be valid in our official support window func (m *managerComponent) deprecatedResources(tenant *operatorv1.Tenant, installNS, truthNS string) []client.Object { - objs := []client.Object{} clusterRoleName := LegacyManagerClusterRole clusterRoleBindingName := LegacyManagerClusterRoleBinding diff --git a/pkg/render/manager_test.go b/pkg/render/manager_test.go index 1f95269c03..478cdd1987 100644 --- a/pkg/render/manager_test.go +++ b/pkg/render/manager_test.go @@ -473,7 +473,8 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { APIGroups: []string{"projectcalico.org"}, Resources: []string{"managedclusters"}, Verbs: []string{"update"}, - }})) + }, + })) roleBindingUpdateManagedClusters := rtest.GetResource(resourcesToCreate, 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{ @@ -483,7 +484,6 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { Namespace: render.ManagerNamespace, }, })) - }) It("should set OIDC Authority environment when auth-type is OIDC", func() { @@ -510,7 +510,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()) @@ -801,7 +801,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()) @@ -1691,7 +1691,7 @@ func renderObjects(roc renderConfig) ([]client.Object, []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.go b/pkg/render/monitor/monitor.go index 2e36cad19d..a25bf37cc1 100644 --- a/pkg/render/monitor/monitor.go +++ b/pkg/render/monitor/monitor.go @@ -1002,7 +1002,6 @@ func (mc *monitorComponent) serviceMonitorQueryServer() *monitoringv1.ServiceMon } func (mc *monitorComponent) operatorRoles() []*rbacv1.Role { - return []*rbacv1.Role{ // list and watch have to be cluster scopes for watches to work. // In controller-runtime, watches are by default non-namespaced. @@ -1058,7 +1057,6 @@ func (mc *monitorComponent) operatorRoles() []*rbacv1.Role { } func (mc *monitorComponent) operatorRoleBindings() []*rbacv1.RoleBinding { - return []*rbacv1.RoleBinding{ { TypeMeta: metav1.TypeMeta{Kind: "RoleBinding", APIVersion: "rbac.authorization.k8s.io/v1"}, diff --git a/pkg/render/monitor/monitor_test.go b/pkg/render/monitor/monitor_test.go index 21b5dfdc8b..4d1b3e6759 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 07e705c469..b2f6d0ed9e 100644 --- a/pkg/render/node.go +++ b/pkg/render/node.go @@ -150,6 +150,8 @@ type NodeConfiguration struct { FelixPrometheusMetricsEnabled bool FelixPrometheusMetricsPort int + + V3CRDs bool } // Node creates the node daemonset and other resources for the daemonset to operate normally. @@ -460,7 +462,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", @@ -486,7 +488,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", }, @@ -495,7 +497,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", @@ -504,7 +506,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", @@ -514,7 +516,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", }, @@ -529,24 +531,19 @@ 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", "ipamhandles", + "ipamconfigurations", + "ipamconfigs", }, 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"}, - 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"}, }, @@ -556,7 +553,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", @@ -569,7 +566,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", }, @@ -618,11 +615,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", + "ipamconfigurations", "ipamconfigs", "clusterinformations", "ippools", @@ -635,7 +633,7 @@ func (c *nodeComponent) cniPluginRole() *rbacv1.ClusterRole { return role } -func (c *nodeComponent) createCalicoPluginConfig() map[string]interface{} { +func (c *nodeComponent) createCalicoPluginConfig() map[string]any { // Determine MTU to use for veth interfaces. // Zero means to use auto-detection. var mtu int32 = 0 @@ -667,22 +665,28 @@ 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{}{ + calicoPluginConfig := map[string]any{ "type": "calico", "datastore_type": "kubernetes", "mtu": mtu, "nodename_file_optional": nodenameFileOptional, "log_file_path": "/var/log/calico/cni/cni.log", "ipam": ipam, - "container_settings": map[string]interface{}{ + "container_settings": map[string]any{ "allow_ip_forwarding": ipForward, }, - "policy": map[string]interface{}{ + "policy": map[string]any{ "type": "k8s", }, "policy_setup_timeout_seconds": linuxPolicySetupTimeoutSeconds, "endpoint_status_dir": filepath.Join(c.varRunCalicoVolume().HostPath.Path, "endpoint-status"), + "calico_api_group": apiGroup, } // Determine logging configuration @@ -710,7 +714,7 @@ func (c *nodeComponent) createCalicoPluginConfig() map[string]interface{} { } // optional properties - kubernetes := map[string]interface{}{ + kubernetes := map[string]any{ "kubeconfig": "__KUBECONFIG_FILEPATH__", } if apiRoot != "" { @@ -719,7 +723,7 @@ func (c *nodeComponent) createCalicoPluginConfig() map[string]interface{} { calicoPluginConfig["kubernetes"] = kubernetes if c.vppDataplaneEnabled() { - calicoPluginConfig["dataplane_options"] = map[string]interface{}{ + calicoPluginConfig["dataplane_options"] = map[string]any{ "type": "grpc", "socket": "unix:///var/run/calico/cni-server.sock", } @@ -728,9 +732,9 @@ func (c *nodeComponent) createCalicoPluginConfig() map[string]interface{} { return calicoPluginConfig } -func (c *nodeComponent) createPortmapPlugin() map[string]interface{} { +func (c *nodeComponent) createPortmapPlugin() map[string]any { // Determine portmap configuration to use. - portmapPlugin := map[string]interface{}{ + portmapPlugin := map[string]any{ "type": "portmap", "snat": true, "capabilities": map[string]bool{ @@ -741,10 +745,10 @@ func (c *nodeComponent) createPortmapPlugin() map[string]interface{} { return portmapPlugin } -func (c *nodeComponent) createTuningPlugin() map[string]interface{} { +func (c *nodeComponent) createTuningPlugin() map[string]any { // tuning plugin (sysctl) sysctl := map[string]string{} - tuningPlugin := map[string]interface{}{ + tuningPlugin := map[string]any{ "type": "tuning", "sysctl": sysctl, } @@ -766,7 +770,7 @@ func (c *nodeComponent) nodeCNIConfigMap() *corev1.ConfigMap { return nil } - plugins := make([]interface{}, 0) + plugins := make([]any, 0) plugins = append(plugins, c.createCalicoPluginConfig()) // optional portmap plugin @@ -801,7 +805,7 @@ func (c *nodeComponent) nodeCNIConfigMap() *corev1.ConfigMap { } } -func (c *nodeComponent) getCalicoIPAM() map[string]interface{} { +func (c *nodeComponent) getCalicoIPAM() map[string]any { // Determine what address families to enable. var assign_ipv4 string var assign_ipv6 string @@ -815,32 +819,32 @@ func (c *nodeComponent) getCalicoIPAM() map[string]interface{} { } else { assign_ipv6 = "false" } - return map[string]interface{}{ + return map[string]any{ "type": "calico-ipam", "assign_ipv4": assign_ipv4, "assign_ipv6": assign_ipv6, } } -func buildHostLocalIPAM(pools []operatorv1.IPPool) map[string]interface{} { +func buildHostLocalIPAM(pools []operatorv1.IPPool) map[string]any { v6 := GetIPv6Pool(pools) != nil v4 := GetIPv4Pool(pools) != nil if v4 && v6 { // Dual-stack - return map[string]interface{}{ + return map[string]any{ "type": "host-local", "ranges": [][]map[string]string{{{"subnet": "usePodCidr"}}, {{"subnet": "usePodCidrIPv6"}}}, } } else if v6 { // Single-stack v6 - return map[string]interface{}{ + return map[string]any{ "type": "host-local", "subnet": "usePodCidrIPv6", } } else { // Single-stack v4 - return map[string]interface{}{ + return map[string]any{ "type": "host-local", "subnet": "usePodCidr", } diff --git a/pkg/render/node_test.go b/pkg/render/node_test.go index e90263a694..68cee56dd3 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 3e171dd6cd..595ed4206d 100644 --- a/pkg/render/nonclusterhost/nonclusterhost.go +++ b/pkg/render/nonclusterhost/nonclusterhost.go @@ -149,7 +149,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", @@ -217,7 +217,7 @@ func (c *nonClusterHostComponent) clusterRole() *rbacv1.ClusterRole { rules = append(rules, []rbacv1.PolicyRule{ { // Used to update labels on the HostEndpoint resource. - 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 5aed70d09b..397fed9874 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{ @@ -111,7 +111,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", @@ -163,7 +163,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 ad8dc7dd5c..89f780856b 100644 --- a/pkg/render/packet_capture_api_test.go +++ b/pkg/render/packet_capture_api_test.go @@ -61,7 +61,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 66998537dc..170ae38dae 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, @@ -468,7 +467,6 @@ func (pr *policyRecommendationComponent) allowTigeraPolicyForPolicyRecommendatio } func (pr *policyRecommendationComponent) deprecatedObjects(isManagedCluster bool) []client.Object { - var deprecatedObjs []client.Object if isManagedCluster { deprecatedObjs = append(deprecatedObjs, []client.Object{ @@ -495,5 +493,4 @@ func (pr *policyRecommendationComponent) deprecatedObjects(isManagedCluster bool } return deprecatedObjs - } diff --git a/pkg/render/policyrecommendation_test.go b/pkg/render/policyrecommendation_test.go index d8ad9f9e60..ee437ad6d2 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() { @@ -694,6 +693,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 9de96b1dda..8ec88bfa2b 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/testutils/policy.go b/pkg/render/testutils/policy.go index d579b6ea42..6513bc54bd 100644 --- a/pkg/render/testutils/policy.go +++ b/pkg/render/testutils/policy.go @@ -15,14 +15,14 @@ package testutils import ( - "github.com/onsi/gomega" - "encoding/json" "fmt" "io" "os" "strings" + "github.com/onsi/gomega" + rtest "github.com/tigera/operator/pkg/render/common/test" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/render/typha.go b/pkg/render/typha.go index dd8418db28..f42bfb4c85 100644 --- a/pkg/render/typha.go +++ b/pkg/render/typha.go @@ -261,7 +261,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", @@ -288,7 +288,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", @@ -297,7 +297,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", @@ -307,7 +307,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", }, @@ -322,7 +322,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", @@ -332,13 +332,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"}, }, @@ -348,7 +348,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 9c0b91f887..9fcb85d680 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 17ad712de1..1d8c885599 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 4f6c8c6ddf..dde6d52c8a 100644 --- a/test/crd_management_test.go +++ b/test/crd_management_test.go @@ -46,9 +46,10 @@ var _ = Describe("CRD management tests", func() { var npCRD *apiextenv1.CustomResourceDefinition var scheme *runtime.Scheme 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()) @@ -63,9 +64,11 @@ var _ = Describe("CRD management tests", func() { TypeMeta: metav1.TypeMeta{Kind: "CustomResourceDefinition", APIVersion: "apiextensions.k8s.io/v1"}, ObjectMeta: metav1.ObjectMeta{Name: "networkpolicies.crd.projectcalico.org"}, } + k := client.ObjectKey{Name: npCRD.Name} err = c.Get(context.Background(), k, npCRD) Expect(err).NotTo(HaveOccurred()) + ns := &corev1.Namespace{ TypeMeta: metav1.TypeMeta{Kind: "Namespace", APIVersion: "v1"}, ObjectMeta: metav1.ObjectMeta{Name: "tigera-operator"}, diff --git a/test/gatewayapi_test.go b/test/gatewayapi_test.go index 0515a8b4ac..688bd9cf00 100644 --- a/test/gatewayapi_test.go +++ b/test/gatewayapi_test.go @@ -53,7 +53,7 @@ var _ = Describe("GatewayAPI tests", func() { var operatorDone chan struct{} BeforeEach(func() { log = logf.Log.WithName("gatewayapi-test-logger") - c, clientset, mgr = setupManagerNoControllers(ManageCRDsDisable, SingleTenant, EnterpriseCRDsExist) + c, clientset, mgr = setupManagerNoControllers() // Start the GatewayAPI controller. shutdownContext, cancel = context.WithCancel(context.TODO()) diff --git a/test/mainline_test.go b/test/mainline_test.go index fef2647415..06f9498ab9 100644 --- a/test/mainline_test.go +++ b/test/mainline_test.go @@ -30,6 +30,7 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -40,10 +41,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" @@ -70,6 +71,7 @@ var _ = Describe("Mainline component function tests", func() { var shutdownContext context.Context var cancel context.CancelFunc var operatorDone chan struct{} + BeforeEach(func() { c, shutdownContext, cancel, mgr = setupManager(ManageCRDsDisable, SingleTenant, EnterpriseCRDsExist) @@ -102,6 +104,8 @@ var _ = Describe("Mainline component function tests", func() { AfterEach(func() { defer func() { cancel() + + By("Waiting for operator to shutdown") Eventually(func() error { select { case <-operatorDone: @@ -288,7 +292,7 @@ func newNonCachingClient(config *rest.Config, options client.Options) (client.Cl return client.New(config, options) } -func setupManagerNoControllers(manageCRDs bool, multiTenant bool, enterpriseCRDsExist bool) (client.Client, *kubernetes.Clientset, manager.Manager) { +func setupManagerNoControllers() (client.Client, *kubernetes.Clientset, manager.Manager) { // Create a Kubernetes client. cfg, err := config.GetConfig() Expect(err).NotTo(HaveOccurred()) @@ -296,9 +300,18 @@ func setupManagerNoControllers(manageCRDs bool, multiTenant bool, enterpriseCRDs clientset, err := kubernetes.NewForConfig(cfg) Expect(err).NotTo(HaveOccurred()) - // Create a manager to use in the tests. + v3CRDs, err := apis.UseV3CRDS(clientset) + Expect(err).NotTo(HaveOccurred()) + + // Create a scheme to use. + s := runtime.NewScheme() + err = apis.AddToScheme(s, v3CRDs) + Expect(err).NotTo(HaveOccurred()) + + // Create a manager to use in the tests, providing the scheme we created. skipNameValidation := true mgr, err := manager.New(cfg, manager.Options{ + Scheme: s, Metrics: server.Options{ BindAddress: "0", }, @@ -316,17 +329,11 @@ func setupManagerNoControllers(manageCRDs bool, multiTenant bool, enterpriseCRDs }) Expect(err).NotTo(HaveOccurred()) - // Setup Scheme for all resources - err = apis.AddToScheme(mgr.GetScheme()) - Expect(err).NotTo(HaveOccurred()) - err = apiextensionsv1.AddToScheme(mgr.GetScheme()) - Expect(err).NotTo(HaveOccurred()) - return mgr.GetClient(), clientset, mgr } func setupManager(manageCRDs bool, multiTenant bool, enterpriseCRDsExist bool) (client.Client, context.Context, context.CancelFunc, manager.Manager) { - client, clientset, mgr := setupManagerNoControllers(manageCRDs, multiTenant, enterpriseCRDsExist) + client, clientset, mgr := setupManagerNoControllers() // Setup all Controllers ctx, cancel := context.WithCancel(context.TODO()) @@ -543,7 +550,7 @@ func verifyCalicoHasDeployed(c client.Client) { func verifyCRDsExist(c client.Client, variant operator.ProductVariant) { crdNames := []string{} - for _, x := range crds.GetCRDs(variant) { + for _, x := range crds.GetCRDs(variant, false) { crdNames = append(crdNames, fmt.Sprintf("%s.%s", x.Spec.Names.Plural, x.Spec.Group)) } @@ -564,6 +571,7 @@ func verifyCRDsExist(c client.Client, variant operator.ProductVariant) { } func waitForProductTeardown(c client.Client) { + By("Waiting for Calico resources to be torn down") Eventually(func() error { ns := &corev1.Namespace{ TypeMeta: metav1.TypeMeta{Kind: "Namespace", APIVersion: "v1"}, @@ -599,13 +607,13 @@ func waitForProductTeardown(c client.Client) { return err } return nil - }, 240*time.Second).ShouldNot(HaveOccurred()) + }, 240*time.Second).ShouldNot(HaveOccurred(), "Calico resources were not torn down in time") } 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 @@ -619,7 +627,7 @@ func cleanupIPPools(c client.Client) { } } return nil - }, 30*time.Second).ShouldNot(HaveOccurred()) + }, 10*time.Second, 1*time.Second).ShouldNot(HaveOccurred()) } func cleanupResources(c client.Client) { diff --git a/test/pool_test.go b/test/pool_test.go index 3371870a7c..642e5e975d 100644 --- a/test/pool_test.go +++ b/test/pool_test.go @@ -28,12 +28,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" 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 @@ -125,7 +125,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()) @@ -140,7 +140,7 @@ var _ = Describe("IPPool FV tests", func() { Expect(ipPools.Items[0].Spec.Disabled).To(Equal(false)) Expect(ipPools.Items[0].Spec.BlockSize).To(Equal(26)) Expect(ipPools.Items[0].Spec.NodeSelector).To(Equal("all()")) - Expect(ipPools.Items[0].Spec.AssignmentMode).To(Equal(operator.AssignmentModeAutomatic)) + Expect(*ipPools.Items[0].Spec.AssignmentMode).To(Equal(v3.Automatic)) // Verify that a default IPv6 pool was created. Expect(ipPools.Items[1].Name).To(Equal("default-ipv6-ippool")) @@ -149,7 +149,7 @@ var _ = Describe("IPPool FV tests", func() { Expect(ipPools.Items[1].Spec.Disabled).To(Equal(false)) Expect(ipPools.Items[1].Spec.BlockSize).To(Equal(122)) Expect(ipPools.Items[1].Spec.NodeSelector).To(Equal("all()")) - Expect(ipPools.Items[1].Spec.AssignmentMode).To(Equal(operator.AssignmentModeAutomatic)) + Expect(*ipPools.Items[1].Spec.AssignmentMode).To(Equal(v3.Automatic)) // Expect the default pools to be marked as managed by the operator. for _, p := range ipPools.Items { @@ -175,7 +175,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()) @@ -190,27 +190,27 @@ var _ = Describe("IPPool FV tests", func() { Expect(ipPools.Items[0].Spec.BlockSize).To(Equal(26)) Expect(ipPools.Items[0].Spec.NodeSelector).To(Equal("all()")) Expect(ipPools.Items[0].Labels).To(HaveLen(1)) - Expect(ipPools.Items[0].Spec.AssignmentMode).To(Equal(operator.AssignmentModeAutomatic)) + Expect(*ipPools.Items[0].Spec.AssignmentMode).To(Equal(v3.Automatic)) }) 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, + AssignmentMode: ptr.To(v3.Automatic), }, } Expect(c.Create(context.Background(), &ipPool)).To(Succeed()) @@ -243,7 +243,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()) @@ -285,7 +285,7 @@ var _ = Describe("IPPool FV tests", func() { Expect(v3Pools.Items[0].Spec.NodeSelector).To(Equal("all()")) Expect(v3Pools.Items[0].Spec.IPIPMode).To(Equal(v3.IPIPMode(v3.IPIPModeAlways))) Expect(v3Pools.Items[0].Spec.VXLANMode).To(Equal(v3.VXLANMode(v3.VXLANModeNever))) - Expect(ipPools.Items[0].Spec.AssignmentMode).To(Equal(operator.AssignmentModeAutomatic)) + Expect(*ipPools.Items[0].Spec.AssignmentMode).To(Equal(v3.Automatic)) }) // This test verifies that the IP pool controller doesn't assume ownership of IP pools that may exist in the @@ -294,18 +294,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. @@ -343,7 +343,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()) diff --git a/test/validation_test.go b/test/validation_test.go index 21cf1b5def..9ffa4c4996 100644 --- a/test/validation_test.go +++ b/test/validation_test.go @@ -31,7 +31,7 @@ import ( var c client.Client func testSetup(t *testing.T) func() { - err := apis.AddToScheme(scheme.Scheme) + err := apis.AddToScheme(scheme.Scheme, false) require.NoError(t, err, "failed to add APIs to scheme") cfg, err := config.GetConfig()