diff --git a/Makefile b/Makefile index c6b427fcf32d..e36f2024493d 100644 --- a/Makefile +++ b/Makefile @@ -289,10 +289,6 @@ generate-manifests-core: $(CONTROLLER_GEN) $(KUSTOMIZE) ## Generate manifests e. paths=./internal/controllers/... \ paths=./internal/webhooks/... \ paths=./internal/api/addons/... \ - paths=./exp/internal/controllers/... \ - paths=./exp/internal/webhooks/... \ - paths=./exp/ipam/internal/webhooks/... \ - paths=./exp/runtime/internal/controllers/... \ crd:crdVersions=v1 \ rbac:roleName=manager-role \ output:crd:dir=./config/crd/bases \ @@ -483,7 +479,7 @@ generate-go-conversions-addons-api: $(CONVERSION_GEN) ## Generate conversions go ./api/addons/v1beta1 .PHONY: generate-go-conversions-core-ipam -generate-go-conversions-core-ipam: $(CONVERSION_GEN) ## Generate conversions go code for core exp IPAM +generate-go-conversions-core-ipam: $(CONVERSION_GEN) ## Generate conversions go code for IPAM $(MAKE) clean-generated-conversions SRC_DIRS="./api/ipam/v1beta1,./api/ipam/v1alpha1" $(CONVERSION_GEN) \ --output-file=zz_generated.conversion.go \ diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index ede44f1b35e0..57c5157e7012 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -121,10 +121,10 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-cluster-x-k8s-io-v1beta2-machineset + path: /mutate-cluster-x-k8s-io-v1beta2-machinepool failurePolicy: Fail matchPolicy: Equivalent - name: default.machineset.cluster.x-k8s.io + name: default.machinepool.cluster.x-k8s.io rules: - apiGroups: - cluster.x-k8s.io @@ -134,7 +134,7 @@ webhooks: - CREATE - UPDATE resources: - - machinesets + - machinepools sideEffects: None - admissionReviewVersions: - v1 @@ -143,20 +143,20 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-runtime-cluster-x-k8s-io-v1beta2-extensionconfig + path: /mutate-cluster-x-k8s-io-v1beta2-machineset failurePolicy: Fail matchPolicy: Equivalent - name: default.extensionconfig.runtime.addons.cluster.x-k8s.io + name: default.machineset.cluster.x-k8s.io rules: - apiGroups: - - runtime.cluster.x-k8s.io + - cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE resources: - - extensionconfigs + - machinesets sideEffects: None - admissionReviewVersions: - v1 @@ -165,20 +165,20 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-cluster-x-k8s-io-v1beta2-machinepool + path: /mutate-runtime-cluster-x-k8s-io-v1beta2-extensionconfig failurePolicy: Fail matchPolicy: Equivalent - name: default.machinepool.cluster.x-k8s.io + name: default.extensionconfig.runtime.addons.cluster.x-k8s.io rules: - apiGroups: - - cluster.x-k8s.io + - runtime.cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE resources: - - machinepools + - extensionconfigs sideEffects: None --- apiVersion: admissionregistration.k8s.io/v1 @@ -283,20 +283,21 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1beta2-machine + path: /validate-ipam-cluster-x-k8s-io-v1beta2-ipaddress failurePolicy: Fail matchPolicy: Equivalent - name: validation.machine.cluster.x-k8s.io + name: validation.ipaddress.ipam.cluster.x-k8s.io rules: - apiGroups: - - cluster.x-k8s.io + - ipam.cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE + - DELETE resources: - - machines + - ipaddresses sideEffects: None - admissionReviewVersions: - v1 @@ -305,20 +306,21 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1beta2-machinedeployment + path: /validate-ipam-cluster-x-k8s-io-v1beta2-ipaddressclaim failurePolicy: Fail matchPolicy: Equivalent - name: validation.machinedeployment.cluster.x-k8s.io + name: validation.ipaddressclaim.ipam.cluster.x-k8s.io rules: - apiGroups: - - cluster.x-k8s.io + - ipam.cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE + - DELETE resources: - - machinedeployments + - ipaddressclaims sideEffects: None - admissionReviewVersions: - v1 @@ -327,10 +329,10 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1beta2-machinedrainrule + path: /validate-cluster-x-k8s-io-v1beta2-machine failurePolicy: Fail matchPolicy: Equivalent - name: validation.machinedrainrule.cluster.x-k8s.io + name: validation.machine.cluster.x-k8s.io rules: - apiGroups: - cluster.x-k8s.io @@ -340,7 +342,7 @@ webhooks: - CREATE - UPDATE resources: - - machinedrainrules + - machines sideEffects: None - admissionReviewVersions: - v1 @@ -349,10 +351,10 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1beta2-machinehealthcheck + path: /validate-cluster-x-k8s-io-v1beta2-machinedeployment failurePolicy: Fail matchPolicy: Equivalent - name: validation.machinehealthcheck.cluster.x-k8s.io + name: validation.machinedeployment.cluster.x-k8s.io rules: - apiGroups: - cluster.x-k8s.io @@ -362,7 +364,7 @@ webhooks: - CREATE - UPDATE resources: - - machinehealthchecks + - machinedeployments sideEffects: None - admissionReviewVersions: - v1 @@ -371,10 +373,10 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1beta2-machineset + path: /validate-cluster-x-k8s-io-v1beta2-machinedrainrule failurePolicy: Fail matchPolicy: Equivalent - name: validation.machineset.cluster.x-k8s.io + name: validation.machinedrainrule.cluster.x-k8s.io rules: - apiGroups: - cluster.x-k8s.io @@ -384,7 +386,7 @@ webhooks: - CREATE - UPDATE resources: - - machinesets + - machinedrainrules sideEffects: None - admissionReviewVersions: - v1 @@ -393,20 +395,20 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-runtime-cluster-x-k8s-io-v1beta2-extensionconfig + path: /validate-cluster-x-k8s-io-v1beta2-machinehealthcheck failurePolicy: Fail matchPolicy: Equivalent - name: validation.extensionconfig.runtime.cluster.x-k8s.io + name: validation.machinehealthcheck.cluster.x-k8s.io rules: - apiGroups: - - runtime.cluster.x-k8s.io + - cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE resources: - - extensionconfigs + - machinehealthchecks sideEffects: None - admissionReviewVersions: - v1 @@ -437,21 +439,20 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-ipam-cluster-x-k8s-io-v1beta2-ipaddress + path: /validate-cluster-x-k8s-io-v1beta2-machineset failurePolicy: Fail matchPolicy: Equivalent - name: validation.ipaddress.ipam.cluster.x-k8s.io + name: validation.machineset.cluster.x-k8s.io rules: - apiGroups: - - ipam.cluster.x-k8s.io + - cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE - - DELETE resources: - - ipaddresses + - machinesets sideEffects: None - admissionReviewVersions: - v1 @@ -460,19 +461,18 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-ipam-cluster-x-k8s-io-v1beta2-ipaddressclaim + path: /validate-runtime-cluster-x-k8s-io-v1beta2-extensionconfig failurePolicy: Fail matchPolicy: Equivalent - name: validation.ipaddressclaim.ipam.cluster.x-k8s.io + name: validation.extensionconfig.runtime.cluster.x-k8s.io rules: - apiGroups: - - ipam.cluster.x-k8s.io + - runtime.cluster.x-k8s.io apiVersions: - v1beta2 operations: - CREATE - UPDATE - - DELETE resources: - - ipaddressclaims + - extensionconfigs sideEffects: None diff --git a/controllers/alias.go b/controllers/alias.go index 63895489b137..ce629e37756b 100644 --- a/controllers/alias.go +++ b/controllers/alias.go @@ -34,9 +34,11 @@ import ( clusterclasscontroller "sigs.k8s.io/cluster-api/internal/controllers/clusterclass" "sigs.k8s.io/cluster-api/internal/controllers/clusterresourceset" "sigs.k8s.io/cluster-api/internal/controllers/clusterresourcesetbinding" + extensionconfigcontroller "sigs.k8s.io/cluster-api/internal/controllers/extensionconfig" machinecontroller "sigs.k8s.io/cluster-api/internal/controllers/machine" machinedeploymentcontroller "sigs.k8s.io/cluster-api/internal/controllers/machinedeployment" machinehealthcheckcontroller "sigs.k8s.io/cluster-api/internal/controllers/machinehealthcheck" + machinepoolcontroller "sigs.k8s.io/cluster-api/internal/controllers/machinepool" machinesetcontroller "sigs.k8s.io/cluster-api/internal/controllers/machineset" clustertopologycontroller "sigs.k8s.io/cluster-api/internal/controllers/topology/cluster" machinedeploymenttopologycontroller "sigs.k8s.io/cluster-api/internal/controllers/topology/machinedeployment" @@ -279,3 +281,41 @@ func (r *ClusterResourceSetBindingReconciler) SetupWithManager(ctx context.Conte WatchFilterValue: r.WatchFilterValue, }).SetupWithManager(ctx, mgr, options) } + +// MachinePoolReconciler reconciles a MachinePool object. +type MachinePoolReconciler struct { + Client client.Client + APIReader client.Reader + ClusterCache clustercache.ClusterCache + + // WatchFilterValue is the label value used to filter events prior to reconciliation. + WatchFilterValue string +} + +func (r *MachinePoolReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error { + return (&machinepoolcontroller.Reconciler{ + Client: r.Client, + APIReader: r.APIReader, + ClusterCache: r.ClusterCache, + WatchFilterValue: r.WatchFilterValue, + }).SetupWithManager(ctx, mgr, options) +} + +// ExtensionConfigReconciler reconciles an ExtensionConfig object. +type ExtensionConfigReconciler struct { + Client client.Client + APIReader client.Reader + RuntimeClient runtimeclient.Client + + // WatchFilterValue is the label value used to filter events prior to reconciliation. + WatchFilterValue string +} + +func (r *ExtensionConfigReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options, partialSecretCache cache.Cache) error { + return (&extensionconfigcontroller.Reconciler{ + Client: r.Client, + APIReader: r.APIReader, + RuntimeClient: r.RuntimeClient, + WatchFilterValue: r.WatchFilterValue, + }).SetupWithManager(ctx, mgr, options, partialSecretCache) +} diff --git a/exp/controllers/alias.go b/exp/controllers/alias.go deleted file mode 100644 index 920ef26da2de..000000000000 --- a/exp/controllers/alias.go +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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 controllers - -import ( - "context" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - - "sigs.k8s.io/cluster-api/controllers/clustercache" - machinepool "sigs.k8s.io/cluster-api/exp/internal/controllers" -) - -// MachinePoolReconciler reconciles a MachinePool object. -type MachinePoolReconciler struct { - Client client.Client - APIReader client.Reader - ClusterCache clustercache.ClusterCache - - // WatchFilterValue is the label value used to filter events prior to reconciliation. - WatchFilterValue string -} - -func (r *MachinePoolReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error { - return (&machinepool.MachinePoolReconciler{ - Client: r.Client, - APIReader: r.APIReader, - ClusterCache: r.ClusterCache, - WatchFilterValue: r.WatchFilterValue, - }).SetupWithManager(ctx, mgr, options) -} diff --git a/exp/hack/boilerplate.go.txt b/exp/hack/boilerplate.go.txt deleted file mode 100644 index b7c650da4701..000000000000 --- a/exp/hack/boilerplate.go.txt +++ /dev/null @@ -1,16 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - diff --git a/exp/internal/controllers/doc.go b/exp/internal/controllers/doc.go deleted file mode 100644 index a58a55ea32f8..000000000000 --- a/exp/internal/controllers/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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 controllers implements experimental controllers. -package controllers diff --git a/exp/internal/webhooks/doc.go b/exp/internal/webhooks/doc.go deleted file mode 100644 index ad3cd005e864..000000000000 --- a/exp/internal/webhooks/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -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 webhooks contains external webhook implementations for some of our API types. -package webhooks diff --git a/exp/ipam/webhooks/alias.go b/exp/ipam/webhooks/alias.go deleted file mode 100644 index 092347cf72f2..000000000000 --- a/exp/ipam/webhooks/alias.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -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 webhooks - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "sigs.k8s.io/cluster-api/exp/ipam/internal/webhooks" -) - -// IPAddress implements a validating and defaulting webhook for IPAddress. -type IPAddress struct { - Client client.Reader -} - -// SetupWebhookWithManager sets up IPAddress webhooks. -func (webhook *IPAddress) SetupWebhookWithManager(mgr ctrl.Manager) error { - return (&webhooks.IPAddress{ - Client: webhook.Client, - }).SetupWebhookWithManager(mgr) -} - -// IPAddressClaim implements a validating and defaulting webhook for IPAddressClaim. -type IPAddressClaim struct { -} - -// SetupWebhookWithManager sets up IPAddressClaim webhooks. -func (webhook *IPAddressClaim) SetupWebhookWithManager(mgr ctrl.Manager) error { - return (&webhooks.IPAddressClaim{}).SetupWebhookWithManager(mgr) -} diff --git a/exp/ipam/webhooks/doc.go b/exp/ipam/webhooks/doc.go deleted file mode 100644 index ff54398db2b2..000000000000 --- a/exp/ipam/webhooks/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -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 webhooks contains external webhook implementations for some of our API types. -package webhooks diff --git a/exp/runtime/controllers/alias.go b/exp/runtime/controllers/alias.go deleted file mode 100644 index 48b1a173a3fc..000000000000 --- a/exp/runtime/controllers/alias.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -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 controllers - -import ( - "context" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - - runtimeclient "sigs.k8s.io/cluster-api/exp/runtime/client" - runtimecontrollers "sigs.k8s.io/cluster-api/exp/runtime/internal/controllers" -) - -// ExtensionConfigReconciler reconciles an ExtensionConfig object. -type ExtensionConfigReconciler struct { - Client client.Client - APIReader client.Reader - RuntimeClient runtimeclient.Client - - // WatchFilterValue is the label value used to filter events prior to reconciliation. - WatchFilterValue string -} - -func (r *ExtensionConfigReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options, partialSecretCache cache.Cache) error { - return (&runtimecontrollers.Reconciler{ - Client: r.Client, - APIReader: r.APIReader, - RuntimeClient: r.RuntimeClient, - WatchFilterValue: r.WatchFilterValue, - }).SetupWithManager(ctx, mgr, options, partialSecretCache) -} diff --git a/exp/runtime/controllers/doc.go b/exp/runtime/controllers/doc.go deleted file mode 100644 index bc5c76004d27..000000000000 --- a/exp/runtime/controllers/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -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 controllers implements the exp/runtime controllers. -package controllers diff --git a/exp/runtime/internal/controllers/doc.go b/exp/runtime/internal/controllers/doc.go deleted file mode 100644 index bc5c76004d27..000000000000 --- a/exp/runtime/internal/controllers/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -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 controllers implements the exp/runtime controllers. -package controllers diff --git a/exp/util/suite_test.go b/exp/util/suite_test.go deleted file mode 100644 index 0cdb28e7f389..000000000000 --- a/exp/util/suite_test.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -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 util - -import ( - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - - clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" -) - -var ( - ctx = ctrl.SetupSignalHandler() - fakeScheme = runtime.NewScheme() -) - -func init() { - _ = clusterv1.AddToScheme(fakeScheme) -} diff --git a/exp/util/util.go b/exp/util/util.go deleted file mode 100644 index 5235cb3c630a..000000000000 --- a/exp/util/util.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 util implements utility functions. -package util - -import ( - "context" - - "github.com/pkg/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/klog/v2" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" - "sigs.k8s.io/cluster-api/util/labels/format" -) - -// GetOwnerMachinePool returns the MachinePool objects owning the current resource. -func GetOwnerMachinePool(ctx context.Context, c client.Client, obj metav1.ObjectMeta) (*clusterv1.MachinePool, error) { - for _, ref := range obj.GetOwnerReferences() { - if ref.Kind != "MachinePool" { - continue - } - gv, err := schema.ParseGroupVersion(ref.APIVersion) - if err != nil { - return nil, errors.WithStack(err) - } - if gv.Group == clusterv1.GroupVersion.Group { - return GetMachinePoolByName(ctx, c, obj.Namespace, ref.Name) - } - } - return nil, nil -} - -// GetMachinePoolByName finds and returns a MachinePool object using the specified params. -func GetMachinePoolByName(ctx context.Context, c client.Client, namespace, name string) (*clusterv1.MachinePool, error) { - m := &clusterv1.MachinePool{} - key := client.ObjectKey{Name: name, Namespace: namespace} - if err := c.Get(ctx, key, m); err != nil { - return nil, err - } - return m, nil -} - -// GetMachinePoolByLabels finds and returns a MachinePool object using the value of clusterv1.MachinePoolNameLabel. -// This differs from GetMachinePoolByName as the label value can be a hash. -func GetMachinePoolByLabels(ctx context.Context, c client.Client, namespace string, labels map[string]string) (*clusterv1.MachinePool, error) { - selector := map[string]string{} - if clusterName, ok := labels[clusterv1.ClusterNameLabel]; ok { - selector = map[string]string{clusterv1.ClusterNameLabel: clusterName} - } - - if poolNameHash, ok := labels[clusterv1.MachinePoolNameLabel]; ok { - machinePoolList := &clusterv1.MachinePoolList{} - if err := c.List(ctx, machinePoolList, client.InNamespace(namespace), client.MatchingLabels(selector)); err != nil { - return nil, errors.Wrapf(err, "failed to list MachinePools using labels %v", selector) - } - - for _, mp := range machinePoolList.Items { - if format.MustFormatValue(mp.Name) == poolNameHash { - return &mp, nil - } - } - } else { - return nil, errors.Errorf("labels missing required key `%s`", clusterv1.MachinePoolNameLabel) - } - - return nil, nil -} - -// MachinePoolToInfrastructureMapFunc returns a handler.MapFunc that watches for -// MachinePool events and returns reconciliation requests for an infrastructure provider object. -func MachinePoolToInfrastructureMapFunc(ctx context.Context, gvk schema.GroupVersionKind) handler.MapFunc { - log := ctrl.LoggerFrom(ctx) - return func(_ context.Context, o client.Object) []reconcile.Request { - m, ok := o.(*clusterv1.MachinePool) - if !ok { - log.V(4).Info("Not a machine pool", "Object", klog.KObj(o)) - return nil - } - log := log.WithValues("MachinePool", klog.KObj(o)) - - gk := gvk.GroupKind() - ref := m.Spec.Template.Spec.InfrastructureRef - // Return early if the GroupKind doesn't match what we expect. - infraGK := ref.GroupKind() - if gk != infraGK { - log.V(4).Info("Infra kind doesn't match filter group kind", "infrastructureGroupKind", infraGK.String()) - return nil - } - - log.V(4).Info("Projecting object") - return []reconcile.Request{ - { - NamespacedName: client.ObjectKey{ - Namespace: m.Namespace, - Name: ref.Name, - }, - }, - } - } -} diff --git a/exp/util/util_test.go b/exp/util/util_test.go deleted file mode 100644 index ff2a546d21ee..000000000000 --- a/exp/util/util_test.go +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -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 util implements utility functions. -package util - -import ( - "fmt" - "testing" - - . "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" - "sigs.k8s.io/cluster-api/util/labels/format" -) - -func TestGetMachinePoolByLabels(t *testing.T) { - g := NewWithT(t) - - longMachinePoolName := "this-is-a-very-long-machinepool-name-that-will-turned-into-a-hash-because-it-is-longer-than-63-characters" - namespace := "default" - - testcases := []struct { - name string - labels map[string]string - machinePools []client.Object - expectedMachinePoolName string - expectedError string - }{ - { - name: "returns a MachinePool with matching labels", - labels: map[string]string{ - clusterv1.MachinePoolNameLabel: "test-pool", - }, - machinePools: []client.Object{ - &clusterv1.MachinePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pool", - Namespace: "default", - }, - }, - &clusterv1.MachinePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: "other-pool", - Namespace: "default", - }, - }, - }, - expectedMachinePoolName: "test-pool", - }, - { - name: "returns a MachinePool with matching labels and cluster name is included", - labels: map[string]string{ - clusterv1.MachinePoolNameLabel: "test-pool", - clusterv1.ClusterNameLabel: "test-cluster", - }, - machinePools: []client.Object{ - &clusterv1.MachinePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pool", - Namespace: "default", - Labels: map[string]string{ - clusterv1.ClusterNameLabel: "test-cluster", - }, - }, - }, - &clusterv1.MachinePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: "other-pool", - Namespace: "default", - Labels: map[string]string{ - clusterv1.ClusterNameLabel: "test-cluster", - }, - }, - }, - }, - expectedMachinePoolName: "test-pool", - }, - { - name: "returns a MachinePool where label is a hash", - labels: map[string]string{ - clusterv1.MachinePoolNameLabel: format.MustFormatValue(longMachinePoolName), - }, - machinePools: []client.Object{ - &clusterv1.MachinePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: longMachinePoolName, - Namespace: "default", - }, - }, - &clusterv1.MachinePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: "other-pool", - Namespace: "default", - }, - }, - }, - expectedMachinePoolName: longMachinePoolName, - }, - { - name: "missing required key", - labels: map[string]string{}, - expectedError: fmt.Sprintf("labels missing required key `%s`", clusterv1.MachinePoolNameLabel), - }, - { - name: "returns nil when no machine pool matches", - labels: map[string]string{ - clusterv1.MachinePoolNameLabel: "test-pool", - }, - machinePools: []client.Object{}, - expectedMachinePoolName: "", - }, - } - - for _, tc := range testcases { - t.Run(tc.name, func(*testing.T) { - clientFake := fake.NewClientBuilder(). - WithScheme(fakeScheme). - WithObjects( - tc.machinePools..., - ).Build() - - mp, err := GetMachinePoolByLabels(ctx, clientFake, namespace, tc.labels) - if tc.expectedError != "" { - g.Expect(err).To(MatchError(tc.expectedError)) - } else { - g.Expect(err).NotTo(HaveOccurred()) - if tc.expectedMachinePoolName != "" { - g.Expect(mp).ToNot(BeNil()) - g.Expect(mp.Name).To(Equal(tc.expectedMachinePoolName)) - } else { - g.Expect(mp).To(BeNil()) - } - } - }) - } -} diff --git a/exp/webhooks/alias.go b/exp/webhooks/alias.go deleted file mode 100644 index 21deef6e7651..000000000000 --- a/exp/webhooks/alias.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -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 webhooks - -import ( - ctrl "sigs.k8s.io/controller-runtime" - - "sigs.k8s.io/cluster-api/exp/internal/webhooks" -) - -// MachinePool implements a validating and defaulting webhook for MachinePool. -type MachinePool struct{} - -// SetupWebhookWithManager sets up MachinePool webhooks. -func (webhook *MachinePool) SetupWebhookWithManager(mgr ctrl.Manager) error { - return (&webhooks.MachinePool{}).SetupWebhookWithManager(mgr) -} diff --git a/exp/webhooks/doc.go b/exp/webhooks/doc.go deleted file mode 100644 index ad3cd005e864..000000000000 --- a/exp/webhooks/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -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 webhooks contains external webhook implementations for some of our API types. -package webhooks diff --git a/exp/ipam/internal/webhooks/doc.go b/internal/controllers/extensionconfig/doc.go similarity index 85% rename from exp/ipam/internal/webhooks/doc.go rename to internal/controllers/extensionconfig/doc.go index fded86ca9afc..60b134aba949 100644 --- a/exp/ipam/internal/webhooks/doc.go +++ b/internal/controllers/extensionconfig/doc.go @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package webhooks implements experimental webhooks. -package webhooks +// Package extensionconfig implements the ExtensionConfig controller. +package extensionconfig diff --git a/exp/runtime/internal/controllers/extensionconfig_controller.go b/internal/controllers/extensionconfig/extensionconfig_controller.go similarity index 99% rename from exp/runtime/internal/controllers/extensionconfig_controller.go rename to internal/controllers/extensionconfig/extensionconfig_controller.go index d85730c41c7a..f5c79a6d6ac2 100644 --- a/exp/runtime/internal/controllers/extensionconfig_controller.go +++ b/internal/controllers/extensionconfig/extensionconfig_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "context" diff --git a/exp/runtime/internal/controllers/extensionconfig_controller_test.go b/internal/controllers/extensionconfig/extensionconfig_controller_test.go similarity index 99% rename from exp/runtime/internal/controllers/extensionconfig_controller_test.go rename to internal/controllers/extensionconfig/extensionconfig_controller_test.go index 49bfba2b8a3d..742922772e46 100644 --- a/exp/runtime/internal/controllers/extensionconfig_controller_test.go +++ b/internal/controllers/extensionconfig/extensionconfig_controller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "context" diff --git a/exp/runtime/internal/controllers/index.go b/internal/controllers/extensionconfig/index.go similarity index 98% rename from exp/runtime/internal/controllers/index.go rename to internal/controllers/extensionconfig/index.go index 34598daeb79a..b4e48f4a8d6a 100644 --- a/exp/runtime/internal/controllers/index.go +++ b/internal/controllers/extensionconfig/index.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "context" diff --git a/exp/runtime/internal/controllers/index_test.go b/internal/controllers/extensionconfig/index_test.go similarity index 98% rename from exp/runtime/internal/controllers/index_test.go rename to internal/controllers/extensionconfig/index_test.go index 6fcbf2c55e85..ab58e9c566bf 100644 --- a/exp/runtime/internal/controllers/index_test.go +++ b/internal/controllers/extensionconfig/index_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "testing" diff --git a/exp/runtime/internal/controllers/suite_test.go b/internal/controllers/extensionconfig/suite_test.go similarity index 98% rename from exp/runtime/internal/controllers/suite_test.go rename to internal/controllers/extensionconfig/suite_test.go index 60cee94f1b5c..617fbf886310 100644 --- a/exp/runtime/internal/controllers/suite_test.go +++ b/internal/controllers/extensionconfig/suite_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "context" diff --git a/exp/runtime/internal/controllers/warmup.go b/internal/controllers/extensionconfig/warmup.go similarity index 99% rename from exp/runtime/internal/controllers/warmup.go rename to internal/controllers/extensionconfig/warmup.go index a7d090e13511..a6d5c7fb82b9 100644 --- a/exp/runtime/internal/controllers/warmup.go +++ b/internal/controllers/extensionconfig/warmup.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "context" diff --git a/exp/runtime/internal/controllers/warmup_test.go b/internal/controllers/extensionconfig/warmup_test.go similarity index 99% rename from exp/runtime/internal/controllers/warmup_test.go rename to internal/controllers/extensionconfig/warmup_test.go index 94a76d0f1e98..b6676f384325 100644 --- a/exp/runtime/internal/controllers/warmup_test.go +++ b/internal/controllers/extensionconfig/warmup_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package extensionconfig import ( "fmt" diff --git a/exp/controllers/doc.go b/internal/controllers/machinepool/doc.go similarity index 87% rename from exp/controllers/doc.go rename to internal/controllers/machinepool/doc.go index a58a55ea32f8..f69e347c6ead 100644 --- a/exp/controllers/doc.go +++ b/internal/controllers/machinepool/doc.go @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package controllers implements experimental controllers. -package controllers +// Package machinepool implements the MachinePool controller. +package machinepool diff --git a/exp/internal/controllers/machinepool_controller.go b/internal/controllers/machinepool/machinepool_controller.go similarity index 92% rename from exp/internal/controllers/machinepool_controller.go rename to internal/controllers/machinepool/machinepool_controller.go index cc72d985782a..c499fd8a3ef7 100644 --- a/exp/internal/controllers/machinepool_controller.go +++ b/internal/controllers/machinepool/machinepool_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "context" @@ -71,8 +71,8 @@ const ( MachinePoolControllerName = "machinepool-controller" ) -// MachinePoolReconciler reconciles a MachinePool object. -type MachinePoolReconciler struct { +// Reconciler reconciles a MachinePool object. +type Reconciler struct { Client client.Client APIReader client.Reader ClusterCache clustercache.ClusterCache @@ -88,7 +88,7 @@ type MachinePoolReconciler struct { predicateLog *logr.Logger } -func (r *MachinePoolReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error { +func (r *Reconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error { if r.Client == nil || r.APIReader == nil || r.ClusterCache == nil { return errors.New("Client, APIReader and ClusterCache must not be nil") } @@ -134,7 +134,7 @@ func (r *MachinePoolReconciler) SetupWithManager(ctx context.Context, mgr ctrl.M return nil } -func (r *MachinePoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Result, reterr error) { +func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Result, reterr error) { log := ctrl.LoggerFrom(ctx) mp := &clusterv1.MachinePool{} @@ -241,7 +241,7 @@ func (r *MachinePoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) return doReconcile(ctx, scope, reconcileNormal) } -func (r *MachinePoolReconciler) reconcileSetOwnerAndLabels(_ context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) reconcileSetOwnerAndLabels(_ context.Context, s *scope) (ctrl.Result, error) { cluster := s.cluster mp := s.machinePool @@ -261,7 +261,7 @@ func (r *MachinePoolReconciler) reconcileSetOwnerAndLabels(_ context.Context, s } // reconcileDelete delete machinePool related resources. -func (r *MachinePoolReconciler) reconcileDelete(ctx context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) reconcileDelete(ctx context.Context, s *scope) (ctrl.Result, error) { if ok, err := r.reconcileDeleteExternal(ctx, s.machinePool); !ok || err != nil { // Return early and don't remove the finalizer if we got an error or // the external reconciliation deletion isn't ready. @@ -283,7 +283,7 @@ func (r *MachinePoolReconciler) reconcileDelete(ctx context.Context, s *scope) ( } // reconcileDeleteNodes delete the cluster nodes. -func (r *MachinePoolReconciler) reconcileDeleteNodes(ctx context.Context, cluster *clusterv1.Cluster, machinePool *clusterv1.MachinePool) error { +func (r *Reconciler) reconcileDeleteNodes(ctx context.Context, cluster *clusterv1.Cluster, machinePool *clusterv1.MachinePool) error { if len(machinePool.Status.NodeRefs) == 0 { return nil } @@ -297,7 +297,7 @@ func (r *MachinePoolReconciler) reconcileDeleteNodes(ctx context.Context, cluste } // isMachinePoolDeleteTimeoutPassed check the machinePool node delete time out. -func (r *MachinePoolReconciler) isMachinePoolNodeDeleteTimeoutPassed(machinePool *clusterv1.MachinePool) bool { +func (r *Reconciler) isMachinePoolNodeDeleteTimeoutPassed(machinePool *clusterv1.MachinePool) bool { if !machinePool.DeletionTimestamp.IsZero() && machinePool.Spec.Template.Spec.Deletion.NodeDeletionTimeoutSeconds != nil { if *machinePool.Spec.Template.Spec.Deletion.NodeDeletionTimeoutSeconds != 0 { deleteTimePlusDuration := machinePool.DeletionTimestamp.Add(time.Duration(*machinePool.Spec.Template.Spec.Deletion.NodeDeletionTimeoutSeconds) * time.Second) @@ -308,7 +308,7 @@ func (r *MachinePoolReconciler) isMachinePoolNodeDeleteTimeoutPassed(machinePool } // reconcileDeleteExternal tries to delete external references, returning true if it cannot find any. -func (r *MachinePoolReconciler) reconcileDeleteExternal(ctx context.Context, machinePool *clusterv1.MachinePool) (bool, error) { +func (r *Reconciler) reconcileDeleteExternal(ctx context.Context, machinePool *clusterv1.MachinePool) (bool, error) { objects := []*unstructured.Unstructured{} references := []clusterv1.ContractVersionedObjectReference{ machinePool.Spec.Template.Spec.Bootstrap.ConfigRef, @@ -344,7 +344,7 @@ func (r *MachinePoolReconciler) reconcileDeleteExternal(ctx context.Context, mac return len(objects) == 0, nil } -func (r *MachinePoolReconciler) watchClusterNodes(ctx context.Context, cluster *clusterv1.Cluster) error { +func (r *Reconciler) watchClusterNodes(ctx context.Context, cluster *clusterv1.Cluster) error { log := ctrl.LoggerFrom(ctx) if !conditions.IsTrue(cluster, clusterv1.ClusterControlPlaneInitializedCondition) { @@ -361,7 +361,7 @@ func (r *MachinePoolReconciler) watchClusterNodes(ctx context.Context, cluster * })) } -func (r *MachinePoolReconciler) nodeToMachinePool(ctx context.Context, o client.Object) []reconcile.Request { +func (r *Reconciler) nodeToMachinePool(ctx context.Context, o client.Object) []reconcile.Request { node, ok := o.(*corev1.Node) if !ok { panic(fmt.Sprintf("Expected a Node but got a %T", o)) @@ -415,7 +415,7 @@ func (r *MachinePoolReconciler) nodeToMachinePool(ctx context.Context, o client. return nil } -func (r *MachinePoolReconciler) getMachinesForMachinePool(ctx context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) getMachinesForMachinePool(ctx context.Context, s *scope) (ctrl.Result, error) { infraMachineSelector := metav1.LabelSelector{ MatchLabels: map[string]string{ clusterv1.MachinePoolNameLabel: format.MustFormatValue(s.machinePool.Name), @@ -445,7 +445,7 @@ func (r *MachinePoolReconciler) getMachinesForMachinePool(ctx context.Context, s return ctrl.Result{}, nil } -func (r *MachinePoolReconciler) setMachinesUptoDate(ctx context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) setMachinesUptoDate(ctx context.Context, s *scope) (ctrl.Result, error) { var errs []error for _, machine := range s.machines { patchHelper, err := patch.NewHelper(machine, r.Client) diff --git a/exp/internal/controllers/machinepool_controller_noderef.go b/internal/controllers/machinepool/machinepool_controller_noderef.go similarity index 93% rename from exp/internal/controllers/machinepool_controller_noderef.go rename to internal/controllers/machinepool/machinepool_controller_noderef.go index a5264c5327dd..cd992155cfbf 100644 --- a/exp/internal/controllers/machinepool_controller_noderef.go +++ b/internal/controllers/machinepool/machinepool_controller_noderef.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "context" @@ -47,7 +47,7 @@ type getNodeReferencesResult struct { ready int } -func (r *MachinePoolReconciler) reconcileNodeRefs(ctx context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) reconcileNodeRefs(ctx context.Context, s *scope) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) cluster := s.cluster mp := s.machinePool @@ -139,7 +139,7 @@ func (r *MachinePoolReconciler) reconcileNodeRefs(ctx context.Context, s *scope) // deleteRetiredNodes deletes nodes that don't have a corresponding ProviderID in Spec.ProviderIDList. // A MachinePool infrastructure provider indicates an instance in the set has been deleted by // removing its ProviderID from the slice. -func (r *MachinePoolReconciler) deleteRetiredNodes(ctx context.Context, c client.Client, nodeRefs []corev1.ObjectReference, providerIDList []string) error { +func (r *Reconciler) deleteRetiredNodes(ctx context.Context, c client.Client, nodeRefs []corev1.ObjectReference, providerIDList []string) error { log := ctrl.LoggerFrom(ctx, "providerIDList", len(providerIDList)) nodeRefsMap := make(map[string]*corev1.Node, len(nodeRefs)) for _, nodeRef := range nodeRefs { @@ -171,7 +171,7 @@ func (r *MachinePoolReconciler) deleteRetiredNodes(ctx context.Context, c client return nil } -func (r *MachinePoolReconciler) getNodeReferences(ctx context.Context, providerIDList []string, minReadySeconds int32, nodeRefsMap map[string]*corev1.Node) (getNodeReferencesResult, error) { +func (r *Reconciler) getNodeReferences(ctx context.Context, providerIDList []string, minReadySeconds int32, nodeRefsMap map[string]*corev1.Node) (getNodeReferencesResult, error) { log := ctrl.LoggerFrom(ctx, "providerIDList", len(providerIDList)) var ready, available int @@ -205,7 +205,7 @@ func (r *MachinePoolReconciler) getNodeReferences(ctx context.Context, providerI } // patchNodes patches the nodes with the cluster name and cluster namespace annotations. -func (r *MachinePoolReconciler) patchNodes(ctx context.Context, c client.Client, references []corev1.ObjectReference, mp *clusterv1.MachinePool) error { +func (r *Reconciler) patchNodes(ctx context.Context, c client.Client, references []corev1.ObjectReference, mp *clusterv1.MachinePool) error { log := ctrl.LoggerFrom(ctx) for _, nodeRef := range references { node := &corev1.Node{} diff --git a/exp/internal/controllers/machinepool_controller_noderef_test.go b/internal/controllers/machinepool/machinepool_controller_noderef_test.go similarity index 99% rename from exp/internal/controllers/machinepool_controller_noderef_test.go rename to internal/controllers/machinepool/machinepool_controller_noderef_test.go index 7065b80865ad..9a04d43efb60 100644 --- a/exp/internal/controllers/machinepool_controller_noderef_test.go +++ b/internal/controllers/machinepool/machinepool_controller_noderef_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "testing" @@ -30,7 +30,7 @@ import ( ) func TestMachinePoolGetNodeReference(t *testing.T) { - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fake.NewClientBuilder().Build(), recorder: record.NewFakeRecorder(32), } @@ -305,7 +305,7 @@ func TestMachinePoolGetNodeReference(t *testing.T) { } func TestMachinePoolPatchNodes(t *testing.T) { - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fake.NewClientBuilder().Build(), recorder: record.NewFakeRecorder(32), } diff --git a/exp/internal/controllers/machinepool_controller_phases.go b/internal/controllers/machinepool/machinepool_controller_phases.go similarity index 94% rename from exp/internal/controllers/machinepool_controller_phases.go rename to internal/controllers/machinepool/machinepool_controller_phases.go index 5af6a19275f9..d311c0444169 100644 --- a/exp/internal/controllers/machinepool_controller_phases.go +++ b/internal/controllers/machinepool/machinepool_controller_phases.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "context" @@ -39,7 +39,6 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" "sigs.k8s.io/cluster-api/controllers/external" capierrors "sigs.k8s.io/cluster-api/errors" - utilexp "sigs.k8s.io/cluster-api/exp/util" "sigs.k8s.io/cluster-api/internal/contract" "sigs.k8s.io/cluster-api/internal/util/ssa" "sigs.k8s.io/cluster-api/util" @@ -51,7 +50,7 @@ import ( "sigs.k8s.io/cluster-api/util/predicates" ) -func (r *MachinePoolReconciler) reconcilePhase(mp *clusterv1.MachinePool) { +func (r *Reconciler) reconcilePhase(mp *clusterv1.MachinePool) { // Set the phase to "pending" if nil. if mp.Status.Phase == "" { mp.Status.SetTypedPhase(clusterv1.MachinePoolPhasePending) @@ -106,7 +105,7 @@ func (r *MachinePoolReconciler) reconcilePhase(mp *clusterv1.MachinePool) { } // reconcileExternal handles generic unstructured objects referenced by a MachinePool. -func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, m *clusterv1.MachinePool, ref clusterv1.ContractVersionedObjectReference) (external.ReconcileOutput, error) { +func (r *Reconciler) reconcileExternal(ctx context.Context, m *clusterv1.MachinePool, ref clusterv1.ContractVersionedObjectReference) (external.ReconcileOutput, error) { log := ctrl.LoggerFrom(ctx) obj, err := external.GetObjectFromContractVersionedRef(ctx, r.Client, ref, m.Namespace) @@ -179,7 +178,7 @@ func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, m *cluste } // reconcileBootstrap reconciles the Spec.Bootstrap.ConfigRef object on a MachinePool. -func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) reconcileBootstrap(ctx context.Context, s *scope) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) m := s.machinePool // Call generic external reconciler if we have an external reference. @@ -249,7 +248,7 @@ func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, s *scope } // reconcileInfrastructure reconciles the Spec.InfrastructureRef object on a MachinePool. -func (r *MachinePoolReconciler) reconcileInfrastructure(ctx context.Context, s *scope) (ctrl.Result, error) { +func (r *Reconciler) reconcileInfrastructure(ctx context.Context, s *scope) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) cluster := s.cluster mp := s.machinePool @@ -357,7 +356,7 @@ func (r *MachinePoolReconciler) reconcileInfrastructure(ctx context.Context, s * // infrastructure is created accordingly. // Note: When supported by the cloud provider implementation of the MachinePool, machines will provide a means to interact // with the corresponding infrastructure (e.g. delete a specific machine in case MachineHealthCheck detects it is unhealthy). -func (r *MachinePoolReconciler) reconcileMachines(ctx context.Context, s *scope, infraMachinePool *unstructured.Unstructured) error { +func (r *Reconciler) reconcileMachines(ctx context.Context, s *scope, infraMachinePool *unstructured.Unstructured) error { log := ctrl.LoggerFrom(ctx) mp := s.machinePool @@ -414,7 +413,7 @@ func (r *MachinePoolReconciler) reconcileMachines(ctx context.Context, s *scope, } // createOrUpdateMachines creates a MachinePool Machine for each infraMachine if it doesn't already exist and sets the owner reference and infraRef. -func (r *MachinePoolReconciler) createOrUpdateMachines(ctx context.Context, s *scope, machines []clusterv1.Machine, infraMachines []unstructured.Unstructured) error { +func (r *Reconciler) createOrUpdateMachines(ctx context.Context, s *scope, machines []clusterv1.Machine, infraMachines []unstructured.Unstructured) error { log := ctrl.LoggerFrom(ctx) // Construct a set of names of infraMachines that already have a Machine. @@ -473,7 +472,7 @@ func (r *MachinePoolReconciler) createOrUpdateMachines(ctx context.Context, s *s // computeDesiredMachine constructs the desired Machine for an infraMachine. // If the Machine exists, it ensures the Machine always owned by the MachinePool. -func (r *MachinePoolReconciler) computeDesiredMachine(mp *clusterv1.MachinePool, infraMachine *unstructured.Unstructured, existingMachine *clusterv1.Machine, existingNode *corev1.Node) *clusterv1.Machine { +func (r *Reconciler) computeDesiredMachine(mp *clusterv1.MachinePool, infraMachine *unstructured.Unstructured, existingMachine *clusterv1.Machine, existingNode *corev1.Node) *clusterv1.Machine { infraRef := clusterv1.ContractVersionedObjectReference{ APIGroup: infraMachine.GroupVersionKind().Group, Kind: infraMachine.GetKind(), @@ -531,11 +530,11 @@ func (r *MachinePoolReconciler) computeDesiredMachine(mp *clusterv1.MachinePool, // infraMachineToMachinePoolMapper is a mapper function that maps an InfraMachine to the MachinePool that owns it. // This is used to trigger an update of the MachinePool when a InfraMachine is changed. -func (r *MachinePoolReconciler) infraMachineToMachinePoolMapper(ctx context.Context, o client.Object) []ctrl.Request { +func (r *Reconciler) infraMachineToMachinePoolMapper(ctx context.Context, o client.Object) []ctrl.Request { log := ctrl.LoggerFrom(ctx) if labels.IsMachinePoolOwned(o) { - machinePool, err := utilexp.GetMachinePoolByLabels(ctx, r.Client, o.GetNamespace(), o.GetLabels()) + machinePool, err := util.GetMachinePoolByLabels(ctx, r.Client, o.GetNamespace(), o.GetLabels()) if err != nil { log.Error(err, "Failed to get MachinePool for InfraMachine", o.GetObjectKind().GroupVersionKind().Kind, klog.KObj(o), "labels", o.GetLabels()) return nil @@ -555,7 +554,7 @@ func (r *MachinePoolReconciler) infraMachineToMachinePoolMapper(ctx context.Cont return nil } -func (r *MachinePoolReconciler) waitForMachineCreation(ctx context.Context, machineList []clusterv1.Machine) error { +func (r *Reconciler) waitForMachineCreation(ctx context.Context, machineList []clusterv1.Machine) error { _ = ctrl.LoggerFrom(ctx) // waitForCacheUpdateTimeout is the amount of time allowed to wait for desired state. @@ -587,7 +586,7 @@ func (r *MachinePoolReconciler) waitForMachineCreation(ctx context.Context, mach return nil } -func (r *MachinePoolReconciler) getNodeRefMap(ctx context.Context, c client.Client) (map[string]*corev1.Node, error) { +func (r *Reconciler) getNodeRefMap(ctx context.Context, c client.Client) (map[string]*corev1.Node, error) { log := ctrl.LoggerFrom(ctx) nodeRefsMap := make(map[string]*corev1.Node) nodeList := corev1.NodeList{} diff --git a/exp/internal/controllers/machinepool_controller_phases_test.go b/internal/controllers/machinepool/machinepool_controller_phases_test.go similarity index 98% rename from exp/internal/controllers/machinepool_controller_phases_test.go rename to internal/controllers/machinepool/machinepool_controller_phases_test.go index 8b89cd313611..6b618eef7ede 100644 --- a/exp/internal/controllers/machinepool_controller_phases_test.go +++ b/internal/controllers/machinepool/machinepool_controller_phases_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "fmt" @@ -129,7 +129,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { infraConfig := defaultInfra.DeepCopy() fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -172,7 +172,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -212,7 +212,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -268,7 +268,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinepool.Status.NodeRefs = []corev1.ObjectReference{{Kind: "Node", Name: "machinepool-test-node"}} fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -340,7 +340,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinepool.Status.NodeRefs = []corev1.ObjectReference{{Kind: "Node", Name: "machinepool-test-node"}} fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -390,7 +390,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinepool.Status.NodeRefs = []corev1.ObjectReference{{Kind: "Node", Name: "machinepool-test-node"}} fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -443,7 +443,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinepool.Status.NodeRefs = []corev1.ObjectReference{{Kind: "Node", Name: "machinepool-test-node"}} fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -513,7 +513,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { } fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -589,7 +589,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinepool.Finalizers = []string{clusterv1.MachinePoolFinalizer} fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -663,7 +663,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinePool.Status.Replicas = ptr.To(int32(1)) fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinePool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -759,7 +759,7 @@ func TestReconcileMachinePoolPhases(t *testing.T) { machinePool.Status.Replicas = ptr.To(int32(1)) fakeClient := fake.NewClientBuilder().WithObjects(defaultCluster, defaultKubeconfigSecret, machinePool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -1099,7 +1099,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { bootstrapConfig := &unstructured.Unstructured{Object: tc.bootstrapConfig} fakeClient := fake.NewClientBuilder().WithObjects(tc.machinepool, bootstrapConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, externalTracker: external.ObjectTracker{ Controller: externalfake.Controller{}, @@ -1307,7 +1307,7 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { infraConfig := &unstructured.Unstructured{Object: tc.infraConfig} fakeClient := fake.NewClientBuilder().WithObjects(tc.machinepool, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: defaultCluster.Name, Namespace: defaultCluster.Namespace}), externalTracker: external.ObjectTracker{ @@ -1399,7 +1399,7 @@ func TestReconcileMachinePoolMachines(t *testing.T) { } g.Expect(env.CreateAndWait(ctx, &unstructured.Unstructured{Object: infraConfig})).To(Succeed()) - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: env, ssaCache: ssa.NewCache(testController), externalTracker: external.ObjectTracker{ @@ -1468,7 +1468,7 @@ func TestReconcileMachinePoolMachines(t *testing.T) { } g.Expect(env.CreateAndWait(ctx, &unstructured.Unstructured{Object: infraConfig})).To(Succeed()) - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: env, ssaCache: ssa.NewCache(testController), externalTracker: external.ObjectTracker{ @@ -1533,7 +1533,7 @@ func TestReconcileMachinePoolMachines(t *testing.T) { } g.Expect(env.CreateAndWait(ctx, &unstructured.Unstructured{Object: infraConfig})).To(Succeed()) - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: env, ssaCache: ssa.NewCache(testController), } @@ -1694,7 +1694,7 @@ func TestInfraMachineToMachinePoolMapper(t *testing.T) { objs = append(objs, mp.DeepCopy()) } - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fake.NewClientBuilder().WithObjects(objs...).Build(), } @@ -1839,7 +1839,7 @@ func TestReconcileMachinePoolScaleToFromZero(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) fakeClient := fake.NewClientBuilder().WithObjects(testCluster, kubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(env.GetClient(), client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), recorder: record.NewFakeRecorder(32), @@ -1907,7 +1907,7 @@ func TestReconcileMachinePoolScaleToFromZero(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) fakeClient := fake.NewClientBuilder().WithObjects(testCluster, kubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(env.GetClient(), client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), recorder: record.NewFakeRecorder(32), @@ -1958,7 +1958,7 @@ func TestReconcileMachinePoolScaleToFromZero(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) fakeClient := fake.NewClientBuilder().WithObjects(testCluster, kubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, recorder: record.NewFakeRecorder(32), ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), @@ -2005,7 +2005,7 @@ func TestReconcileMachinePoolScaleToFromZero(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) fakeClient := fake.NewClientBuilder().WithObjects(testCluster, kubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, recorder: record.NewFakeRecorder(32), ClusterCache: clustercache.NewFakeClusterCache(fakeClient, client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), @@ -2074,7 +2074,7 @@ func TestReconcileMachinePoolScaleToFromZero(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) fakeClient := fake.NewClientBuilder().WithObjects(testCluster, kubeconfigSecret, machinepool, bootstrapConfig, infraConfig, builder.TestBootstrapConfigCRD, builder.TestInfrastructureMachineTemplateCRD).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fakeClient, ClusterCache: clustercache.NewFakeClusterCache(env.GetClient(), client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), recorder: record.NewFakeRecorder(32), @@ -2304,7 +2304,7 @@ func TestMachinePoolReconciler_getNodeRefMap(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { g := NewWithT(t) - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fake.NewClientBuilder().Build(), recorder: record.NewFakeRecorder(32), } @@ -2326,7 +2326,7 @@ func TestMachinePoolReconciler_getNodeRefMap(t *testing.T) { } } -func reconcileNormalFuncsForTest(mpr *MachinePoolReconciler) []machinePoolReconcileFunc { +func reconcileNormalFuncsForTest(mpr *Reconciler) []machinePoolReconcileFunc { return []machinePoolReconcileFunc{ mpr.reconcileSetOwnerAndLabels, mpr.reconcileBootstrap, diff --git a/exp/internal/controllers/machinepool_controller_scope.go b/internal/controllers/machinepool/machinepool_controller_scope.go similarity index 99% rename from exp/internal/controllers/machinepool_controller_scope.go rename to internal/controllers/machinepool/machinepool_controller_scope.go index 1bb60bb4759f..026bb393bae2 100644 --- a/exp/internal/controllers/machinepool_controller_scope.go +++ b/internal/controllers/machinepool/machinepool_controller_scope.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "errors" diff --git a/exp/internal/controllers/machinepool_controller_status.go b/internal/controllers/machinepool/machinepool_controller_status.go similarity index 95% rename from exp/internal/controllers/machinepool_controller_status.go rename to internal/controllers/machinepool/machinepool_controller_status.go index 6f5df81ad9c8..24d23c15272c 100644 --- a/exp/internal/controllers/machinepool_controller_status.go +++ b/internal/controllers/machinepool/machinepool_controller_status.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "context" @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/cluster-api/util/conditions" ) -func (r *MachinePoolReconciler) updateStatus(ctx context.Context, s *scope) error { +func (r *Reconciler) updateStatus(ctx context.Context, s *scope) error { log := ctrl.LoggerFrom(ctx) if s.infraMachinePool == nil { diff --git a/exp/internal/controllers/machinepool_controller_test.go b/internal/controllers/machinepool/machinepool_controller_test.go similarity index 99% rename from exp/internal/controllers/machinepool_controller_test.go rename to internal/controllers/machinepool/machinepool_controller_test.go index b4bd2741a0ce..8d4bb8ad15e9 100644 --- a/exp/internal/controllers/machinepool_controller_test.go +++ b/internal/controllers/machinepool/machinepool_controller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "context" @@ -123,7 +123,7 @@ func TestMachinePoolFinalizer(t *testing.T) { t.Run(tc.name, func(t *testing.T) { g := NewWithT(t) - mr := &MachinePoolReconciler{ + mr := &Reconciler{ Client: fake.NewClientBuilder().WithObjects( clusterCorrectMeta, machinePoolValidCluster, @@ -257,7 +257,7 @@ func TestMachinePoolOwnerReference(t *testing.T) { machinePoolValidCluster, machinePoolValidMachinePool, ).WithStatusSubresource(&clusterv1.MachinePool{}).Build() - mr := &MachinePoolReconciler{ + mr := &Reconciler{ Client: fakeClient, APIReader: fakeClient, } @@ -607,7 +607,7 @@ func TestReconcileMachinePoolRequest(t *testing.T) { }, }).WithObjects(trackerObjects...).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: clientFake, APIReader: clientFake, ClusterCache: clustercache.NewFakeClusterCache(trackerClientFake, client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), @@ -732,7 +732,7 @@ func TestMachinePoolNodeDeleteTimeoutPassed(t *testing.T) { t.Run(tc.name, func(t *testing.T) { g := NewWithT(t) - timeoutPassed := (&MachinePoolReconciler{}).isMachinePoolNodeDeleteTimeoutPassed(tc.machinePool) + timeoutPassed := (&Reconciler{}).isMachinePoolNodeDeleteTimeoutPassed(tc.machinePool) g.Expect(timeoutPassed).To(Equal(tc.want)) }) } @@ -842,7 +842,7 @@ func TestReconcileMachinePoolDeleteExternal(t *testing.T) { objs = append(objs, infraConfig) } - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: fake.NewClientBuilder().WithObjects(objs...).Build(), } @@ -897,7 +897,7 @@ func TestRemoveMachinePoolFinalizerAfterDeleteReconcile(t *testing.T) { } key := client.ObjectKey{Namespace: m.Namespace, Name: m.Name} clientFake := fake.NewClientBuilder().WithObjects(testCluster, m, builder.TestInfrastructureMachinePoolCRD).WithStatusSubresource(&clusterv1.MachinePool{}).Build() - mr := &MachinePoolReconciler{ + mr := &Reconciler{ Client: clientFake, ClusterCache: clustercache.NewFakeClusterCache(clientFake, client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), } @@ -1185,7 +1185,7 @@ func TestMachinePoolConditions(t *testing.T) { builder.TestInfrastructureMachinePoolCRD, ).WithStatusSubresource(&clusterv1.MachinePool{}).Build() - r := &MachinePoolReconciler{ + r := &Reconciler{ Client: clientFake, APIReader: clientFake, ClusterCache: clustercache.NewFakeClusterCache(clientFake, client.ObjectKey{Name: testCluster.Name, Namespace: testCluster.Namespace}), diff --git a/exp/internal/controllers/suite_test.go b/internal/controllers/machinepool/suite_test.go similarity index 98% rename from exp/internal/controllers/suite_test.go rename to internal/controllers/machinepool/suite_test.go index 70c597ecaf7b..23fe04bebad5 100644 --- a/exp/internal/controllers/suite_test.go +++ b/internal/controllers/machinepool/suite_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package machinepool import ( "context" @@ -74,7 +74,7 @@ func TestMain(m *testing.M) { clusterCache.(interface{ Shutdown() }).Shutdown() }() - if err := (&MachinePoolReconciler{ + if err := (&Reconciler{ Client: mgr.GetClient(), APIReader: mgr.GetAPIReader(), ClusterCache: clusterCache, diff --git a/internal/test/envtest/environment.go b/internal/test/envtest/environment.go index 90148275d8cc..568cd7549e64 100644 --- a/internal/test/envtest/environment.go +++ b/internal/test/envtest/environment.go @@ -68,8 +68,6 @@ import ( bootstrapwebhooks "sigs.k8s.io/cluster-api/bootstrap/kubeadm/webhooks" "sigs.k8s.io/cluster-api/cmd/clusterctl/log" controlplanewebhooks "sigs.k8s.io/cluster-api/controlplane/kubeadm/webhooks" - expipamwebhooks "sigs.k8s.io/cluster-api/exp/ipam/webhooks" - expapiwebhooks "sigs.k8s.io/cluster-api/exp/webhooks" "sigs.k8s.io/cluster-api/feature" internalwebhooks "sigs.k8s.io/cluster-api/internal/webhooks" "sigs.k8s.io/cluster-api/util/kubeconfig" @@ -386,16 +384,16 @@ func newEnvironment(scheme *runtime.Scheme, additionalCRDDirectoryPaths []string if err := (&webhooks.ClusterResourceSetBinding{}).SetupWebhookWithManager(mgr); err != nil { klog.Fatalf("unable to create webhook for ClusterResourceSetBinding: %+v", err) } - if err := (&expapiwebhooks.MachinePool{}).SetupWebhookWithManager(mgr); err != nil { + if err := (&webhooks.MachinePool{}).SetupWebhookWithManager(mgr); err != nil { klog.Fatalf("unable to create webhook for machinepool: %+v", err) } if err := (&webhooks.ExtensionConfig{}).SetupWebhookWithManager(mgr); err != nil { klog.Fatalf("unable to create webhook for extensionconfig: %+v", err) } - if err := (&expipamwebhooks.IPAddress{}).SetupWebhookWithManager(mgr); err != nil { + if err := (&webhooks.IPAddress{}).SetupWebhookWithManager(mgr); err != nil { klog.Fatalf("unable to create webhook for ipaddress: %v", err) } - if err := (&expipamwebhooks.IPAddressClaim{}).SetupWebhookWithManager(mgr); err != nil { + if err := (&webhooks.IPAddressClaim{}).SetupWebhookWithManager(mgr); err != nil { klog.Fatalf("unable to create webhook for ipaddressclaim: %v", err) } diff --git a/exp/ipam/internal/webhooks/ipaddress.go b/internal/webhooks/ipaddress.go similarity index 100% rename from exp/ipam/internal/webhooks/ipaddress.go rename to internal/webhooks/ipaddress.go diff --git a/exp/ipam/internal/webhooks/ipaddress_test.go b/internal/webhooks/ipaddress_test.go similarity index 100% rename from exp/ipam/internal/webhooks/ipaddress_test.go rename to internal/webhooks/ipaddress_test.go diff --git a/exp/ipam/internal/webhooks/ipaddressclaim.go b/internal/webhooks/ipaddressclaim.go similarity index 100% rename from exp/ipam/internal/webhooks/ipaddressclaim.go rename to internal/webhooks/ipaddressclaim.go diff --git a/exp/ipam/internal/webhooks/ipaddressclaim_test.go b/internal/webhooks/ipaddressclaim_test.go similarity index 100% rename from exp/ipam/internal/webhooks/ipaddressclaim_test.go rename to internal/webhooks/ipaddressclaim_test.go diff --git a/exp/internal/webhooks/machinepool.go b/internal/webhooks/machinepool.go similarity index 99% rename from exp/internal/webhooks/machinepool.go rename to internal/webhooks/machinepool.go index 9b440eeca5fd..0336db1e9dfb 100644 --- a/exp/internal/webhooks/machinepool.go +++ b/internal/webhooks/machinepool.go @@ -37,8 +37,6 @@ import ( "sigs.k8s.io/cluster-api/util/version" ) -const defaultNodeDeletionTimeoutSeconds = int32(10) - func (webhook *MachinePool) SetupWebhookWithManager(mgr ctrl.Manager) error { if webhook.decoder == nil { webhook.decoder = admission.NewDecoder(mgr.GetScheme()) diff --git a/exp/internal/webhooks/machinepool_test.go b/internal/webhooks/machinepool_test.go similarity index 99% rename from exp/internal/webhooks/machinepool_test.go rename to internal/webhooks/machinepool_test.go index 365c3131a2d7..1c8e576f8d7c 100644 --- a/exp/internal/webhooks/machinepool_test.go +++ b/internal/webhooks/machinepool_test.go @@ -24,15 +24,12 @@ import ( . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" "sigs.k8s.io/cluster-api/internal/webhooks/util" ) -var ctx = ctrl.SetupSignalHandler() - func TestMachinePoolDefault(t *testing.T) { g := NewWithT(t) diff --git a/main.go b/main.go index b09815fa29af..f1d831201c1a 100644 --- a/main.go +++ b/main.go @@ -69,12 +69,8 @@ import ( "sigs.k8s.io/cluster-api/controllers/clustercache" "sigs.k8s.io/cluster-api/controllers/crdmigrator" "sigs.k8s.io/cluster-api/controllers/remote" - expcontrollers "sigs.k8s.io/cluster-api/exp/controllers" - expipamwebhooks "sigs.k8s.io/cluster-api/exp/ipam/webhooks" runtimecatalog "sigs.k8s.io/cluster-api/exp/runtime/catalog" runtimeclient "sigs.k8s.io/cluster-api/exp/runtime/client" - runtimecontrollers "sigs.k8s.io/cluster-api/exp/runtime/controllers" - expwebhooks "sigs.k8s.io/cluster-api/exp/webhooks" "sigs.k8s.io/cluster-api/feature" addonsv1alpha3 "sigs.k8s.io/cluster-api/internal/api/addons/v1alpha3" addonsv1alpha4 "sigs.k8s.io/cluster-api/internal/api/addons/v1alpha4" @@ -622,7 +618,7 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager, watchNamespaces map } if feature.Gates.Enabled(feature.RuntimeSDK) { - if err = (&runtimecontrollers.ExtensionConfigReconciler{ + if err = (&controllers.ExtensionConfigReconciler{ Client: mgr.GetClient(), APIReader: mgr.GetAPIReader(), RuntimeClient: runtimeClient, @@ -721,7 +717,7 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager, watchNamespaces map } if feature.Gates.Enabled(feature.MachinePool) { - if err := (&expcontrollers.MachinePoolReconciler{ + if err := (&controllers.MachinePoolReconciler{ Client: mgr.GetClient(), APIReader: mgr.GetAPIReader(), ClusterCache: clusterCache, @@ -807,7 +803,7 @@ func setupWebhooks(ctx context.Context, mgr ctrl.Manager, clusterCacheReader web // NOTE: MachinePool is behind MachinePool feature gate flag; the webhook // is going to prevent creating or updating new objects in case the feature flag is disabled - if err := (&expwebhooks.MachinePool{}).SetupWebhookWithManager(mgr); err != nil { + if err := (&webhooks.MachinePool{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "Unable to create webhook", "webhook", "MachinePool") os.Exit(1) } @@ -837,14 +833,14 @@ func setupWebhooks(ctx context.Context, mgr ctrl.Manager, clusterCacheReader web os.Exit(1) } - if err := (&expipamwebhooks.IPAddress{ + if err := (&webhooks.IPAddress{ // We are using GetAPIReader here to avoid caching all IPAddressClaims Client: mgr.GetAPIReader(), }).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "Unable to create webhook", "webhook", "IPAddress") os.Exit(1) } - if err := (&expipamwebhooks.IPAddressClaim{}).SetupWebhookWithManager(mgr); err != nil { + if err := (&webhooks.IPAddressClaim{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "Unable to create webhook", "webhook", "IPAddressClaim") os.Exit(1) } diff --git a/test/infrastructure/docker/exp/internal/controllers/dockermachinepool_controller.go b/test/infrastructure/docker/exp/internal/controllers/dockermachinepool_controller.go index f84e0b7ec1ab..735e7e0a5011 100644 --- a/test/infrastructure/docker/exp/internal/controllers/dockermachinepool_controller.go +++ b/test/infrastructure/docker/exp/internal/controllers/dockermachinepool_controller.go @@ -39,7 +39,6 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" "sigs.k8s.io/cluster-api/controllers/external" - utilexp "sigs.k8s.io/cluster-api/exp/util" "sigs.k8s.io/cluster-api/internal/util/ssa" "sigs.k8s.io/cluster-api/test/infrastructure/container" infrav1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta2" @@ -91,7 +90,7 @@ func (r *DockerMachinePoolReconciler) Reconcile(ctx context.Context, req ctrl.Re } // Fetch the MachinePool. - machinePool, err := utilexp.GetOwnerMachinePool(ctx, r.Client, dockerMachinePool.ObjectMeta) + machinePool, err := util.GetOwnerMachinePool(ctx, r.Client, dockerMachinePool.ObjectMeta) if err != nil { return ctrl.Result{}, err } @@ -170,7 +169,7 @@ func (r *DockerMachinePoolReconciler) SetupWithManager(ctx context.Context, mgr WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(mgr.GetScheme(), predicateLog, r.WatchFilterValue)). Watches( &clusterv1.MachinePool{}, - handler.EnqueueRequestsFromMapFunc(utilexp.MachinePoolToInfrastructureMapFunc(ctx, + handler.EnqueueRequestsFromMapFunc(util.MachinePoolToInfrastructureMapFunc(ctx, infraexpv1.GroupVersion.WithKind("DockerMachinePool"))), builder.WithPredicates(predicates.ResourceIsChanged(mgr.GetScheme(), predicateLog)), ). diff --git a/test/infrastructure/docker/internal/controllers/backends/docker/dockermachine_backend.go b/test/infrastructure/docker/internal/controllers/backends/docker/dockermachine_backend.go index df08570e0105..adb6624546ce 100644 --- a/test/infrastructure/docker/internal/controllers/backends/docker/dockermachine_backend.go +++ b/test/infrastructure/docker/internal/controllers/backends/docker/dockermachine_backend.go @@ -36,7 +36,6 @@ import ( bootstrapv1 "sigs.k8s.io/cluster-api/api/bootstrap/kubeadm/v1beta2" clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" "sigs.k8s.io/cluster-api/controllers/clustercache" - utilexp "sigs.k8s.io/cluster-api/exp/util" "sigs.k8s.io/cluster-api/test/infrastructure/container" infrav1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta2" "sigs.k8s.io/cluster-api/test/infrastructure/docker/internal/docker" @@ -85,7 +84,7 @@ func (r *MachineBackendReconciler) ReconcileNormal(ctx context.Context, cluster var version string if labels.IsMachinePoolOwned(dockerMachine) { - machinePool, err := utilexp.GetMachinePoolByLabels(ctx, r.Client, dockerMachine.GetNamespace(), dockerMachine.Labels) + machinePool, err := util.GetMachinePoolByLabels(ctx, r.Client, dockerMachine.GetNamespace(), dockerMachine.Labels) if err != nil { return ctrl.Result{}, errors.Wrapf(err, "failed to get machine pool for DockerMachine %s/%s", dockerMachine.GetNamespace(), dockerMachine.GetName()) } diff --git a/util/util.go b/util/util.go index 684ef3d07b8c..6da588595b72 100644 --- a/util/util.go +++ b/util/util.go @@ -37,6 +37,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/klog/v2" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -751,3 +752,89 @@ func MergeMap(maps ...map[string]string) map[string]string { } return m } + +// GetOwnerMachinePool returns the MachinePool objects owning the current resource. +func GetOwnerMachinePool(ctx context.Context, c client.Client, obj metav1.ObjectMeta) (*clusterv1.MachinePool, error) { + for _, ref := range obj.GetOwnerReferences() { + if ref.Kind != "MachinePool" { + continue + } + gv, err := schema.ParseGroupVersion(ref.APIVersion) + if err != nil { + return nil, errors.WithStack(err) + } + if gv.Group == clusterv1.GroupVersion.Group { + return GetMachinePoolByName(ctx, c, obj.Namespace, ref.Name) + } + } + return nil, nil +} + +// GetMachinePoolByName finds and returns a MachinePool object using the specified params. +func GetMachinePoolByName(ctx context.Context, c client.Client, namespace, name string) (*clusterv1.MachinePool, error) { + m := &clusterv1.MachinePool{} + key := client.ObjectKey{Name: name, Namespace: namespace} + if err := c.Get(ctx, key, m); err != nil { + return nil, err + } + return m, nil +} + +// GetMachinePoolByLabels finds and returns a MachinePool object using the value of clusterv1.MachinePoolNameLabel. +// This differs from GetMachinePoolByName as the label value can be a hash. +func GetMachinePoolByLabels(ctx context.Context, c client.Client, namespace string, labels map[string]string) (*clusterv1.MachinePool, error) { + selector := map[string]string{} + if clusterName, ok := labels[clusterv1.ClusterNameLabel]; ok { + selector = map[string]string{clusterv1.ClusterNameLabel: clusterName} + } + + if poolNameHash, ok := labels[clusterv1.MachinePoolNameLabel]; ok { + machinePoolList := &clusterv1.MachinePoolList{} + if err := c.List(ctx, machinePoolList, client.InNamespace(namespace), client.MatchingLabels(selector)); err != nil { + return nil, errors.Wrapf(err, "failed to list MachinePools using labels %v", selector) + } + + for _, mp := range machinePoolList.Items { + if format.MustFormatValue(mp.Name) == poolNameHash { + return &mp, nil + } + } + } else { + return nil, errors.Errorf("labels missing required key `%s`", clusterv1.MachinePoolNameLabel) + } + + return nil, nil +} + +// MachinePoolToInfrastructureMapFunc returns a handler.MapFunc that watches for +// MachinePool events and returns reconciliation requests for an infrastructure provider object. +func MachinePoolToInfrastructureMapFunc(ctx context.Context, gvk schema.GroupVersionKind) handler.MapFunc { + log := ctrl.LoggerFrom(ctx) + return func(_ context.Context, o client.Object) []reconcile.Request { + m, ok := o.(*clusterv1.MachinePool) + if !ok { + log.V(4).Info("Not a machine pool", "Object", klog.KObj(o)) + return nil + } + log := log.WithValues("MachinePool", klog.KObj(o)) + + gk := gvk.GroupKind() + ref := m.Spec.Template.Spec.InfrastructureRef + // Return early if the GroupKind doesn't match what we expect. + infraGK := ref.GroupKind() + if gk != infraGK { + log.V(4).Info("Infra kind doesn't match filter group kind", "infrastructureGroupKind", infraGK.String()) + return nil + } + + log.V(4).Info("Projecting object") + return []reconcile.Request{ + { + NamespacedName: client.ObjectKey{ + Namespace: m.Namespace, + Name: ref.Name, + }, + }, + } + } +} diff --git a/util/util_test.go b/util/util_test.go index d90e0db47438..68470131fd6e 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -1059,3 +1059,127 @@ func TestUnstructuredUnmarshalField(t *testing.T) { }) } } + +func TestGetMachinePoolByLabels(t *testing.T) { + g := NewWithT(t) + + longMachinePoolName := "this-is-a-very-long-machinepool-name-that-will-turned-into-a-hash-because-it-is-longer-than-63-characters" + namespace := "default" + + testcases := []struct { + name string + labels map[string]string + machinePools []client.Object + expectedMachinePoolName string + expectedError string + }{ + { + name: "returns a MachinePool with matching labels", + labels: map[string]string{ + clusterv1.MachinePoolNameLabel: "test-pool", + }, + machinePools: []client.Object{ + &clusterv1.MachinePool{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pool", + Namespace: "default", + }, + }, + &clusterv1.MachinePool{ + ObjectMeta: metav1.ObjectMeta{ + Name: "other-pool", + Namespace: "default", + }, + }, + }, + expectedMachinePoolName: "test-pool", + }, + { + name: "returns a MachinePool with matching labels and cluster name is included", + labels: map[string]string{ + clusterv1.MachinePoolNameLabel: "test-pool", + clusterv1.ClusterNameLabel: "test-cluster", + }, + machinePools: []client.Object{ + &clusterv1.MachinePool{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pool", + Namespace: "default", + Labels: map[string]string{ + clusterv1.ClusterNameLabel: "test-cluster", + }, + }, + }, + &clusterv1.MachinePool{ + ObjectMeta: metav1.ObjectMeta{ + Name: "other-pool", + Namespace: "default", + Labels: map[string]string{ + clusterv1.ClusterNameLabel: "test-cluster", + }, + }, + }, + }, + expectedMachinePoolName: "test-pool", + }, + { + name: "returns a MachinePool where label is a hash", + labels: map[string]string{ + clusterv1.MachinePoolNameLabel: format.MustFormatValue(longMachinePoolName), + }, + machinePools: []client.Object{ + &clusterv1.MachinePool{ + ObjectMeta: metav1.ObjectMeta{ + Name: longMachinePoolName, + Namespace: "default", + }, + }, + &clusterv1.MachinePool{ + ObjectMeta: metav1.ObjectMeta{ + Name: "other-pool", + Namespace: "default", + }, + }, + }, + expectedMachinePoolName: longMachinePoolName, + }, + { + name: "missing required key", + labels: map[string]string{}, + expectedError: fmt.Sprintf("labels missing required key `%s`", clusterv1.MachinePoolNameLabel), + }, + { + name: "returns nil when no machine pool matches", + labels: map[string]string{ + clusterv1.MachinePoolNameLabel: "test-pool", + }, + machinePools: []client.Object{}, + expectedMachinePoolName: "", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(*testing.T) { + fakeScheme := runtime.NewScheme() + _ = clusterv1.AddToScheme(fakeScheme) + clientFake := fake.NewClientBuilder(). + WithScheme(fakeScheme). + WithObjects( + tc.machinePools..., + ).Build() + + mp, err := GetMachinePoolByLabels(ctx, clientFake, namespace, tc.labels) + if tc.expectedError != "" { + g.Expect(err).To(MatchError(tc.expectedError)) + } else { + g.Expect(err).NotTo(HaveOccurred()) + if tc.expectedMachinePoolName != "" { + g.Expect(mp).ToNot(BeNil()) + g.Expect(mp.Name).To(Equal(tc.expectedMachinePoolName)) + } else { + g.Expect(mp).To(BeNil()) + } + } + }) + } +} diff --git a/webhooks/alias.go b/webhooks/alias.go index a52055a0c2e2..5c6567fe0fde 100644 --- a/webhooks/alias.go +++ b/webhooks/alias.go @@ -134,3 +134,32 @@ type ExtensionConfig struct{} func (webhook *ExtensionConfig) SetupWebhookWithManager(mgr ctrl.Manager) error { return (&runtimewebhooks.ExtensionConfig{}).SetupWebhookWithManager(mgr) } + +// MachinePool implements a validating and defaulting webhook for MachinePool. +type MachinePool struct{} + +// SetupWebhookWithManager sets up MachinePool webhooks. +func (webhook *MachinePool) SetupWebhookWithManager(mgr ctrl.Manager) error { + return (&webhooks.MachinePool{}).SetupWebhookWithManager(mgr) +} + +// IPAddress implements a validating and defaulting webhook for IPAddress. +type IPAddress struct { + Client client.Reader +} + +// SetupWebhookWithManager sets up IPAddress webhooks. +func (webhook *IPAddress) SetupWebhookWithManager(mgr ctrl.Manager) error { + return (&webhooks.IPAddress{ + Client: webhook.Client, + }).SetupWebhookWithManager(mgr) +} + +// IPAddressClaim implements a validating and defaulting webhook for IPAddressClaim. +type IPAddressClaim struct { +} + +// SetupWebhookWithManager sets up IPAddressClaim webhooks. +func (webhook *IPAddressClaim) SetupWebhookWithManager(mgr ctrl.Manager) error { + return (&webhooks.IPAddressClaim{}).SetupWebhookWithManager(mgr) +}