diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/.gitignore b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e660fd93d3196215552065b1e63bf6a2f393ed86 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/.gitignore @@ -0,0 +1 @@ +bin/ diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d9c503ed916d5e1367cf05c6c0a1a4a561078f6b --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile @@ -0,0 +1,34 @@ +GO111MODULE = on +export GO111MODULE +GOFLAGS ?= -mod=vendor +export GOFLAGS +GOPROXY ?= +export GOPROXY + +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +ENVTEST_K8S_VERSION = 1.28 + +PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) +ENVTEST = go run ${PROJECT_DIR}/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest +GOLANGCI_LINT = go run ${PROJECT_DIR}/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint + +.PHONY: all +all: lint unit + +.PHONY: vendor +vendor: ## Update vendor directory + go mod tidy + go mod vendor + go mod verify + +.PHONY: lint +lint: ## Go lint your code + ( GOLANGCI_LINT_CACHE=$(PROJECT_DIR)/.cache $(GOLANGCI_LINT) run --config ../.golangci.yaml --timeout 10m ) + +.PHONY: unit +unit: ## Run unit tests + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path --bin-dir $(PROJECT_DIR)/bin)" ./hack/test.sh + +.PHONY: help +help: + @grep -E '^[a-zA-Z/0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/cleanup.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/cleanup.go new file mode 100644 index 0000000000000000000000000000000000000000..cb1b317177c1c80aa13b11b5cad87a3a30bcbf32 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/cleanup.go @@ -0,0 +1,150 @@ +/* +Copyright 2022 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutils + +import ( + "context" + "fmt" + + "github.com/onsi/gomega" + + corev1resourcebuilder "github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1" + corev1 "k8s.io/api/core/v1" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + coreclient "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" +) + +// CleanupResources will clean up resources of the types of objects given in a particular namespace if given. +// The namespace will then be removed once it has been emptied. +// This utility is intended to be used in AfterEach blocks to clean up from a specific test. +// It calls various gomega assertions so will fail a test if there are any errors. +func CleanupResources(g gomega.Gomega, ctx context.Context, cfg *rest.Config, k8sClient client.Client, namespace string, objs ...client.Object) { + for _, obj := range objs { + cleanupResource(g, ctx, k8sClient, namespace, obj) + } + + if namespace != "" { + removeNamespace(g, ctx, cfg, k8sClient, namespace) + } +} + +// cleanupResource removes all of a particular resource within a namespace. +func cleanupResource(g gomega.Gomega, ctx context.Context, k8sClient client.Client, namespace string, obj client.Object) { + removeFinalizersFromAll(g, ctx, k8sClient, namespace, obj) + + g.Eventually(func() (client.ObjectList, error) { + if err := k8sClient.DeleteAllOf(ctx, obj, client.InNamespace(namespace)); err != nil { + return nil, fmt.Errorf("error deleting resource list: %w", err) + } + + listObj := newListFromObject(g, k8sClient, obj) + + return komega.ObjectList(listObj, client.InNamespace(namespace))() + }).Should(gomega.HaveField("Items", gomega.HaveLen(0))) +} + +// removeFinalizersFromAll removes any finalizers from all of the objects of the given object kind, +// in the namespace provided. +func removeFinalizersFromAll(g gomega.Gomega, ctx context.Context, k8sClient client.Client, namespace string, obj client.Object) { + listObj := newListFromObject(g, k8sClient, obj) + + g.Expect(k8sClient.List(ctx, listObj, client.InNamespace(namespace))).Should(gomega.Succeed()) + + listItems, err := apimeta.ExtractList(listObj) + g.Expect(err).ToNot(gomega.HaveOccurred()) + + for _, item := range listItems { + o, ok := item.(client.Object) + g.Expect(ok).To(gomega.BeTrue()) + + removeFinalizers(g, o) + } +} + +// removeFinalizers removes all finalizers from the object given. +// Finalizers must be removed one by one else the API server will reject the update. +func removeFinalizers(g gomega.Gomega, obj client.Object) { + filter := func(finalizers []string, toRemove string) []string { + out := []string{} + + for _, f := range finalizers { + if f != toRemove { + out = append(out, f) + } + } + + return out + } + + for _, finalizer := range obj.GetFinalizers() { + g.Eventually(komega.Update(obj, func() { + obj.SetFinalizers(filter(obj.GetFinalizers(), finalizer)) + })).Should(gomega.Succeed()) + } +} + +// newListFromObject converts an individual object type into a list object type to allow the +// the list to be checked for emptiness. +func newListFromObject(g gomega.Gomega, k8sClient client.Client, obj client.Object) client.ObjectList { + objGVKs, _, err := k8sClient.Scheme().ObjectKinds(obj) + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(objGVKs).To(gomega.HaveLen(1)) + + listGVK := objGVKs[0] + listGVK.Kind = fmt.Sprintf("%sList", listGVK.Kind) + + newObj, err := k8sClient.Scheme().New(listGVK) + g.Expect(err).ToNot(gomega.HaveOccurred()) + + listObj, ok := newObj.(client.ObjectList) + g.Expect(ok).To(gomega.BeTrue()) + + return listObj +} + +// removeNamespace handles the namespace finalization act that is normally performed by the garbage collector +// once it is happy that the namespace has no objects left within it. +func removeNamespace(g gomega.Gomega, ctx context.Context, cfg *rest.Config, k8sClient client.Client, namespace string) { + coreClient, err := coreclient.NewForConfig(cfg) + g.Expect(err).ToNot(gomega.HaveOccurred()) + + nsBuilder := corev1resourcebuilder.Namespace().WithName(namespace) + + // Delete the namespace + ns := nsBuilder.Build() + g.Expect(k8sClient.Delete(ctx, ns)).To(gomega.Succeed()) + + // Remove the finalizer + g.Eventually(func() error { + if err := komega.Get(ns)(); err != nil { + return fmt.Errorf("could not get namespace: %w", err) + } + ns.Spec.Finalizers = []corev1.FinalizerName{} + + _, err := coreClient.Namespaces().Finalize(ctx, ns, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("could not finalize namespace: %w", err) + } + + return nil + }).Should(gomega.Succeed()) +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/conditions.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/conditions.go new file mode 100644 index 0000000000000000000000000000000000000000..728b02cd8fb1d33d50cb179fe83aea8d0c57d5d0 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/conditions.go @@ -0,0 +1,232 @@ +/* +Copyright 2022 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutils + +import ( + "errors" + "fmt" + "strings" + + "github.com/onsi/gomega" + "github.com/onsi/gomega/types" + + configv1 "github.com/openshift/api/config/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// errActualTypeMismatchCondition is used when the type of the actual object does not match the expected type of Condition. +var errActualTypeMismatchCondition = errors.New("actual should be of type Condition") + +// MatchConditions returns a custom matcher to check equality of a slice of metav1.Condtion. +func MatchConditions(expected []metav1.Condition) types.GomegaMatcher { + return &matchConditions{ + expected: expected, + } +} + +type matchConditions struct { + expected []metav1.Condition +} + +// Match checks for equality between the actual and expected objects. +func (m matchConditions) Match(actual interface{}) (success bool, err error) { + elems := []interface{}{} + for _, condition := range m.expected { + elems = append(elems, MatchCondition(condition)) + } + + ok, err := gomega.ConsistOf(elems).Match(actual) + if !ok { + return false, wrap(err, "conditions did not match") + } + + return true, nil +} + +// FailureMessage is the message returned to the test when the actual and expected +// objects do not match. +func (m matchConditions) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto match\n\t%#v\n", actual, m.expected) +} + +// NegatedFailureMessage is the negated version of the FailureMessage. +func (m matchConditions) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto not match\n\t%#v\n", actual, m.expected) +} + +// MatchCondition returns a custom matcher to check equality of metav1.Condition. +func MatchCondition(expected metav1.Condition) types.GomegaMatcher { + return &matchCondition{ + expected: expected, + } +} + +type matchCondition struct { + expected metav1.Condition +} + +// Match checks for equality between the actual and expected objects. +// +//nolint:dupl +func (m matchCondition) Match(actual interface{}) (success bool, err error) { + actualCondition, ok := actual.(metav1.Condition) + if !ok { + return false, errActualTypeMismatchCondition + } + + ok, err = gomega.Equal(m.expected.Type).Match(actualCondition.Type) + if !ok { + return false, wrap(err, "condition type does not match") + } + + ok, err = gomega.Equal(m.expected.Status).Match(actualCondition.Status) + if !ok { + return false, wrap(err, "condition status does not match") + } + + ok, err = gomega.Equal(m.expected.Reason).Match(actualCondition.Reason) + if !ok { + return false, wrap(err, "condition reason does not match") + } + + ok, err = gomega.Equal(m.expected.Message).Match(actualCondition.Message) + if !ok { + return false, wrap(err, "condition message does not match") + } + + return true, nil +} + +// FailureMessage is the message returned to the test when the actual and expected +// objects do not match. +func (m matchCondition) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto match\n\t%#v\n", actual, m.expected) +} + +// NegatedFailureMessage is the negated version of the FailureMessage. +func (m matchCondition) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto not match\n\t%#v\n", actual, m.expected) +} + +// errActualTypeMismatchClusterOperatorStatusCondition is used when the type of the actual object does not match +// the expected type of ClusterOperatorStatusCondition. +var errActualTypeMismatchClusterOperatorStatusCondition = errors.New("actual should be of type ClusterOperatorStatusCondition") + +// MatchClusterOperatorStatusConditions returns a custom matcher to check equality of configv1.ClusterOperatorStatusConditions. +func MatchClusterOperatorStatusConditions(expected []configv1.ClusterOperatorStatusCondition) types.GomegaMatcher { + return &matchClusterOperatorConditions{ + expected: expected, + } +} + +type matchClusterOperatorConditions struct { + expected []configv1.ClusterOperatorStatusCondition +} + +// Match checks for equality between the actual and expected objects. +func (m matchClusterOperatorConditions) Match(actual interface{}) (success bool, err error) { + elems := []interface{}{} + for _, condition := range m.expected { + elems = append(elems, MatchClusterOperatorStatusCondition(condition)) + } + + ok, err := gomega.ConsistOf(elems).Match(actual) + if !ok { + return false, wrap(err, "conditions did not match") + } + + return true, nil +} + +// FailureMessage is the message returned to the test when the actual and expected +// objects do not match. +func (m matchClusterOperatorConditions) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto match\n\t%#v\n", actual, m.expected) +} + +// NegatedFailureMessage is the negated version of the FailureMessage. +func (m matchClusterOperatorConditions) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto not match\n\t%#v\n", actual, m.expected) +} + +// MatchClusterOperatorStatusCondition returns a custom matcher to check equality of configv1.ClusterOperatorStatusCondition. +func MatchClusterOperatorStatusCondition(expected configv1.ClusterOperatorStatusCondition) types.GomegaMatcher { + return &matchClusterOperatorCondition{ + expected: expected, + } +} + +type matchClusterOperatorCondition struct { + expected configv1.ClusterOperatorStatusCondition +} + +// Match checks for equality between the actual and expected objects. +// +//nolint:dupl +func (m matchClusterOperatorCondition) Match(actual interface{}) (success bool, err error) { + actualCondition, ok := actual.(configv1.ClusterOperatorStatusCondition) + if !ok { + return false, errActualTypeMismatchClusterOperatorStatusCondition + } + + ok, err = gomega.Equal(m.expected.Type).Match(actualCondition.Type) + if !ok { + return false, wrap(err, "condition type does not match") + } + + ok, err = gomega.Equal(m.expected.Status).Match(actualCondition.Status) + if !ok { + return false, wrap(err, "condition status does not match") + } + + ok, err = gomega.Equal(m.expected.Reason).Match(actualCondition.Reason) + if !ok { + return false, wrap(err, "condition reason does not match") + } + + ok, err = gomega.Equal(m.expected.Message).Match(actualCondition.Message) + if !ok { + return false, wrap(err, "condition message does not match") + } + + return true, nil +} + +// FailureMessage is the message returned to the test when the actual and expected +// objects do not match. +func (m matchClusterOperatorCondition) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto match\n\t%#v\n", actual, m.expected) +} + +// NegatedFailureMessage is the negated version of the FailureMessage. +func (m matchClusterOperatorCondition) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("expected\n\t%#v\nto not match\n\t%#v\n", actual, m.expected) +} + +// wrap wraps an error with the given message if the error isn't nil. +func wrap(err error, msg string) error { + if err == nil { + return nil + } + + if !strings.HasSuffix(msg, "%w") { + msg = fmt.Sprintf("%s: %%w", msg) + } + + // We are expecting the passed messages to wrap the error, so skip linting. + return fmt.Errorf(msg, err) //nolint:goerr113 +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/logger.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/logger.go new file mode 100644 index 0000000000000000000000000000000000000000..ea36f78319ebf97a925dfdb20384084648beaf81 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/logger.go @@ -0,0 +1,116 @@ +/* +Copyright 2022 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutils + +import ( + "github.com/go-logr/logr" +) + +// LogEntry captures the information about a particular log line. +type LogEntry struct { + // Error is the error passed to an error log line. + Error error + + // KeysAndValues are the keys and values that were logged with + // the log line. + KeysAndValues []interface{} + + // Level is the level of the info log line. + Level int + + // Messages is the message from the log line. + Message string +} + +// TestLogger provides a logr.Logger and access to a list of log +// entries logged via the logger. +type TestLogger interface { + Entries() []LogEntry + Logger() logr.Logger +} + +// NewTestLogger constructs a new TestLogger. +func NewTestLogger() TestLogger { + l := &testLogger{ + entries: &[]LogEntry{}, + } + l.logger = logr.New(l) + + return l +} + +// testLogger is an implementation of the TestLogger interface. +type testLogger struct { + entries *[]LogEntry + keysAndValues []interface{} + logger logr.Logger + runtimeInfo logr.RuntimeInfo +} + +// Logger provides the TestLoggers logr.Logger. +func (t *testLogger) Logger() logr.Logger { + return t.logger +} + +// Entries returns the previously logged log entries. +func (t *testLogger) Entries() []LogEntry { + return *t.entries +} + +// Init configures the logr.LogSink implementation. +func (t *testLogger) Init(info logr.RuntimeInfo) { + t.runtimeInfo = info +} + +// Enabled is used to determine whether an info log should be logged. +func (t *testLogger) Enabled(_ int) bool { + // Always return true so that we capture every log line in the test. + return true +} + +// Info accepts an info log line. +func (t *testLogger) Info(level int, msg string, keysAndValues ...interface{}) { + *t.entries = append(*t.entries, LogEntry{ + KeysAndValues: append(t.keysAndValues, keysAndValues...), + Level: level, + Message: msg, + }) +} + +// Error accepts an error log line. +func (t *testLogger) Error(err error, msg string, keysAndValues ...interface{}) { + *t.entries = append(*t.entries, LogEntry{ + Error: err, + KeysAndValues: append(t.keysAndValues, keysAndValues...), + Message: msg, + }) +} + +// WithValues creates a child logger with additional keys and values attached. +func (t *testLogger) WithValues(keysAndValues ...interface{}) logr.LogSink { + return &testLogger{ + runtimeInfo: t.runtimeInfo, + logger: t.logger, + entries: t.entries, + keysAndValues: append(t.keysAndValues, keysAndValues...), + } +} + +// WithName sets the name of the logger. This is not currently supported. +func (t *testLogger) WithName(name string) logr.LogSink { + return t +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/configmap.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/configmap.go new file mode 100644 index 0000000000000000000000000000000000000000..c99ba7277f2a45e3b95439812e11d2263ea4b803 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/configmap.go @@ -0,0 +1,92 @@ +/* +Copyright 2023 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ConfigMap creates a new ConfigMap builder. +func ConfigMap() ConfigMapBuilder { + return ConfigMapBuilder{} +} + +// ConfigMapBuilder is used to build out a ConfigMap object. +type ConfigMapBuilder struct { + generateName string + name string + namespace string + labels map[string]string + data map[string]string +} + +// Build builds a new ConfigMap based on the configuration provided. +func (m ConfigMapBuilder) Build() *corev1.ConfigMap { + ConfigMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: m.generateName, + Name: m.name, + Namespace: m.namespace, + Labels: m.labels, + }, + Data: m.data, + } + + return ConfigMap +} + +// WithData sets the data for the ConfigMap builder. +func (m ConfigMapBuilder) WithData(data map[string]string) ConfigMapBuilder { + m.data = data + return m +} + +// WithGenerateName sets the generateName for the ConfigMap builder. +func (m ConfigMapBuilder) WithGenerateName(generateName string) ConfigMapBuilder { + m.generateName = generateName + return m +} + +// WithLabel sets the labels for the ConfigMap builder. +func (m ConfigMapBuilder) WithLabel(key, value string) ConfigMapBuilder { + if m.labels == nil { + m.labels = make(map[string]string) + } + + m.labels[key] = value + + return m +} + +// WithLabels sets the labels for the ConfigMap builder. +func (m ConfigMapBuilder) WithLabels(labels map[string]string) ConfigMapBuilder { + m.labels = labels + return m +} + +// WithName sets the name for the ConfigMap builder. +func (m ConfigMapBuilder) WithName(name string) ConfigMapBuilder { + m.name = name + return m +} + +// WithNamespace sets the namespace for the ConfigMap builder. +func (m ConfigMapBuilder) WithNamespace(namespace string) ConfigMapBuilder { + m.namespace = namespace + return m +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/namespace.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/namespace.go new file mode 100644 index 0000000000000000000000000000000000000000..e2cd1f859c510496dd48fcd83dde23c0dedd1781 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/namespace.go @@ -0,0 +1,55 @@ +/* +Copyright 2022 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Namespace creates a new namespace builder. +func Namespace() NamespaceBuilder { + return NamespaceBuilder{} +} + +// NamespaceBuilder is used to build out a namespace object. +type NamespaceBuilder struct { + generateName string + name string +} + +// Build builds a new namespace based on the configuration provided. +func (n NamespaceBuilder) Build() *corev1.Namespace { + return &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: n.generateName, + Name: n.name, + }, + } +} + +// WithGenerateName sets the generateName for the namespace builder. +func (n NamespaceBuilder) WithGenerateName(generateName string) NamespaceBuilder { + n.generateName = generateName + return n +} + +// WithName sets the name for the namespace builder. +func (n NamespaceBuilder) WithName(name string) NamespaceBuilder { + n.name = name + return n +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/node.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/node.go new file mode 100644 index 0000000000000000000000000000000000000000..ff103b767880c7d0092a0e36131b80b6de893562 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/node.go @@ -0,0 +1,121 @@ +/* +Copyright 2022 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + masterNodeRoleLabel = "node-role.kubernetes.io/master" + workerNodeRoleLabel = "node-role.kubernetes.io/worker" +) + +// Node creates a new node builder. +func Node() NodeBuilder { + return NodeBuilder{} +} + +// NodeBuilder is used to build out a node object. +type NodeBuilder struct { + generateName string + name string + labels map[string]string + conditions []corev1.NodeCondition +} + +// Build builds a new node based on the configuration provided. +func (m NodeBuilder) Build() *corev1.Node { + node := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: m.generateName, + Name: m.name, + Labels: m.labels, + }, + Status: corev1.NodeStatus{ + Conditions: m.conditions, + }, + } + + return node +} + +// AsWorker sets the worker role on the node labels for the node builder. +func (m NodeBuilder) AsWorker() NodeBuilder { + return m.WithLabel(workerNodeRoleLabel, "") +} + +// AsMaster sets the master role on the node labels for the node builder. +func (m NodeBuilder) AsMaster() NodeBuilder { + return m.WithLabel(masterNodeRoleLabel, "") +} + +// AsNotReady sets the node as ready for the node builder. +func (m NodeBuilder) AsNotReady() NodeBuilder { + return m.WithConditions([]corev1.NodeCondition{ + { + Type: corev1.NodeReady, + Status: corev1.ConditionFalse, + }, + }) +} + +// AsReady sets the node as ready for the node builder. +func (m NodeBuilder) AsReady() NodeBuilder { + return m.WithConditions([]corev1.NodeCondition{ + { + Type: corev1.NodeReady, + Status: corev1.ConditionTrue, + }, + }) +} + +// WithConditions sets the conditions for the node builder. +func (m NodeBuilder) WithConditions(conditions []corev1.NodeCondition) NodeBuilder { + m.conditions = conditions + return m +} + +// WithGenerateName sets the generateName for the node builder. +func (m NodeBuilder) WithGenerateName(generateName string) NodeBuilder { + m.generateName = generateName + return m +} + +// WithLabel sets the labels for the node builder. +func (m NodeBuilder) WithLabel(key, value string) NodeBuilder { + if m.labels == nil { + m.labels = make(map[string]string) + } + + m.labels[key] = value + + return m +} + +// WithLabels sets the labels for the node builder. +func (m NodeBuilder) WithLabels(labels map[string]string) NodeBuilder { + m.labels = labels + return m +} + +// WithName sets the name for the node builder. +func (m NodeBuilder) WithName(name string) NodeBuilder { + m.name = name + return m +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/secret.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/secret.go new file mode 100644 index 0000000000000000000000000000000000000000..98d8ce04fb291552a340eb719ed9232b04e6681b --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/secret.go @@ -0,0 +1,92 @@ +/* +Copyright 2023 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Secret creates a new Secret builder. +func Secret() SecretBuilder { + return SecretBuilder{} +} + +// SecretBuilder is used to build out a Secret object. +type SecretBuilder struct { + generateName string + name string + namespace string + labels map[string]string + data map[string][]byte +} + +// Build builds a new Secret based on the configuration provided. +func (m SecretBuilder) Build() *corev1.Secret { + Secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: m.generateName, + Name: m.name, + Namespace: m.namespace, + Labels: m.labels, + }, + Data: m.data, + } + + return Secret +} + +// WithData sets the data for the Secret builder. +func (m SecretBuilder) WithData(data map[string][]byte) SecretBuilder { + m.data = data + return m +} + +// WithGenerateName sets the generateName for the Secret builder. +func (m SecretBuilder) WithGenerateName(generateName string) SecretBuilder { + m.generateName = generateName + return m +} + +// WithLabel sets the labels for the Secret builder. +func (m SecretBuilder) WithLabel(key, value string) SecretBuilder { + if m.labels == nil { + m.labels = make(map[string]string) + } + + m.labels[key] = value + + return m +} + +// WithLabels sets the labels for the Secret builder. +func (m SecretBuilder) WithLabels(labels map[string]string) SecretBuilder { + m.labels = labels + return m +} + +// WithName sets the name for the Secret builder. +func (m SecretBuilder) WithName(name string) SecretBuilder { + m.name = name + return m +} + +// WithNamespace sets the namespace for the Secret builder. +func (m SecretBuilder) WithNamespace(namespace string) SecretBuilder { + m.namespace = namespace + return m +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/service.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/service.go new file mode 100644 index 0000000000000000000000000000000000000000..6ff97d8d27b38d110fc31aafc8271ca8fd6379ea --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1/service.go @@ -0,0 +1,102 @@ +/* +Copyright 2023 Red Hat, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Service creates a new Service builder. +func Service() ServiceBuilder { + return ServiceBuilder{} +} + +// ServiceBuilder is used to build out a Service object. +type ServiceBuilder struct { + generateName string + name string + namespace string + labels map[string]string + selector map[string]string + ports []corev1.ServicePort +} + +// Build builds a new Service based on the configuration provided. +func (m ServiceBuilder) Build() *corev1.Service { + Service := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: m.generateName, + Name: m.name, + Namespace: m.namespace, + Labels: m.labels, + }, + Spec: corev1.ServiceSpec{ + Ports: m.ports, + Selector: m.selector, + }, + } + + return Service +} + +// WithGenerateName sets the generateName for the Service builder. +func (m ServiceBuilder) WithGenerateName(generateName string) ServiceBuilder { + m.generateName = generateName + return m +} + +// WithLabel sets the labels for the Service builder. +func (m ServiceBuilder) WithLabel(key, value string) ServiceBuilder { + if m.labels == nil { + m.labels = make(map[string]string) + } + + m.labels[key] = value + + return m +} + +// WithLabels sets the labels for the Service builder. +func (m ServiceBuilder) WithLabels(labels map[string]string) ServiceBuilder { + m.labels = labels + return m +} + +// WithName sets the name for the Service builder. +func (m ServiceBuilder) WithName(name string) ServiceBuilder { + m.name = name + return m +} + +// WithNamespace sets the namespace for the Service builder. +func (m ServiceBuilder) WithNamespace(namespace string) ServiceBuilder { + m.namespace = namespace + return m +} + +// WithPorts sets the ports for the Service builder. +func (m ServiceBuilder) WithPorts(ports []corev1.ServicePort) ServiceBuilder { + m.ports = ports + return m +} + +// WithSelector sets the selector for the Service builder. +func (m ServiceBuilder) WithSelector(selector map[string]string) ServiceBuilder { + m.selector = selector + return m +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/tools.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/tools.go new file mode 100644 index 0000000000000000000000000000000000000000..3e758e892daaae549886fb33c5f232256d8e7b29 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/tools.go @@ -0,0 +1,13 @@ +//go:build tools +// +build tools + +// Official workaround to track tool dependencies with go modules: +// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module + +package tools + +import ( + _ "github.com/golangci/golangci-lint/cmd/golangci-lint" + _ "github.com/onsi/ginkgo/v2/ginkgo" + _ "sigs.k8s.io/controller-runtime/tools/setup-envtest" +) diff --git a/vendor/modules.txt b/vendor/modules.txt index 19bdbec2c75d181a92bca5edf60440cc8af623e4..b89681e536a7c4922ebca2b35c2842371e4a5030 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -833,8 +833,10 @@ github.com/openshift/client-go/operator/applyconfigurations/internal github.com/openshift/client-go/operator/applyconfigurations/operator/v1 # github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20240626103413-ddea9c7c0aca ## explicit; go 1.21 +github.com/openshift/cluster-api-actuator-pkg/testutils github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/config/v1 +github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1 github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1 # github.com/openshift/cluster-control-plane-machine-set-operator v0.0.0-20240909043600-373ac49835bf ## explicit; go 1.22.0