diff --git a/.github/workflows/build_test_ci.yml b/.github/workflows/build_test_ci.yml index d8ec43936..88c489382 100644 --- a/.github/workflows/build_test_ci.yml +++ b/.github/workflows/build_test_ci.yml @@ -103,6 +103,7 @@ jobs: e2e-test: needs: [go-build-test, docker-build] runs-on: ubuntu-latest + if: github.event.pull_request.draft == false steps: - name: Harden Runner uses: step-security/harden-runner@v2 diff --git a/Makefile b/Makefile index 0e981e066..cd5ac59ec 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,13 @@ IMAGE_NAME ?= cluster-api-provider-linode CONTROLLER_IMAGE ?= $(REGISTRY)/$(IMAGE_NAME) TAG ?= dev ENVTEST_K8S_VERSION := 1.28.0 +VERSION ?= $(shell git describe --always --tag --dirty=-dev) BUILD_ARGS := --build-arg VERSION=$(VERSION) SHELL = /usr/bin/env bash -o pipefail .SHELLFLAGS = -ec CONTAINER_TOOL ?= docker MDBOOK_DEV_HOST = 0.0.0.0 MDBOOK_DEV_PORT = 3000 -VERSION ?= $(shell git describe --always --tag --dirty=-dev) # ENVTEST_K8S_VERSION # - refers to the version of kubebuilder assets to be downloaded by envtest binary. diff --git a/cloud/scope/client.go b/cloud/scope/client.go index a215b4836..4ac98c377 100644 --- a/cloud/scope/client.go +++ b/cloud/scope/client.go @@ -3,10 +3,27 @@ package scope import ( "context" + "github.com/linode/linodego" "sigs.k8s.io/cluster-api/util/patch" "sigs.k8s.io/controller-runtime/pkg/client" ) +// LinodeObjectStorageClient defines functions suitable for provisioning object storage buckets and keys. +type LinodeObjectStorageClient interface { + GetObjectStorageBucket(ctx context.Context, cluster, label string) (*linodego.ObjectStorageBucket, error) + CreateObjectStorageBucket(ctx context.Context, opts linodego.ObjectStorageBucketCreateOptions) (*linodego.ObjectStorageBucket, error) + CreateObjectStorageKey(ctx context.Context, opts linodego.ObjectStorageKeyCreateOptions) (*linodego.ObjectStorageKey, error) + DeleteObjectStorageKey(ctx context.Context, keyID int) error +} + +// LinodeObjectStorageClientBuilder is a function that returns a LinodeObjectStorageClient. +type LinodeObjectStorageClientBuilder func(apiKey string) (LinodeObjectStorageClient, error) + +// CreateLinodeObjectStorageClient is the main implementation of LinodeObjectStorageClientBuilder. +func CreateLinodeObjectStorageClient(apiKey string) (LinodeObjectStorageClient, error) { + return CreateLinodeClient(apiKey) +} + type k8sClient interface { client.Client } diff --git a/cloud/scope/cluster.go b/cloud/scope/cluster.go index b550ecd12..6947588e1 100644 --- a/cloud/scope/cluster.go +++ b/cloud/scope/cluster.go @@ -61,7 +61,7 @@ func NewClusterScope(ctx context.Context, apiKey string, params ClusterScopePara } apiKey = string(data) } - linodeClient, err := createLinodeClient(apiKey) + linodeClient, err := CreateLinodeClient(apiKey) if err != nil { return nil, fmt.Errorf("failed to create linode client: %w", err) } diff --git a/cloud/scope/cluster_test.go b/cloud/scope/cluster_test.go index 40806e634..51bbc23de 100644 --- a/cloud/scope/cluster_test.go +++ b/cloud/scope/cluster_test.go @@ -141,7 +141,7 @@ func TestClusterScopeMethods(t *testing.T) { mockPatchHelper := mock.NewMockPatchHelper(ctrl) mockK8sClient := mock.NewMockk8sClient(ctrl) - lClient, err := createLinodeClient("test-key") + lClient, err := CreateLinodeClient("test-key") if err != nil { t.Errorf("createLinodeClient() error = %v", err) } diff --git a/cloud/scope/common.go b/cloud/scope/common.go index f75cd58b9..b14de5f32 100644 --- a/cloud/scope/common.go +++ b/cloud/scope/common.go @@ -17,7 +17,7 @@ import ( type patchNewHelper func(obj client.Object, crClient client.Client) (*patch.Helper, error) -func createLinodeClient(apiKey string) (*linodego.Client, error) { +func CreateLinodeClient(apiKey string) (*linodego.Client, error) { if apiKey == "" { return nil, errors.New("missing Linode API key") } diff --git a/cloud/scope/common_test.go b/cloud/scope/common_test.go index b3671a6d3..7eec6e8aa 100644 --- a/cloud/scope/common_test.go +++ b/cloud/scope/common_test.go @@ -40,7 +40,7 @@ func TestCreateLinodeClient(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { t.Parallel() - got, err := createLinodeClient(testCase.apiKey) + got, err := CreateLinodeClient(testCase.apiKey) if testCase.expectedErr != nil { assert.EqualError(t, err, testCase.expectedErr.Error()) diff --git a/cloud/scope/machine.go b/cloud/scope/machine.go index 5ff257c62..cbfc04a08 100644 --- a/cloud/scope/machine.go +++ b/cloud/scope/machine.go @@ -83,7 +83,7 @@ func NewMachineScope(ctx context.Context, apiKey string, params MachineScopePara } apiKey = string(data) } - linodeClient, err := createLinodeClient(apiKey) + linodeClient, err := CreateLinodeClient(apiKey) if err != nil { return nil, fmt.Errorf("failed to create linode client: %w", err) } diff --git a/cloud/scope/object_storage_bucket.go b/cloud/scope/object_storage_bucket.go index 88d2fd6a5..63c9bb4ed 100644 --- a/cloud/scope/object_storage_bucket.go +++ b/cloud/scope/object_storage_bucket.go @@ -17,16 +17,17 @@ import ( ) type ObjectStorageBucketScopeParams struct { - Client client.Client - Bucket *infrav1alpha1.LinodeObjectStorageBucket - Logger *logr.Logger + Client client.Client + LinodeClientBuilder LinodeObjectStorageClientBuilder + Bucket *infrav1alpha1.LinodeObjectStorageBucket + Logger *logr.Logger } type ObjectStorageBucketScope struct { client client.Client Bucket *infrav1alpha1.LinodeObjectStorageBucket Logger logr.Logger - LinodeClient *linodego.Client + LinodeClient LinodeObjectStorageClient BucketPatchHelper *patch.Helper } @@ -40,6 +41,9 @@ func validateObjectStorageBucketScopeParams(params ObjectStorageBucketScopeParam if params.Logger == nil { return errors.New("logger is required when creating an ObjectStorageBucketScope") } + if params.LinodeClientBuilder == nil { + return errors.New("LinodeClientBuilder is required when creating an ObjectStorageBucketScope") + } return nil } @@ -57,7 +61,7 @@ func NewObjectStorageBucketScope(ctx context.Context, apiKey string, params Obje } apiKey = string(data) } - linodeClient, err := createLinodeClient(apiKey) + linodeClient, err := params.LinodeClientBuilder(apiKey) if err != nil { return nil, fmt.Errorf("failed to create linode client: %w", err) } diff --git a/cloud/scope/vpc.go b/cloud/scope/vpc.go index 2b8f3deda..10b092b44 100644 --- a/cloud/scope/vpc.go +++ b/cloud/scope/vpc.go @@ -67,7 +67,7 @@ func NewVPCScope(ctx context.Context, apiKey string, params VPCScopeParams) (*VP } apiKey = string(data) } - linodeClient, err := createLinodeClient(apiKey) + linodeClient, err := CreateLinodeClient(apiKey) if err != nil { return nil, fmt.Errorf("failed to create linode client: %w", err) } diff --git a/cmd/main.go b/cmd/main.go index ff661f4db..0c2fd063f 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -32,6 +32,7 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" infrastructurev1alpha1 "github.com/linode/cluster-api-provider-linode/api/v1alpha1" + "github.com/linode/cluster-api-provider-linode/cloud/scope" controller2 "github.com/linode/cluster-api-provider-linode/controller" "github.com/linode/cluster-api-provider-linode/version" @@ -140,12 +141,13 @@ func main() { os.Exit(1) } if err = (&controller2.LinodeObjectStorageBucketReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Logger: ctrl.Log.WithName("LinodeObjectStorageBucketReconciler"), - Recorder: mgr.GetEventRecorderFor("LinodeObjectStorageBucketReconciler"), - WatchFilterValue: objectStorageBucketWatchFilter, - LinodeApiKey: linodeToken, + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Logger: ctrl.Log.WithName("LinodeObjectStorageBucketReconciler"), + Recorder: mgr.GetEventRecorderFor("LinodeObjectStorageBucketReconciler"), + WatchFilterValue: objectStorageBucketWatchFilter, + LinodeApiKey: linodeToken, + LinodeClientBuilder: scope.CreateLinodeObjectStorageClient, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "LinodeObjectStorageBucket") os.Exit(1) diff --git a/controller/linodeobjectstoragebucket_controller.go b/controller/linodeobjectstoragebucket_controller.go index c6e8879af..a781a6d44 100644 --- a/controller/linodeobjectstoragebucket_controller.go +++ b/controller/linodeobjectstoragebucket_controller.go @@ -47,12 +47,13 @@ import ( // LinodeObjectStorageBucketReconciler reconciles a LinodeObjectStorageBucket object type LinodeObjectStorageBucketReconciler struct { client.Client - Scheme *runtime.Scheme - Logger logr.Logger - Recorder record.EventRecorder - LinodeApiKey string - WatchFilterValue string - ReconcileTimeout time.Duration + Scheme *runtime.Scheme + Logger logr.Logger + Recorder record.EventRecorder + LinodeApiKey string + LinodeClientBuilder scope.LinodeObjectStorageClientBuilder + WatchFilterValue string + ReconcileTimeout time.Duration } // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodeobjectstoragebuckets,verbs=get;list;watch;create;update;patch;delete @@ -90,9 +91,10 @@ func (r *LinodeObjectStorageBucketReconciler) Reconcile(ctx context.Context, req ctx, r.LinodeApiKey, scope.ObjectStorageBucketScopeParams{ - Client: r.Client, - Bucket: objectStorageBucket, - Logger: &logger, + Client: r.Client, + LinodeClientBuilder: r.LinodeClientBuilder, + Bucket: objectStorageBucket, + Logger: &logger, }, ) if err != nil { @@ -173,7 +175,7 @@ func (r *LinodeObjectStorageBucketReconciler) reconcileApply(ctx context.Context bScope.Bucket.Status.LastKeyGeneration = bScope.Bucket.Spec.KeyGeneration } - r.Recorder.Event(bScope.Bucket, corev1.EventTypeNormal, "Ready", "Object storage bucket configuration applied") + r.Recorder.Event(bScope.Bucket, corev1.EventTypeNormal, "Ready", "Object storage bucket applied") bScope.Bucket.Status.Ready = true conditions.MarkTrue(bScope.Bucket, clusterv1.ReadyCondition) @@ -199,6 +201,8 @@ func (r *LinodeObjectStorageBucketReconciler) reconcileDelete(ctx context.Contex return err } + r.Recorder.Event(bScope.Bucket, clusterv1.DeletedReason, "Ready", "Object storage bucket deleted") + return nil } diff --git a/controller/linodeobjectstoragebucket_controller_test.go b/controller/linodeobjectstoragebucket_controller_test.go new file mode 100644 index 000000000..2633a5591 --- /dev/null +++ b/controller/linodeobjectstoragebucket_controller_test.go @@ -0,0 +1,184 @@ +// /* +// Copyright 2023 Akamai Technologies, 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 controller + +import ( + "context" + "fmt" + "time" + + "github.com/linode/linodego" + "go.uber.org/mock/gomock" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/record" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + infrav1 "github.com/linode/cluster-api-provider-linode/api/v1alpha1" + "github.com/linode/cluster-api-provider-linode/cloud/scope" + "github.com/linode/cluster-api-provider-linode/mock" + "github.com/linode/cluster-api-provider-linode/util" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func mockClientBuilder(m *mock.MockLinodeObjectStorageClient) scope.LinodeObjectStorageClientBuilder { + return func(_ string) (scope.LinodeObjectStorageClient, error) { + return m, nil + } +} + +var _ = Describe("LinodeObjectStorageBucket controller", func() { + ctx := context.Background() + + obj := &infrav1.LinodeObjectStorageBucket{ + ObjectMeta: metav1.ObjectMeta{ + Name: "sample-bucket", + Namespace: "default", + }, + Spec: infrav1.LinodeObjectStorageBucketSpec{ + Cluster: "cluster", + Label: util.Pointer("sample"), + }, + } + + recorder := record.NewFakeRecorder(3) + + secretName := fmt.Sprintf(scope.AccessKeyNameTemplate, *obj.Spec.Label) + + var secret corev1.Secret + var mockCtrl *gomock.Controller + + BeforeEach(func() { + // Create a new gomock controller for each test run + mockCtrl = gomock.NewController(GinkgoT()) + }) + + AfterEach(func() { + // At the end of each test run, tell the gomock controller it's done + // so it can check configured expectations and validate the methods called + mockCtrl.Finish() + }) + + It("should reconcile an object apply", func() { + mockClient := mock.NewMockLinodeObjectStorageClient(mockCtrl) + + getCall := mockClient.EXPECT(). + GetObjectStorageBucket(gomock.Any(), obj.Spec.Cluster, gomock.Any()). + Return(nil, nil). + Times(1) + + createBucketCall := mockClient.EXPECT(). + CreateObjectStorageBucket(gomock.Any(), gomock.Any()). + Return(&linodego.ObjectStorageBucket{ + Label: *obj.Spec.Label, + Cluster: obj.Spec.Cluster, + Created: util.Pointer(time.Now()), + Hostname: "hostname", + }, nil). + Times(1). + After(getCall) + + for idx, permission := range []string{"rw", "ro"} { + mockClient.EXPECT(). + CreateObjectStorageKey( + gomock.Any(), + gomock.Cond(func(opt any) bool { + createOpt, ok := opt.(linodego.ObjectStorageKeyCreateOptions) + if !ok { + return false + } + + return createOpt.Label == fmt.Sprintf("%s-%s", *obj.Spec.Label, permission) + }), + ). + Return(&linodego.ObjectStorageKey{ID: idx}, nil). + Times(1). + After(createBucketCall) + } + + reconciler := &LinodeObjectStorageBucketReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + Logger: ctrl.Log.WithName("LinodeObjectStorageBucketReconciler"), + Recorder: recorder, + LinodeClientBuilder: mockClientBuilder(mockClient), + } + + objectKey := client.ObjectKeyFromObject(obj) + Expect(k8sClient.Create(ctx, obj)).To(Succeed()) + _, err := reconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: objectKey, + }) + Expect(err).NotTo(HaveOccurred()) + + By("updating its status fields") + Expect(k8sClient.Get(ctx, objectKey, obj)).To(Succeed()) + Expect(*obj.Status.Hostname).To(Equal("hostname")) + Expect(*obj.Status.KeySecretName).To(Equal(secretName)) + Expect(*obj.Status.LastKeyGeneration).To(Equal(*obj.Spec.KeyGeneration)) + Expect(*obj.Status.LastKeyGeneration).To(Equal(0)) + Expect(obj.Status.Ready).To(BeTrue()) + + By("creating a Secret with access keys") + Expect(k8sClient.Get(ctx, client.ObjectKey{ + Name: secretName, + Namespace: obj.Namespace, + }, &secret)).To(Succeed()) + Expect(secret.Data["read_write"]).To(Not(BeNil())) + Expect(secret.Data["read_only"]).To(Not(BeNil())) + + By("recording the expected event") + Expect(<-recorder.Events).To(ContainSubstring("Object storage bucket applied")) + }) + + It("should reconcile an object delete", func() { + mockClient := mock.NewMockLinodeObjectStorageClient(mockCtrl) + + for i := range 2 { + mockClient.EXPECT(). + DeleteObjectStorageKey(gomock.Any(), i). + Return(nil). + Times(1) + } + + reconciler := &LinodeObjectStorageBucketReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + Logger: ctrl.Log.WithName("LinodeObjectStorageBucketReconciler"), + Recorder: recorder, + LinodeClientBuilder: mockClientBuilder(mockClient), + } + + objectKey := client.ObjectKeyFromObject(obj) + Expect(k8sClient.Delete(ctx, obj)).To(Succeed()) + _, err := reconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: objectKey, + }) + Expect(err).NotTo(HaveOccurred()) + + By("removing the finalizer so it is deleted") + Expect(apierrors.IsNotFound(k8sClient.Get(ctx, objectKey, obj))).To(BeTrue()) + + By("recording the expected event") + Expect(<-recorder.Events).To(ContainSubstring("Object storage bucket deleted")) + }) +}) diff --git a/controller/suite_test.go b/controller/suite_test.go index 4fe9135e1..cb9aab151 100644 --- a/controller/suite_test.go +++ b/controller/suite_test.go @@ -29,7 +29,8 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - infrastructurev1alpha1 "github.com/linode/cluster-api-provider-linode/api/v1alpha1" + infrav1 "github.com/linode/cluster-api-provider-linode/api/v1alpha1" + //+kubebuilder:scaffold:imports . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -64,7 +65,7 @@ var _ = BeforeSuite(func() { // default path defined in controller-runtime which is /usr/local/kubebuilder/. // Note that you must have the required binaries setup under the bin directory to perform // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", + BinaryAssetsDirectory: filepath.Join("..", "bin", "k8s", fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), } @@ -74,15 +75,13 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = infrastructurev1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) + Expect(infrav1.AddToScheme(scheme.Scheme)).To(Succeed()) //+kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) - }) var _ = AfterSuite(func() { diff --git a/go.mod b/go.mod index 89220da7c..d4d47f935 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-logr/logr v1.4.1 github.com/google/uuid v1.6.0 github.com/linode/linodego v1.29.0 - github.com/onsi/ginkgo/v2 v2.15.0 + github.com/onsi/ginkgo/v2 v2.16.0 github.com/onsi/gomega v1.31.1 github.com/stretchr/testify v1.9.0 go.uber.org/automaxprocs v1.5.3 @@ -25,7 +25,6 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/zapr v1.3.0 // indirect @@ -37,7 +36,6 @@ require ( github.com/gobuffalo/flect v1.0.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -61,13 +59,12 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.17.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect diff --git a/go.sum b/go.sum index 711237634..a77f9ecb0 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -115,8 +113,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM= +github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -157,7 +155,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= @@ -180,18 +177,14 @@ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjs golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -203,18 +196,15 @@ golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5H golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -245,11 +235,10 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/mock/client.go b/mock/client.go index f044b30f0..6895442fe 100644 --- a/mock/client.go +++ b/mock/client.go @@ -13,6 +13,7 @@ import ( context "context" reflect "reflect" + linodego "github.com/linode/linodego" gomock "go.uber.org/mock/gomock" meta "k8s.io/apimachinery/pkg/api/meta" runtime "k8s.io/apimachinery/pkg/runtime" @@ -21,6 +22,88 @@ import ( client "sigs.k8s.io/controller-runtime/pkg/client" ) +// MockLinodeObjectStorageClient is a mock of LinodeObjectStorageClient interface. +type MockLinodeObjectStorageClient struct { + ctrl *gomock.Controller + recorder *MockLinodeObjectStorageClientMockRecorder +} + +// MockLinodeObjectStorageClientMockRecorder is the mock recorder for MockLinodeObjectStorageClient. +type MockLinodeObjectStorageClientMockRecorder struct { + mock *MockLinodeObjectStorageClient +} + +// NewMockLinodeObjectStorageClient creates a new mock instance. +func NewMockLinodeObjectStorageClient(ctrl *gomock.Controller) *MockLinodeObjectStorageClient { + mock := &MockLinodeObjectStorageClient{ctrl: ctrl} + mock.recorder = &MockLinodeObjectStorageClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockLinodeObjectStorageClient) EXPECT() *MockLinodeObjectStorageClientMockRecorder { + return m.recorder +} + +// CreateObjectStorageBucket mocks base method. +func (m *MockLinodeObjectStorageClient) CreateObjectStorageBucket(ctx context.Context, opts linodego.ObjectStorageBucketCreateOptions) (*linodego.ObjectStorageBucket, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateObjectStorageBucket", ctx, opts) + ret0, _ := ret[0].(*linodego.ObjectStorageBucket) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateObjectStorageBucket indicates an expected call of CreateObjectStorageBucket. +func (mr *MockLinodeObjectStorageClientMockRecorder) CreateObjectStorageBucket(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateObjectStorageBucket", reflect.TypeOf((*MockLinodeObjectStorageClient)(nil).CreateObjectStorageBucket), ctx, opts) +} + +// CreateObjectStorageKey mocks base method. +func (m *MockLinodeObjectStorageClient) CreateObjectStorageKey(ctx context.Context, opts linodego.ObjectStorageKeyCreateOptions) (*linodego.ObjectStorageKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateObjectStorageKey", ctx, opts) + ret0, _ := ret[0].(*linodego.ObjectStorageKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateObjectStorageKey indicates an expected call of CreateObjectStorageKey. +func (mr *MockLinodeObjectStorageClientMockRecorder) CreateObjectStorageKey(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateObjectStorageKey", reflect.TypeOf((*MockLinodeObjectStorageClient)(nil).CreateObjectStorageKey), ctx, opts) +} + +// DeleteObjectStorageKey mocks base method. +func (m *MockLinodeObjectStorageClient) DeleteObjectStorageKey(ctx context.Context, keyID int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObjectStorageKey", ctx, keyID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteObjectStorageKey indicates an expected call of DeleteObjectStorageKey. +func (mr *MockLinodeObjectStorageClientMockRecorder) DeleteObjectStorageKey(ctx, keyID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectStorageKey", reflect.TypeOf((*MockLinodeObjectStorageClient)(nil).DeleteObjectStorageKey), ctx, keyID) +} + +// GetObjectStorageBucket mocks base method. +func (m *MockLinodeObjectStorageClient) GetObjectStorageBucket(ctx context.Context, cluster, label string) (*linodego.ObjectStorageBucket, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectStorageBucket", ctx, cluster, label) + ret0, _ := ret[0].(*linodego.ObjectStorageBucket) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectStorageBucket indicates an expected call of GetObjectStorageBucket. +func (mr *MockLinodeObjectStorageClientMockRecorder) GetObjectStorageBucket(ctx, cluster, label any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectStorageBucket", reflect.TypeOf((*MockLinodeObjectStorageClient)(nil).GetObjectStorageBucket), ctx, cluster, label) +} + // Mockk8sClient is a mock of k8sClient interface. type Mockk8sClient struct { ctrl *gomock.Controller