From a08bc073379f09028e453d78bd5139d35312e82a Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 16 Feb 2021 09:38:31 +0100 Subject: [PATCH 01/12] api/v1beta1: add S3Bucket field to AWSClusterSpec As a preparation for using it as an alternative backend to Secret Manager for OS-es, which do not support Secret Manager, like Flatcar Container Linux. Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- api/v1alpha3/awscluster_conversion.go | 6 + api/v1alpha3/zz_generated.conversion.go | 16 +-- api/v1alpha4/awscluster_conversion.go | 2 + api/v1alpha4/conversion.go | 6 + api/v1alpha4/zz_generated.conversion.go | 32 ++--- api/v1beta1/awscluster_types.go | 23 ++++ api/v1beta1/awscluster_webhook.go | 2 + api/v1beta1/awscluster_webhook_test.go | 130 +++++++++++++++++- api/v1beta1/conditions_consts.go | 8 ++ api/v1beta1/s3bucket.go | 73 ++++++++++ api/v1beta1/zz_generated.deepcopy.go | 45 ++++++ ...tructure.cluster.x-k8s.io_awsclusters.yaml | 29 ++++ ....cluster.x-k8s.io_awsclustertemplates.yaml | 29 ++++ 13 files changed, 370 insertions(+), 31 deletions(-) create mode 100644 api/v1beta1/s3bucket.go diff --git a/api/v1alpha3/awscluster_conversion.go b/api/v1alpha3/awscluster_conversion.go index abd18f90b6..444e4384c1 100644 --- a/api/v1alpha3/awscluster_conversion.go +++ b/api/v1alpha3/awscluster_conversion.go @@ -54,6 +54,8 @@ func (r *AWSCluster) ConvertTo(dstRaw conversion.Hub) error { restoreControlPlaneLoadBalancer(restored.Spec.ControlPlaneLoadBalancer, dst.Spec.ControlPlaneLoadBalancer) } + dst.Spec.S3Bucket = restored.Spec.S3Bucket + return nil } @@ -125,3 +127,7 @@ func Convert_v1beta1_NetworkStatus_To_v1alpha3_Network(in *infrav1.NetworkStatus func Convert_v1beta1_AWSLoadBalancerSpec_To_v1alpha3_AWSLoadBalancerSpec(in *infrav1.AWSLoadBalancerSpec, out *AWSLoadBalancerSpec, s apiconversion.Scope) error { return autoConvert_v1beta1_AWSLoadBalancerSpec_To_v1alpha3_AWSLoadBalancerSpec(in, out, s) } + +func Convert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(in *infrav1.AWSClusterSpec, out *AWSClusterSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(in, out, s) +} diff --git a/api/v1alpha3/zz_generated.conversion.go b/api/v1alpha3/zz_generated.conversion.go index edff3fd470..1cc3372f03 100644 --- a/api/v1alpha3/zz_generated.conversion.go +++ b/api/v1alpha3/zz_generated.conversion.go @@ -136,11 +136,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.AWSClusterSpec)(nil), (*AWSClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(a.(*v1beta1.AWSClusterSpec), b.(*AWSClusterSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*AWSClusterStaticIdentity)(nil), (*v1beta1.AWSClusterStaticIdentity)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_AWSClusterStaticIdentity_To_v1beta1_AWSClusterStaticIdentity(a.(*AWSClusterStaticIdentity), b.(*v1beta1.AWSClusterStaticIdentity), scope) }); err != nil { @@ -486,6 +481,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.AWSClusterSpec)(nil), (*AWSClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(a.(*v1beta1.AWSClusterSpec), b.(*AWSClusterSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.AWSClusterStaticIdentitySpec)(nil), (*AWSClusterStaticIdentitySpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_AWSClusterStaticIdentitySpec_To_v1alpha3_AWSClusterStaticIdentitySpec(a.(*v1beta1.AWSClusterStaticIdentitySpec), b.(*AWSClusterStaticIdentitySpec), scope) }); err != nil { @@ -832,14 +832,10 @@ func autoConvert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(in *v1beta1.A return err } out.IdentityRef = (*AWSIdentityReference)(unsafe.Pointer(in.IdentityRef)) + // WARNING: in.S3Bucket requires manual conversion: does not exist in peer-type return nil } -// Convert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec is an autogenerated conversion function. -func Convert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(in *v1beta1.AWSClusterSpec, out *AWSClusterSpec, s conversion.Scope) error { - return autoConvert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(in, out, s) -} - func autoConvert_v1alpha3_AWSClusterStaticIdentity_To_v1beta1_AWSClusterStaticIdentity(in *AWSClusterStaticIdentity, out *v1beta1.AWSClusterStaticIdentity, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1alpha3_AWSClusterStaticIdentitySpec_To_v1beta1_AWSClusterStaticIdentitySpec(&in.Spec, &out.Spec, s); err != nil { diff --git a/api/v1alpha4/awscluster_conversion.go b/api/v1alpha4/awscluster_conversion.go index 983f9285cc..90dbac081a 100644 --- a/api/v1alpha4/awscluster_conversion.go +++ b/api/v1alpha4/awscluster_conversion.go @@ -45,6 +45,8 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error { restoreControlPlaneLoadBalancer(restored.Spec.ControlPlaneLoadBalancer, dst.Spec.ControlPlaneLoadBalancer) } + dst.Spec.S3Bucket = restored.Spec.S3Bucket + return nil } diff --git a/api/v1alpha4/conversion.go b/api/v1alpha4/conversion.go index 82f4d56d56..6b1644fbe9 100644 --- a/api/v1alpha4/conversion.go +++ b/api/v1alpha4/conversion.go @@ -18,6 +18,8 @@ package v1alpha4 import ( apiconversion "k8s.io/apimachinery/pkg/conversion" + conversion "k8s.io/apimachinery/pkg/conversion" + v1beta1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" clusterv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ) @@ -31,3 +33,7 @@ func Convert_v1alpha4_ObjectMeta_To_v1beta1_ObjectMeta(in *clusterv1alpha4.Objec func Convert_v1beta1_ObjectMeta_To_v1alpha4_ObjectMeta(in *clusterv1.ObjectMeta, out *clusterv1alpha4.ObjectMeta, s apiconversion.Scope) error { return clusterv1alpha4.Convert_v1beta1_ObjectMeta_To_v1alpha4_ObjectMeta(in, out, s) } + +func Convert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in *v1beta1.AWSClusterSpec, out *AWSClusterSpec, s conversion.Scope) error { + return autoConvert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in, out, s) +} diff --git a/api/v1alpha4/zz_generated.conversion.go b/api/v1alpha4/zz_generated.conversion.go index 2d398170b2..834ec7bb5a 100644 --- a/api/v1alpha4/zz_generated.conversion.go +++ b/api/v1alpha4/zz_generated.conversion.go @@ -145,11 +145,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.AWSClusterSpec)(nil), (*AWSClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(a.(*v1beta1.AWSClusterSpec), b.(*AWSClusterSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*AWSClusterStaticIdentity)(nil), (*v1beta1.AWSClusterStaticIdentity)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_AWSClusterStaticIdentity_To_v1beta1_AWSClusterStaticIdentity(a.(*AWSClusterStaticIdentity), b.(*v1beta1.AWSClusterStaticIdentity), scope) }); err != nil { @@ -265,11 +260,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta1.AWSMachineSpec)(nil), (*AWSMachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(a.(*v1beta1.AWSMachineSpec), b.(*AWSMachineSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*AWSMachineStatus)(nil), (*v1beta1.AWSMachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_AWSMachineStatus_To_v1beta1_AWSMachineStatus(a.(*AWSMachineStatus), b.(*v1beta1.AWSMachineStatus), scope) }); err != nil { @@ -545,6 +535,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.AWSClusterSpec)(nil), (*AWSClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(a.(*v1beta1.AWSClusterSpec), b.(*AWSClusterSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.AWSClusterTemplateResource)(nil), (*AWSClusterTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_AWSClusterTemplateResource_To_v1alpha4_AWSClusterTemplateResource(a.(*v1beta1.AWSClusterTemplateResource), b.(*AWSClusterTemplateResource), scope) }); err != nil { @@ -555,6 +550,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.AWSMachineSpec)(nil), (*AWSMachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(a.(*v1beta1.AWSMachineSpec), b.(*AWSMachineSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.AWSMachineTemplateResource)(nil), (*AWSMachineTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_AWSMachineTemplateResource_To_v1alpha4_AWSMachineTemplateResource(a.(*v1beta1.AWSMachineTemplateResource), b.(*AWSMachineTemplateResource), scope) }); err != nil { @@ -893,14 +893,10 @@ func autoConvert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in *v1beta1.A return err } out.IdentityRef = (*AWSIdentityReference)(unsafe.Pointer(in.IdentityRef)) + // WARNING: in.S3Bucket requires manual conversion: does not exist in peer-type return nil } -// Convert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec is an autogenerated conversion function. -func Convert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in *v1beta1.AWSClusterSpec, out *AWSClusterSpec, s conversion.Scope) error { - return autoConvert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in, out, s) -} - func autoConvert_v1alpha4_AWSClusterStaticIdentity_To_v1beta1_AWSClusterStaticIdentity(in *AWSClusterStaticIdentity, out *v1beta1.AWSClusterStaticIdentity, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1alpha4_AWSClusterStaticIdentitySpec_To_v1beta1_AWSClusterStaticIdentitySpec(&in.Spec, &out.Spec, s); err != nil { @@ -1356,16 +1352,12 @@ func autoConvert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(in *v1beta1.A if err := Convert_v1beta1_CloudInit_To_v1alpha4_CloudInit(&in.CloudInit, &out.CloudInit, s); err != nil { return err } + // WARNING: in.Ignition requires manual conversion: does not exist in peer-type out.SpotMarketOptions = (*SpotMarketOptions)(unsafe.Pointer(in.SpotMarketOptions)) out.Tenancy = in.Tenancy return nil } -// Convert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec is an autogenerated conversion function. -func Convert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(in *v1beta1.AWSMachineSpec, out *AWSMachineSpec, s conversion.Scope) error { - return autoConvert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(in, out, s) -} - func autoConvert_v1alpha4_AWSMachineStatus_To_v1beta1_AWSMachineStatus(in *AWSMachineStatus, out *v1beta1.AWSMachineStatus, s conversion.Scope) error { out.Ready = in.Ready out.Interruptible = in.Interruptible diff --git a/api/v1beta1/awscluster_types.go b/api/v1beta1/awscluster_types.go index 984d366257..23b5304145 100644 --- a/api/v1beta1/awscluster_types.go +++ b/api/v1beta1/awscluster_types.go @@ -90,6 +90,13 @@ type AWSClusterSpec struct { // IdentityRef is a reference to a identity to be used when reconciling this cluster // +optional IdentityRef *AWSIdentityReference `json:"identityRef,omitempty"` + + // S3Bucket contains options to configure a supporting S3 bucket for this + // cluster - currently used for nodes requiring Ignition + // (https://coreos.github.io/ignition/) for bootstrapping (requires + // BootstrapFormatIgnition feature flag to be enabled). + // +optional + S3Bucket *S3Bucket `json:"s3Bucket,omitempty"` } // AWSIdentityKind defines allowed AWS identity types. @@ -198,6 +205,22 @@ type AWSClusterStatus struct { Conditions clusterv1.Conditions `json:"conditions,omitempty"` } +type S3Bucket struct { + // ControlPlaneIAMInstanceProfile is a name of the IAMInstanceProfile, which will be allowed + // to read control-plane node bootstrap data from S3 Bucket. + ControlPlaneIAMInstanceProfile string `json:"controlPlaneIAMInstanceProfile"` + + // NodesIAMInstanceProfiles is a list of IAM instance profiles, which will be allowed to read + // worker nodes bootstrap data from S3 Bucket. + NodesIAMInstanceProfiles []string `json:"nodesIAMInstanceProfiles"` + + // Name defines name of S3 Bucket to be created. + // +kubebuilder:validation:MinLength:=3 + // +kubebuilder:validation:MaxLength:=63 + // +kubebuilder:validation:Pattern=`^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$` + Name string `json:"name"` +} + // +kubebuilder:object:root=true // +kubebuilder:resource:path=awsclusters,scope=Namespaced,categories=cluster-api,shortName=awsc // +kubebuilder:storageversion diff --git a/api/v1beta1/awscluster_webhook.go b/api/v1beta1/awscluster_webhook.go index d827a2fe36..f208de50fd 100644 --- a/api/v1beta1/awscluster_webhook.go +++ b/api/v1beta1/awscluster_webhook.go @@ -55,6 +55,7 @@ func (r *AWSCluster) ValidateCreate() error { allErrs = append(allErrs, r.Spec.Bastion.Validate()...) allErrs = append(allErrs, r.validateSSHKeyName()...) allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...) + allErrs = append(allErrs, r.Spec.S3Bucket.Validate()...) return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) } @@ -164,6 +165,7 @@ func (r *AWSCluster) ValidateUpdate(old runtime.Object) error { allErrs = append(allErrs, r.Spec.Bastion.Validate()...) allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...) + allErrs = append(allErrs, r.Spec.S3Bucket.Validate()...) return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) } diff --git a/api/v1beta1/awscluster_webhook_test.go b/api/v1beta1/awscluster_webhook_test.go index 42614b3fb1..08fbcd0d2f 100644 --- a/api/v1beta1/awscluster_webhook_test.go +++ b/api/v1beta1/awscluster_webhook_test.go @@ -94,6 +94,132 @@ func TestAWSCluster_ValidateCreate(t *testing.T) { }, wantErr: true, }, + { + name: "accepts bucket name with acceptable characters", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "abcdefghijklmnoprstuwxyz-0123456789", + ControlPlaneIAMInstanceProfile: "control-plane.cluster-api-provider-aws.sigs.k8s.io", + NodesIAMInstanceProfiles: []string{"nodes.cluster-api-provider-aws.sigs.k8s.io"}, + }, + }, + }, + }, + { + name: "rejects empty bucket name", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{}, + }, + }, + wantErr: true, + }, + { + name: "rejects bucket name shorter than 3 characters", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "fo", + }, + }, + }, + wantErr: true, + }, + { + name: "rejects bucket name longer than 63 characters", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: strings.Repeat("a", 64), + }, + }, + }, + wantErr: true, + }, + { + name: "rejects bucket name starting with not letter or number", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "-foo", + }, + }, + }, + wantErr: true, + }, + { + name: "rejects bucket name ending with not letter or number", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "foo-", + }, + }, + }, + wantErr: true, + }, + { + name: "rejects bucket name formatted as IP address", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "8.8.8.8", + }, + }, + }, + wantErr: true, + }, + { + name: "requires bucket control plane IAM instance profile to be not empty", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "foo", + ControlPlaneIAMInstanceProfile: "", + }, + }, + }, + wantErr: true, + }, + { + name: "requires at least one bucket node IAM instance profile", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "foo", + ControlPlaneIAMInstanceProfile: "foo", + }, + }, + }, + wantErr: true, + }, + { + name: "requires all bucket node IAM instance profiles to be not empty", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "foo", + ControlPlaneIAMInstanceProfile: "foo", + NodesIAMInstanceProfiles: []string{""}, + }, + }, + }, + wantErr: true, + }, + { + name: "does not return error when all IAM instance profiles are populated", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + S3Bucket: &S3Bucket{ + Name: "foo", + ControlPlaneIAMInstanceProfile: "foo", + NodesIAMInstanceProfiles: []string{"bar"}, + }, + }, + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -123,7 +249,9 @@ func TestAWSCluster_ValidateCreate(t *testing.T) { return err == nil }, 10*time.Second).Should(Equal(true)) - tt.expect(g, c.Spec.ControlPlaneLoadBalancer) + if tt.expect != nil { + tt.expect(g, c.Spec.ControlPlaneLoadBalancer) + } }) } } diff --git a/api/v1beta1/conditions_consts.go b/api/v1beta1/conditions_consts.go index 07bb369829..94d8cf0af8 100644 --- a/api/v1beta1/conditions_consts.go +++ b/api/v1beta1/conditions_consts.go @@ -157,3 +157,11 @@ const ( // ELBDetachFailedReason used when a control plane node fails to detach from an ELB. ELBDetachFailedReason = "ELBDetachFailed" ) + +const ( + // S3BucketReadyCondition indicates an S3 bucket has been created successfully. + S3BucketReadyCondition clusterv1.ConditionType = "S3BucketCreated" + + // S3BucketFailedReason is used when any errors occur during reconciliation of an S3 bucket. + S3BucketFailedReason = "S3BucketCreationFailed" +) diff --git a/api/v1beta1/s3bucket.go b/api/v1beta1/s3bucket.go new file mode 100644 index 0000000000..4a1c0a4358 --- /dev/null +++ b/api/v1beta1/s3bucket.go @@ -0,0 +1,73 @@ +/* +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 v1beta1 + +import ( + "fmt" + "net" + + "k8s.io/apimachinery/pkg/util/validation/field" +) + +// Validate validates S3Bucket fields. +func (b *S3Bucket) Validate() []*field.Error { + var errs field.ErrorList + + if b == nil { + return errs + } + + if b.Name == "" { + errs = append(errs, field.Required(field.NewPath("spec", "s3Bucket", "name"), "can't be empty")) + } + + if b.ControlPlaneIAMInstanceProfile == "" { + errs = append(errs, + field.Required(field.NewPath("spec", "s3Bucket", "controlPlaneIAMInstanceProfiles"), "can't be empty")) + } + + if len(b.NodesIAMInstanceProfiles) == 0 { + errs = append(errs, + field.Required(field.NewPath("spec", "s3Bucket", "nodesIAMInstanceProfiles"), "can't be empty")) + } + + for i, iamInstanceProfile := range b.NodesIAMInstanceProfiles { + if iamInstanceProfile == "" { + errs = append(errs, + field.Required(field.NewPath("spec", "s3Bucket", fmt.Sprintf("nodesIAMInstanceProfiles[%d]", i)), "can't be empty")) + } + } + + if b.Name != "" { + errs = append(errs, validateS3BucketName(b.Name)...) + } + + return errs +} + +// Validation rules taken from https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html. +func validateS3BucketName(name string) []*field.Error { + var errs field.ErrorList + + path := field.NewPath("spec", "s3Bucket", "name") + + if net.ParseIP(name) != nil { + errs = append(errs, field.Invalid(path, name, "must not be formatted as an IP address (for example, 192.168.5.4)")) + } + + return errs +} diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 839659a1b0..96241f5454 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -313,6 +313,11 @@ func (in *AWSClusterSpec) DeepCopyInto(out *AWSClusterSpec) { *out = new(AWSIdentityReference) **out = **in } + if in.S3Bucket != nil { + in, out := &in.S3Bucket, &out.S3Bucket + *out = new(S3Bucket) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSClusterSpec. @@ -710,6 +715,11 @@ func (in *AWSMachineSpec) DeepCopyInto(out *AWSMachineSpec) { **out = **in } out.CloudInit = in.CloudInit + if in.Ignition != nil { + in, out := &in.Ignition, &out.Ignition + *out = new(Ignition) + **out = **in + } if in.SpotMarketOptions != nil { in, out := &in.SpotMarketOptions, &out.SpotMarketOptions *out = new(SpotMarketOptions) @@ -1167,6 +1177,21 @@ func (in *Filter) DeepCopy() *Filter { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Ignition) DeepCopyInto(out *Ignition) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ignition. +func (in *Ignition) DeepCopy() *Ignition { + if in == nil { + return nil + } + out := new(Ignition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRule) DeepCopyInto(out *IngressRule) { *out = *in @@ -1375,6 +1400,26 @@ func (in *RouteTable) DeepCopy() *RouteTable { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *S3Bucket) DeepCopyInto(out *S3Bucket) { + *out = *in + if in.NodesIAMInstanceProfiles != nil { + in, out := &in.NodesIAMInstanceProfiles, &out.NodesIAMInstanceProfiles + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3Bucket. +func (in *S3Bucket) DeepCopy() *S3Bucket { + if in == nil { + return nil + } + out := new(S3Bucket) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecurityGroup) DeepCopyInto(out *SecurityGroup) { *out = *in diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml index 248d52b686..08c3e27d93 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml @@ -1855,6 +1855,35 @@ spec: region: description: The AWS Region the cluster lives in. type: string + s3Bucket: + description: S3Bucket contains options to configure a supporting S3 + bucket for this cluster - currently used for nodes requiring Ignition + (https://coreos.github.io/ignition/) for bootstrapping (requires + BootstrapFormatIgnition feature flag to be enabled). + properties: + controlPlaneIAMInstanceProfile: + description: ControlPlaneIAMInstanceProfile is a name of the IAMInstanceProfile, + which will be allowed to read control-plane node bootstrap data + from S3 Bucket. + type: string + name: + description: Name defines name of S3 Bucket to be created. + maxLength: 63 + minLength: 3 + pattern: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ + type: string + nodesIAMInstanceProfiles: + description: NodesIAMInstanceProfiles is a list of IAM instance + profiles, which will be allowed to read worker nodes bootstrap + data from S3 Bucket. + items: + type: string + type: array + required: + - controlPlaneIAMInstanceProfile + - name + - nodesIAMInstanceProfiles + type: object sshKeyName: description: SSHKeyName is the name of the ssh key to attach to the bastion host. Valid values are empty string (do not use SSH keys), diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml index 7d46209438..b5d35f4a4b 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml @@ -690,6 +690,35 @@ spec: region: description: The AWS Region the cluster lives in. type: string + s3Bucket: + description: S3Bucket contains options to configure a supporting + S3 bucket for this cluster - currently used for nodes requiring + Ignition (https://coreos.github.io/ignition/) for bootstrapping + (requires BootstrapFormatIgnition feature flag to be enabled). + properties: + controlPlaneIAMInstanceProfile: + description: ControlPlaneIAMInstanceProfile is a name + of the IAMInstanceProfile, which will be allowed to + read control-plane node bootstrap data from S3 Bucket. + type: string + name: + description: Name defines name of S3 Bucket to be created. + maxLength: 63 + minLength: 3 + pattern: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ + type: string + nodesIAMInstanceProfiles: + description: NodesIAMInstanceProfiles is a list of IAM + instance profiles, which will be allowed to read worker + nodes bootstrap data from S3 Bucket. + items: + type: string + type: array + required: + - controlPlaneIAMInstanceProfile + - name + - nodesIAMInstanceProfiles + type: object sshKeyName: description: SSHKeyName is the name of the ssh key to attach to the bastion host. Valid values are empty string (do not From a897f04eeca4f0b10d6a10328832f038244d0e1b Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 16 Feb 2021 09:41:07 +0100 Subject: [PATCH 02/12] pkg/cloud/scope: add interface for getting S3Bucket spec from cluster It will be consumed by new S3 service implementing S3 access for creating bootstrapping data for systems, which do not support pulling user data from Secret Manager, like Ignition. Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- pkg/cloud/scope/cluster.go | 4 ++++ pkg/cloud/scope/s3.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 pkg/cloud/scope/s3.go diff --git a/pkg/cloud/scope/cluster.go b/pkg/cloud/scope/cluster.go index 74dea1622c..ea0de632d0 100644 --- a/pkg/cloud/scope/cluster.go +++ b/pkg/cloud/scope/cluster.go @@ -197,6 +197,10 @@ func (s *ClusterScope) ControlPlaneEndpoint() clusterv1.APIEndpoint { return s.AWSCluster.Spec.ControlPlaneEndpoint } +func (s *ClusterScope) Bucket() *infrav1.S3Bucket { + return s.AWSCluster.Spec.S3Bucket +} + // ControlPlaneConfigMapName returns the name of the ConfigMap used to // coordinate the bootstrapping of control plane nodes. func (s *ClusterScope) ControlPlaneConfigMapName() string { diff --git a/pkg/cloud/scope/s3.go b/pkg/cloud/scope/s3.go new file mode 100644 index 0000000000..a1a67f462a --- /dev/null +++ b/pkg/cloud/scope/s3.go @@ -0,0 +1,29 @@ +/* +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 scope + +import ( + infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud" +) + +// S3Scope is the interface for the scope to be used with the S3 service. +type S3Scope interface { + cloud.ClusterScoper + + Bucket() *infrav1.S3Bucket +} From 07a296fbded194c606ab64e2999486c837cb09da Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 16 Feb 2021 09:46:50 +0100 Subject: [PATCH 03/12] pkg/cloud/services/s3: initial commit This commit adds initial implementation of S3 service, which will be used to store bootstrap data for nodes, which do not support pulling them from Secret Manager, like ones using Ignition as bootstrap system. This commit also adds a function for creating a real S3 client similar to other functions in this package. Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- pkg/cloud/scope/clients.go | 12 + pkg/cloud/services/interfaces.go | 8 + pkg/cloud/services/mock_services/doc.go | 2 + .../objectstore_machine_interface_mock.go | 108 + pkg/cloud/services/s3/mock_s3iface/doc.go | 20 + .../services/s3/mock_s3iface/s3api_mock.go | 5150 +++++++++++++++++ pkg/cloud/services/s3/mock_stsiface/doc.go | 20 + .../services/s3/mock_stsiface/stsapi_mock.go | 453 ++ pkg/cloud/services/s3/s3.go | 288 + pkg/cloud/services/s3/s3_test.go | 762 +++ 10 files changed, 6823 insertions(+) create mode 100644 pkg/cloud/services/mock_services/objectstore_machine_interface_mock.go create mode 100644 pkg/cloud/services/s3/mock_s3iface/doc.go create mode 100644 pkg/cloud/services/s3/mock_s3iface/s3api_mock.go create mode 100644 pkg/cloud/services/s3/mock_stsiface/doc.go create mode 100644 pkg/cloud/services/s3/mock_stsiface/stsapi_mock.go create mode 100644 pkg/cloud/services/s3/s3.go create mode 100644 pkg/cloud/services/s3/s3_test.go diff --git a/pkg/cloud/scope/clients.go b/pkg/cloud/scope/clients.go index bdd64a2ecb..90aab64d39 100644 --- a/pkg/cloud/scope/clients.go +++ b/pkg/cloud/scope/clients.go @@ -34,6 +34,8 @@ import ( "github.com/aws/aws-sdk-go/service/iam/iamiface" "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3iface" "github.com/aws/aws-sdk-go/service/secretsmanager" "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" "github.com/aws/aws-sdk-go/service/sqs" @@ -182,6 +184,16 @@ func NewSSMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger clou return ssmClient } +// NewS3Client creates a new S3 API client for a given session. +func NewS3Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) s3iface.S3API { + s3Client := s3.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger))) + s3Client.Handlers.Build.PushFrontNamed(getUserAgentHandler()) + s3Client.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName())) + s3Client.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target)) + + return s3Client +} + func recordAWSPermissionsIssue(target runtime.Object) func(r *request.Request) { return func(r *request.Request) { if awsErr, ok := r.Error.(awserr.Error); ok { diff --git a/pkg/cloud/services/interfaces.go b/pkg/cloud/services/interfaces.go index 84988ee2c2..b71abeca14 100644 --- a/pkg/cloud/services/interfaces.go +++ b/pkg/cloud/services/interfaces.go @@ -102,3 +102,11 @@ type SecurityGroupInterface interface { DeleteSecurityGroups() error ReconcileSecurityGroups() error } + +// ObjectStoreInterface encapsulates the methods exposed to the machine actuator. +type ObjectStoreInterface interface { + DeleteBucket() error + ReconcileBucket() error + Delete(m *scope.MachineScope) error + Create(m *scope.MachineScope, data []byte) (objectURL string, err error) +} diff --git a/pkg/cloud/services/mock_services/doc.go b/pkg/cloud/services/mock_services/doc.go index 2f15e2df48..ec34fdb5e3 100644 --- a/pkg/cloud/services/mock_services/doc.go +++ b/pkg/cloud/services/mock_services/doc.go @@ -19,6 +19,8 @@ limitations under the License. //go:generate /usr/bin/env bash -c "cat ../../../../hack/boilerplate/boilerplate.generatego.txt ec2_interface_mock.go > _ec2_interface_mock.go && mv _ec2_interface_mock.go ec2_interface_mock.go" //go:generate ../../../../hack/tools/bin/mockgen -destination secretsmanager_machine_interface_mock.go -package mock_services sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services SecretInterface //go:generate /usr/bin/env bash -c "cat ../../../../hack/boilerplate/boilerplate.generatego.txt secretsmanager_machine_interface_mock.go > _secretsmanager_machine_interface_mock.go && mv _secretsmanager_machine_interface_mock.go secretsmanager_machine_interface_mock.go" +//go:generate ../../../../hack/tools/bin/mockgen -destination objectstore_machine_interface_mock.go -package mock_services sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services ObjectStoreInterface +//go:generate /usr/bin/env bash -c "cat ../../../../hack/boilerplate/boilerplate.generatego.txt objectstore_machine_interface_mock.go > _objectstore_machine_interface_mock.go && mv _objectstore_machine_interface_mock.go objectstore_machine_interface_mock.go" //go:generate ../../../../hack/tools/bin/mockgen -destination autoscaling_interface_mock.go -package mock_services sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services ASGInterface //go:generate /usr/bin/env bash -c "cat ../../../../hack/boilerplate/boilerplate.generatego.txt autoscaling_interface_mock.go > _autoscaling_interface_mock.go && mv _autoscaling_interface_mock.go autoscaling_interface_mock.go" //go:generate ../../../../hack/tools/bin/mockgen -destination elb_interface_mock.go -package mock_services sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services ELBInterface diff --git a/pkg/cloud/services/mock_services/objectstore_machine_interface_mock.go b/pkg/cloud/services/mock_services/objectstore_machine_interface_mock.go new file mode 100644 index 0000000000..ada2a6d76a --- /dev/null +++ b/pkg/cloud/services/mock_services/objectstore_machine_interface_mock.go @@ -0,0 +1,108 @@ +/* +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. +*/ + +// Code generated by MockGen. DO NOT EDIT. +// Source: sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services (interfaces: ObjectStoreInterface) + +// Package mock_services is a generated GoMock package. +package mock_services + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + scope "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope" +) + +// MockObjectStoreInterface is a mock of ObjectStoreInterface interface. +type MockObjectStoreInterface struct { + ctrl *gomock.Controller + recorder *MockObjectStoreInterfaceMockRecorder +} + +// MockObjectStoreInterfaceMockRecorder is the mock recorder for MockObjectStoreInterface. +type MockObjectStoreInterfaceMockRecorder struct { + mock *MockObjectStoreInterface +} + +// NewMockObjectStoreInterface creates a new mock instance. +func NewMockObjectStoreInterface(ctrl *gomock.Controller) *MockObjectStoreInterface { + mock := &MockObjectStoreInterface{ctrl: ctrl} + mock.recorder = &MockObjectStoreInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockObjectStoreInterface) EXPECT() *MockObjectStoreInterfaceMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockObjectStoreInterface) Create(arg0 *scope.MachineScope, arg1 []byte) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockObjectStoreInterfaceMockRecorder) Create(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockObjectStoreInterface)(nil).Create), arg0, arg1) +} + +// Delete mocks base method. +func (m *MockObjectStoreInterface) Delete(arg0 *scope.MachineScope) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockObjectStoreInterfaceMockRecorder) Delete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockObjectStoreInterface)(nil).Delete), arg0) +} + +// DeleteBucket mocks base method. +func (m *MockObjectStoreInterface) DeleteBucket() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucket") + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteBucket indicates an expected call of DeleteBucket. +func (mr *MockObjectStoreInterfaceMockRecorder) DeleteBucket() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucket", reflect.TypeOf((*MockObjectStoreInterface)(nil).DeleteBucket)) +} + +// ReconcileBucket mocks base method. +func (m *MockObjectStoreInterface) ReconcileBucket() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReconcileBucket") + ret0, _ := ret[0].(error) + return ret0 +} + +// ReconcileBucket indicates an expected call of ReconcileBucket. +func (mr *MockObjectStoreInterfaceMockRecorder) ReconcileBucket() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileBucket", reflect.TypeOf((*MockObjectStoreInterface)(nil).ReconcileBucket)) +} diff --git a/pkg/cloud/services/s3/mock_s3iface/doc.go b/pkg/cloud/services/s3/mock_s3iface/doc.go new file mode 100644 index 0000000000..ac3047d5d2 --- /dev/null +++ b/pkg/cloud/services/s3/mock_s3iface/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 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. +*/ + +// Run go generate to regenerate this mock. +//go:generate ../../../../../hack/tools/bin/mockgen -destination s3api_mock.go -package mock_s3iface github.com/aws/aws-sdk-go/service/s3/s3iface S3API +//go:generate /usr/bin/env bash -c "cat ../../../../../hack/boilerplate/boilerplate.generatego.txt s3api_mock.go > _s3api_mock.go && mv _s3api_mock.go s3api_mock.go" +package mock_s3iface //nolint diff --git a/pkg/cloud/services/s3/mock_s3iface/s3api_mock.go b/pkg/cloud/services/s3/mock_s3iface/s3api_mock.go new file mode 100644 index 0000000000..cf011b6de7 --- /dev/null +++ b/pkg/cloud/services/s3/mock_s3iface/s3api_mock.go @@ -0,0 +1,5150 @@ +/* +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. +*/ + +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/aws/aws-sdk-go/service/s3/s3iface (interfaces: S3API) + +// Package mock_s3iface is a generated GoMock package. +package mock_s3iface + +import ( + context "context" + reflect "reflect" + + request "github.com/aws/aws-sdk-go/aws/request" + s3 "github.com/aws/aws-sdk-go/service/s3" + gomock "github.com/golang/mock/gomock" +) + +// MockS3API is a mock of S3API interface. +type MockS3API struct { + ctrl *gomock.Controller + recorder *MockS3APIMockRecorder +} + +// MockS3APIMockRecorder is the mock recorder for MockS3API. +type MockS3APIMockRecorder struct { + mock *MockS3API +} + +// NewMockS3API creates a new mock instance. +func NewMockS3API(ctrl *gomock.Controller) *MockS3API { + mock := &MockS3API{ctrl: ctrl} + mock.recorder = &MockS3APIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockS3API) EXPECT() *MockS3APIMockRecorder { + return m.recorder +} + +// AbortMultipartUpload mocks base method. +func (m *MockS3API) AbortMultipartUpload(arg0 *s3.AbortMultipartUploadInput) (*s3.AbortMultipartUploadOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AbortMultipartUpload", arg0) + ret0, _ := ret[0].(*s3.AbortMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AbortMultipartUpload indicates an expected call of AbortMultipartUpload. +func (mr *MockS3APIMockRecorder) AbortMultipartUpload(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortMultipartUpload", reflect.TypeOf((*MockS3API)(nil).AbortMultipartUpload), arg0) +} + +// AbortMultipartUploadRequest mocks base method. +func (m *MockS3API) AbortMultipartUploadRequest(arg0 *s3.AbortMultipartUploadInput) (*request.Request, *s3.AbortMultipartUploadOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AbortMultipartUploadRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.AbortMultipartUploadOutput) + return ret0, ret1 +} + +// AbortMultipartUploadRequest indicates an expected call of AbortMultipartUploadRequest. +func (mr *MockS3APIMockRecorder) AbortMultipartUploadRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortMultipartUploadRequest", reflect.TypeOf((*MockS3API)(nil).AbortMultipartUploadRequest), arg0) +} + +// AbortMultipartUploadWithContext mocks base method. +func (m *MockS3API) AbortMultipartUploadWithContext(arg0 context.Context, arg1 *s3.AbortMultipartUploadInput, arg2 ...request.Option) (*s3.AbortMultipartUploadOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AbortMultipartUploadWithContext", varargs...) + ret0, _ := ret[0].(*s3.AbortMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AbortMultipartUploadWithContext indicates an expected call of AbortMultipartUploadWithContext. +func (mr *MockS3APIMockRecorder) AbortMultipartUploadWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortMultipartUploadWithContext", reflect.TypeOf((*MockS3API)(nil).AbortMultipartUploadWithContext), varargs...) +} + +// CompleteMultipartUpload mocks base method. +func (m *MockS3API) CompleteMultipartUpload(arg0 *s3.CompleteMultipartUploadInput) (*s3.CompleteMultipartUploadOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CompleteMultipartUpload", arg0) + ret0, _ := ret[0].(*s3.CompleteMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CompleteMultipartUpload indicates an expected call of CompleteMultipartUpload. +func (mr *MockS3APIMockRecorder) CompleteMultipartUpload(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteMultipartUpload", reflect.TypeOf((*MockS3API)(nil).CompleteMultipartUpload), arg0) +} + +// CompleteMultipartUploadRequest mocks base method. +func (m *MockS3API) CompleteMultipartUploadRequest(arg0 *s3.CompleteMultipartUploadInput) (*request.Request, *s3.CompleteMultipartUploadOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CompleteMultipartUploadRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.CompleteMultipartUploadOutput) + return ret0, ret1 +} + +// CompleteMultipartUploadRequest indicates an expected call of CompleteMultipartUploadRequest. +func (mr *MockS3APIMockRecorder) CompleteMultipartUploadRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteMultipartUploadRequest", reflect.TypeOf((*MockS3API)(nil).CompleteMultipartUploadRequest), arg0) +} + +// CompleteMultipartUploadWithContext mocks base method. +func (m *MockS3API) CompleteMultipartUploadWithContext(arg0 context.Context, arg1 *s3.CompleteMultipartUploadInput, arg2 ...request.Option) (*s3.CompleteMultipartUploadOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CompleteMultipartUploadWithContext", varargs...) + ret0, _ := ret[0].(*s3.CompleteMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CompleteMultipartUploadWithContext indicates an expected call of CompleteMultipartUploadWithContext. +func (mr *MockS3APIMockRecorder) CompleteMultipartUploadWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteMultipartUploadWithContext", reflect.TypeOf((*MockS3API)(nil).CompleteMultipartUploadWithContext), varargs...) +} + +// CopyObject mocks base method. +func (m *MockS3API) CopyObject(arg0 *s3.CopyObjectInput) (*s3.CopyObjectOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CopyObject", arg0) + ret0, _ := ret[0].(*s3.CopyObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CopyObject indicates an expected call of CopyObject. +func (mr *MockS3APIMockRecorder) CopyObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyObject", reflect.TypeOf((*MockS3API)(nil).CopyObject), arg0) +} + +// CopyObjectRequest mocks base method. +func (m *MockS3API) CopyObjectRequest(arg0 *s3.CopyObjectInput) (*request.Request, *s3.CopyObjectOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CopyObjectRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.CopyObjectOutput) + return ret0, ret1 +} + +// CopyObjectRequest indicates an expected call of CopyObjectRequest. +func (mr *MockS3APIMockRecorder) CopyObjectRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyObjectRequest", reflect.TypeOf((*MockS3API)(nil).CopyObjectRequest), arg0) +} + +// CopyObjectWithContext mocks base method. +func (m *MockS3API) CopyObjectWithContext(arg0 context.Context, arg1 *s3.CopyObjectInput, arg2 ...request.Option) (*s3.CopyObjectOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CopyObjectWithContext", varargs...) + ret0, _ := ret[0].(*s3.CopyObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CopyObjectWithContext indicates an expected call of CopyObjectWithContext. +func (mr *MockS3APIMockRecorder) CopyObjectWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyObjectWithContext", reflect.TypeOf((*MockS3API)(nil).CopyObjectWithContext), varargs...) +} + +// CreateBucket mocks base method. +func (m *MockS3API) CreateBucket(arg0 *s3.CreateBucketInput) (*s3.CreateBucketOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateBucket", arg0) + ret0, _ := ret[0].(*s3.CreateBucketOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateBucket indicates an expected call of CreateBucket. +func (mr *MockS3APIMockRecorder) CreateBucket(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBucket", reflect.TypeOf((*MockS3API)(nil).CreateBucket), arg0) +} + +// CreateBucketRequest mocks base method. +func (m *MockS3API) CreateBucketRequest(arg0 *s3.CreateBucketInput) (*request.Request, *s3.CreateBucketOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateBucketRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.CreateBucketOutput) + return ret0, ret1 +} + +// CreateBucketRequest indicates an expected call of CreateBucketRequest. +func (mr *MockS3APIMockRecorder) CreateBucketRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBucketRequest", reflect.TypeOf((*MockS3API)(nil).CreateBucketRequest), arg0) +} + +// CreateBucketWithContext mocks base method. +func (m *MockS3API) CreateBucketWithContext(arg0 context.Context, arg1 *s3.CreateBucketInput, arg2 ...request.Option) (*s3.CreateBucketOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateBucketWithContext", varargs...) + ret0, _ := ret[0].(*s3.CreateBucketOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateBucketWithContext indicates an expected call of CreateBucketWithContext. +func (mr *MockS3APIMockRecorder) CreateBucketWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBucketWithContext", reflect.TypeOf((*MockS3API)(nil).CreateBucketWithContext), varargs...) +} + +// CreateMultipartUpload mocks base method. +func (m *MockS3API) CreateMultipartUpload(arg0 *s3.CreateMultipartUploadInput) (*s3.CreateMultipartUploadOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateMultipartUpload", arg0) + ret0, _ := ret[0].(*s3.CreateMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateMultipartUpload indicates an expected call of CreateMultipartUpload. +func (mr *MockS3APIMockRecorder) CreateMultipartUpload(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMultipartUpload", reflect.TypeOf((*MockS3API)(nil).CreateMultipartUpload), arg0) +} + +// CreateMultipartUploadRequest mocks base method. +func (m *MockS3API) CreateMultipartUploadRequest(arg0 *s3.CreateMultipartUploadInput) (*request.Request, *s3.CreateMultipartUploadOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateMultipartUploadRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.CreateMultipartUploadOutput) + return ret0, ret1 +} + +// CreateMultipartUploadRequest indicates an expected call of CreateMultipartUploadRequest. +func (mr *MockS3APIMockRecorder) CreateMultipartUploadRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMultipartUploadRequest", reflect.TypeOf((*MockS3API)(nil).CreateMultipartUploadRequest), arg0) +} + +// CreateMultipartUploadWithContext mocks base method. +func (m *MockS3API) CreateMultipartUploadWithContext(arg0 context.Context, arg1 *s3.CreateMultipartUploadInput, arg2 ...request.Option) (*s3.CreateMultipartUploadOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateMultipartUploadWithContext", varargs...) + ret0, _ := ret[0].(*s3.CreateMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateMultipartUploadWithContext indicates an expected call of CreateMultipartUploadWithContext. +func (mr *MockS3APIMockRecorder) CreateMultipartUploadWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMultipartUploadWithContext", reflect.TypeOf((*MockS3API)(nil).CreateMultipartUploadWithContext), varargs...) +} + +// DeleteBucket mocks base method. +func (m *MockS3API) DeleteBucket(arg0 *s3.DeleteBucketInput) (*s3.DeleteBucketOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucket", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucket indicates an expected call of DeleteBucket. +func (mr *MockS3APIMockRecorder) DeleteBucket(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucket", reflect.TypeOf((*MockS3API)(nil).DeleteBucket), arg0) +} + +// DeleteBucketAnalyticsConfiguration mocks base method. +func (m *MockS3API) DeleteBucketAnalyticsConfiguration(arg0 *s3.DeleteBucketAnalyticsConfigurationInput) (*s3.DeleteBucketAnalyticsConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketAnalyticsConfiguration", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketAnalyticsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketAnalyticsConfiguration indicates an expected call of DeleteBucketAnalyticsConfiguration. +func (mr *MockS3APIMockRecorder) DeleteBucketAnalyticsConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketAnalyticsConfiguration", reflect.TypeOf((*MockS3API)(nil).DeleteBucketAnalyticsConfiguration), arg0) +} + +// DeleteBucketAnalyticsConfigurationRequest mocks base method. +func (m *MockS3API) DeleteBucketAnalyticsConfigurationRequest(arg0 *s3.DeleteBucketAnalyticsConfigurationInput) (*request.Request, *s3.DeleteBucketAnalyticsConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketAnalyticsConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketAnalyticsConfigurationOutput) + return ret0, ret1 +} + +// DeleteBucketAnalyticsConfigurationRequest indicates an expected call of DeleteBucketAnalyticsConfigurationRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketAnalyticsConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketAnalyticsConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketAnalyticsConfigurationRequest), arg0) +} + +// DeleteBucketAnalyticsConfigurationWithContext mocks base method. +func (m *MockS3API) DeleteBucketAnalyticsConfigurationWithContext(arg0 context.Context, arg1 *s3.DeleteBucketAnalyticsConfigurationInput, arg2 ...request.Option) (*s3.DeleteBucketAnalyticsConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketAnalyticsConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketAnalyticsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketAnalyticsConfigurationWithContext indicates an expected call of DeleteBucketAnalyticsConfigurationWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketAnalyticsConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketAnalyticsConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketAnalyticsConfigurationWithContext), varargs...) +} + +// DeleteBucketCors mocks base method. +func (m *MockS3API) DeleteBucketCors(arg0 *s3.DeleteBucketCorsInput) (*s3.DeleteBucketCorsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketCors", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketCorsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketCors indicates an expected call of DeleteBucketCors. +func (mr *MockS3APIMockRecorder) DeleteBucketCors(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketCors", reflect.TypeOf((*MockS3API)(nil).DeleteBucketCors), arg0) +} + +// DeleteBucketCorsRequest mocks base method. +func (m *MockS3API) DeleteBucketCorsRequest(arg0 *s3.DeleteBucketCorsInput) (*request.Request, *s3.DeleteBucketCorsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketCorsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketCorsOutput) + return ret0, ret1 +} + +// DeleteBucketCorsRequest indicates an expected call of DeleteBucketCorsRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketCorsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketCorsRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketCorsRequest), arg0) +} + +// DeleteBucketCorsWithContext mocks base method. +func (m *MockS3API) DeleteBucketCorsWithContext(arg0 context.Context, arg1 *s3.DeleteBucketCorsInput, arg2 ...request.Option) (*s3.DeleteBucketCorsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketCorsWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketCorsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketCorsWithContext indicates an expected call of DeleteBucketCorsWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketCorsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketCorsWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketCorsWithContext), varargs...) +} + +// DeleteBucketEncryption mocks base method. +func (m *MockS3API) DeleteBucketEncryption(arg0 *s3.DeleteBucketEncryptionInput) (*s3.DeleteBucketEncryptionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketEncryption", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketEncryptionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketEncryption indicates an expected call of DeleteBucketEncryption. +func (mr *MockS3APIMockRecorder) DeleteBucketEncryption(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketEncryption", reflect.TypeOf((*MockS3API)(nil).DeleteBucketEncryption), arg0) +} + +// DeleteBucketEncryptionRequest mocks base method. +func (m *MockS3API) DeleteBucketEncryptionRequest(arg0 *s3.DeleteBucketEncryptionInput) (*request.Request, *s3.DeleteBucketEncryptionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketEncryptionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketEncryptionOutput) + return ret0, ret1 +} + +// DeleteBucketEncryptionRequest indicates an expected call of DeleteBucketEncryptionRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketEncryptionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketEncryptionRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketEncryptionRequest), arg0) +} + +// DeleteBucketEncryptionWithContext mocks base method. +func (m *MockS3API) DeleteBucketEncryptionWithContext(arg0 context.Context, arg1 *s3.DeleteBucketEncryptionInput, arg2 ...request.Option) (*s3.DeleteBucketEncryptionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketEncryptionWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketEncryptionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketEncryptionWithContext indicates an expected call of DeleteBucketEncryptionWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketEncryptionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketEncryptionWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketEncryptionWithContext), varargs...) +} + +// DeleteBucketIntelligentTieringConfiguration mocks base method. +func (m *MockS3API) DeleteBucketIntelligentTieringConfiguration(arg0 *s3.DeleteBucketIntelligentTieringConfigurationInput) (*s3.DeleteBucketIntelligentTieringConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketIntelligentTieringConfiguration", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketIntelligentTieringConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketIntelligentTieringConfiguration indicates an expected call of DeleteBucketIntelligentTieringConfiguration. +func (mr *MockS3APIMockRecorder) DeleteBucketIntelligentTieringConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketIntelligentTieringConfiguration", reflect.TypeOf((*MockS3API)(nil).DeleteBucketIntelligentTieringConfiguration), arg0) +} + +// DeleteBucketIntelligentTieringConfigurationRequest mocks base method. +func (m *MockS3API) DeleteBucketIntelligentTieringConfigurationRequest(arg0 *s3.DeleteBucketIntelligentTieringConfigurationInput) (*request.Request, *s3.DeleteBucketIntelligentTieringConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketIntelligentTieringConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketIntelligentTieringConfigurationOutput) + return ret0, ret1 +} + +// DeleteBucketIntelligentTieringConfigurationRequest indicates an expected call of DeleteBucketIntelligentTieringConfigurationRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketIntelligentTieringConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketIntelligentTieringConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketIntelligentTieringConfigurationRequest), arg0) +} + +// DeleteBucketIntelligentTieringConfigurationWithContext mocks base method. +func (m *MockS3API) DeleteBucketIntelligentTieringConfigurationWithContext(arg0 context.Context, arg1 *s3.DeleteBucketIntelligentTieringConfigurationInput, arg2 ...request.Option) (*s3.DeleteBucketIntelligentTieringConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketIntelligentTieringConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketIntelligentTieringConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketIntelligentTieringConfigurationWithContext indicates an expected call of DeleteBucketIntelligentTieringConfigurationWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketIntelligentTieringConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketIntelligentTieringConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketIntelligentTieringConfigurationWithContext), varargs...) +} + +// DeleteBucketInventoryConfiguration mocks base method. +func (m *MockS3API) DeleteBucketInventoryConfiguration(arg0 *s3.DeleteBucketInventoryConfigurationInput) (*s3.DeleteBucketInventoryConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketInventoryConfiguration", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketInventoryConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketInventoryConfiguration indicates an expected call of DeleteBucketInventoryConfiguration. +func (mr *MockS3APIMockRecorder) DeleteBucketInventoryConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketInventoryConfiguration", reflect.TypeOf((*MockS3API)(nil).DeleteBucketInventoryConfiguration), arg0) +} + +// DeleteBucketInventoryConfigurationRequest mocks base method. +func (m *MockS3API) DeleteBucketInventoryConfigurationRequest(arg0 *s3.DeleteBucketInventoryConfigurationInput) (*request.Request, *s3.DeleteBucketInventoryConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketInventoryConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketInventoryConfigurationOutput) + return ret0, ret1 +} + +// DeleteBucketInventoryConfigurationRequest indicates an expected call of DeleteBucketInventoryConfigurationRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketInventoryConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketInventoryConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketInventoryConfigurationRequest), arg0) +} + +// DeleteBucketInventoryConfigurationWithContext mocks base method. +func (m *MockS3API) DeleteBucketInventoryConfigurationWithContext(arg0 context.Context, arg1 *s3.DeleteBucketInventoryConfigurationInput, arg2 ...request.Option) (*s3.DeleteBucketInventoryConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketInventoryConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketInventoryConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketInventoryConfigurationWithContext indicates an expected call of DeleteBucketInventoryConfigurationWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketInventoryConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketInventoryConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketInventoryConfigurationWithContext), varargs...) +} + +// DeleteBucketLifecycle mocks base method. +func (m *MockS3API) DeleteBucketLifecycle(arg0 *s3.DeleteBucketLifecycleInput) (*s3.DeleteBucketLifecycleOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketLifecycle", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketLifecycleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketLifecycle indicates an expected call of DeleteBucketLifecycle. +func (mr *MockS3APIMockRecorder) DeleteBucketLifecycle(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketLifecycle", reflect.TypeOf((*MockS3API)(nil).DeleteBucketLifecycle), arg0) +} + +// DeleteBucketLifecycleRequest mocks base method. +func (m *MockS3API) DeleteBucketLifecycleRequest(arg0 *s3.DeleteBucketLifecycleInput) (*request.Request, *s3.DeleteBucketLifecycleOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketLifecycleRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketLifecycleOutput) + return ret0, ret1 +} + +// DeleteBucketLifecycleRequest indicates an expected call of DeleteBucketLifecycleRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketLifecycleRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketLifecycleRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketLifecycleRequest), arg0) +} + +// DeleteBucketLifecycleWithContext mocks base method. +func (m *MockS3API) DeleteBucketLifecycleWithContext(arg0 context.Context, arg1 *s3.DeleteBucketLifecycleInput, arg2 ...request.Option) (*s3.DeleteBucketLifecycleOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketLifecycleWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketLifecycleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketLifecycleWithContext indicates an expected call of DeleteBucketLifecycleWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketLifecycleWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketLifecycleWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketLifecycleWithContext), varargs...) +} + +// DeleteBucketMetricsConfiguration mocks base method. +func (m *MockS3API) DeleteBucketMetricsConfiguration(arg0 *s3.DeleteBucketMetricsConfigurationInput) (*s3.DeleteBucketMetricsConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketMetricsConfiguration", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketMetricsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketMetricsConfiguration indicates an expected call of DeleteBucketMetricsConfiguration. +func (mr *MockS3APIMockRecorder) DeleteBucketMetricsConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketMetricsConfiguration", reflect.TypeOf((*MockS3API)(nil).DeleteBucketMetricsConfiguration), arg0) +} + +// DeleteBucketMetricsConfigurationRequest mocks base method. +func (m *MockS3API) DeleteBucketMetricsConfigurationRequest(arg0 *s3.DeleteBucketMetricsConfigurationInput) (*request.Request, *s3.DeleteBucketMetricsConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketMetricsConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketMetricsConfigurationOutput) + return ret0, ret1 +} + +// DeleteBucketMetricsConfigurationRequest indicates an expected call of DeleteBucketMetricsConfigurationRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketMetricsConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketMetricsConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketMetricsConfigurationRequest), arg0) +} + +// DeleteBucketMetricsConfigurationWithContext mocks base method. +func (m *MockS3API) DeleteBucketMetricsConfigurationWithContext(arg0 context.Context, arg1 *s3.DeleteBucketMetricsConfigurationInput, arg2 ...request.Option) (*s3.DeleteBucketMetricsConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketMetricsConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketMetricsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketMetricsConfigurationWithContext indicates an expected call of DeleteBucketMetricsConfigurationWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketMetricsConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketMetricsConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketMetricsConfigurationWithContext), varargs...) +} + +// DeleteBucketOwnershipControls mocks base method. +func (m *MockS3API) DeleteBucketOwnershipControls(arg0 *s3.DeleteBucketOwnershipControlsInput) (*s3.DeleteBucketOwnershipControlsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketOwnershipControls", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketOwnershipControlsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketOwnershipControls indicates an expected call of DeleteBucketOwnershipControls. +func (mr *MockS3APIMockRecorder) DeleteBucketOwnershipControls(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketOwnershipControls", reflect.TypeOf((*MockS3API)(nil).DeleteBucketOwnershipControls), arg0) +} + +// DeleteBucketOwnershipControlsRequest mocks base method. +func (m *MockS3API) DeleteBucketOwnershipControlsRequest(arg0 *s3.DeleteBucketOwnershipControlsInput) (*request.Request, *s3.DeleteBucketOwnershipControlsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketOwnershipControlsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketOwnershipControlsOutput) + return ret0, ret1 +} + +// DeleteBucketOwnershipControlsRequest indicates an expected call of DeleteBucketOwnershipControlsRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketOwnershipControlsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketOwnershipControlsRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketOwnershipControlsRequest), arg0) +} + +// DeleteBucketOwnershipControlsWithContext mocks base method. +func (m *MockS3API) DeleteBucketOwnershipControlsWithContext(arg0 context.Context, arg1 *s3.DeleteBucketOwnershipControlsInput, arg2 ...request.Option) (*s3.DeleteBucketOwnershipControlsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketOwnershipControlsWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketOwnershipControlsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketOwnershipControlsWithContext indicates an expected call of DeleteBucketOwnershipControlsWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketOwnershipControlsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketOwnershipControlsWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketOwnershipControlsWithContext), varargs...) +} + +// DeleteBucketPolicy mocks base method. +func (m *MockS3API) DeleteBucketPolicy(arg0 *s3.DeleteBucketPolicyInput) (*s3.DeleteBucketPolicyOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketPolicy", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketPolicy indicates an expected call of DeleteBucketPolicy. +func (mr *MockS3APIMockRecorder) DeleteBucketPolicy(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketPolicy", reflect.TypeOf((*MockS3API)(nil).DeleteBucketPolicy), arg0) +} + +// DeleteBucketPolicyRequest mocks base method. +func (m *MockS3API) DeleteBucketPolicyRequest(arg0 *s3.DeleteBucketPolicyInput) (*request.Request, *s3.DeleteBucketPolicyOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketPolicyRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketPolicyOutput) + return ret0, ret1 +} + +// DeleteBucketPolicyRequest indicates an expected call of DeleteBucketPolicyRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketPolicyRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketPolicyRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketPolicyRequest), arg0) +} + +// DeleteBucketPolicyWithContext mocks base method. +func (m *MockS3API) DeleteBucketPolicyWithContext(arg0 context.Context, arg1 *s3.DeleteBucketPolicyInput, arg2 ...request.Option) (*s3.DeleteBucketPolicyOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketPolicyWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketPolicyWithContext indicates an expected call of DeleteBucketPolicyWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketPolicyWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketPolicyWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketPolicyWithContext), varargs...) +} + +// DeleteBucketReplication mocks base method. +func (m *MockS3API) DeleteBucketReplication(arg0 *s3.DeleteBucketReplicationInput) (*s3.DeleteBucketReplicationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketReplication", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketReplicationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketReplication indicates an expected call of DeleteBucketReplication. +func (mr *MockS3APIMockRecorder) DeleteBucketReplication(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketReplication", reflect.TypeOf((*MockS3API)(nil).DeleteBucketReplication), arg0) +} + +// DeleteBucketReplicationRequest mocks base method. +func (m *MockS3API) DeleteBucketReplicationRequest(arg0 *s3.DeleteBucketReplicationInput) (*request.Request, *s3.DeleteBucketReplicationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketReplicationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketReplicationOutput) + return ret0, ret1 +} + +// DeleteBucketReplicationRequest indicates an expected call of DeleteBucketReplicationRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketReplicationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketReplicationRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketReplicationRequest), arg0) +} + +// DeleteBucketReplicationWithContext mocks base method. +func (m *MockS3API) DeleteBucketReplicationWithContext(arg0 context.Context, arg1 *s3.DeleteBucketReplicationInput, arg2 ...request.Option) (*s3.DeleteBucketReplicationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketReplicationWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketReplicationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketReplicationWithContext indicates an expected call of DeleteBucketReplicationWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketReplicationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketReplicationWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketReplicationWithContext), varargs...) +} + +// DeleteBucketRequest mocks base method. +func (m *MockS3API) DeleteBucketRequest(arg0 *s3.DeleteBucketInput) (*request.Request, *s3.DeleteBucketOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketOutput) + return ret0, ret1 +} + +// DeleteBucketRequest indicates an expected call of DeleteBucketRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketRequest), arg0) +} + +// DeleteBucketTagging mocks base method. +func (m *MockS3API) DeleteBucketTagging(arg0 *s3.DeleteBucketTaggingInput) (*s3.DeleteBucketTaggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketTagging", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketTagging indicates an expected call of DeleteBucketTagging. +func (mr *MockS3APIMockRecorder) DeleteBucketTagging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketTagging", reflect.TypeOf((*MockS3API)(nil).DeleteBucketTagging), arg0) +} + +// DeleteBucketTaggingRequest mocks base method. +func (m *MockS3API) DeleteBucketTaggingRequest(arg0 *s3.DeleteBucketTaggingInput) (*request.Request, *s3.DeleteBucketTaggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketTaggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketTaggingOutput) + return ret0, ret1 +} + +// DeleteBucketTaggingRequest indicates an expected call of DeleteBucketTaggingRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketTaggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketTaggingRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketTaggingRequest), arg0) +} + +// DeleteBucketTaggingWithContext mocks base method. +func (m *MockS3API) DeleteBucketTaggingWithContext(arg0 context.Context, arg1 *s3.DeleteBucketTaggingInput, arg2 ...request.Option) (*s3.DeleteBucketTaggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketTaggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketTaggingWithContext indicates an expected call of DeleteBucketTaggingWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketTaggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketTaggingWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketTaggingWithContext), varargs...) +} + +// DeleteBucketWebsite mocks base method. +func (m *MockS3API) DeleteBucketWebsite(arg0 *s3.DeleteBucketWebsiteInput) (*s3.DeleteBucketWebsiteOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketWebsite", arg0) + ret0, _ := ret[0].(*s3.DeleteBucketWebsiteOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketWebsite indicates an expected call of DeleteBucketWebsite. +func (mr *MockS3APIMockRecorder) DeleteBucketWebsite(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketWebsite", reflect.TypeOf((*MockS3API)(nil).DeleteBucketWebsite), arg0) +} + +// DeleteBucketWebsiteRequest mocks base method. +func (m *MockS3API) DeleteBucketWebsiteRequest(arg0 *s3.DeleteBucketWebsiteInput) (*request.Request, *s3.DeleteBucketWebsiteOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBucketWebsiteRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteBucketWebsiteOutput) + return ret0, ret1 +} + +// DeleteBucketWebsiteRequest indicates an expected call of DeleteBucketWebsiteRequest. +func (mr *MockS3APIMockRecorder) DeleteBucketWebsiteRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketWebsiteRequest", reflect.TypeOf((*MockS3API)(nil).DeleteBucketWebsiteRequest), arg0) +} + +// DeleteBucketWebsiteWithContext mocks base method. +func (m *MockS3API) DeleteBucketWebsiteWithContext(arg0 context.Context, arg1 *s3.DeleteBucketWebsiteInput, arg2 ...request.Option) (*s3.DeleteBucketWebsiteOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketWebsiteWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketWebsiteOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketWebsiteWithContext indicates an expected call of DeleteBucketWebsiteWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketWebsiteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketWebsiteWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketWebsiteWithContext), varargs...) +} + +// DeleteBucketWithContext mocks base method. +func (m *MockS3API) DeleteBucketWithContext(arg0 context.Context, arg1 *s3.DeleteBucketInput, arg2 ...request.Option) (*s3.DeleteBucketOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteBucketWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteBucketOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBucketWithContext indicates an expected call of DeleteBucketWithContext. +func (mr *MockS3APIMockRecorder) DeleteBucketWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteBucketWithContext), varargs...) +} + +// DeleteObject mocks base method. +func (m *MockS3API) DeleteObject(arg0 *s3.DeleteObjectInput) (*s3.DeleteObjectOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObject", arg0) + ret0, _ := ret[0].(*s3.DeleteObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteObject indicates an expected call of DeleteObject. +func (mr *MockS3APIMockRecorder) DeleteObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObject", reflect.TypeOf((*MockS3API)(nil).DeleteObject), arg0) +} + +// DeleteObjectRequest mocks base method. +func (m *MockS3API) DeleteObjectRequest(arg0 *s3.DeleteObjectInput) (*request.Request, *s3.DeleteObjectOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObjectRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteObjectOutput) + return ret0, ret1 +} + +// DeleteObjectRequest indicates an expected call of DeleteObjectRequest. +func (mr *MockS3APIMockRecorder) DeleteObjectRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectRequest", reflect.TypeOf((*MockS3API)(nil).DeleteObjectRequest), arg0) +} + +// DeleteObjectTagging mocks base method. +func (m *MockS3API) DeleteObjectTagging(arg0 *s3.DeleteObjectTaggingInput) (*s3.DeleteObjectTaggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObjectTagging", arg0) + ret0, _ := ret[0].(*s3.DeleteObjectTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteObjectTagging indicates an expected call of DeleteObjectTagging. +func (mr *MockS3APIMockRecorder) DeleteObjectTagging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectTagging", reflect.TypeOf((*MockS3API)(nil).DeleteObjectTagging), arg0) +} + +// DeleteObjectTaggingRequest mocks base method. +func (m *MockS3API) DeleteObjectTaggingRequest(arg0 *s3.DeleteObjectTaggingInput) (*request.Request, *s3.DeleteObjectTaggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObjectTaggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteObjectTaggingOutput) + return ret0, ret1 +} + +// DeleteObjectTaggingRequest indicates an expected call of DeleteObjectTaggingRequest. +func (mr *MockS3APIMockRecorder) DeleteObjectTaggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectTaggingRequest", reflect.TypeOf((*MockS3API)(nil).DeleteObjectTaggingRequest), arg0) +} + +// DeleteObjectTaggingWithContext mocks base method. +func (m *MockS3API) DeleteObjectTaggingWithContext(arg0 context.Context, arg1 *s3.DeleteObjectTaggingInput, arg2 ...request.Option) (*s3.DeleteObjectTaggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteObjectTaggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteObjectTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteObjectTaggingWithContext indicates an expected call of DeleteObjectTaggingWithContext. +func (mr *MockS3APIMockRecorder) DeleteObjectTaggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectTaggingWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteObjectTaggingWithContext), varargs...) +} + +// DeleteObjectWithContext mocks base method. +func (m *MockS3API) DeleteObjectWithContext(arg0 context.Context, arg1 *s3.DeleteObjectInput, arg2 ...request.Option) (*s3.DeleteObjectOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteObjectWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteObjectWithContext indicates an expected call of DeleteObjectWithContext. +func (mr *MockS3APIMockRecorder) DeleteObjectWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteObjectWithContext), varargs...) +} + +// DeleteObjects mocks base method. +func (m *MockS3API) DeleteObjects(arg0 *s3.DeleteObjectsInput) (*s3.DeleteObjectsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObjects", arg0) + ret0, _ := ret[0].(*s3.DeleteObjectsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteObjects indicates an expected call of DeleteObjects. +func (mr *MockS3APIMockRecorder) DeleteObjects(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjects", reflect.TypeOf((*MockS3API)(nil).DeleteObjects), arg0) +} + +// DeleteObjectsRequest mocks base method. +func (m *MockS3API) DeleteObjectsRequest(arg0 *s3.DeleteObjectsInput) (*request.Request, *s3.DeleteObjectsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteObjectsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeleteObjectsOutput) + return ret0, ret1 +} + +// DeleteObjectsRequest indicates an expected call of DeleteObjectsRequest. +func (mr *MockS3APIMockRecorder) DeleteObjectsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectsRequest", reflect.TypeOf((*MockS3API)(nil).DeleteObjectsRequest), arg0) +} + +// DeleteObjectsWithContext mocks base method. +func (m *MockS3API) DeleteObjectsWithContext(arg0 context.Context, arg1 *s3.DeleteObjectsInput, arg2 ...request.Option) (*s3.DeleteObjectsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteObjectsWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeleteObjectsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteObjectsWithContext indicates an expected call of DeleteObjectsWithContext. +func (mr *MockS3APIMockRecorder) DeleteObjectsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObjectsWithContext", reflect.TypeOf((*MockS3API)(nil).DeleteObjectsWithContext), varargs...) +} + +// DeletePublicAccessBlock mocks base method. +func (m *MockS3API) DeletePublicAccessBlock(arg0 *s3.DeletePublicAccessBlockInput) (*s3.DeletePublicAccessBlockOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeletePublicAccessBlock", arg0) + ret0, _ := ret[0].(*s3.DeletePublicAccessBlockOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeletePublicAccessBlock indicates an expected call of DeletePublicAccessBlock. +func (mr *MockS3APIMockRecorder) DeletePublicAccessBlock(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePublicAccessBlock", reflect.TypeOf((*MockS3API)(nil).DeletePublicAccessBlock), arg0) +} + +// DeletePublicAccessBlockRequest mocks base method. +func (m *MockS3API) DeletePublicAccessBlockRequest(arg0 *s3.DeletePublicAccessBlockInput) (*request.Request, *s3.DeletePublicAccessBlockOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeletePublicAccessBlockRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.DeletePublicAccessBlockOutput) + return ret0, ret1 +} + +// DeletePublicAccessBlockRequest indicates an expected call of DeletePublicAccessBlockRequest. +func (mr *MockS3APIMockRecorder) DeletePublicAccessBlockRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePublicAccessBlockRequest", reflect.TypeOf((*MockS3API)(nil).DeletePublicAccessBlockRequest), arg0) +} + +// DeletePublicAccessBlockWithContext mocks base method. +func (m *MockS3API) DeletePublicAccessBlockWithContext(arg0 context.Context, arg1 *s3.DeletePublicAccessBlockInput, arg2 ...request.Option) (*s3.DeletePublicAccessBlockOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeletePublicAccessBlockWithContext", varargs...) + ret0, _ := ret[0].(*s3.DeletePublicAccessBlockOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeletePublicAccessBlockWithContext indicates an expected call of DeletePublicAccessBlockWithContext. +func (mr *MockS3APIMockRecorder) DeletePublicAccessBlockWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePublicAccessBlockWithContext", reflect.TypeOf((*MockS3API)(nil).DeletePublicAccessBlockWithContext), varargs...) +} + +// GetBucketAccelerateConfiguration mocks base method. +func (m *MockS3API) GetBucketAccelerateConfiguration(arg0 *s3.GetBucketAccelerateConfigurationInput) (*s3.GetBucketAccelerateConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketAccelerateConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetBucketAccelerateConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketAccelerateConfiguration indicates an expected call of GetBucketAccelerateConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketAccelerateConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAccelerateConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketAccelerateConfiguration), arg0) +} + +// GetBucketAccelerateConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketAccelerateConfigurationRequest(arg0 *s3.GetBucketAccelerateConfigurationInput) (*request.Request, *s3.GetBucketAccelerateConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketAccelerateConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketAccelerateConfigurationOutput) + return ret0, ret1 +} + +// GetBucketAccelerateConfigurationRequest indicates an expected call of GetBucketAccelerateConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketAccelerateConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAccelerateConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketAccelerateConfigurationRequest), arg0) +} + +// GetBucketAccelerateConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketAccelerateConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketAccelerateConfigurationInput, arg2 ...request.Option) (*s3.GetBucketAccelerateConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketAccelerateConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketAccelerateConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketAccelerateConfigurationWithContext indicates an expected call of GetBucketAccelerateConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketAccelerateConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAccelerateConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketAccelerateConfigurationWithContext), varargs...) +} + +// GetBucketAcl mocks base method. +func (m *MockS3API) GetBucketAcl(arg0 *s3.GetBucketAclInput) (*s3.GetBucketAclOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketAcl", arg0) + ret0, _ := ret[0].(*s3.GetBucketAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketAcl indicates an expected call of GetBucketAcl. +func (mr *MockS3APIMockRecorder) GetBucketAcl(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAcl", reflect.TypeOf((*MockS3API)(nil).GetBucketAcl), arg0) +} + +// GetBucketAclRequest mocks base method. +func (m *MockS3API) GetBucketAclRequest(arg0 *s3.GetBucketAclInput) (*request.Request, *s3.GetBucketAclOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketAclRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketAclOutput) + return ret0, ret1 +} + +// GetBucketAclRequest indicates an expected call of GetBucketAclRequest. +func (mr *MockS3APIMockRecorder) GetBucketAclRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAclRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketAclRequest), arg0) +} + +// GetBucketAclWithContext mocks base method. +func (m *MockS3API) GetBucketAclWithContext(arg0 context.Context, arg1 *s3.GetBucketAclInput, arg2 ...request.Option) (*s3.GetBucketAclOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketAclWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketAclWithContext indicates an expected call of GetBucketAclWithContext. +func (mr *MockS3APIMockRecorder) GetBucketAclWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAclWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketAclWithContext), varargs...) +} + +// GetBucketAnalyticsConfiguration mocks base method. +func (m *MockS3API) GetBucketAnalyticsConfiguration(arg0 *s3.GetBucketAnalyticsConfigurationInput) (*s3.GetBucketAnalyticsConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketAnalyticsConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetBucketAnalyticsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketAnalyticsConfiguration indicates an expected call of GetBucketAnalyticsConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketAnalyticsConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAnalyticsConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketAnalyticsConfiguration), arg0) +} + +// GetBucketAnalyticsConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketAnalyticsConfigurationRequest(arg0 *s3.GetBucketAnalyticsConfigurationInput) (*request.Request, *s3.GetBucketAnalyticsConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketAnalyticsConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketAnalyticsConfigurationOutput) + return ret0, ret1 +} + +// GetBucketAnalyticsConfigurationRequest indicates an expected call of GetBucketAnalyticsConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketAnalyticsConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAnalyticsConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketAnalyticsConfigurationRequest), arg0) +} + +// GetBucketAnalyticsConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketAnalyticsConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketAnalyticsConfigurationInput, arg2 ...request.Option) (*s3.GetBucketAnalyticsConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketAnalyticsConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketAnalyticsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketAnalyticsConfigurationWithContext indicates an expected call of GetBucketAnalyticsConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketAnalyticsConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketAnalyticsConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketAnalyticsConfigurationWithContext), varargs...) +} + +// GetBucketCors mocks base method. +func (m *MockS3API) GetBucketCors(arg0 *s3.GetBucketCorsInput) (*s3.GetBucketCorsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketCors", arg0) + ret0, _ := ret[0].(*s3.GetBucketCorsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketCors indicates an expected call of GetBucketCors. +func (mr *MockS3APIMockRecorder) GetBucketCors(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketCors", reflect.TypeOf((*MockS3API)(nil).GetBucketCors), arg0) +} + +// GetBucketCorsRequest mocks base method. +func (m *MockS3API) GetBucketCorsRequest(arg0 *s3.GetBucketCorsInput) (*request.Request, *s3.GetBucketCorsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketCorsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketCorsOutput) + return ret0, ret1 +} + +// GetBucketCorsRequest indicates an expected call of GetBucketCorsRequest. +func (mr *MockS3APIMockRecorder) GetBucketCorsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketCorsRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketCorsRequest), arg0) +} + +// GetBucketCorsWithContext mocks base method. +func (m *MockS3API) GetBucketCorsWithContext(arg0 context.Context, arg1 *s3.GetBucketCorsInput, arg2 ...request.Option) (*s3.GetBucketCorsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketCorsWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketCorsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketCorsWithContext indicates an expected call of GetBucketCorsWithContext. +func (mr *MockS3APIMockRecorder) GetBucketCorsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketCorsWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketCorsWithContext), varargs...) +} + +// GetBucketEncryption mocks base method. +func (m *MockS3API) GetBucketEncryption(arg0 *s3.GetBucketEncryptionInput) (*s3.GetBucketEncryptionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketEncryption", arg0) + ret0, _ := ret[0].(*s3.GetBucketEncryptionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketEncryption indicates an expected call of GetBucketEncryption. +func (mr *MockS3APIMockRecorder) GetBucketEncryption(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketEncryption", reflect.TypeOf((*MockS3API)(nil).GetBucketEncryption), arg0) +} + +// GetBucketEncryptionRequest mocks base method. +func (m *MockS3API) GetBucketEncryptionRequest(arg0 *s3.GetBucketEncryptionInput) (*request.Request, *s3.GetBucketEncryptionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketEncryptionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketEncryptionOutput) + return ret0, ret1 +} + +// GetBucketEncryptionRequest indicates an expected call of GetBucketEncryptionRequest. +func (mr *MockS3APIMockRecorder) GetBucketEncryptionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketEncryptionRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketEncryptionRequest), arg0) +} + +// GetBucketEncryptionWithContext mocks base method. +func (m *MockS3API) GetBucketEncryptionWithContext(arg0 context.Context, arg1 *s3.GetBucketEncryptionInput, arg2 ...request.Option) (*s3.GetBucketEncryptionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketEncryptionWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketEncryptionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketEncryptionWithContext indicates an expected call of GetBucketEncryptionWithContext. +func (mr *MockS3APIMockRecorder) GetBucketEncryptionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketEncryptionWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketEncryptionWithContext), varargs...) +} + +// GetBucketIntelligentTieringConfiguration mocks base method. +func (m *MockS3API) GetBucketIntelligentTieringConfiguration(arg0 *s3.GetBucketIntelligentTieringConfigurationInput) (*s3.GetBucketIntelligentTieringConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketIntelligentTieringConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetBucketIntelligentTieringConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketIntelligentTieringConfiguration indicates an expected call of GetBucketIntelligentTieringConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketIntelligentTieringConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketIntelligentTieringConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketIntelligentTieringConfiguration), arg0) +} + +// GetBucketIntelligentTieringConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketIntelligentTieringConfigurationRequest(arg0 *s3.GetBucketIntelligentTieringConfigurationInput) (*request.Request, *s3.GetBucketIntelligentTieringConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketIntelligentTieringConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketIntelligentTieringConfigurationOutput) + return ret0, ret1 +} + +// GetBucketIntelligentTieringConfigurationRequest indicates an expected call of GetBucketIntelligentTieringConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketIntelligentTieringConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketIntelligentTieringConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketIntelligentTieringConfigurationRequest), arg0) +} + +// GetBucketIntelligentTieringConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketIntelligentTieringConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketIntelligentTieringConfigurationInput, arg2 ...request.Option) (*s3.GetBucketIntelligentTieringConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketIntelligentTieringConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketIntelligentTieringConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketIntelligentTieringConfigurationWithContext indicates an expected call of GetBucketIntelligentTieringConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketIntelligentTieringConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketIntelligentTieringConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketIntelligentTieringConfigurationWithContext), varargs...) +} + +// GetBucketInventoryConfiguration mocks base method. +func (m *MockS3API) GetBucketInventoryConfiguration(arg0 *s3.GetBucketInventoryConfigurationInput) (*s3.GetBucketInventoryConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketInventoryConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetBucketInventoryConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketInventoryConfiguration indicates an expected call of GetBucketInventoryConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketInventoryConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketInventoryConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketInventoryConfiguration), arg0) +} + +// GetBucketInventoryConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketInventoryConfigurationRequest(arg0 *s3.GetBucketInventoryConfigurationInput) (*request.Request, *s3.GetBucketInventoryConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketInventoryConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketInventoryConfigurationOutput) + return ret0, ret1 +} + +// GetBucketInventoryConfigurationRequest indicates an expected call of GetBucketInventoryConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketInventoryConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketInventoryConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketInventoryConfigurationRequest), arg0) +} + +// GetBucketInventoryConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketInventoryConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketInventoryConfigurationInput, arg2 ...request.Option) (*s3.GetBucketInventoryConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketInventoryConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketInventoryConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketInventoryConfigurationWithContext indicates an expected call of GetBucketInventoryConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketInventoryConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketInventoryConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketInventoryConfigurationWithContext), varargs...) +} + +// GetBucketLifecycle mocks base method. +func (m *MockS3API) GetBucketLifecycle(arg0 *s3.GetBucketLifecycleInput) (*s3.GetBucketLifecycleOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLifecycle", arg0) + ret0, _ := ret[0].(*s3.GetBucketLifecycleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLifecycle indicates an expected call of GetBucketLifecycle. +func (mr *MockS3APIMockRecorder) GetBucketLifecycle(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLifecycle", reflect.TypeOf((*MockS3API)(nil).GetBucketLifecycle), arg0) +} + +// GetBucketLifecycleConfiguration mocks base method. +func (m *MockS3API) GetBucketLifecycleConfiguration(arg0 *s3.GetBucketLifecycleConfigurationInput) (*s3.GetBucketLifecycleConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLifecycleConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetBucketLifecycleConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLifecycleConfiguration indicates an expected call of GetBucketLifecycleConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketLifecycleConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLifecycleConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketLifecycleConfiguration), arg0) +} + +// GetBucketLifecycleConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketLifecycleConfigurationRequest(arg0 *s3.GetBucketLifecycleConfigurationInput) (*request.Request, *s3.GetBucketLifecycleConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLifecycleConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketLifecycleConfigurationOutput) + return ret0, ret1 +} + +// GetBucketLifecycleConfigurationRequest indicates an expected call of GetBucketLifecycleConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketLifecycleConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLifecycleConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketLifecycleConfigurationRequest), arg0) +} + +// GetBucketLifecycleConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketLifecycleConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketLifecycleConfigurationInput, arg2 ...request.Option) (*s3.GetBucketLifecycleConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketLifecycleConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketLifecycleConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLifecycleConfigurationWithContext indicates an expected call of GetBucketLifecycleConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketLifecycleConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLifecycleConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketLifecycleConfigurationWithContext), varargs...) +} + +// GetBucketLifecycleRequest mocks base method. +func (m *MockS3API) GetBucketLifecycleRequest(arg0 *s3.GetBucketLifecycleInput) (*request.Request, *s3.GetBucketLifecycleOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLifecycleRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketLifecycleOutput) + return ret0, ret1 +} + +// GetBucketLifecycleRequest indicates an expected call of GetBucketLifecycleRequest. +func (mr *MockS3APIMockRecorder) GetBucketLifecycleRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLifecycleRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketLifecycleRequest), arg0) +} + +// GetBucketLifecycleWithContext mocks base method. +func (m *MockS3API) GetBucketLifecycleWithContext(arg0 context.Context, arg1 *s3.GetBucketLifecycleInput, arg2 ...request.Option) (*s3.GetBucketLifecycleOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketLifecycleWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketLifecycleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLifecycleWithContext indicates an expected call of GetBucketLifecycleWithContext. +func (mr *MockS3APIMockRecorder) GetBucketLifecycleWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLifecycleWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketLifecycleWithContext), varargs...) +} + +// GetBucketLocation mocks base method. +func (m *MockS3API) GetBucketLocation(arg0 *s3.GetBucketLocationInput) (*s3.GetBucketLocationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLocation", arg0) + ret0, _ := ret[0].(*s3.GetBucketLocationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLocation indicates an expected call of GetBucketLocation. +func (mr *MockS3APIMockRecorder) GetBucketLocation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLocation", reflect.TypeOf((*MockS3API)(nil).GetBucketLocation), arg0) +} + +// GetBucketLocationRequest mocks base method. +func (m *MockS3API) GetBucketLocationRequest(arg0 *s3.GetBucketLocationInput) (*request.Request, *s3.GetBucketLocationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLocationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketLocationOutput) + return ret0, ret1 +} + +// GetBucketLocationRequest indicates an expected call of GetBucketLocationRequest. +func (mr *MockS3APIMockRecorder) GetBucketLocationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLocationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketLocationRequest), arg0) +} + +// GetBucketLocationWithContext mocks base method. +func (m *MockS3API) GetBucketLocationWithContext(arg0 context.Context, arg1 *s3.GetBucketLocationInput, arg2 ...request.Option) (*s3.GetBucketLocationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketLocationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketLocationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLocationWithContext indicates an expected call of GetBucketLocationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketLocationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLocationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketLocationWithContext), varargs...) +} + +// GetBucketLogging mocks base method. +func (m *MockS3API) GetBucketLogging(arg0 *s3.GetBucketLoggingInput) (*s3.GetBucketLoggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLogging", arg0) + ret0, _ := ret[0].(*s3.GetBucketLoggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLogging indicates an expected call of GetBucketLogging. +func (mr *MockS3APIMockRecorder) GetBucketLogging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLogging", reflect.TypeOf((*MockS3API)(nil).GetBucketLogging), arg0) +} + +// GetBucketLoggingRequest mocks base method. +func (m *MockS3API) GetBucketLoggingRequest(arg0 *s3.GetBucketLoggingInput) (*request.Request, *s3.GetBucketLoggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketLoggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketLoggingOutput) + return ret0, ret1 +} + +// GetBucketLoggingRequest indicates an expected call of GetBucketLoggingRequest. +func (mr *MockS3APIMockRecorder) GetBucketLoggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLoggingRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketLoggingRequest), arg0) +} + +// GetBucketLoggingWithContext mocks base method. +func (m *MockS3API) GetBucketLoggingWithContext(arg0 context.Context, arg1 *s3.GetBucketLoggingInput, arg2 ...request.Option) (*s3.GetBucketLoggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketLoggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketLoggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketLoggingWithContext indicates an expected call of GetBucketLoggingWithContext. +func (mr *MockS3APIMockRecorder) GetBucketLoggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketLoggingWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketLoggingWithContext), varargs...) +} + +// GetBucketMetricsConfiguration mocks base method. +func (m *MockS3API) GetBucketMetricsConfiguration(arg0 *s3.GetBucketMetricsConfigurationInput) (*s3.GetBucketMetricsConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketMetricsConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetBucketMetricsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketMetricsConfiguration indicates an expected call of GetBucketMetricsConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketMetricsConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketMetricsConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketMetricsConfiguration), arg0) +} + +// GetBucketMetricsConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketMetricsConfigurationRequest(arg0 *s3.GetBucketMetricsConfigurationInput) (*request.Request, *s3.GetBucketMetricsConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketMetricsConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketMetricsConfigurationOutput) + return ret0, ret1 +} + +// GetBucketMetricsConfigurationRequest indicates an expected call of GetBucketMetricsConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketMetricsConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketMetricsConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketMetricsConfigurationRequest), arg0) +} + +// GetBucketMetricsConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketMetricsConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketMetricsConfigurationInput, arg2 ...request.Option) (*s3.GetBucketMetricsConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketMetricsConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketMetricsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketMetricsConfigurationWithContext indicates an expected call of GetBucketMetricsConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketMetricsConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketMetricsConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketMetricsConfigurationWithContext), varargs...) +} + +// GetBucketNotification mocks base method. +func (m *MockS3API) GetBucketNotification(arg0 *s3.GetBucketNotificationConfigurationRequest) (*s3.NotificationConfigurationDeprecated, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketNotification", arg0) + ret0, _ := ret[0].(*s3.NotificationConfigurationDeprecated) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketNotification indicates an expected call of GetBucketNotification. +func (mr *MockS3APIMockRecorder) GetBucketNotification(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketNotification", reflect.TypeOf((*MockS3API)(nil).GetBucketNotification), arg0) +} + +// GetBucketNotificationConfiguration mocks base method. +func (m *MockS3API) GetBucketNotificationConfiguration(arg0 *s3.GetBucketNotificationConfigurationRequest) (*s3.NotificationConfiguration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketNotificationConfiguration", arg0) + ret0, _ := ret[0].(*s3.NotificationConfiguration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketNotificationConfiguration indicates an expected call of GetBucketNotificationConfiguration. +func (mr *MockS3APIMockRecorder) GetBucketNotificationConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketNotificationConfiguration", reflect.TypeOf((*MockS3API)(nil).GetBucketNotificationConfiguration), arg0) +} + +// GetBucketNotificationConfigurationRequest mocks base method. +func (m *MockS3API) GetBucketNotificationConfigurationRequest(arg0 *s3.GetBucketNotificationConfigurationRequest) (*request.Request, *s3.NotificationConfiguration) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketNotificationConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.NotificationConfiguration) + return ret0, ret1 +} + +// GetBucketNotificationConfigurationRequest indicates an expected call of GetBucketNotificationConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetBucketNotificationConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketNotificationConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketNotificationConfigurationRequest), arg0) +} + +// GetBucketNotificationConfigurationWithContext mocks base method. +func (m *MockS3API) GetBucketNotificationConfigurationWithContext(arg0 context.Context, arg1 *s3.GetBucketNotificationConfigurationRequest, arg2 ...request.Option) (*s3.NotificationConfiguration, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketNotificationConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.NotificationConfiguration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketNotificationConfigurationWithContext indicates an expected call of GetBucketNotificationConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketNotificationConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketNotificationConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketNotificationConfigurationWithContext), varargs...) +} + +// GetBucketNotificationRequest mocks base method. +func (m *MockS3API) GetBucketNotificationRequest(arg0 *s3.GetBucketNotificationConfigurationRequest) (*request.Request, *s3.NotificationConfigurationDeprecated) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketNotificationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.NotificationConfigurationDeprecated) + return ret0, ret1 +} + +// GetBucketNotificationRequest indicates an expected call of GetBucketNotificationRequest. +func (mr *MockS3APIMockRecorder) GetBucketNotificationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketNotificationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketNotificationRequest), arg0) +} + +// GetBucketNotificationWithContext mocks base method. +func (m *MockS3API) GetBucketNotificationWithContext(arg0 context.Context, arg1 *s3.GetBucketNotificationConfigurationRequest, arg2 ...request.Option) (*s3.NotificationConfigurationDeprecated, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketNotificationWithContext", varargs...) + ret0, _ := ret[0].(*s3.NotificationConfigurationDeprecated) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketNotificationWithContext indicates an expected call of GetBucketNotificationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketNotificationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketNotificationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketNotificationWithContext), varargs...) +} + +// GetBucketOwnershipControls mocks base method. +func (m *MockS3API) GetBucketOwnershipControls(arg0 *s3.GetBucketOwnershipControlsInput) (*s3.GetBucketOwnershipControlsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketOwnershipControls", arg0) + ret0, _ := ret[0].(*s3.GetBucketOwnershipControlsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketOwnershipControls indicates an expected call of GetBucketOwnershipControls. +func (mr *MockS3APIMockRecorder) GetBucketOwnershipControls(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketOwnershipControls", reflect.TypeOf((*MockS3API)(nil).GetBucketOwnershipControls), arg0) +} + +// GetBucketOwnershipControlsRequest mocks base method. +func (m *MockS3API) GetBucketOwnershipControlsRequest(arg0 *s3.GetBucketOwnershipControlsInput) (*request.Request, *s3.GetBucketOwnershipControlsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketOwnershipControlsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketOwnershipControlsOutput) + return ret0, ret1 +} + +// GetBucketOwnershipControlsRequest indicates an expected call of GetBucketOwnershipControlsRequest. +func (mr *MockS3APIMockRecorder) GetBucketOwnershipControlsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketOwnershipControlsRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketOwnershipControlsRequest), arg0) +} + +// GetBucketOwnershipControlsWithContext mocks base method. +func (m *MockS3API) GetBucketOwnershipControlsWithContext(arg0 context.Context, arg1 *s3.GetBucketOwnershipControlsInput, arg2 ...request.Option) (*s3.GetBucketOwnershipControlsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketOwnershipControlsWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketOwnershipControlsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketOwnershipControlsWithContext indicates an expected call of GetBucketOwnershipControlsWithContext. +func (mr *MockS3APIMockRecorder) GetBucketOwnershipControlsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketOwnershipControlsWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketOwnershipControlsWithContext), varargs...) +} + +// GetBucketPolicy mocks base method. +func (m *MockS3API) GetBucketPolicy(arg0 *s3.GetBucketPolicyInput) (*s3.GetBucketPolicyOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketPolicy", arg0) + ret0, _ := ret[0].(*s3.GetBucketPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketPolicy indicates an expected call of GetBucketPolicy. +func (mr *MockS3APIMockRecorder) GetBucketPolicy(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketPolicy", reflect.TypeOf((*MockS3API)(nil).GetBucketPolicy), arg0) +} + +// GetBucketPolicyRequest mocks base method. +func (m *MockS3API) GetBucketPolicyRequest(arg0 *s3.GetBucketPolicyInput) (*request.Request, *s3.GetBucketPolicyOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketPolicyRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketPolicyOutput) + return ret0, ret1 +} + +// GetBucketPolicyRequest indicates an expected call of GetBucketPolicyRequest. +func (mr *MockS3APIMockRecorder) GetBucketPolicyRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketPolicyRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketPolicyRequest), arg0) +} + +// GetBucketPolicyStatus mocks base method. +func (m *MockS3API) GetBucketPolicyStatus(arg0 *s3.GetBucketPolicyStatusInput) (*s3.GetBucketPolicyStatusOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketPolicyStatus", arg0) + ret0, _ := ret[0].(*s3.GetBucketPolicyStatusOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketPolicyStatus indicates an expected call of GetBucketPolicyStatus. +func (mr *MockS3APIMockRecorder) GetBucketPolicyStatus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketPolicyStatus", reflect.TypeOf((*MockS3API)(nil).GetBucketPolicyStatus), arg0) +} + +// GetBucketPolicyStatusRequest mocks base method. +func (m *MockS3API) GetBucketPolicyStatusRequest(arg0 *s3.GetBucketPolicyStatusInput) (*request.Request, *s3.GetBucketPolicyStatusOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketPolicyStatusRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketPolicyStatusOutput) + return ret0, ret1 +} + +// GetBucketPolicyStatusRequest indicates an expected call of GetBucketPolicyStatusRequest. +func (mr *MockS3APIMockRecorder) GetBucketPolicyStatusRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketPolicyStatusRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketPolicyStatusRequest), arg0) +} + +// GetBucketPolicyStatusWithContext mocks base method. +func (m *MockS3API) GetBucketPolicyStatusWithContext(arg0 context.Context, arg1 *s3.GetBucketPolicyStatusInput, arg2 ...request.Option) (*s3.GetBucketPolicyStatusOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketPolicyStatusWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketPolicyStatusOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketPolicyStatusWithContext indicates an expected call of GetBucketPolicyStatusWithContext. +func (mr *MockS3APIMockRecorder) GetBucketPolicyStatusWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketPolicyStatusWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketPolicyStatusWithContext), varargs...) +} + +// GetBucketPolicyWithContext mocks base method. +func (m *MockS3API) GetBucketPolicyWithContext(arg0 context.Context, arg1 *s3.GetBucketPolicyInput, arg2 ...request.Option) (*s3.GetBucketPolicyOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketPolicyWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketPolicyWithContext indicates an expected call of GetBucketPolicyWithContext. +func (mr *MockS3APIMockRecorder) GetBucketPolicyWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketPolicyWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketPolicyWithContext), varargs...) +} + +// GetBucketReplication mocks base method. +func (m *MockS3API) GetBucketReplication(arg0 *s3.GetBucketReplicationInput) (*s3.GetBucketReplicationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketReplication", arg0) + ret0, _ := ret[0].(*s3.GetBucketReplicationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketReplication indicates an expected call of GetBucketReplication. +func (mr *MockS3APIMockRecorder) GetBucketReplication(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketReplication", reflect.TypeOf((*MockS3API)(nil).GetBucketReplication), arg0) +} + +// GetBucketReplicationRequest mocks base method. +func (m *MockS3API) GetBucketReplicationRequest(arg0 *s3.GetBucketReplicationInput) (*request.Request, *s3.GetBucketReplicationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketReplicationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketReplicationOutput) + return ret0, ret1 +} + +// GetBucketReplicationRequest indicates an expected call of GetBucketReplicationRequest. +func (mr *MockS3APIMockRecorder) GetBucketReplicationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketReplicationRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketReplicationRequest), arg0) +} + +// GetBucketReplicationWithContext mocks base method. +func (m *MockS3API) GetBucketReplicationWithContext(arg0 context.Context, arg1 *s3.GetBucketReplicationInput, arg2 ...request.Option) (*s3.GetBucketReplicationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketReplicationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketReplicationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketReplicationWithContext indicates an expected call of GetBucketReplicationWithContext. +func (mr *MockS3APIMockRecorder) GetBucketReplicationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketReplicationWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketReplicationWithContext), varargs...) +} + +// GetBucketRequestPayment mocks base method. +func (m *MockS3API) GetBucketRequestPayment(arg0 *s3.GetBucketRequestPaymentInput) (*s3.GetBucketRequestPaymentOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketRequestPayment", arg0) + ret0, _ := ret[0].(*s3.GetBucketRequestPaymentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketRequestPayment indicates an expected call of GetBucketRequestPayment. +func (mr *MockS3APIMockRecorder) GetBucketRequestPayment(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketRequestPayment", reflect.TypeOf((*MockS3API)(nil).GetBucketRequestPayment), arg0) +} + +// GetBucketRequestPaymentRequest mocks base method. +func (m *MockS3API) GetBucketRequestPaymentRequest(arg0 *s3.GetBucketRequestPaymentInput) (*request.Request, *s3.GetBucketRequestPaymentOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketRequestPaymentRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketRequestPaymentOutput) + return ret0, ret1 +} + +// GetBucketRequestPaymentRequest indicates an expected call of GetBucketRequestPaymentRequest. +func (mr *MockS3APIMockRecorder) GetBucketRequestPaymentRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketRequestPaymentRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketRequestPaymentRequest), arg0) +} + +// GetBucketRequestPaymentWithContext mocks base method. +func (m *MockS3API) GetBucketRequestPaymentWithContext(arg0 context.Context, arg1 *s3.GetBucketRequestPaymentInput, arg2 ...request.Option) (*s3.GetBucketRequestPaymentOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketRequestPaymentWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketRequestPaymentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketRequestPaymentWithContext indicates an expected call of GetBucketRequestPaymentWithContext. +func (mr *MockS3APIMockRecorder) GetBucketRequestPaymentWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketRequestPaymentWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketRequestPaymentWithContext), varargs...) +} + +// GetBucketTagging mocks base method. +func (m *MockS3API) GetBucketTagging(arg0 *s3.GetBucketTaggingInput) (*s3.GetBucketTaggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketTagging", arg0) + ret0, _ := ret[0].(*s3.GetBucketTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketTagging indicates an expected call of GetBucketTagging. +func (mr *MockS3APIMockRecorder) GetBucketTagging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketTagging", reflect.TypeOf((*MockS3API)(nil).GetBucketTagging), arg0) +} + +// GetBucketTaggingRequest mocks base method. +func (m *MockS3API) GetBucketTaggingRequest(arg0 *s3.GetBucketTaggingInput) (*request.Request, *s3.GetBucketTaggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketTaggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketTaggingOutput) + return ret0, ret1 +} + +// GetBucketTaggingRequest indicates an expected call of GetBucketTaggingRequest. +func (mr *MockS3APIMockRecorder) GetBucketTaggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketTaggingRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketTaggingRequest), arg0) +} + +// GetBucketTaggingWithContext mocks base method. +func (m *MockS3API) GetBucketTaggingWithContext(arg0 context.Context, arg1 *s3.GetBucketTaggingInput, arg2 ...request.Option) (*s3.GetBucketTaggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketTaggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketTaggingWithContext indicates an expected call of GetBucketTaggingWithContext. +func (mr *MockS3APIMockRecorder) GetBucketTaggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketTaggingWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketTaggingWithContext), varargs...) +} + +// GetBucketVersioning mocks base method. +func (m *MockS3API) GetBucketVersioning(arg0 *s3.GetBucketVersioningInput) (*s3.GetBucketVersioningOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketVersioning", arg0) + ret0, _ := ret[0].(*s3.GetBucketVersioningOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketVersioning indicates an expected call of GetBucketVersioning. +func (mr *MockS3APIMockRecorder) GetBucketVersioning(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketVersioning", reflect.TypeOf((*MockS3API)(nil).GetBucketVersioning), arg0) +} + +// GetBucketVersioningRequest mocks base method. +func (m *MockS3API) GetBucketVersioningRequest(arg0 *s3.GetBucketVersioningInput) (*request.Request, *s3.GetBucketVersioningOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketVersioningRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketVersioningOutput) + return ret0, ret1 +} + +// GetBucketVersioningRequest indicates an expected call of GetBucketVersioningRequest. +func (mr *MockS3APIMockRecorder) GetBucketVersioningRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketVersioningRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketVersioningRequest), arg0) +} + +// GetBucketVersioningWithContext mocks base method. +func (m *MockS3API) GetBucketVersioningWithContext(arg0 context.Context, arg1 *s3.GetBucketVersioningInput, arg2 ...request.Option) (*s3.GetBucketVersioningOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketVersioningWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketVersioningOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketVersioningWithContext indicates an expected call of GetBucketVersioningWithContext. +func (mr *MockS3APIMockRecorder) GetBucketVersioningWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketVersioningWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketVersioningWithContext), varargs...) +} + +// GetBucketWebsite mocks base method. +func (m *MockS3API) GetBucketWebsite(arg0 *s3.GetBucketWebsiteInput) (*s3.GetBucketWebsiteOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketWebsite", arg0) + ret0, _ := ret[0].(*s3.GetBucketWebsiteOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketWebsite indicates an expected call of GetBucketWebsite. +func (mr *MockS3APIMockRecorder) GetBucketWebsite(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketWebsite", reflect.TypeOf((*MockS3API)(nil).GetBucketWebsite), arg0) +} + +// GetBucketWebsiteRequest mocks base method. +func (m *MockS3API) GetBucketWebsiteRequest(arg0 *s3.GetBucketWebsiteInput) (*request.Request, *s3.GetBucketWebsiteOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBucketWebsiteRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetBucketWebsiteOutput) + return ret0, ret1 +} + +// GetBucketWebsiteRequest indicates an expected call of GetBucketWebsiteRequest. +func (mr *MockS3APIMockRecorder) GetBucketWebsiteRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketWebsiteRequest", reflect.TypeOf((*MockS3API)(nil).GetBucketWebsiteRequest), arg0) +} + +// GetBucketWebsiteWithContext mocks base method. +func (m *MockS3API) GetBucketWebsiteWithContext(arg0 context.Context, arg1 *s3.GetBucketWebsiteInput, arg2 ...request.Option) (*s3.GetBucketWebsiteOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetBucketWebsiteWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetBucketWebsiteOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBucketWebsiteWithContext indicates an expected call of GetBucketWebsiteWithContext. +func (mr *MockS3APIMockRecorder) GetBucketWebsiteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketWebsiteWithContext", reflect.TypeOf((*MockS3API)(nil).GetBucketWebsiteWithContext), varargs...) +} + +// GetObject mocks base method. +func (m *MockS3API) GetObject(arg0 *s3.GetObjectInput) (*s3.GetObjectOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObject", arg0) + ret0, _ := ret[0].(*s3.GetObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObject indicates an expected call of GetObject. +func (mr *MockS3APIMockRecorder) GetObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObject", reflect.TypeOf((*MockS3API)(nil).GetObject), arg0) +} + +// GetObjectAcl mocks base method. +func (m *MockS3API) GetObjectAcl(arg0 *s3.GetObjectAclInput) (*s3.GetObjectAclOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectAcl", arg0) + ret0, _ := ret[0].(*s3.GetObjectAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectAcl indicates an expected call of GetObjectAcl. +func (mr *MockS3APIMockRecorder) GetObjectAcl(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectAcl", reflect.TypeOf((*MockS3API)(nil).GetObjectAcl), arg0) +} + +// GetObjectAclRequest mocks base method. +func (m *MockS3API) GetObjectAclRequest(arg0 *s3.GetObjectAclInput) (*request.Request, *s3.GetObjectAclOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectAclRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectAclOutput) + return ret0, ret1 +} + +// GetObjectAclRequest indicates an expected call of GetObjectAclRequest. +func (mr *MockS3APIMockRecorder) GetObjectAclRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectAclRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectAclRequest), arg0) +} + +// GetObjectAclWithContext mocks base method. +func (m *MockS3API) GetObjectAclWithContext(arg0 context.Context, arg1 *s3.GetObjectAclInput, arg2 ...request.Option) (*s3.GetObjectAclOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectAclWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectAclWithContext indicates an expected call of GetObjectAclWithContext. +func (mr *MockS3APIMockRecorder) GetObjectAclWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectAclWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectAclWithContext), varargs...) +} + +// GetObjectLegalHold mocks base method. +func (m *MockS3API) GetObjectLegalHold(arg0 *s3.GetObjectLegalHoldInput) (*s3.GetObjectLegalHoldOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectLegalHold", arg0) + ret0, _ := ret[0].(*s3.GetObjectLegalHoldOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectLegalHold indicates an expected call of GetObjectLegalHold. +func (mr *MockS3APIMockRecorder) GetObjectLegalHold(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectLegalHold", reflect.TypeOf((*MockS3API)(nil).GetObjectLegalHold), arg0) +} + +// GetObjectLegalHoldRequest mocks base method. +func (m *MockS3API) GetObjectLegalHoldRequest(arg0 *s3.GetObjectLegalHoldInput) (*request.Request, *s3.GetObjectLegalHoldOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectLegalHoldRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectLegalHoldOutput) + return ret0, ret1 +} + +// GetObjectLegalHoldRequest indicates an expected call of GetObjectLegalHoldRequest. +func (mr *MockS3APIMockRecorder) GetObjectLegalHoldRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectLegalHoldRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectLegalHoldRequest), arg0) +} + +// GetObjectLegalHoldWithContext mocks base method. +func (m *MockS3API) GetObjectLegalHoldWithContext(arg0 context.Context, arg1 *s3.GetObjectLegalHoldInput, arg2 ...request.Option) (*s3.GetObjectLegalHoldOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectLegalHoldWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectLegalHoldOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectLegalHoldWithContext indicates an expected call of GetObjectLegalHoldWithContext. +func (mr *MockS3APIMockRecorder) GetObjectLegalHoldWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectLegalHoldWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectLegalHoldWithContext), varargs...) +} + +// GetObjectLockConfiguration mocks base method. +func (m *MockS3API) GetObjectLockConfiguration(arg0 *s3.GetObjectLockConfigurationInput) (*s3.GetObjectLockConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectLockConfiguration", arg0) + ret0, _ := ret[0].(*s3.GetObjectLockConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectLockConfiguration indicates an expected call of GetObjectLockConfiguration. +func (mr *MockS3APIMockRecorder) GetObjectLockConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectLockConfiguration", reflect.TypeOf((*MockS3API)(nil).GetObjectLockConfiguration), arg0) +} + +// GetObjectLockConfigurationRequest mocks base method. +func (m *MockS3API) GetObjectLockConfigurationRequest(arg0 *s3.GetObjectLockConfigurationInput) (*request.Request, *s3.GetObjectLockConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectLockConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectLockConfigurationOutput) + return ret0, ret1 +} + +// GetObjectLockConfigurationRequest indicates an expected call of GetObjectLockConfigurationRequest. +func (mr *MockS3APIMockRecorder) GetObjectLockConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectLockConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectLockConfigurationRequest), arg0) +} + +// GetObjectLockConfigurationWithContext mocks base method. +func (m *MockS3API) GetObjectLockConfigurationWithContext(arg0 context.Context, arg1 *s3.GetObjectLockConfigurationInput, arg2 ...request.Option) (*s3.GetObjectLockConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectLockConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectLockConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectLockConfigurationWithContext indicates an expected call of GetObjectLockConfigurationWithContext. +func (mr *MockS3APIMockRecorder) GetObjectLockConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectLockConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectLockConfigurationWithContext), varargs...) +} + +// GetObjectRequest mocks base method. +func (m *MockS3API) GetObjectRequest(arg0 *s3.GetObjectInput) (*request.Request, *s3.GetObjectOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectOutput) + return ret0, ret1 +} + +// GetObjectRequest indicates an expected call of GetObjectRequest. +func (mr *MockS3APIMockRecorder) GetObjectRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectRequest), arg0) +} + +// GetObjectRetention mocks base method. +func (m *MockS3API) GetObjectRetention(arg0 *s3.GetObjectRetentionInput) (*s3.GetObjectRetentionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectRetention", arg0) + ret0, _ := ret[0].(*s3.GetObjectRetentionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectRetention indicates an expected call of GetObjectRetention. +func (mr *MockS3APIMockRecorder) GetObjectRetention(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectRetention", reflect.TypeOf((*MockS3API)(nil).GetObjectRetention), arg0) +} + +// GetObjectRetentionRequest mocks base method. +func (m *MockS3API) GetObjectRetentionRequest(arg0 *s3.GetObjectRetentionInput) (*request.Request, *s3.GetObjectRetentionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectRetentionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectRetentionOutput) + return ret0, ret1 +} + +// GetObjectRetentionRequest indicates an expected call of GetObjectRetentionRequest. +func (mr *MockS3APIMockRecorder) GetObjectRetentionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectRetentionRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectRetentionRequest), arg0) +} + +// GetObjectRetentionWithContext mocks base method. +func (m *MockS3API) GetObjectRetentionWithContext(arg0 context.Context, arg1 *s3.GetObjectRetentionInput, arg2 ...request.Option) (*s3.GetObjectRetentionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectRetentionWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectRetentionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectRetentionWithContext indicates an expected call of GetObjectRetentionWithContext. +func (mr *MockS3APIMockRecorder) GetObjectRetentionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectRetentionWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectRetentionWithContext), varargs...) +} + +// GetObjectTagging mocks base method. +func (m *MockS3API) GetObjectTagging(arg0 *s3.GetObjectTaggingInput) (*s3.GetObjectTaggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectTagging", arg0) + ret0, _ := ret[0].(*s3.GetObjectTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectTagging indicates an expected call of GetObjectTagging. +func (mr *MockS3APIMockRecorder) GetObjectTagging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTagging", reflect.TypeOf((*MockS3API)(nil).GetObjectTagging), arg0) +} + +// GetObjectTaggingRequest mocks base method. +func (m *MockS3API) GetObjectTaggingRequest(arg0 *s3.GetObjectTaggingInput) (*request.Request, *s3.GetObjectTaggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectTaggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectTaggingOutput) + return ret0, ret1 +} + +// GetObjectTaggingRequest indicates an expected call of GetObjectTaggingRequest. +func (mr *MockS3APIMockRecorder) GetObjectTaggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTaggingRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectTaggingRequest), arg0) +} + +// GetObjectTaggingWithContext mocks base method. +func (m *MockS3API) GetObjectTaggingWithContext(arg0 context.Context, arg1 *s3.GetObjectTaggingInput, arg2 ...request.Option) (*s3.GetObjectTaggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectTaggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectTaggingWithContext indicates an expected call of GetObjectTaggingWithContext. +func (mr *MockS3APIMockRecorder) GetObjectTaggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTaggingWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectTaggingWithContext), varargs...) +} + +// GetObjectTorrent mocks base method. +func (m *MockS3API) GetObjectTorrent(arg0 *s3.GetObjectTorrentInput) (*s3.GetObjectTorrentOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectTorrent", arg0) + ret0, _ := ret[0].(*s3.GetObjectTorrentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectTorrent indicates an expected call of GetObjectTorrent. +func (mr *MockS3APIMockRecorder) GetObjectTorrent(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTorrent", reflect.TypeOf((*MockS3API)(nil).GetObjectTorrent), arg0) +} + +// GetObjectTorrentRequest mocks base method. +func (m *MockS3API) GetObjectTorrentRequest(arg0 *s3.GetObjectTorrentInput) (*request.Request, *s3.GetObjectTorrentOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectTorrentRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetObjectTorrentOutput) + return ret0, ret1 +} + +// GetObjectTorrentRequest indicates an expected call of GetObjectTorrentRequest. +func (mr *MockS3APIMockRecorder) GetObjectTorrentRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTorrentRequest", reflect.TypeOf((*MockS3API)(nil).GetObjectTorrentRequest), arg0) +} + +// GetObjectTorrentWithContext mocks base method. +func (m *MockS3API) GetObjectTorrentWithContext(arg0 context.Context, arg1 *s3.GetObjectTorrentInput, arg2 ...request.Option) (*s3.GetObjectTorrentOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectTorrentWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectTorrentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectTorrentWithContext indicates an expected call of GetObjectTorrentWithContext. +func (mr *MockS3APIMockRecorder) GetObjectTorrentWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectTorrentWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectTorrentWithContext), varargs...) +} + +// GetObjectWithContext mocks base method. +func (m *MockS3API) GetObjectWithContext(arg0 context.Context, arg1 *s3.GetObjectInput, arg2 ...request.Option) (*s3.GetObjectOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetObjectWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectWithContext indicates an expected call of GetObjectWithContext. +func (mr *MockS3APIMockRecorder) GetObjectWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectWithContext", reflect.TypeOf((*MockS3API)(nil).GetObjectWithContext), varargs...) +} + +// GetPublicAccessBlock mocks base method. +func (m *MockS3API) GetPublicAccessBlock(arg0 *s3.GetPublicAccessBlockInput) (*s3.GetPublicAccessBlockOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPublicAccessBlock", arg0) + ret0, _ := ret[0].(*s3.GetPublicAccessBlockOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPublicAccessBlock indicates an expected call of GetPublicAccessBlock. +func (mr *MockS3APIMockRecorder) GetPublicAccessBlock(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPublicAccessBlock", reflect.TypeOf((*MockS3API)(nil).GetPublicAccessBlock), arg0) +} + +// GetPublicAccessBlockRequest mocks base method. +func (m *MockS3API) GetPublicAccessBlockRequest(arg0 *s3.GetPublicAccessBlockInput) (*request.Request, *s3.GetPublicAccessBlockOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPublicAccessBlockRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.GetPublicAccessBlockOutput) + return ret0, ret1 +} + +// GetPublicAccessBlockRequest indicates an expected call of GetPublicAccessBlockRequest. +func (mr *MockS3APIMockRecorder) GetPublicAccessBlockRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPublicAccessBlockRequest", reflect.TypeOf((*MockS3API)(nil).GetPublicAccessBlockRequest), arg0) +} + +// GetPublicAccessBlockWithContext mocks base method. +func (m *MockS3API) GetPublicAccessBlockWithContext(arg0 context.Context, arg1 *s3.GetPublicAccessBlockInput, arg2 ...request.Option) (*s3.GetPublicAccessBlockOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetPublicAccessBlockWithContext", varargs...) + ret0, _ := ret[0].(*s3.GetPublicAccessBlockOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPublicAccessBlockWithContext indicates an expected call of GetPublicAccessBlockWithContext. +func (mr *MockS3APIMockRecorder) GetPublicAccessBlockWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPublicAccessBlockWithContext", reflect.TypeOf((*MockS3API)(nil).GetPublicAccessBlockWithContext), varargs...) +} + +// HeadBucket mocks base method. +func (m *MockS3API) HeadBucket(arg0 *s3.HeadBucketInput) (*s3.HeadBucketOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeadBucket", arg0) + ret0, _ := ret[0].(*s3.HeadBucketOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeadBucket indicates an expected call of HeadBucket. +func (mr *MockS3APIMockRecorder) HeadBucket(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadBucket", reflect.TypeOf((*MockS3API)(nil).HeadBucket), arg0) +} + +// HeadBucketRequest mocks base method. +func (m *MockS3API) HeadBucketRequest(arg0 *s3.HeadBucketInput) (*request.Request, *s3.HeadBucketOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeadBucketRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.HeadBucketOutput) + return ret0, ret1 +} + +// HeadBucketRequest indicates an expected call of HeadBucketRequest. +func (mr *MockS3APIMockRecorder) HeadBucketRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadBucketRequest", reflect.TypeOf((*MockS3API)(nil).HeadBucketRequest), arg0) +} + +// HeadBucketWithContext mocks base method. +func (m *MockS3API) HeadBucketWithContext(arg0 context.Context, arg1 *s3.HeadBucketInput, arg2 ...request.Option) (*s3.HeadBucketOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "HeadBucketWithContext", varargs...) + ret0, _ := ret[0].(*s3.HeadBucketOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeadBucketWithContext indicates an expected call of HeadBucketWithContext. +func (mr *MockS3APIMockRecorder) HeadBucketWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadBucketWithContext", reflect.TypeOf((*MockS3API)(nil).HeadBucketWithContext), varargs...) +} + +// HeadObject mocks base method. +func (m *MockS3API) HeadObject(arg0 *s3.HeadObjectInput) (*s3.HeadObjectOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeadObject", arg0) + ret0, _ := ret[0].(*s3.HeadObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeadObject indicates an expected call of HeadObject. +func (mr *MockS3APIMockRecorder) HeadObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadObject", reflect.TypeOf((*MockS3API)(nil).HeadObject), arg0) +} + +// HeadObjectRequest mocks base method. +func (m *MockS3API) HeadObjectRequest(arg0 *s3.HeadObjectInput) (*request.Request, *s3.HeadObjectOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeadObjectRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.HeadObjectOutput) + return ret0, ret1 +} + +// HeadObjectRequest indicates an expected call of HeadObjectRequest. +func (mr *MockS3APIMockRecorder) HeadObjectRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadObjectRequest", reflect.TypeOf((*MockS3API)(nil).HeadObjectRequest), arg0) +} + +// HeadObjectWithContext mocks base method. +func (m *MockS3API) HeadObjectWithContext(arg0 context.Context, arg1 *s3.HeadObjectInput, arg2 ...request.Option) (*s3.HeadObjectOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "HeadObjectWithContext", varargs...) + ret0, _ := ret[0].(*s3.HeadObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeadObjectWithContext indicates an expected call of HeadObjectWithContext. +func (mr *MockS3APIMockRecorder) HeadObjectWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadObjectWithContext", reflect.TypeOf((*MockS3API)(nil).HeadObjectWithContext), varargs...) +} + +// ListBucketAnalyticsConfigurations mocks base method. +func (m *MockS3API) ListBucketAnalyticsConfigurations(arg0 *s3.ListBucketAnalyticsConfigurationsInput) (*s3.ListBucketAnalyticsConfigurationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketAnalyticsConfigurations", arg0) + ret0, _ := ret[0].(*s3.ListBucketAnalyticsConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketAnalyticsConfigurations indicates an expected call of ListBucketAnalyticsConfigurations. +func (mr *MockS3APIMockRecorder) ListBucketAnalyticsConfigurations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketAnalyticsConfigurations", reflect.TypeOf((*MockS3API)(nil).ListBucketAnalyticsConfigurations), arg0) +} + +// ListBucketAnalyticsConfigurationsRequest mocks base method. +func (m *MockS3API) ListBucketAnalyticsConfigurationsRequest(arg0 *s3.ListBucketAnalyticsConfigurationsInput) (*request.Request, *s3.ListBucketAnalyticsConfigurationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketAnalyticsConfigurationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListBucketAnalyticsConfigurationsOutput) + return ret0, ret1 +} + +// ListBucketAnalyticsConfigurationsRequest indicates an expected call of ListBucketAnalyticsConfigurationsRequest. +func (mr *MockS3APIMockRecorder) ListBucketAnalyticsConfigurationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketAnalyticsConfigurationsRequest", reflect.TypeOf((*MockS3API)(nil).ListBucketAnalyticsConfigurationsRequest), arg0) +} + +// ListBucketAnalyticsConfigurationsWithContext mocks base method. +func (m *MockS3API) ListBucketAnalyticsConfigurationsWithContext(arg0 context.Context, arg1 *s3.ListBucketAnalyticsConfigurationsInput, arg2 ...request.Option) (*s3.ListBucketAnalyticsConfigurationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListBucketAnalyticsConfigurationsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListBucketAnalyticsConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketAnalyticsConfigurationsWithContext indicates an expected call of ListBucketAnalyticsConfigurationsWithContext. +func (mr *MockS3APIMockRecorder) ListBucketAnalyticsConfigurationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketAnalyticsConfigurationsWithContext", reflect.TypeOf((*MockS3API)(nil).ListBucketAnalyticsConfigurationsWithContext), varargs...) +} + +// ListBucketIntelligentTieringConfigurations mocks base method. +func (m *MockS3API) ListBucketIntelligentTieringConfigurations(arg0 *s3.ListBucketIntelligentTieringConfigurationsInput) (*s3.ListBucketIntelligentTieringConfigurationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketIntelligentTieringConfigurations", arg0) + ret0, _ := ret[0].(*s3.ListBucketIntelligentTieringConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketIntelligentTieringConfigurations indicates an expected call of ListBucketIntelligentTieringConfigurations. +func (mr *MockS3APIMockRecorder) ListBucketIntelligentTieringConfigurations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketIntelligentTieringConfigurations", reflect.TypeOf((*MockS3API)(nil).ListBucketIntelligentTieringConfigurations), arg0) +} + +// ListBucketIntelligentTieringConfigurationsRequest mocks base method. +func (m *MockS3API) ListBucketIntelligentTieringConfigurationsRequest(arg0 *s3.ListBucketIntelligentTieringConfigurationsInput) (*request.Request, *s3.ListBucketIntelligentTieringConfigurationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketIntelligentTieringConfigurationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListBucketIntelligentTieringConfigurationsOutput) + return ret0, ret1 +} + +// ListBucketIntelligentTieringConfigurationsRequest indicates an expected call of ListBucketIntelligentTieringConfigurationsRequest. +func (mr *MockS3APIMockRecorder) ListBucketIntelligentTieringConfigurationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketIntelligentTieringConfigurationsRequest", reflect.TypeOf((*MockS3API)(nil).ListBucketIntelligentTieringConfigurationsRequest), arg0) +} + +// ListBucketIntelligentTieringConfigurationsWithContext mocks base method. +func (m *MockS3API) ListBucketIntelligentTieringConfigurationsWithContext(arg0 context.Context, arg1 *s3.ListBucketIntelligentTieringConfigurationsInput, arg2 ...request.Option) (*s3.ListBucketIntelligentTieringConfigurationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListBucketIntelligentTieringConfigurationsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListBucketIntelligentTieringConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketIntelligentTieringConfigurationsWithContext indicates an expected call of ListBucketIntelligentTieringConfigurationsWithContext. +func (mr *MockS3APIMockRecorder) ListBucketIntelligentTieringConfigurationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketIntelligentTieringConfigurationsWithContext", reflect.TypeOf((*MockS3API)(nil).ListBucketIntelligentTieringConfigurationsWithContext), varargs...) +} + +// ListBucketInventoryConfigurations mocks base method. +func (m *MockS3API) ListBucketInventoryConfigurations(arg0 *s3.ListBucketInventoryConfigurationsInput) (*s3.ListBucketInventoryConfigurationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketInventoryConfigurations", arg0) + ret0, _ := ret[0].(*s3.ListBucketInventoryConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketInventoryConfigurations indicates an expected call of ListBucketInventoryConfigurations. +func (mr *MockS3APIMockRecorder) ListBucketInventoryConfigurations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketInventoryConfigurations", reflect.TypeOf((*MockS3API)(nil).ListBucketInventoryConfigurations), arg0) +} + +// ListBucketInventoryConfigurationsRequest mocks base method. +func (m *MockS3API) ListBucketInventoryConfigurationsRequest(arg0 *s3.ListBucketInventoryConfigurationsInput) (*request.Request, *s3.ListBucketInventoryConfigurationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketInventoryConfigurationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListBucketInventoryConfigurationsOutput) + return ret0, ret1 +} + +// ListBucketInventoryConfigurationsRequest indicates an expected call of ListBucketInventoryConfigurationsRequest. +func (mr *MockS3APIMockRecorder) ListBucketInventoryConfigurationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketInventoryConfigurationsRequest", reflect.TypeOf((*MockS3API)(nil).ListBucketInventoryConfigurationsRequest), arg0) +} + +// ListBucketInventoryConfigurationsWithContext mocks base method. +func (m *MockS3API) ListBucketInventoryConfigurationsWithContext(arg0 context.Context, arg1 *s3.ListBucketInventoryConfigurationsInput, arg2 ...request.Option) (*s3.ListBucketInventoryConfigurationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListBucketInventoryConfigurationsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListBucketInventoryConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketInventoryConfigurationsWithContext indicates an expected call of ListBucketInventoryConfigurationsWithContext. +func (mr *MockS3APIMockRecorder) ListBucketInventoryConfigurationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketInventoryConfigurationsWithContext", reflect.TypeOf((*MockS3API)(nil).ListBucketInventoryConfigurationsWithContext), varargs...) +} + +// ListBucketMetricsConfigurations mocks base method. +func (m *MockS3API) ListBucketMetricsConfigurations(arg0 *s3.ListBucketMetricsConfigurationsInput) (*s3.ListBucketMetricsConfigurationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketMetricsConfigurations", arg0) + ret0, _ := ret[0].(*s3.ListBucketMetricsConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketMetricsConfigurations indicates an expected call of ListBucketMetricsConfigurations. +func (mr *MockS3APIMockRecorder) ListBucketMetricsConfigurations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketMetricsConfigurations", reflect.TypeOf((*MockS3API)(nil).ListBucketMetricsConfigurations), arg0) +} + +// ListBucketMetricsConfigurationsRequest mocks base method. +func (m *MockS3API) ListBucketMetricsConfigurationsRequest(arg0 *s3.ListBucketMetricsConfigurationsInput) (*request.Request, *s3.ListBucketMetricsConfigurationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketMetricsConfigurationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListBucketMetricsConfigurationsOutput) + return ret0, ret1 +} + +// ListBucketMetricsConfigurationsRequest indicates an expected call of ListBucketMetricsConfigurationsRequest. +func (mr *MockS3APIMockRecorder) ListBucketMetricsConfigurationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketMetricsConfigurationsRequest", reflect.TypeOf((*MockS3API)(nil).ListBucketMetricsConfigurationsRequest), arg0) +} + +// ListBucketMetricsConfigurationsWithContext mocks base method. +func (m *MockS3API) ListBucketMetricsConfigurationsWithContext(arg0 context.Context, arg1 *s3.ListBucketMetricsConfigurationsInput, arg2 ...request.Option) (*s3.ListBucketMetricsConfigurationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListBucketMetricsConfigurationsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListBucketMetricsConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketMetricsConfigurationsWithContext indicates an expected call of ListBucketMetricsConfigurationsWithContext. +func (mr *MockS3APIMockRecorder) ListBucketMetricsConfigurationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketMetricsConfigurationsWithContext", reflect.TypeOf((*MockS3API)(nil).ListBucketMetricsConfigurationsWithContext), varargs...) +} + +// ListBuckets mocks base method. +func (m *MockS3API) ListBuckets(arg0 *s3.ListBucketsInput) (*s3.ListBucketsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBuckets", arg0) + ret0, _ := ret[0].(*s3.ListBucketsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBuckets indicates an expected call of ListBuckets. +func (mr *MockS3APIMockRecorder) ListBuckets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBuckets", reflect.TypeOf((*MockS3API)(nil).ListBuckets), arg0) +} + +// ListBucketsRequest mocks base method. +func (m *MockS3API) ListBucketsRequest(arg0 *s3.ListBucketsInput) (*request.Request, *s3.ListBucketsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBucketsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListBucketsOutput) + return ret0, ret1 +} + +// ListBucketsRequest indicates an expected call of ListBucketsRequest. +func (mr *MockS3APIMockRecorder) ListBucketsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketsRequest", reflect.TypeOf((*MockS3API)(nil).ListBucketsRequest), arg0) +} + +// ListBucketsWithContext mocks base method. +func (m *MockS3API) ListBucketsWithContext(arg0 context.Context, arg1 *s3.ListBucketsInput, arg2 ...request.Option) (*s3.ListBucketsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListBucketsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListBucketsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBucketsWithContext indicates an expected call of ListBucketsWithContext. +func (mr *MockS3APIMockRecorder) ListBucketsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBucketsWithContext", reflect.TypeOf((*MockS3API)(nil).ListBucketsWithContext), varargs...) +} + +// ListMultipartUploads mocks base method. +func (m *MockS3API) ListMultipartUploads(arg0 *s3.ListMultipartUploadsInput) (*s3.ListMultipartUploadsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListMultipartUploads", arg0) + ret0, _ := ret[0].(*s3.ListMultipartUploadsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListMultipartUploads indicates an expected call of ListMultipartUploads. +func (mr *MockS3APIMockRecorder) ListMultipartUploads(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMultipartUploads", reflect.TypeOf((*MockS3API)(nil).ListMultipartUploads), arg0) +} + +// ListMultipartUploadsPages mocks base method. +func (m *MockS3API) ListMultipartUploadsPages(arg0 *s3.ListMultipartUploadsInput, arg1 func(*s3.ListMultipartUploadsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListMultipartUploadsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListMultipartUploadsPages indicates an expected call of ListMultipartUploadsPages. +func (mr *MockS3APIMockRecorder) ListMultipartUploadsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMultipartUploadsPages", reflect.TypeOf((*MockS3API)(nil).ListMultipartUploadsPages), arg0, arg1) +} + +// ListMultipartUploadsPagesWithContext mocks base method. +func (m *MockS3API) ListMultipartUploadsPagesWithContext(arg0 context.Context, arg1 *s3.ListMultipartUploadsInput, arg2 func(*s3.ListMultipartUploadsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListMultipartUploadsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListMultipartUploadsPagesWithContext indicates an expected call of ListMultipartUploadsPagesWithContext. +func (mr *MockS3APIMockRecorder) ListMultipartUploadsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMultipartUploadsPagesWithContext", reflect.TypeOf((*MockS3API)(nil).ListMultipartUploadsPagesWithContext), varargs...) +} + +// ListMultipartUploadsRequest mocks base method. +func (m *MockS3API) ListMultipartUploadsRequest(arg0 *s3.ListMultipartUploadsInput) (*request.Request, *s3.ListMultipartUploadsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListMultipartUploadsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListMultipartUploadsOutput) + return ret0, ret1 +} + +// ListMultipartUploadsRequest indicates an expected call of ListMultipartUploadsRequest. +func (mr *MockS3APIMockRecorder) ListMultipartUploadsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMultipartUploadsRequest", reflect.TypeOf((*MockS3API)(nil).ListMultipartUploadsRequest), arg0) +} + +// ListMultipartUploadsWithContext mocks base method. +func (m *MockS3API) ListMultipartUploadsWithContext(arg0 context.Context, arg1 *s3.ListMultipartUploadsInput, arg2 ...request.Option) (*s3.ListMultipartUploadsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListMultipartUploadsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListMultipartUploadsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListMultipartUploadsWithContext indicates an expected call of ListMultipartUploadsWithContext. +func (mr *MockS3APIMockRecorder) ListMultipartUploadsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMultipartUploadsWithContext", reflect.TypeOf((*MockS3API)(nil).ListMultipartUploadsWithContext), varargs...) +} + +// ListObjectVersions mocks base method. +func (m *MockS3API) ListObjectVersions(arg0 *s3.ListObjectVersionsInput) (*s3.ListObjectVersionsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectVersions", arg0) + ret0, _ := ret[0].(*s3.ListObjectVersionsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectVersions indicates an expected call of ListObjectVersions. +func (mr *MockS3APIMockRecorder) ListObjectVersions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectVersions", reflect.TypeOf((*MockS3API)(nil).ListObjectVersions), arg0) +} + +// ListObjectVersionsPages mocks base method. +func (m *MockS3API) ListObjectVersionsPages(arg0 *s3.ListObjectVersionsInput, arg1 func(*s3.ListObjectVersionsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectVersionsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListObjectVersionsPages indicates an expected call of ListObjectVersionsPages. +func (mr *MockS3APIMockRecorder) ListObjectVersionsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectVersionsPages", reflect.TypeOf((*MockS3API)(nil).ListObjectVersionsPages), arg0, arg1) +} + +// ListObjectVersionsPagesWithContext mocks base method. +func (m *MockS3API) ListObjectVersionsPagesWithContext(arg0 context.Context, arg1 *s3.ListObjectVersionsInput, arg2 func(*s3.ListObjectVersionsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListObjectVersionsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListObjectVersionsPagesWithContext indicates an expected call of ListObjectVersionsPagesWithContext. +func (mr *MockS3APIMockRecorder) ListObjectVersionsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectVersionsPagesWithContext", reflect.TypeOf((*MockS3API)(nil).ListObjectVersionsPagesWithContext), varargs...) +} + +// ListObjectVersionsRequest mocks base method. +func (m *MockS3API) ListObjectVersionsRequest(arg0 *s3.ListObjectVersionsInput) (*request.Request, *s3.ListObjectVersionsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectVersionsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListObjectVersionsOutput) + return ret0, ret1 +} + +// ListObjectVersionsRequest indicates an expected call of ListObjectVersionsRequest. +func (mr *MockS3APIMockRecorder) ListObjectVersionsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectVersionsRequest", reflect.TypeOf((*MockS3API)(nil).ListObjectVersionsRequest), arg0) +} + +// ListObjectVersionsWithContext mocks base method. +func (m *MockS3API) ListObjectVersionsWithContext(arg0 context.Context, arg1 *s3.ListObjectVersionsInput, arg2 ...request.Option) (*s3.ListObjectVersionsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListObjectVersionsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListObjectVersionsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectVersionsWithContext indicates an expected call of ListObjectVersionsWithContext. +func (mr *MockS3APIMockRecorder) ListObjectVersionsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectVersionsWithContext", reflect.TypeOf((*MockS3API)(nil).ListObjectVersionsWithContext), varargs...) +} + +// ListObjects mocks base method. +func (m *MockS3API) ListObjects(arg0 *s3.ListObjectsInput) (*s3.ListObjectsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjects", arg0) + ret0, _ := ret[0].(*s3.ListObjectsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjects indicates an expected call of ListObjects. +func (mr *MockS3APIMockRecorder) ListObjects(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjects", reflect.TypeOf((*MockS3API)(nil).ListObjects), arg0) +} + +// ListObjectsPages mocks base method. +func (m *MockS3API) ListObjectsPages(arg0 *s3.ListObjectsInput, arg1 func(*s3.ListObjectsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListObjectsPages indicates an expected call of ListObjectsPages. +func (mr *MockS3APIMockRecorder) ListObjectsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsPages", reflect.TypeOf((*MockS3API)(nil).ListObjectsPages), arg0, arg1) +} + +// ListObjectsPagesWithContext mocks base method. +func (m *MockS3API) ListObjectsPagesWithContext(arg0 context.Context, arg1 *s3.ListObjectsInput, arg2 func(*s3.ListObjectsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListObjectsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListObjectsPagesWithContext indicates an expected call of ListObjectsPagesWithContext. +func (mr *MockS3APIMockRecorder) ListObjectsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsPagesWithContext", reflect.TypeOf((*MockS3API)(nil).ListObjectsPagesWithContext), varargs...) +} + +// ListObjectsRequest mocks base method. +func (m *MockS3API) ListObjectsRequest(arg0 *s3.ListObjectsInput) (*request.Request, *s3.ListObjectsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListObjectsOutput) + return ret0, ret1 +} + +// ListObjectsRequest indicates an expected call of ListObjectsRequest. +func (mr *MockS3APIMockRecorder) ListObjectsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsRequest", reflect.TypeOf((*MockS3API)(nil).ListObjectsRequest), arg0) +} + +// ListObjectsV2 mocks base method. +func (m *MockS3API) ListObjectsV2(arg0 *s3.ListObjectsV2Input) (*s3.ListObjectsV2Output, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectsV2", arg0) + ret0, _ := ret[0].(*s3.ListObjectsV2Output) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectsV2 indicates an expected call of ListObjectsV2. +func (mr *MockS3APIMockRecorder) ListObjectsV2(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsV2", reflect.TypeOf((*MockS3API)(nil).ListObjectsV2), arg0) +} + +// ListObjectsV2Pages mocks base method. +func (m *MockS3API) ListObjectsV2Pages(arg0 *s3.ListObjectsV2Input, arg1 func(*s3.ListObjectsV2Output, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectsV2Pages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListObjectsV2Pages indicates an expected call of ListObjectsV2Pages. +func (mr *MockS3APIMockRecorder) ListObjectsV2Pages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsV2Pages", reflect.TypeOf((*MockS3API)(nil).ListObjectsV2Pages), arg0, arg1) +} + +// ListObjectsV2PagesWithContext mocks base method. +func (m *MockS3API) ListObjectsV2PagesWithContext(arg0 context.Context, arg1 *s3.ListObjectsV2Input, arg2 func(*s3.ListObjectsV2Output, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListObjectsV2PagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListObjectsV2PagesWithContext indicates an expected call of ListObjectsV2PagesWithContext. +func (mr *MockS3APIMockRecorder) ListObjectsV2PagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsV2PagesWithContext", reflect.TypeOf((*MockS3API)(nil).ListObjectsV2PagesWithContext), varargs...) +} + +// ListObjectsV2Request mocks base method. +func (m *MockS3API) ListObjectsV2Request(arg0 *s3.ListObjectsV2Input) (*request.Request, *s3.ListObjectsV2Output) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectsV2Request", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListObjectsV2Output) + return ret0, ret1 +} + +// ListObjectsV2Request indicates an expected call of ListObjectsV2Request. +func (mr *MockS3APIMockRecorder) ListObjectsV2Request(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsV2Request", reflect.TypeOf((*MockS3API)(nil).ListObjectsV2Request), arg0) +} + +// ListObjectsV2WithContext mocks base method. +func (m *MockS3API) ListObjectsV2WithContext(arg0 context.Context, arg1 *s3.ListObjectsV2Input, arg2 ...request.Option) (*s3.ListObjectsV2Output, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListObjectsV2WithContext", varargs...) + ret0, _ := ret[0].(*s3.ListObjectsV2Output) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectsV2WithContext indicates an expected call of ListObjectsV2WithContext. +func (mr *MockS3APIMockRecorder) ListObjectsV2WithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsV2WithContext", reflect.TypeOf((*MockS3API)(nil).ListObjectsV2WithContext), varargs...) +} + +// ListObjectsWithContext mocks base method. +func (m *MockS3API) ListObjectsWithContext(arg0 context.Context, arg1 *s3.ListObjectsInput, arg2 ...request.Option) (*s3.ListObjectsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListObjectsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListObjectsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectsWithContext indicates an expected call of ListObjectsWithContext. +func (mr *MockS3APIMockRecorder) ListObjectsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectsWithContext", reflect.TypeOf((*MockS3API)(nil).ListObjectsWithContext), varargs...) +} + +// ListParts mocks base method. +func (m *MockS3API) ListParts(arg0 *s3.ListPartsInput) (*s3.ListPartsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListParts", arg0) + ret0, _ := ret[0].(*s3.ListPartsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListParts indicates an expected call of ListParts. +func (mr *MockS3APIMockRecorder) ListParts(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListParts", reflect.TypeOf((*MockS3API)(nil).ListParts), arg0) +} + +// ListPartsPages mocks base method. +func (m *MockS3API) ListPartsPages(arg0 *s3.ListPartsInput, arg1 func(*s3.ListPartsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListPartsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListPartsPages indicates an expected call of ListPartsPages. +func (mr *MockS3APIMockRecorder) ListPartsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPartsPages", reflect.TypeOf((*MockS3API)(nil).ListPartsPages), arg0, arg1) +} + +// ListPartsPagesWithContext mocks base method. +func (m *MockS3API) ListPartsPagesWithContext(arg0 context.Context, arg1 *s3.ListPartsInput, arg2 func(*s3.ListPartsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListPartsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListPartsPagesWithContext indicates an expected call of ListPartsPagesWithContext. +func (mr *MockS3APIMockRecorder) ListPartsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPartsPagesWithContext", reflect.TypeOf((*MockS3API)(nil).ListPartsPagesWithContext), varargs...) +} + +// ListPartsRequest mocks base method. +func (m *MockS3API) ListPartsRequest(arg0 *s3.ListPartsInput) (*request.Request, *s3.ListPartsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListPartsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.ListPartsOutput) + return ret0, ret1 +} + +// ListPartsRequest indicates an expected call of ListPartsRequest. +func (mr *MockS3APIMockRecorder) ListPartsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPartsRequest", reflect.TypeOf((*MockS3API)(nil).ListPartsRequest), arg0) +} + +// ListPartsWithContext mocks base method. +func (m *MockS3API) ListPartsWithContext(arg0 context.Context, arg1 *s3.ListPartsInput, arg2 ...request.Option) (*s3.ListPartsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListPartsWithContext", varargs...) + ret0, _ := ret[0].(*s3.ListPartsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListPartsWithContext indicates an expected call of ListPartsWithContext. +func (mr *MockS3APIMockRecorder) ListPartsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPartsWithContext", reflect.TypeOf((*MockS3API)(nil).ListPartsWithContext), varargs...) +} + +// PutBucketAccelerateConfiguration mocks base method. +func (m *MockS3API) PutBucketAccelerateConfiguration(arg0 *s3.PutBucketAccelerateConfigurationInput) (*s3.PutBucketAccelerateConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketAccelerateConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketAccelerateConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketAccelerateConfiguration indicates an expected call of PutBucketAccelerateConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketAccelerateConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAccelerateConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketAccelerateConfiguration), arg0) +} + +// PutBucketAccelerateConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketAccelerateConfigurationRequest(arg0 *s3.PutBucketAccelerateConfigurationInput) (*request.Request, *s3.PutBucketAccelerateConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketAccelerateConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketAccelerateConfigurationOutput) + return ret0, ret1 +} + +// PutBucketAccelerateConfigurationRequest indicates an expected call of PutBucketAccelerateConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketAccelerateConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAccelerateConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketAccelerateConfigurationRequest), arg0) +} + +// PutBucketAccelerateConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketAccelerateConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketAccelerateConfigurationInput, arg2 ...request.Option) (*s3.PutBucketAccelerateConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketAccelerateConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketAccelerateConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketAccelerateConfigurationWithContext indicates an expected call of PutBucketAccelerateConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketAccelerateConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAccelerateConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketAccelerateConfigurationWithContext), varargs...) +} + +// PutBucketAcl mocks base method. +func (m *MockS3API) PutBucketAcl(arg0 *s3.PutBucketAclInput) (*s3.PutBucketAclOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketAcl", arg0) + ret0, _ := ret[0].(*s3.PutBucketAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketAcl indicates an expected call of PutBucketAcl. +func (mr *MockS3APIMockRecorder) PutBucketAcl(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAcl", reflect.TypeOf((*MockS3API)(nil).PutBucketAcl), arg0) +} + +// PutBucketAclRequest mocks base method. +func (m *MockS3API) PutBucketAclRequest(arg0 *s3.PutBucketAclInput) (*request.Request, *s3.PutBucketAclOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketAclRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketAclOutput) + return ret0, ret1 +} + +// PutBucketAclRequest indicates an expected call of PutBucketAclRequest. +func (mr *MockS3APIMockRecorder) PutBucketAclRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAclRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketAclRequest), arg0) +} + +// PutBucketAclWithContext mocks base method. +func (m *MockS3API) PutBucketAclWithContext(arg0 context.Context, arg1 *s3.PutBucketAclInput, arg2 ...request.Option) (*s3.PutBucketAclOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketAclWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketAclWithContext indicates an expected call of PutBucketAclWithContext. +func (mr *MockS3APIMockRecorder) PutBucketAclWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAclWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketAclWithContext), varargs...) +} + +// PutBucketAnalyticsConfiguration mocks base method. +func (m *MockS3API) PutBucketAnalyticsConfiguration(arg0 *s3.PutBucketAnalyticsConfigurationInput) (*s3.PutBucketAnalyticsConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketAnalyticsConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketAnalyticsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketAnalyticsConfiguration indicates an expected call of PutBucketAnalyticsConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketAnalyticsConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAnalyticsConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketAnalyticsConfiguration), arg0) +} + +// PutBucketAnalyticsConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketAnalyticsConfigurationRequest(arg0 *s3.PutBucketAnalyticsConfigurationInput) (*request.Request, *s3.PutBucketAnalyticsConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketAnalyticsConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketAnalyticsConfigurationOutput) + return ret0, ret1 +} + +// PutBucketAnalyticsConfigurationRequest indicates an expected call of PutBucketAnalyticsConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketAnalyticsConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAnalyticsConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketAnalyticsConfigurationRequest), arg0) +} + +// PutBucketAnalyticsConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketAnalyticsConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketAnalyticsConfigurationInput, arg2 ...request.Option) (*s3.PutBucketAnalyticsConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketAnalyticsConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketAnalyticsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketAnalyticsConfigurationWithContext indicates an expected call of PutBucketAnalyticsConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketAnalyticsConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketAnalyticsConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketAnalyticsConfigurationWithContext), varargs...) +} + +// PutBucketCors mocks base method. +func (m *MockS3API) PutBucketCors(arg0 *s3.PutBucketCorsInput) (*s3.PutBucketCorsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketCors", arg0) + ret0, _ := ret[0].(*s3.PutBucketCorsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketCors indicates an expected call of PutBucketCors. +func (mr *MockS3APIMockRecorder) PutBucketCors(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketCors", reflect.TypeOf((*MockS3API)(nil).PutBucketCors), arg0) +} + +// PutBucketCorsRequest mocks base method. +func (m *MockS3API) PutBucketCorsRequest(arg0 *s3.PutBucketCorsInput) (*request.Request, *s3.PutBucketCorsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketCorsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketCorsOutput) + return ret0, ret1 +} + +// PutBucketCorsRequest indicates an expected call of PutBucketCorsRequest. +func (mr *MockS3APIMockRecorder) PutBucketCorsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketCorsRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketCorsRequest), arg0) +} + +// PutBucketCorsWithContext mocks base method. +func (m *MockS3API) PutBucketCorsWithContext(arg0 context.Context, arg1 *s3.PutBucketCorsInput, arg2 ...request.Option) (*s3.PutBucketCorsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketCorsWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketCorsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketCorsWithContext indicates an expected call of PutBucketCorsWithContext. +func (mr *MockS3APIMockRecorder) PutBucketCorsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketCorsWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketCorsWithContext), varargs...) +} + +// PutBucketEncryption mocks base method. +func (m *MockS3API) PutBucketEncryption(arg0 *s3.PutBucketEncryptionInput) (*s3.PutBucketEncryptionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketEncryption", arg0) + ret0, _ := ret[0].(*s3.PutBucketEncryptionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketEncryption indicates an expected call of PutBucketEncryption. +func (mr *MockS3APIMockRecorder) PutBucketEncryption(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketEncryption", reflect.TypeOf((*MockS3API)(nil).PutBucketEncryption), arg0) +} + +// PutBucketEncryptionRequest mocks base method. +func (m *MockS3API) PutBucketEncryptionRequest(arg0 *s3.PutBucketEncryptionInput) (*request.Request, *s3.PutBucketEncryptionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketEncryptionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketEncryptionOutput) + return ret0, ret1 +} + +// PutBucketEncryptionRequest indicates an expected call of PutBucketEncryptionRequest. +func (mr *MockS3APIMockRecorder) PutBucketEncryptionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketEncryptionRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketEncryptionRequest), arg0) +} + +// PutBucketEncryptionWithContext mocks base method. +func (m *MockS3API) PutBucketEncryptionWithContext(arg0 context.Context, arg1 *s3.PutBucketEncryptionInput, arg2 ...request.Option) (*s3.PutBucketEncryptionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketEncryptionWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketEncryptionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketEncryptionWithContext indicates an expected call of PutBucketEncryptionWithContext. +func (mr *MockS3APIMockRecorder) PutBucketEncryptionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketEncryptionWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketEncryptionWithContext), varargs...) +} + +// PutBucketIntelligentTieringConfiguration mocks base method. +func (m *MockS3API) PutBucketIntelligentTieringConfiguration(arg0 *s3.PutBucketIntelligentTieringConfigurationInput) (*s3.PutBucketIntelligentTieringConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketIntelligentTieringConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketIntelligentTieringConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketIntelligentTieringConfiguration indicates an expected call of PutBucketIntelligentTieringConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketIntelligentTieringConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketIntelligentTieringConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketIntelligentTieringConfiguration), arg0) +} + +// PutBucketIntelligentTieringConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketIntelligentTieringConfigurationRequest(arg0 *s3.PutBucketIntelligentTieringConfigurationInput) (*request.Request, *s3.PutBucketIntelligentTieringConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketIntelligentTieringConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketIntelligentTieringConfigurationOutput) + return ret0, ret1 +} + +// PutBucketIntelligentTieringConfigurationRequest indicates an expected call of PutBucketIntelligentTieringConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketIntelligentTieringConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketIntelligentTieringConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketIntelligentTieringConfigurationRequest), arg0) +} + +// PutBucketIntelligentTieringConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketIntelligentTieringConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketIntelligentTieringConfigurationInput, arg2 ...request.Option) (*s3.PutBucketIntelligentTieringConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketIntelligentTieringConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketIntelligentTieringConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketIntelligentTieringConfigurationWithContext indicates an expected call of PutBucketIntelligentTieringConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketIntelligentTieringConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketIntelligentTieringConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketIntelligentTieringConfigurationWithContext), varargs...) +} + +// PutBucketInventoryConfiguration mocks base method. +func (m *MockS3API) PutBucketInventoryConfiguration(arg0 *s3.PutBucketInventoryConfigurationInput) (*s3.PutBucketInventoryConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketInventoryConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketInventoryConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketInventoryConfiguration indicates an expected call of PutBucketInventoryConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketInventoryConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketInventoryConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketInventoryConfiguration), arg0) +} + +// PutBucketInventoryConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketInventoryConfigurationRequest(arg0 *s3.PutBucketInventoryConfigurationInput) (*request.Request, *s3.PutBucketInventoryConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketInventoryConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketInventoryConfigurationOutput) + return ret0, ret1 +} + +// PutBucketInventoryConfigurationRequest indicates an expected call of PutBucketInventoryConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketInventoryConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketInventoryConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketInventoryConfigurationRequest), arg0) +} + +// PutBucketInventoryConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketInventoryConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketInventoryConfigurationInput, arg2 ...request.Option) (*s3.PutBucketInventoryConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketInventoryConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketInventoryConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketInventoryConfigurationWithContext indicates an expected call of PutBucketInventoryConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketInventoryConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketInventoryConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketInventoryConfigurationWithContext), varargs...) +} + +// PutBucketLifecycle mocks base method. +func (m *MockS3API) PutBucketLifecycle(arg0 *s3.PutBucketLifecycleInput) (*s3.PutBucketLifecycleOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketLifecycle", arg0) + ret0, _ := ret[0].(*s3.PutBucketLifecycleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketLifecycle indicates an expected call of PutBucketLifecycle. +func (mr *MockS3APIMockRecorder) PutBucketLifecycle(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLifecycle", reflect.TypeOf((*MockS3API)(nil).PutBucketLifecycle), arg0) +} + +// PutBucketLifecycleConfiguration mocks base method. +func (m *MockS3API) PutBucketLifecycleConfiguration(arg0 *s3.PutBucketLifecycleConfigurationInput) (*s3.PutBucketLifecycleConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketLifecycleConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketLifecycleConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketLifecycleConfiguration indicates an expected call of PutBucketLifecycleConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketLifecycleConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLifecycleConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketLifecycleConfiguration), arg0) +} + +// PutBucketLifecycleConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketLifecycleConfigurationRequest(arg0 *s3.PutBucketLifecycleConfigurationInput) (*request.Request, *s3.PutBucketLifecycleConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketLifecycleConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketLifecycleConfigurationOutput) + return ret0, ret1 +} + +// PutBucketLifecycleConfigurationRequest indicates an expected call of PutBucketLifecycleConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketLifecycleConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLifecycleConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketLifecycleConfigurationRequest), arg0) +} + +// PutBucketLifecycleConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketLifecycleConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketLifecycleConfigurationInput, arg2 ...request.Option) (*s3.PutBucketLifecycleConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketLifecycleConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketLifecycleConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketLifecycleConfigurationWithContext indicates an expected call of PutBucketLifecycleConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketLifecycleConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLifecycleConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketLifecycleConfigurationWithContext), varargs...) +} + +// PutBucketLifecycleRequest mocks base method. +func (m *MockS3API) PutBucketLifecycleRequest(arg0 *s3.PutBucketLifecycleInput) (*request.Request, *s3.PutBucketLifecycleOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketLifecycleRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketLifecycleOutput) + return ret0, ret1 +} + +// PutBucketLifecycleRequest indicates an expected call of PutBucketLifecycleRequest. +func (mr *MockS3APIMockRecorder) PutBucketLifecycleRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLifecycleRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketLifecycleRequest), arg0) +} + +// PutBucketLifecycleWithContext mocks base method. +func (m *MockS3API) PutBucketLifecycleWithContext(arg0 context.Context, arg1 *s3.PutBucketLifecycleInput, arg2 ...request.Option) (*s3.PutBucketLifecycleOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketLifecycleWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketLifecycleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketLifecycleWithContext indicates an expected call of PutBucketLifecycleWithContext. +func (mr *MockS3APIMockRecorder) PutBucketLifecycleWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLifecycleWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketLifecycleWithContext), varargs...) +} + +// PutBucketLogging mocks base method. +func (m *MockS3API) PutBucketLogging(arg0 *s3.PutBucketLoggingInput) (*s3.PutBucketLoggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketLogging", arg0) + ret0, _ := ret[0].(*s3.PutBucketLoggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketLogging indicates an expected call of PutBucketLogging. +func (mr *MockS3APIMockRecorder) PutBucketLogging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLogging", reflect.TypeOf((*MockS3API)(nil).PutBucketLogging), arg0) +} + +// PutBucketLoggingRequest mocks base method. +func (m *MockS3API) PutBucketLoggingRequest(arg0 *s3.PutBucketLoggingInput) (*request.Request, *s3.PutBucketLoggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketLoggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketLoggingOutput) + return ret0, ret1 +} + +// PutBucketLoggingRequest indicates an expected call of PutBucketLoggingRequest. +func (mr *MockS3APIMockRecorder) PutBucketLoggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLoggingRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketLoggingRequest), arg0) +} + +// PutBucketLoggingWithContext mocks base method. +func (m *MockS3API) PutBucketLoggingWithContext(arg0 context.Context, arg1 *s3.PutBucketLoggingInput, arg2 ...request.Option) (*s3.PutBucketLoggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketLoggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketLoggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketLoggingWithContext indicates an expected call of PutBucketLoggingWithContext. +func (mr *MockS3APIMockRecorder) PutBucketLoggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketLoggingWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketLoggingWithContext), varargs...) +} + +// PutBucketMetricsConfiguration mocks base method. +func (m *MockS3API) PutBucketMetricsConfiguration(arg0 *s3.PutBucketMetricsConfigurationInput) (*s3.PutBucketMetricsConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketMetricsConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketMetricsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketMetricsConfiguration indicates an expected call of PutBucketMetricsConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketMetricsConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketMetricsConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketMetricsConfiguration), arg0) +} + +// PutBucketMetricsConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketMetricsConfigurationRequest(arg0 *s3.PutBucketMetricsConfigurationInput) (*request.Request, *s3.PutBucketMetricsConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketMetricsConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketMetricsConfigurationOutput) + return ret0, ret1 +} + +// PutBucketMetricsConfigurationRequest indicates an expected call of PutBucketMetricsConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketMetricsConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketMetricsConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketMetricsConfigurationRequest), arg0) +} + +// PutBucketMetricsConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketMetricsConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketMetricsConfigurationInput, arg2 ...request.Option) (*s3.PutBucketMetricsConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketMetricsConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketMetricsConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketMetricsConfigurationWithContext indicates an expected call of PutBucketMetricsConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketMetricsConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketMetricsConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketMetricsConfigurationWithContext), varargs...) +} + +// PutBucketNotification mocks base method. +func (m *MockS3API) PutBucketNotification(arg0 *s3.PutBucketNotificationInput) (*s3.PutBucketNotificationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketNotification", arg0) + ret0, _ := ret[0].(*s3.PutBucketNotificationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketNotification indicates an expected call of PutBucketNotification. +func (mr *MockS3APIMockRecorder) PutBucketNotification(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketNotification", reflect.TypeOf((*MockS3API)(nil).PutBucketNotification), arg0) +} + +// PutBucketNotificationConfiguration mocks base method. +func (m *MockS3API) PutBucketNotificationConfiguration(arg0 *s3.PutBucketNotificationConfigurationInput) (*s3.PutBucketNotificationConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketNotificationConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutBucketNotificationConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketNotificationConfiguration indicates an expected call of PutBucketNotificationConfiguration. +func (mr *MockS3APIMockRecorder) PutBucketNotificationConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketNotificationConfiguration", reflect.TypeOf((*MockS3API)(nil).PutBucketNotificationConfiguration), arg0) +} + +// PutBucketNotificationConfigurationRequest mocks base method. +func (m *MockS3API) PutBucketNotificationConfigurationRequest(arg0 *s3.PutBucketNotificationConfigurationInput) (*request.Request, *s3.PutBucketNotificationConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketNotificationConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketNotificationConfigurationOutput) + return ret0, ret1 +} + +// PutBucketNotificationConfigurationRequest indicates an expected call of PutBucketNotificationConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutBucketNotificationConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketNotificationConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketNotificationConfigurationRequest), arg0) +} + +// PutBucketNotificationConfigurationWithContext mocks base method. +func (m *MockS3API) PutBucketNotificationConfigurationWithContext(arg0 context.Context, arg1 *s3.PutBucketNotificationConfigurationInput, arg2 ...request.Option) (*s3.PutBucketNotificationConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketNotificationConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketNotificationConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketNotificationConfigurationWithContext indicates an expected call of PutBucketNotificationConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketNotificationConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketNotificationConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketNotificationConfigurationWithContext), varargs...) +} + +// PutBucketNotificationRequest mocks base method. +func (m *MockS3API) PutBucketNotificationRequest(arg0 *s3.PutBucketNotificationInput) (*request.Request, *s3.PutBucketNotificationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketNotificationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketNotificationOutput) + return ret0, ret1 +} + +// PutBucketNotificationRequest indicates an expected call of PutBucketNotificationRequest. +func (mr *MockS3APIMockRecorder) PutBucketNotificationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketNotificationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketNotificationRequest), arg0) +} + +// PutBucketNotificationWithContext mocks base method. +func (m *MockS3API) PutBucketNotificationWithContext(arg0 context.Context, arg1 *s3.PutBucketNotificationInput, arg2 ...request.Option) (*s3.PutBucketNotificationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketNotificationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketNotificationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketNotificationWithContext indicates an expected call of PutBucketNotificationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketNotificationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketNotificationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketNotificationWithContext), varargs...) +} + +// PutBucketOwnershipControls mocks base method. +func (m *MockS3API) PutBucketOwnershipControls(arg0 *s3.PutBucketOwnershipControlsInput) (*s3.PutBucketOwnershipControlsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketOwnershipControls", arg0) + ret0, _ := ret[0].(*s3.PutBucketOwnershipControlsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketOwnershipControls indicates an expected call of PutBucketOwnershipControls. +func (mr *MockS3APIMockRecorder) PutBucketOwnershipControls(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketOwnershipControls", reflect.TypeOf((*MockS3API)(nil).PutBucketOwnershipControls), arg0) +} + +// PutBucketOwnershipControlsRequest mocks base method. +func (m *MockS3API) PutBucketOwnershipControlsRequest(arg0 *s3.PutBucketOwnershipControlsInput) (*request.Request, *s3.PutBucketOwnershipControlsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketOwnershipControlsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketOwnershipControlsOutput) + return ret0, ret1 +} + +// PutBucketOwnershipControlsRequest indicates an expected call of PutBucketOwnershipControlsRequest. +func (mr *MockS3APIMockRecorder) PutBucketOwnershipControlsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketOwnershipControlsRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketOwnershipControlsRequest), arg0) +} + +// PutBucketOwnershipControlsWithContext mocks base method. +func (m *MockS3API) PutBucketOwnershipControlsWithContext(arg0 context.Context, arg1 *s3.PutBucketOwnershipControlsInput, arg2 ...request.Option) (*s3.PutBucketOwnershipControlsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketOwnershipControlsWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketOwnershipControlsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketOwnershipControlsWithContext indicates an expected call of PutBucketOwnershipControlsWithContext. +func (mr *MockS3APIMockRecorder) PutBucketOwnershipControlsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketOwnershipControlsWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketOwnershipControlsWithContext), varargs...) +} + +// PutBucketPolicy mocks base method. +func (m *MockS3API) PutBucketPolicy(arg0 *s3.PutBucketPolicyInput) (*s3.PutBucketPolicyOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketPolicy", arg0) + ret0, _ := ret[0].(*s3.PutBucketPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketPolicy indicates an expected call of PutBucketPolicy. +func (mr *MockS3APIMockRecorder) PutBucketPolicy(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketPolicy", reflect.TypeOf((*MockS3API)(nil).PutBucketPolicy), arg0) +} + +// PutBucketPolicyRequest mocks base method. +func (m *MockS3API) PutBucketPolicyRequest(arg0 *s3.PutBucketPolicyInput) (*request.Request, *s3.PutBucketPolicyOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketPolicyRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketPolicyOutput) + return ret0, ret1 +} + +// PutBucketPolicyRequest indicates an expected call of PutBucketPolicyRequest. +func (mr *MockS3APIMockRecorder) PutBucketPolicyRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketPolicyRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketPolicyRequest), arg0) +} + +// PutBucketPolicyWithContext mocks base method. +func (m *MockS3API) PutBucketPolicyWithContext(arg0 context.Context, arg1 *s3.PutBucketPolicyInput, arg2 ...request.Option) (*s3.PutBucketPolicyOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketPolicyWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketPolicyWithContext indicates an expected call of PutBucketPolicyWithContext. +func (mr *MockS3APIMockRecorder) PutBucketPolicyWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketPolicyWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketPolicyWithContext), varargs...) +} + +// PutBucketReplication mocks base method. +func (m *MockS3API) PutBucketReplication(arg0 *s3.PutBucketReplicationInput) (*s3.PutBucketReplicationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketReplication", arg0) + ret0, _ := ret[0].(*s3.PutBucketReplicationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketReplication indicates an expected call of PutBucketReplication. +func (mr *MockS3APIMockRecorder) PutBucketReplication(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketReplication", reflect.TypeOf((*MockS3API)(nil).PutBucketReplication), arg0) +} + +// PutBucketReplicationRequest mocks base method. +func (m *MockS3API) PutBucketReplicationRequest(arg0 *s3.PutBucketReplicationInput) (*request.Request, *s3.PutBucketReplicationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketReplicationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketReplicationOutput) + return ret0, ret1 +} + +// PutBucketReplicationRequest indicates an expected call of PutBucketReplicationRequest. +func (mr *MockS3APIMockRecorder) PutBucketReplicationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketReplicationRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketReplicationRequest), arg0) +} + +// PutBucketReplicationWithContext mocks base method. +func (m *MockS3API) PutBucketReplicationWithContext(arg0 context.Context, arg1 *s3.PutBucketReplicationInput, arg2 ...request.Option) (*s3.PutBucketReplicationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketReplicationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketReplicationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketReplicationWithContext indicates an expected call of PutBucketReplicationWithContext. +func (mr *MockS3APIMockRecorder) PutBucketReplicationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketReplicationWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketReplicationWithContext), varargs...) +} + +// PutBucketRequestPayment mocks base method. +func (m *MockS3API) PutBucketRequestPayment(arg0 *s3.PutBucketRequestPaymentInput) (*s3.PutBucketRequestPaymentOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketRequestPayment", arg0) + ret0, _ := ret[0].(*s3.PutBucketRequestPaymentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketRequestPayment indicates an expected call of PutBucketRequestPayment. +func (mr *MockS3APIMockRecorder) PutBucketRequestPayment(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketRequestPayment", reflect.TypeOf((*MockS3API)(nil).PutBucketRequestPayment), arg0) +} + +// PutBucketRequestPaymentRequest mocks base method. +func (m *MockS3API) PutBucketRequestPaymentRequest(arg0 *s3.PutBucketRequestPaymentInput) (*request.Request, *s3.PutBucketRequestPaymentOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketRequestPaymentRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketRequestPaymentOutput) + return ret0, ret1 +} + +// PutBucketRequestPaymentRequest indicates an expected call of PutBucketRequestPaymentRequest. +func (mr *MockS3APIMockRecorder) PutBucketRequestPaymentRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketRequestPaymentRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketRequestPaymentRequest), arg0) +} + +// PutBucketRequestPaymentWithContext mocks base method. +func (m *MockS3API) PutBucketRequestPaymentWithContext(arg0 context.Context, arg1 *s3.PutBucketRequestPaymentInput, arg2 ...request.Option) (*s3.PutBucketRequestPaymentOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketRequestPaymentWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketRequestPaymentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketRequestPaymentWithContext indicates an expected call of PutBucketRequestPaymentWithContext. +func (mr *MockS3APIMockRecorder) PutBucketRequestPaymentWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketRequestPaymentWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketRequestPaymentWithContext), varargs...) +} + +// PutBucketTagging mocks base method. +func (m *MockS3API) PutBucketTagging(arg0 *s3.PutBucketTaggingInput) (*s3.PutBucketTaggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketTagging", arg0) + ret0, _ := ret[0].(*s3.PutBucketTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketTagging indicates an expected call of PutBucketTagging. +func (mr *MockS3APIMockRecorder) PutBucketTagging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketTagging", reflect.TypeOf((*MockS3API)(nil).PutBucketTagging), arg0) +} + +// PutBucketTaggingRequest mocks base method. +func (m *MockS3API) PutBucketTaggingRequest(arg0 *s3.PutBucketTaggingInput) (*request.Request, *s3.PutBucketTaggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketTaggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketTaggingOutput) + return ret0, ret1 +} + +// PutBucketTaggingRequest indicates an expected call of PutBucketTaggingRequest. +func (mr *MockS3APIMockRecorder) PutBucketTaggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketTaggingRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketTaggingRequest), arg0) +} + +// PutBucketTaggingWithContext mocks base method. +func (m *MockS3API) PutBucketTaggingWithContext(arg0 context.Context, arg1 *s3.PutBucketTaggingInput, arg2 ...request.Option) (*s3.PutBucketTaggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketTaggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketTaggingWithContext indicates an expected call of PutBucketTaggingWithContext. +func (mr *MockS3APIMockRecorder) PutBucketTaggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketTaggingWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketTaggingWithContext), varargs...) +} + +// PutBucketVersioning mocks base method. +func (m *MockS3API) PutBucketVersioning(arg0 *s3.PutBucketVersioningInput) (*s3.PutBucketVersioningOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketVersioning", arg0) + ret0, _ := ret[0].(*s3.PutBucketVersioningOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketVersioning indicates an expected call of PutBucketVersioning. +func (mr *MockS3APIMockRecorder) PutBucketVersioning(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketVersioning", reflect.TypeOf((*MockS3API)(nil).PutBucketVersioning), arg0) +} + +// PutBucketVersioningRequest mocks base method. +func (m *MockS3API) PutBucketVersioningRequest(arg0 *s3.PutBucketVersioningInput) (*request.Request, *s3.PutBucketVersioningOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketVersioningRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketVersioningOutput) + return ret0, ret1 +} + +// PutBucketVersioningRequest indicates an expected call of PutBucketVersioningRequest. +func (mr *MockS3APIMockRecorder) PutBucketVersioningRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketVersioningRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketVersioningRequest), arg0) +} + +// PutBucketVersioningWithContext mocks base method. +func (m *MockS3API) PutBucketVersioningWithContext(arg0 context.Context, arg1 *s3.PutBucketVersioningInput, arg2 ...request.Option) (*s3.PutBucketVersioningOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketVersioningWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketVersioningOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketVersioningWithContext indicates an expected call of PutBucketVersioningWithContext. +func (mr *MockS3APIMockRecorder) PutBucketVersioningWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketVersioningWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketVersioningWithContext), varargs...) +} + +// PutBucketWebsite mocks base method. +func (m *MockS3API) PutBucketWebsite(arg0 *s3.PutBucketWebsiteInput) (*s3.PutBucketWebsiteOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketWebsite", arg0) + ret0, _ := ret[0].(*s3.PutBucketWebsiteOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketWebsite indicates an expected call of PutBucketWebsite. +func (mr *MockS3APIMockRecorder) PutBucketWebsite(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketWebsite", reflect.TypeOf((*MockS3API)(nil).PutBucketWebsite), arg0) +} + +// PutBucketWebsiteRequest mocks base method. +func (m *MockS3API) PutBucketWebsiteRequest(arg0 *s3.PutBucketWebsiteInput) (*request.Request, *s3.PutBucketWebsiteOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutBucketWebsiteRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutBucketWebsiteOutput) + return ret0, ret1 +} + +// PutBucketWebsiteRequest indicates an expected call of PutBucketWebsiteRequest. +func (mr *MockS3APIMockRecorder) PutBucketWebsiteRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketWebsiteRequest", reflect.TypeOf((*MockS3API)(nil).PutBucketWebsiteRequest), arg0) +} + +// PutBucketWebsiteWithContext mocks base method. +func (m *MockS3API) PutBucketWebsiteWithContext(arg0 context.Context, arg1 *s3.PutBucketWebsiteInput, arg2 ...request.Option) (*s3.PutBucketWebsiteOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutBucketWebsiteWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutBucketWebsiteOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutBucketWebsiteWithContext indicates an expected call of PutBucketWebsiteWithContext. +func (mr *MockS3APIMockRecorder) PutBucketWebsiteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBucketWebsiteWithContext", reflect.TypeOf((*MockS3API)(nil).PutBucketWebsiteWithContext), varargs...) +} + +// PutObject mocks base method. +func (m *MockS3API) PutObject(arg0 *s3.PutObjectInput) (*s3.PutObjectOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObject", arg0) + ret0, _ := ret[0].(*s3.PutObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObject indicates an expected call of PutObject. +func (mr *MockS3APIMockRecorder) PutObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockS3API)(nil).PutObject), arg0) +} + +// PutObjectAcl mocks base method. +func (m *MockS3API) PutObjectAcl(arg0 *s3.PutObjectAclInput) (*s3.PutObjectAclOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectAcl", arg0) + ret0, _ := ret[0].(*s3.PutObjectAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectAcl indicates an expected call of PutObjectAcl. +func (mr *MockS3APIMockRecorder) PutObjectAcl(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectAcl", reflect.TypeOf((*MockS3API)(nil).PutObjectAcl), arg0) +} + +// PutObjectAclRequest mocks base method. +func (m *MockS3API) PutObjectAclRequest(arg0 *s3.PutObjectAclInput) (*request.Request, *s3.PutObjectAclOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectAclRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutObjectAclOutput) + return ret0, ret1 +} + +// PutObjectAclRequest indicates an expected call of PutObjectAclRequest. +func (mr *MockS3APIMockRecorder) PutObjectAclRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectAclRequest", reflect.TypeOf((*MockS3API)(nil).PutObjectAclRequest), arg0) +} + +// PutObjectAclWithContext mocks base method. +func (m *MockS3API) PutObjectAclWithContext(arg0 context.Context, arg1 *s3.PutObjectAclInput, arg2 ...request.Option) (*s3.PutObjectAclOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutObjectAclWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutObjectAclOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectAclWithContext indicates an expected call of PutObjectAclWithContext. +func (mr *MockS3APIMockRecorder) PutObjectAclWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectAclWithContext", reflect.TypeOf((*MockS3API)(nil).PutObjectAclWithContext), varargs...) +} + +// PutObjectLegalHold mocks base method. +func (m *MockS3API) PutObjectLegalHold(arg0 *s3.PutObjectLegalHoldInput) (*s3.PutObjectLegalHoldOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectLegalHold", arg0) + ret0, _ := ret[0].(*s3.PutObjectLegalHoldOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectLegalHold indicates an expected call of PutObjectLegalHold. +func (mr *MockS3APIMockRecorder) PutObjectLegalHold(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectLegalHold", reflect.TypeOf((*MockS3API)(nil).PutObjectLegalHold), arg0) +} + +// PutObjectLegalHoldRequest mocks base method. +func (m *MockS3API) PutObjectLegalHoldRequest(arg0 *s3.PutObjectLegalHoldInput) (*request.Request, *s3.PutObjectLegalHoldOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectLegalHoldRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutObjectLegalHoldOutput) + return ret0, ret1 +} + +// PutObjectLegalHoldRequest indicates an expected call of PutObjectLegalHoldRequest. +func (mr *MockS3APIMockRecorder) PutObjectLegalHoldRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectLegalHoldRequest", reflect.TypeOf((*MockS3API)(nil).PutObjectLegalHoldRequest), arg0) +} + +// PutObjectLegalHoldWithContext mocks base method. +func (m *MockS3API) PutObjectLegalHoldWithContext(arg0 context.Context, arg1 *s3.PutObjectLegalHoldInput, arg2 ...request.Option) (*s3.PutObjectLegalHoldOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutObjectLegalHoldWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutObjectLegalHoldOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectLegalHoldWithContext indicates an expected call of PutObjectLegalHoldWithContext. +func (mr *MockS3APIMockRecorder) PutObjectLegalHoldWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectLegalHoldWithContext", reflect.TypeOf((*MockS3API)(nil).PutObjectLegalHoldWithContext), varargs...) +} + +// PutObjectLockConfiguration mocks base method. +func (m *MockS3API) PutObjectLockConfiguration(arg0 *s3.PutObjectLockConfigurationInput) (*s3.PutObjectLockConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectLockConfiguration", arg0) + ret0, _ := ret[0].(*s3.PutObjectLockConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectLockConfiguration indicates an expected call of PutObjectLockConfiguration. +func (mr *MockS3APIMockRecorder) PutObjectLockConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectLockConfiguration", reflect.TypeOf((*MockS3API)(nil).PutObjectLockConfiguration), arg0) +} + +// PutObjectLockConfigurationRequest mocks base method. +func (m *MockS3API) PutObjectLockConfigurationRequest(arg0 *s3.PutObjectLockConfigurationInput) (*request.Request, *s3.PutObjectLockConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectLockConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutObjectLockConfigurationOutput) + return ret0, ret1 +} + +// PutObjectLockConfigurationRequest indicates an expected call of PutObjectLockConfigurationRequest. +func (mr *MockS3APIMockRecorder) PutObjectLockConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectLockConfigurationRequest", reflect.TypeOf((*MockS3API)(nil).PutObjectLockConfigurationRequest), arg0) +} + +// PutObjectLockConfigurationWithContext mocks base method. +func (m *MockS3API) PutObjectLockConfigurationWithContext(arg0 context.Context, arg1 *s3.PutObjectLockConfigurationInput, arg2 ...request.Option) (*s3.PutObjectLockConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutObjectLockConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutObjectLockConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectLockConfigurationWithContext indicates an expected call of PutObjectLockConfigurationWithContext. +func (mr *MockS3APIMockRecorder) PutObjectLockConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectLockConfigurationWithContext", reflect.TypeOf((*MockS3API)(nil).PutObjectLockConfigurationWithContext), varargs...) +} + +// PutObjectRequest mocks base method. +func (m *MockS3API) PutObjectRequest(arg0 *s3.PutObjectInput) (*request.Request, *s3.PutObjectOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutObjectOutput) + return ret0, ret1 +} + +// PutObjectRequest indicates an expected call of PutObjectRequest. +func (mr *MockS3APIMockRecorder) PutObjectRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectRequest", reflect.TypeOf((*MockS3API)(nil).PutObjectRequest), arg0) +} + +// PutObjectRetention mocks base method. +func (m *MockS3API) PutObjectRetention(arg0 *s3.PutObjectRetentionInput) (*s3.PutObjectRetentionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectRetention", arg0) + ret0, _ := ret[0].(*s3.PutObjectRetentionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectRetention indicates an expected call of PutObjectRetention. +func (mr *MockS3APIMockRecorder) PutObjectRetention(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectRetention", reflect.TypeOf((*MockS3API)(nil).PutObjectRetention), arg0) +} + +// PutObjectRetentionRequest mocks base method. +func (m *MockS3API) PutObjectRetentionRequest(arg0 *s3.PutObjectRetentionInput) (*request.Request, *s3.PutObjectRetentionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectRetentionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutObjectRetentionOutput) + return ret0, ret1 +} + +// PutObjectRetentionRequest indicates an expected call of PutObjectRetentionRequest. +func (mr *MockS3APIMockRecorder) PutObjectRetentionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectRetentionRequest", reflect.TypeOf((*MockS3API)(nil).PutObjectRetentionRequest), arg0) +} + +// PutObjectRetentionWithContext mocks base method. +func (m *MockS3API) PutObjectRetentionWithContext(arg0 context.Context, arg1 *s3.PutObjectRetentionInput, arg2 ...request.Option) (*s3.PutObjectRetentionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutObjectRetentionWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutObjectRetentionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectRetentionWithContext indicates an expected call of PutObjectRetentionWithContext. +func (mr *MockS3APIMockRecorder) PutObjectRetentionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectRetentionWithContext", reflect.TypeOf((*MockS3API)(nil).PutObjectRetentionWithContext), varargs...) +} + +// PutObjectTagging mocks base method. +func (m *MockS3API) PutObjectTagging(arg0 *s3.PutObjectTaggingInput) (*s3.PutObjectTaggingOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectTagging", arg0) + ret0, _ := ret[0].(*s3.PutObjectTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectTagging indicates an expected call of PutObjectTagging. +func (mr *MockS3APIMockRecorder) PutObjectTagging(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectTagging", reflect.TypeOf((*MockS3API)(nil).PutObjectTagging), arg0) +} + +// PutObjectTaggingRequest mocks base method. +func (m *MockS3API) PutObjectTaggingRequest(arg0 *s3.PutObjectTaggingInput) (*request.Request, *s3.PutObjectTaggingOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutObjectTaggingRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutObjectTaggingOutput) + return ret0, ret1 +} + +// PutObjectTaggingRequest indicates an expected call of PutObjectTaggingRequest. +func (mr *MockS3APIMockRecorder) PutObjectTaggingRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectTaggingRequest", reflect.TypeOf((*MockS3API)(nil).PutObjectTaggingRequest), arg0) +} + +// PutObjectTaggingWithContext mocks base method. +func (m *MockS3API) PutObjectTaggingWithContext(arg0 context.Context, arg1 *s3.PutObjectTaggingInput, arg2 ...request.Option) (*s3.PutObjectTaggingOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutObjectTaggingWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutObjectTaggingOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectTaggingWithContext indicates an expected call of PutObjectTaggingWithContext. +func (mr *MockS3APIMockRecorder) PutObjectTaggingWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectTaggingWithContext", reflect.TypeOf((*MockS3API)(nil).PutObjectTaggingWithContext), varargs...) +} + +// PutObjectWithContext mocks base method. +func (m *MockS3API) PutObjectWithContext(arg0 context.Context, arg1 *s3.PutObjectInput, arg2 ...request.Option) (*s3.PutObjectOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutObjectWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutObjectWithContext indicates an expected call of PutObjectWithContext. +func (mr *MockS3APIMockRecorder) PutObjectWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObjectWithContext", reflect.TypeOf((*MockS3API)(nil).PutObjectWithContext), varargs...) +} + +// PutPublicAccessBlock mocks base method. +func (m *MockS3API) PutPublicAccessBlock(arg0 *s3.PutPublicAccessBlockInput) (*s3.PutPublicAccessBlockOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutPublicAccessBlock", arg0) + ret0, _ := ret[0].(*s3.PutPublicAccessBlockOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutPublicAccessBlock indicates an expected call of PutPublicAccessBlock. +func (mr *MockS3APIMockRecorder) PutPublicAccessBlock(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPublicAccessBlock", reflect.TypeOf((*MockS3API)(nil).PutPublicAccessBlock), arg0) +} + +// PutPublicAccessBlockRequest mocks base method. +func (m *MockS3API) PutPublicAccessBlockRequest(arg0 *s3.PutPublicAccessBlockInput) (*request.Request, *s3.PutPublicAccessBlockOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutPublicAccessBlockRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.PutPublicAccessBlockOutput) + return ret0, ret1 +} + +// PutPublicAccessBlockRequest indicates an expected call of PutPublicAccessBlockRequest. +func (mr *MockS3APIMockRecorder) PutPublicAccessBlockRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPublicAccessBlockRequest", reflect.TypeOf((*MockS3API)(nil).PutPublicAccessBlockRequest), arg0) +} + +// PutPublicAccessBlockWithContext mocks base method. +func (m *MockS3API) PutPublicAccessBlockWithContext(arg0 context.Context, arg1 *s3.PutPublicAccessBlockInput, arg2 ...request.Option) (*s3.PutPublicAccessBlockOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PutPublicAccessBlockWithContext", varargs...) + ret0, _ := ret[0].(*s3.PutPublicAccessBlockOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutPublicAccessBlockWithContext indicates an expected call of PutPublicAccessBlockWithContext. +func (mr *MockS3APIMockRecorder) PutPublicAccessBlockWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPublicAccessBlockWithContext", reflect.TypeOf((*MockS3API)(nil).PutPublicAccessBlockWithContext), varargs...) +} + +// RestoreObject mocks base method. +func (m *MockS3API) RestoreObject(arg0 *s3.RestoreObjectInput) (*s3.RestoreObjectOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RestoreObject", arg0) + ret0, _ := ret[0].(*s3.RestoreObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RestoreObject indicates an expected call of RestoreObject. +func (mr *MockS3APIMockRecorder) RestoreObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoreObject", reflect.TypeOf((*MockS3API)(nil).RestoreObject), arg0) +} + +// RestoreObjectRequest mocks base method. +func (m *MockS3API) RestoreObjectRequest(arg0 *s3.RestoreObjectInput) (*request.Request, *s3.RestoreObjectOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RestoreObjectRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.RestoreObjectOutput) + return ret0, ret1 +} + +// RestoreObjectRequest indicates an expected call of RestoreObjectRequest. +func (mr *MockS3APIMockRecorder) RestoreObjectRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoreObjectRequest", reflect.TypeOf((*MockS3API)(nil).RestoreObjectRequest), arg0) +} + +// RestoreObjectWithContext mocks base method. +func (m *MockS3API) RestoreObjectWithContext(arg0 context.Context, arg1 *s3.RestoreObjectInput, arg2 ...request.Option) (*s3.RestoreObjectOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RestoreObjectWithContext", varargs...) + ret0, _ := ret[0].(*s3.RestoreObjectOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RestoreObjectWithContext indicates an expected call of RestoreObjectWithContext. +func (mr *MockS3APIMockRecorder) RestoreObjectWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoreObjectWithContext", reflect.TypeOf((*MockS3API)(nil).RestoreObjectWithContext), varargs...) +} + +// SelectObjectContent mocks base method. +func (m *MockS3API) SelectObjectContent(arg0 *s3.SelectObjectContentInput) (*s3.SelectObjectContentOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SelectObjectContent", arg0) + ret0, _ := ret[0].(*s3.SelectObjectContentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SelectObjectContent indicates an expected call of SelectObjectContent. +func (mr *MockS3APIMockRecorder) SelectObjectContent(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectObjectContent", reflect.TypeOf((*MockS3API)(nil).SelectObjectContent), arg0) +} + +// SelectObjectContentRequest mocks base method. +func (m *MockS3API) SelectObjectContentRequest(arg0 *s3.SelectObjectContentInput) (*request.Request, *s3.SelectObjectContentOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SelectObjectContentRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.SelectObjectContentOutput) + return ret0, ret1 +} + +// SelectObjectContentRequest indicates an expected call of SelectObjectContentRequest. +func (mr *MockS3APIMockRecorder) SelectObjectContentRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectObjectContentRequest", reflect.TypeOf((*MockS3API)(nil).SelectObjectContentRequest), arg0) +} + +// SelectObjectContentWithContext mocks base method. +func (m *MockS3API) SelectObjectContentWithContext(arg0 context.Context, arg1 *s3.SelectObjectContentInput, arg2 ...request.Option) (*s3.SelectObjectContentOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SelectObjectContentWithContext", varargs...) + ret0, _ := ret[0].(*s3.SelectObjectContentOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SelectObjectContentWithContext indicates an expected call of SelectObjectContentWithContext. +func (mr *MockS3APIMockRecorder) SelectObjectContentWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectObjectContentWithContext", reflect.TypeOf((*MockS3API)(nil).SelectObjectContentWithContext), varargs...) +} + +// UploadPart mocks base method. +func (m *MockS3API) UploadPart(arg0 *s3.UploadPartInput) (*s3.UploadPartOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UploadPart", arg0) + ret0, _ := ret[0].(*s3.UploadPartOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UploadPart indicates an expected call of UploadPart. +func (mr *MockS3APIMockRecorder) UploadPart(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPart", reflect.TypeOf((*MockS3API)(nil).UploadPart), arg0) +} + +// UploadPartCopy mocks base method. +func (m *MockS3API) UploadPartCopy(arg0 *s3.UploadPartCopyInput) (*s3.UploadPartCopyOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UploadPartCopy", arg0) + ret0, _ := ret[0].(*s3.UploadPartCopyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UploadPartCopy indicates an expected call of UploadPartCopy. +func (mr *MockS3APIMockRecorder) UploadPartCopy(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPartCopy", reflect.TypeOf((*MockS3API)(nil).UploadPartCopy), arg0) +} + +// UploadPartCopyRequest mocks base method. +func (m *MockS3API) UploadPartCopyRequest(arg0 *s3.UploadPartCopyInput) (*request.Request, *s3.UploadPartCopyOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UploadPartCopyRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.UploadPartCopyOutput) + return ret0, ret1 +} + +// UploadPartCopyRequest indicates an expected call of UploadPartCopyRequest. +func (mr *MockS3APIMockRecorder) UploadPartCopyRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPartCopyRequest", reflect.TypeOf((*MockS3API)(nil).UploadPartCopyRequest), arg0) +} + +// UploadPartCopyWithContext mocks base method. +func (m *MockS3API) UploadPartCopyWithContext(arg0 context.Context, arg1 *s3.UploadPartCopyInput, arg2 ...request.Option) (*s3.UploadPartCopyOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UploadPartCopyWithContext", varargs...) + ret0, _ := ret[0].(*s3.UploadPartCopyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UploadPartCopyWithContext indicates an expected call of UploadPartCopyWithContext. +func (mr *MockS3APIMockRecorder) UploadPartCopyWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPartCopyWithContext", reflect.TypeOf((*MockS3API)(nil).UploadPartCopyWithContext), varargs...) +} + +// UploadPartRequest mocks base method. +func (m *MockS3API) UploadPartRequest(arg0 *s3.UploadPartInput) (*request.Request, *s3.UploadPartOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UploadPartRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.UploadPartOutput) + return ret0, ret1 +} + +// UploadPartRequest indicates an expected call of UploadPartRequest. +func (mr *MockS3APIMockRecorder) UploadPartRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPartRequest", reflect.TypeOf((*MockS3API)(nil).UploadPartRequest), arg0) +} + +// UploadPartWithContext mocks base method. +func (m *MockS3API) UploadPartWithContext(arg0 context.Context, arg1 *s3.UploadPartInput, arg2 ...request.Option) (*s3.UploadPartOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UploadPartWithContext", varargs...) + ret0, _ := ret[0].(*s3.UploadPartOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UploadPartWithContext indicates an expected call of UploadPartWithContext. +func (mr *MockS3APIMockRecorder) UploadPartWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPartWithContext", reflect.TypeOf((*MockS3API)(nil).UploadPartWithContext), varargs...) +} + +// WaitUntilBucketExists mocks base method. +func (m *MockS3API) WaitUntilBucketExists(arg0 *s3.HeadBucketInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilBucketExists", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilBucketExists indicates an expected call of WaitUntilBucketExists. +func (mr *MockS3APIMockRecorder) WaitUntilBucketExists(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilBucketExists", reflect.TypeOf((*MockS3API)(nil).WaitUntilBucketExists), arg0) +} + +// WaitUntilBucketExistsWithContext mocks base method. +func (m *MockS3API) WaitUntilBucketExistsWithContext(arg0 context.Context, arg1 *s3.HeadBucketInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilBucketExistsWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilBucketExistsWithContext indicates an expected call of WaitUntilBucketExistsWithContext. +func (mr *MockS3APIMockRecorder) WaitUntilBucketExistsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilBucketExistsWithContext", reflect.TypeOf((*MockS3API)(nil).WaitUntilBucketExistsWithContext), varargs...) +} + +// WaitUntilBucketNotExists mocks base method. +func (m *MockS3API) WaitUntilBucketNotExists(arg0 *s3.HeadBucketInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilBucketNotExists", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilBucketNotExists indicates an expected call of WaitUntilBucketNotExists. +func (mr *MockS3APIMockRecorder) WaitUntilBucketNotExists(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilBucketNotExists", reflect.TypeOf((*MockS3API)(nil).WaitUntilBucketNotExists), arg0) +} + +// WaitUntilBucketNotExistsWithContext mocks base method. +func (m *MockS3API) WaitUntilBucketNotExistsWithContext(arg0 context.Context, arg1 *s3.HeadBucketInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilBucketNotExistsWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilBucketNotExistsWithContext indicates an expected call of WaitUntilBucketNotExistsWithContext. +func (mr *MockS3APIMockRecorder) WaitUntilBucketNotExistsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilBucketNotExistsWithContext", reflect.TypeOf((*MockS3API)(nil).WaitUntilBucketNotExistsWithContext), varargs...) +} + +// WaitUntilObjectExists mocks base method. +func (m *MockS3API) WaitUntilObjectExists(arg0 *s3.HeadObjectInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilObjectExists", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilObjectExists indicates an expected call of WaitUntilObjectExists. +func (mr *MockS3APIMockRecorder) WaitUntilObjectExists(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilObjectExists", reflect.TypeOf((*MockS3API)(nil).WaitUntilObjectExists), arg0) +} + +// WaitUntilObjectExistsWithContext mocks base method. +func (m *MockS3API) WaitUntilObjectExistsWithContext(arg0 context.Context, arg1 *s3.HeadObjectInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilObjectExistsWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilObjectExistsWithContext indicates an expected call of WaitUntilObjectExistsWithContext. +func (mr *MockS3APIMockRecorder) WaitUntilObjectExistsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilObjectExistsWithContext", reflect.TypeOf((*MockS3API)(nil).WaitUntilObjectExistsWithContext), varargs...) +} + +// WaitUntilObjectNotExists mocks base method. +func (m *MockS3API) WaitUntilObjectNotExists(arg0 *s3.HeadObjectInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilObjectNotExists", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilObjectNotExists indicates an expected call of WaitUntilObjectNotExists. +func (mr *MockS3APIMockRecorder) WaitUntilObjectNotExists(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilObjectNotExists", reflect.TypeOf((*MockS3API)(nil).WaitUntilObjectNotExists), arg0) +} + +// WaitUntilObjectNotExistsWithContext mocks base method. +func (m *MockS3API) WaitUntilObjectNotExistsWithContext(arg0 context.Context, arg1 *s3.HeadObjectInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilObjectNotExistsWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilObjectNotExistsWithContext indicates an expected call of WaitUntilObjectNotExistsWithContext. +func (mr *MockS3APIMockRecorder) WaitUntilObjectNotExistsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilObjectNotExistsWithContext", reflect.TypeOf((*MockS3API)(nil).WaitUntilObjectNotExistsWithContext), varargs...) +} + +// WriteGetObjectResponse mocks base method. +func (m *MockS3API) WriteGetObjectResponse(arg0 *s3.WriteGetObjectResponseInput) (*s3.WriteGetObjectResponseOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteGetObjectResponse", arg0) + ret0, _ := ret[0].(*s3.WriteGetObjectResponseOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WriteGetObjectResponse indicates an expected call of WriteGetObjectResponse. +func (mr *MockS3APIMockRecorder) WriteGetObjectResponse(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteGetObjectResponse", reflect.TypeOf((*MockS3API)(nil).WriteGetObjectResponse), arg0) +} + +// WriteGetObjectResponseRequest mocks base method. +func (m *MockS3API) WriteGetObjectResponseRequest(arg0 *s3.WriteGetObjectResponseInput) (*request.Request, *s3.WriteGetObjectResponseOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteGetObjectResponseRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*s3.WriteGetObjectResponseOutput) + return ret0, ret1 +} + +// WriteGetObjectResponseRequest indicates an expected call of WriteGetObjectResponseRequest. +func (mr *MockS3APIMockRecorder) WriteGetObjectResponseRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteGetObjectResponseRequest", reflect.TypeOf((*MockS3API)(nil).WriteGetObjectResponseRequest), arg0) +} + +// WriteGetObjectResponseWithContext mocks base method. +func (m *MockS3API) WriteGetObjectResponseWithContext(arg0 context.Context, arg1 *s3.WriteGetObjectResponseInput, arg2 ...request.Option) (*s3.WriteGetObjectResponseOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WriteGetObjectResponseWithContext", varargs...) + ret0, _ := ret[0].(*s3.WriteGetObjectResponseOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WriteGetObjectResponseWithContext indicates an expected call of WriteGetObjectResponseWithContext. +func (mr *MockS3APIMockRecorder) WriteGetObjectResponseWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteGetObjectResponseWithContext", reflect.TypeOf((*MockS3API)(nil).WriteGetObjectResponseWithContext), varargs...) +} diff --git a/pkg/cloud/services/s3/mock_stsiface/doc.go b/pkg/cloud/services/s3/mock_stsiface/doc.go new file mode 100644 index 0000000000..b4f8d4edb4 --- /dev/null +++ b/pkg/cloud/services/s3/mock_stsiface/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 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. +*/ + +// Run go generate to regenerate this mock. +//go:generate ../../../../../hack/tools/bin/mockgen -destination stsapi_mock.go -package mock_stsiface github.com/aws/aws-sdk-go/service/sts/stsiface STSAPI +//go:generate /usr/bin/env bash -c "cat ../../../../../hack/boilerplate/boilerplate.generatego.txt stsapi_mock.go > _stsapi_mock.go && mv _stsapi_mock.go stsapi_mock.go" +package mock_stsiface //nolint diff --git a/pkg/cloud/services/s3/mock_stsiface/stsapi_mock.go b/pkg/cloud/services/s3/mock_stsiface/stsapi_mock.go new file mode 100644 index 0000000000..7fccef4109 --- /dev/null +++ b/pkg/cloud/services/s3/mock_stsiface/stsapi_mock.go @@ -0,0 +1,453 @@ +/* +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. +*/ + +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/aws/aws-sdk-go/service/sts/stsiface (interfaces: STSAPI) + +// Package mock_stsiface is a generated GoMock package. +package mock_stsiface + +import ( + context "context" + reflect "reflect" + + request "github.com/aws/aws-sdk-go/aws/request" + sts "github.com/aws/aws-sdk-go/service/sts" + gomock "github.com/golang/mock/gomock" +) + +// MockSTSAPI is a mock of STSAPI interface. +type MockSTSAPI struct { + ctrl *gomock.Controller + recorder *MockSTSAPIMockRecorder +} + +// MockSTSAPIMockRecorder is the mock recorder for MockSTSAPI. +type MockSTSAPIMockRecorder struct { + mock *MockSTSAPI +} + +// NewMockSTSAPI creates a new mock instance. +func NewMockSTSAPI(ctrl *gomock.Controller) *MockSTSAPI { + mock := &MockSTSAPI{ctrl: ctrl} + mock.recorder = &MockSTSAPIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSTSAPI) EXPECT() *MockSTSAPIMockRecorder { + return m.recorder +} + +// AssumeRole mocks base method. +func (m *MockSTSAPI) AssumeRole(arg0 *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssumeRole", arg0) + ret0, _ := ret[0].(*sts.AssumeRoleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssumeRole indicates an expected call of AssumeRole. +func (mr *MockSTSAPIMockRecorder) AssumeRole(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRole", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRole), arg0) +} + +// AssumeRoleRequest mocks base method. +func (m *MockSTSAPI) AssumeRoleRequest(arg0 *sts.AssumeRoleInput) (*request.Request, *sts.AssumeRoleOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssumeRoleRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.AssumeRoleOutput) + return ret0, ret1 +} + +// AssumeRoleRequest indicates an expected call of AssumeRoleRequest. +func (mr *MockSTSAPIMockRecorder) AssumeRoleRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleRequest", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleRequest), arg0) +} + +// AssumeRoleWithContext mocks base method. +func (m *MockSTSAPI) AssumeRoleWithContext(arg0 context.Context, arg1 *sts.AssumeRoleInput, arg2 ...request.Option) (*sts.AssumeRoleOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AssumeRoleWithContext", varargs...) + ret0, _ := ret[0].(*sts.AssumeRoleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssumeRoleWithContext indicates an expected call of AssumeRoleWithContext. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithContext", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithContext), varargs...) +} + +// AssumeRoleWithSAML mocks base method. +func (m *MockSTSAPI) AssumeRoleWithSAML(arg0 *sts.AssumeRoleWithSAMLInput) (*sts.AssumeRoleWithSAMLOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssumeRoleWithSAML", arg0) + ret0, _ := ret[0].(*sts.AssumeRoleWithSAMLOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssumeRoleWithSAML indicates an expected call of AssumeRoleWithSAML. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithSAML(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithSAML", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithSAML), arg0) +} + +// AssumeRoleWithSAMLRequest mocks base method. +func (m *MockSTSAPI) AssumeRoleWithSAMLRequest(arg0 *sts.AssumeRoleWithSAMLInput) (*request.Request, *sts.AssumeRoleWithSAMLOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssumeRoleWithSAMLRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.AssumeRoleWithSAMLOutput) + return ret0, ret1 +} + +// AssumeRoleWithSAMLRequest indicates an expected call of AssumeRoleWithSAMLRequest. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithSAMLRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithSAMLRequest", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithSAMLRequest), arg0) +} + +// AssumeRoleWithSAMLWithContext mocks base method. +func (m *MockSTSAPI) AssumeRoleWithSAMLWithContext(arg0 context.Context, arg1 *sts.AssumeRoleWithSAMLInput, arg2 ...request.Option) (*sts.AssumeRoleWithSAMLOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AssumeRoleWithSAMLWithContext", varargs...) + ret0, _ := ret[0].(*sts.AssumeRoleWithSAMLOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssumeRoleWithSAMLWithContext indicates an expected call of AssumeRoleWithSAMLWithContext. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithSAMLWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithSAMLWithContext", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithSAMLWithContext), varargs...) +} + +// AssumeRoleWithWebIdentity mocks base method. +func (m *MockSTSAPI) AssumeRoleWithWebIdentity(arg0 *sts.AssumeRoleWithWebIdentityInput) (*sts.AssumeRoleWithWebIdentityOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssumeRoleWithWebIdentity", arg0) + ret0, _ := ret[0].(*sts.AssumeRoleWithWebIdentityOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssumeRoleWithWebIdentity indicates an expected call of AssumeRoleWithWebIdentity. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithWebIdentity(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithWebIdentity", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithWebIdentity), arg0) +} + +// AssumeRoleWithWebIdentityRequest mocks base method. +func (m *MockSTSAPI) AssumeRoleWithWebIdentityRequest(arg0 *sts.AssumeRoleWithWebIdentityInput) (*request.Request, *sts.AssumeRoleWithWebIdentityOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssumeRoleWithWebIdentityRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.AssumeRoleWithWebIdentityOutput) + return ret0, ret1 +} + +// AssumeRoleWithWebIdentityRequest indicates an expected call of AssumeRoleWithWebIdentityRequest. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithWebIdentityRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithWebIdentityRequest", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithWebIdentityRequest), arg0) +} + +// AssumeRoleWithWebIdentityWithContext mocks base method. +func (m *MockSTSAPI) AssumeRoleWithWebIdentityWithContext(arg0 context.Context, arg1 *sts.AssumeRoleWithWebIdentityInput, arg2 ...request.Option) (*sts.AssumeRoleWithWebIdentityOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AssumeRoleWithWebIdentityWithContext", varargs...) + ret0, _ := ret[0].(*sts.AssumeRoleWithWebIdentityOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssumeRoleWithWebIdentityWithContext indicates an expected call of AssumeRoleWithWebIdentityWithContext. +func (mr *MockSTSAPIMockRecorder) AssumeRoleWithWebIdentityWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithWebIdentityWithContext", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithWebIdentityWithContext), varargs...) +} + +// DecodeAuthorizationMessage mocks base method. +func (m *MockSTSAPI) DecodeAuthorizationMessage(arg0 *sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DecodeAuthorizationMessage", arg0) + ret0, _ := ret[0].(*sts.DecodeAuthorizationMessageOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DecodeAuthorizationMessage indicates an expected call of DecodeAuthorizationMessage. +func (mr *MockSTSAPIMockRecorder) DecodeAuthorizationMessage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeAuthorizationMessage", reflect.TypeOf((*MockSTSAPI)(nil).DecodeAuthorizationMessage), arg0) +} + +// DecodeAuthorizationMessageRequest mocks base method. +func (m *MockSTSAPI) DecodeAuthorizationMessageRequest(arg0 *sts.DecodeAuthorizationMessageInput) (*request.Request, *sts.DecodeAuthorizationMessageOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DecodeAuthorizationMessageRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.DecodeAuthorizationMessageOutput) + return ret0, ret1 +} + +// DecodeAuthorizationMessageRequest indicates an expected call of DecodeAuthorizationMessageRequest. +func (mr *MockSTSAPIMockRecorder) DecodeAuthorizationMessageRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeAuthorizationMessageRequest", reflect.TypeOf((*MockSTSAPI)(nil).DecodeAuthorizationMessageRequest), arg0) +} + +// DecodeAuthorizationMessageWithContext mocks base method. +func (m *MockSTSAPI) DecodeAuthorizationMessageWithContext(arg0 context.Context, arg1 *sts.DecodeAuthorizationMessageInput, arg2 ...request.Option) (*sts.DecodeAuthorizationMessageOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DecodeAuthorizationMessageWithContext", varargs...) + ret0, _ := ret[0].(*sts.DecodeAuthorizationMessageOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DecodeAuthorizationMessageWithContext indicates an expected call of DecodeAuthorizationMessageWithContext. +func (mr *MockSTSAPIMockRecorder) DecodeAuthorizationMessageWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeAuthorizationMessageWithContext", reflect.TypeOf((*MockSTSAPI)(nil).DecodeAuthorizationMessageWithContext), varargs...) +} + +// GetAccessKeyInfo mocks base method. +func (m *MockSTSAPI) GetAccessKeyInfo(arg0 *sts.GetAccessKeyInfoInput) (*sts.GetAccessKeyInfoOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccessKeyInfo", arg0) + ret0, _ := ret[0].(*sts.GetAccessKeyInfoOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAccessKeyInfo indicates an expected call of GetAccessKeyInfo. +func (mr *MockSTSAPIMockRecorder) GetAccessKeyInfo(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessKeyInfo", reflect.TypeOf((*MockSTSAPI)(nil).GetAccessKeyInfo), arg0) +} + +// GetAccessKeyInfoRequest mocks base method. +func (m *MockSTSAPI) GetAccessKeyInfoRequest(arg0 *sts.GetAccessKeyInfoInput) (*request.Request, *sts.GetAccessKeyInfoOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccessKeyInfoRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.GetAccessKeyInfoOutput) + return ret0, ret1 +} + +// GetAccessKeyInfoRequest indicates an expected call of GetAccessKeyInfoRequest. +func (mr *MockSTSAPIMockRecorder) GetAccessKeyInfoRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessKeyInfoRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetAccessKeyInfoRequest), arg0) +} + +// GetAccessKeyInfoWithContext mocks base method. +func (m *MockSTSAPI) GetAccessKeyInfoWithContext(arg0 context.Context, arg1 *sts.GetAccessKeyInfoInput, arg2 ...request.Option) (*sts.GetAccessKeyInfoOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetAccessKeyInfoWithContext", varargs...) + ret0, _ := ret[0].(*sts.GetAccessKeyInfoOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAccessKeyInfoWithContext indicates an expected call of GetAccessKeyInfoWithContext. +func (mr *MockSTSAPIMockRecorder) GetAccessKeyInfoWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessKeyInfoWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetAccessKeyInfoWithContext), varargs...) +} + +// GetCallerIdentity mocks base method. +func (m *MockSTSAPI) GetCallerIdentity(arg0 *sts.GetCallerIdentityInput) (*sts.GetCallerIdentityOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCallerIdentity", arg0) + ret0, _ := ret[0].(*sts.GetCallerIdentityOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCallerIdentity indicates an expected call of GetCallerIdentity. +func (mr *MockSTSAPIMockRecorder) GetCallerIdentity(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCallerIdentity", reflect.TypeOf((*MockSTSAPI)(nil).GetCallerIdentity), arg0) +} + +// GetCallerIdentityRequest mocks base method. +func (m *MockSTSAPI) GetCallerIdentityRequest(arg0 *sts.GetCallerIdentityInput) (*request.Request, *sts.GetCallerIdentityOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCallerIdentityRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.GetCallerIdentityOutput) + return ret0, ret1 +} + +// GetCallerIdentityRequest indicates an expected call of GetCallerIdentityRequest. +func (mr *MockSTSAPIMockRecorder) GetCallerIdentityRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCallerIdentityRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetCallerIdentityRequest), arg0) +} + +// GetCallerIdentityWithContext mocks base method. +func (m *MockSTSAPI) GetCallerIdentityWithContext(arg0 context.Context, arg1 *sts.GetCallerIdentityInput, arg2 ...request.Option) (*sts.GetCallerIdentityOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetCallerIdentityWithContext", varargs...) + ret0, _ := ret[0].(*sts.GetCallerIdentityOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCallerIdentityWithContext indicates an expected call of GetCallerIdentityWithContext. +func (mr *MockSTSAPIMockRecorder) GetCallerIdentityWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCallerIdentityWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetCallerIdentityWithContext), varargs...) +} + +// GetFederationToken mocks base method. +func (m *MockSTSAPI) GetFederationToken(arg0 *sts.GetFederationTokenInput) (*sts.GetFederationTokenOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFederationToken", arg0) + ret0, _ := ret[0].(*sts.GetFederationTokenOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFederationToken indicates an expected call of GetFederationToken. +func (mr *MockSTSAPIMockRecorder) GetFederationToken(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFederationToken", reflect.TypeOf((*MockSTSAPI)(nil).GetFederationToken), arg0) +} + +// GetFederationTokenRequest mocks base method. +func (m *MockSTSAPI) GetFederationTokenRequest(arg0 *sts.GetFederationTokenInput) (*request.Request, *sts.GetFederationTokenOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFederationTokenRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.GetFederationTokenOutput) + return ret0, ret1 +} + +// GetFederationTokenRequest indicates an expected call of GetFederationTokenRequest. +func (mr *MockSTSAPIMockRecorder) GetFederationTokenRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFederationTokenRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetFederationTokenRequest), arg0) +} + +// GetFederationTokenWithContext mocks base method. +func (m *MockSTSAPI) GetFederationTokenWithContext(arg0 context.Context, arg1 *sts.GetFederationTokenInput, arg2 ...request.Option) (*sts.GetFederationTokenOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetFederationTokenWithContext", varargs...) + ret0, _ := ret[0].(*sts.GetFederationTokenOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFederationTokenWithContext indicates an expected call of GetFederationTokenWithContext. +func (mr *MockSTSAPIMockRecorder) GetFederationTokenWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFederationTokenWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetFederationTokenWithContext), varargs...) +} + +// GetSessionToken mocks base method. +func (m *MockSTSAPI) GetSessionToken(arg0 *sts.GetSessionTokenInput) (*sts.GetSessionTokenOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSessionToken", arg0) + ret0, _ := ret[0].(*sts.GetSessionTokenOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSessionToken indicates an expected call of GetSessionToken. +func (mr *MockSTSAPIMockRecorder) GetSessionToken(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionToken", reflect.TypeOf((*MockSTSAPI)(nil).GetSessionToken), arg0) +} + +// GetSessionTokenRequest mocks base method. +func (m *MockSTSAPI) GetSessionTokenRequest(arg0 *sts.GetSessionTokenInput) (*request.Request, *sts.GetSessionTokenOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSessionTokenRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*sts.GetSessionTokenOutput) + return ret0, ret1 +} + +// GetSessionTokenRequest indicates an expected call of GetSessionTokenRequest. +func (mr *MockSTSAPIMockRecorder) GetSessionTokenRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionTokenRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetSessionTokenRequest), arg0) +} + +// GetSessionTokenWithContext mocks base method. +func (m *MockSTSAPI) GetSessionTokenWithContext(arg0 context.Context, arg1 *sts.GetSessionTokenInput, arg2 ...request.Option) (*sts.GetSessionTokenOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetSessionTokenWithContext", varargs...) + ret0, _ := ret[0].(*sts.GetSessionTokenOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSessionTokenWithContext indicates an expected call of GetSessionTokenWithContext. +func (mr *MockSTSAPIMockRecorder) GetSessionTokenWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionTokenWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetSessionTokenWithContext), varargs...) +} diff --git a/pkg/cloud/services/s3/s3.go b/pkg/cloud/services/s3/s3.go new file mode 100644 index 0000000000..c7c243bc83 --- /dev/null +++ b/pkg/cloud/services/s3/s3.go @@ -0,0 +1,288 @@ +/* +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 s3 + +import ( + "bytes" + "encoding/json" + "fmt" + "net/url" + "path" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3iface" + "github.com/aws/aws-sdk-go/service/sts" + "github.com/aws/aws-sdk-go/service/sts/stsiface" + "github.com/pkg/errors" + + iam "sigs.k8s.io/cluster-api-provider-aws/iam/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope" +) + +// Service holds a collection of interfaces. +// The interfaces are broken down like this to group functions together. +// One alternative is to have a large list of functions from the ec2 client. +type Service struct { + scope scope.S3Scope + S3Client s3iface.S3API + STSClient stsiface.STSAPI +} + +// NewService returns a new service given the api clients. +func NewService(s3Scope scope.S3Scope) *Service { + s3Client := scope.NewS3Client(s3Scope, s3Scope, s3Scope, s3Scope.InfraCluster()) + STSClient := scope.NewSTSClient(s3Scope, s3Scope, s3Scope, s3Scope.InfraCluster()) + + return &Service{ + scope: s3Scope, + S3Client: s3Client, + STSClient: STSClient, + } +} + +func (s *Service) ReconcileBucket() error { + if !s.bucketManagementEnabled() { + return nil + } + + bucketName := s.bucketName() + + if err := s.createBucketIfNotExist(bucketName); err != nil { + return errors.Wrap(err, "ensuring bucket exists") + } + + if err := s.ensureBucketPolicy(bucketName); err != nil { + return errors.Wrap(err, "ensuring bucket policy") + } + + return nil +} + +func (s *Service) DeleteBucket() error { + if !s.bucketManagementEnabled() { + return nil + } + + bucketName := s.bucketName() + + log := s.scope.WithValues("name", bucketName) + + log.Info("Deleting S3 Bucket") + + _, err := s.S3Client.DeleteBucket(&s3.DeleteBucketInput{ + Bucket: aws.String(bucketName), + }) + if err == nil { + return nil + } + + aerr, ok := err.(awserr.Error) + if !ok { + return errors.Wrap(err, "deleting S3 bucket") + } + + switch aerr.Code() { + case s3.ErrCodeNoSuchBucket: + log.Info("Bucket already removed") + case "BucketNotEmpty": + log.Info("Bucket not empty, skipping removal") + default: + return errors.Wrap(aerr, "deleting S3 bucket") + } + + return nil +} + +func (s *Service) Create(m *scope.MachineScope, data []byte) (string, error) { + if !s.bucketManagementEnabled() { + return "", errors.New("requested object creation but bucket management is not enabled") + } + + if m == nil { + return "", errors.New("machine scope can't be nil") + } + + if len(data) == 0 { + return "", errors.New("got empty data") + } + + bucket := s.bucketName() + key := s.bootstrapDataKey(m) + + s.scope.Info("Creating object", "bucket_name", bucket, "key", key) + + if _, err := s.S3Client.PutObject(&s3.PutObjectInput{ + Body: aws.ReadSeekCloser(bytes.NewReader(data)), + Bucket: aws.String(bucket), + Key: aws.String(key), + ServerSideEncryption: aws.String("aws:kms"), + }); err != nil { + return "", errors.Wrap(err, "putting object") + } + + objectURL := &url.URL{ + Scheme: "s3", + Host: bucket, + Path: key, + } + + return objectURL.String(), nil +} + +func (s *Service) Delete(m *scope.MachineScope) error { + if !s.bucketManagementEnabled() { + return errors.New("requested object creation but bucket management is not enabled") + } + + if m == nil { + return errors.New("machine scope can't be nil") + } + + bucket := s.bucketName() + key := s.bootstrapDataKey(m) + + s.scope.Info("Deleting object", "bucket_name", bucket, "key", key) + + _, err := s.S3Client.DeleteObject(&s3.DeleteObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + }) + if err == nil { + return nil + } + + aerr, ok := err.(awserr.Error) + if !ok { + return errors.Wrap(err, "deleting S3 object") + } + + switch aerr.Code() { + case s3.ErrCodeNoSuchBucket: + default: + return errors.Wrap(aerr, "deleting S3 object") + } + + return nil +} + +func (s *Service) createBucketIfNotExist(bucketName string) error { + input := &s3.CreateBucketInput{ + Bucket: aws.String(bucketName), + } + + _, err := s.S3Client.CreateBucket(input) + if err == nil { + s.scope.Info("Created bucket", "bucket_name", bucketName) + + return nil + } + + aerr, ok := err.(awserr.Error) + if !ok { + return errors.Wrap(err, "creating S3 bucket") + } + + switch aerr.Code() { + // If bucket already exists, all good. + // + // TODO: This will fail if bucket is shared with other cluster. + case s3.ErrCodeBucketAlreadyOwnedByYou: + return nil + default: + return errors.Wrap(aerr, "creating S3 bucket") + } +} + +func (s *Service) ensureBucketPolicy(bucketName string) error { + bucketPolicy, err := s.bucketPolicy(bucketName) + if err != nil { + return errors.Wrap(err, "generating Bucket policy") + } + + input := &s3.PutBucketPolicyInput{ + Bucket: aws.String(bucketName), + Policy: aws.String(bucketPolicy), + } + + if _, err := s.S3Client.PutBucketPolicy(input); err != nil { + return errors.Wrap(err, "creating S3 bucket policy") + } + + s.scope.V(4).Info("Updated bucket policy", "bucket_name", bucketName) + + return nil +} + +func (s *Service) bucketPolicy(bucketName string) (string, error) { + accountID, err := s.STSClient.GetCallerIdentity(&sts.GetCallerIdentityInput{}) + if err != nil { + return "", errors.Wrap(err, "getting account ID") + } + + bucket := s.scope.Bucket() + + statements := []iam.StatementEntry{ + { + Sid: "control-plane", + Effect: iam.EffectAllow, + Principal: map[iam.PrincipalType]iam.PrincipalID{ + iam.PrincipalAWS: []string{fmt.Sprintf("arn:aws:iam::%s:role/%s", *accountID.Account, bucket.ControlPlaneIAMInstanceProfile)}, + }, + Action: []string{"s3:GetObject"}, + Resource: []string{fmt.Sprintf("arn:aws:s3:::%s/control-plane/*", bucketName)}, + }, + } + + for _, iamInstanceProfile := range bucket.NodesIAMInstanceProfiles { + statements = append(statements, iam.StatementEntry{ + Sid: iamInstanceProfile, + Effect: iam.EffectAllow, + Principal: map[iam.PrincipalType]iam.PrincipalID{ + iam.PrincipalAWS: []string{fmt.Sprintf("arn:aws:iam::%s:role/%s", *accountID.Account, iamInstanceProfile)}, + }, + Action: []string{"s3:GetObject"}, + Resource: []string{fmt.Sprintf("arn:aws:s3:::%s/node/*", bucketName)}, + }) + } + + policy := iam.PolicyDocument{ + Version: "2012-10-17", + Statement: statements, + } + + policyRaw, err := json.Marshal(policy) + if err != nil { + return "", errors.Wrap(err, "building bucket policy") + } + + return string(policyRaw), nil +} + +func (s *Service) bucketManagementEnabled() bool { + return s.scope.Bucket() != nil +} + +func (s *Service) bucketName() string { + return s.scope.Bucket().Name +} + +func (s *Service) bootstrapDataKey(m *scope.MachineScope) string { + // Use machine name as object key. + return path.Join(m.Role(), m.Name()) +} diff --git a/pkg/cloud/services/s3/s3_test.go b/pkg/cloud/services/s3/s3_test.go new file mode 100644 index 0000000000..965b6dc7df --- /dev/null +++ b/pkg/cloud/services/s3/s3_test.go @@ -0,0 +1,762 @@ +/* +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 s3_test + +import ( + "errors" + "fmt" + "io/ioutil" + "net/url" + "reflect" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + s3svc "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/sts" + "github.com/golang/mock/gomock" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + + infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" + iamv1 "sigs.k8s.io/cluster-api-provider-aws/iam/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/s3" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/s3/mock_s3iface" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/s3/mock_stsiface" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + testClusterName = "test-cluster" + testClusterNamespace = "test-namespace" +) + +func Test_Reconcile_bucket(t *testing.T) { + t.Parallel() + + t.Run("does_nothing_when_bucket_management_is_disabled", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, nil) + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("creates_bucket_with_configured_name", func(t *testing.T) { + t.Parallel() + + expectedBucketName := "baz" + + svc, s3Mock := testService(t, &infrav1.S3Bucket{ + Name: expectedBucketName, + }) + + input := &s3svc.CreateBucketInput{ + Bucket: aws.String(expectedBucketName), + } + + s3Mock.EXPECT().CreateBucket(gomock.Eq(input)).Return(nil, nil).Times(1) + s3Mock.EXPECT().PutBucketPolicy(gomock.Any()).Return(nil, nil).Times(1) + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("hashes_default_bucket_name_if_name_exceeds_maximum_length", func(t *testing.T) { + t.Parallel() + + mockCtrl := gomock.NewController(t) + s3Mock := mock_s3iface.NewMockS3API(mockCtrl) + stsMock := mock_stsiface.NewMockSTSAPI(mockCtrl) + + getCallerIdentityResult := &sts.GetCallerIdentityOutput{Account: aws.String("foo")} + stsMock.EXPECT().GetCallerIdentity(gomock.Any()).Return(getCallerIdentityResult, nil).AnyTimes() + + scheme := runtime.NewScheme() + _ = infrav1.AddToScheme(scheme) + client := fake.NewClientBuilder().WithScheme(scheme).Build() + + longName := strings.Repeat("a", 40) + scope, err := scope.NewClusterScope(scope.ClusterScopeParams{ + Client: client, + Cluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: longName, + Namespace: longName, + }, + }, + AWSCluster: &infrav1.AWSCluster{ + Spec: infrav1.AWSClusterSpec{ + S3Bucket: &infrav1.S3Bucket{}, + }, + }, + }) + if err != nil { + t.Fatalf("Failed to create test context: %v", err) + } + + svc := s3.NewService(scope) + svc.S3Client = s3Mock + svc.STSClient = stsMock + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Do(func(input *s3svc.CreateBucketInput) { + if input.Bucket == nil { + t.Fatalf("CreateBucket request must have Bucket specified") + } + + if strings.Contains(*input.Bucket, longName) { + t.Fatalf("Default bucket name be hashed when it's very long, got: %q", *input.Bucket) + } + }).Return(nil, nil).Times(1) + + s3Mock.EXPECT().PutBucketPolicy(gomock.Any()).Return(nil, nil).Times(1) + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("creates_bucket_with_policy_allowing_controlplane_and_worker_nodes_to_read_their_secrets", func(t *testing.T) { + t.Parallel() + + bucketName := "bar" + + svc, s3Mock := testService(t, &infrav1.S3Bucket{ + Name: bucketName, + ControlPlaneIAMInstanceProfile: fmt.Sprintf("control-plane%s", iamv1.DefaultNameSuffix), + NodesIAMInstanceProfiles: []string{ + fmt.Sprintf("nodes%s", iamv1.DefaultNameSuffix), + }, + }) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, nil).Times(1) + s3Mock.EXPECT().PutBucketPolicy(gomock.Any()).Do(func(input *s3svc.PutBucketPolicyInput) { + if input.Policy == nil { + t.Fatalf("Policy must be defined") + } + + policy := *input.Policy + + if !strings.Contains(policy, "role/control-plane") { + t.Errorf("At least one policy should include a reference to control-plane role, got: %v", policy) + } + + if !strings.Contains(policy, "role/node") { + t.Errorf("At least one policy should include a reference to node role, got: %v", policy) + } + + if !strings.Contains(policy, fmt.Sprintf("%s/control-plane/*", bucketName)) { + t.Errorf("At least one policy should apply for all objects with %q prefix, got: %v", "control-plane", policy) + } + + if !strings.Contains(policy, fmt.Sprintf("%s/node/*", bucketName)) { + t.Errorf("At least one policy should apply for all objects with %q prefix, got: %v", "node", policy) + } + }).Return(nil, nil).Times(1) + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("is_idempotent", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, nil).Times(2) + s3Mock.EXPECT().PutBucketPolicy(gomock.Any()).Return(nil, nil).Times(2) + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("ignores_when_bucket_already_exists_but_its_owned_by_the_same_account", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + err := awserr.New(s3svc.ErrCodeBucketAlreadyOwnedByYou, "err", errors.New("err")) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, err).Times(1) + s3Mock.EXPECT().PutBucketPolicy(gomock.Any()).Return(nil, nil).Times(1) + + if err := svc.ReconcileBucket(); err != nil { + t.Fatalf("Unexpected error, got: %v", err) + } + }) + + t.Run("returns_error_when", func(t *testing.T) { + t.Parallel() + + t.Run("bucket_creation_fails", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, errors.New("error")).Times(1) + + if err := svc.ReconcileBucket(); err == nil { + t.Fatalf("Expected error") + } + }) + + t.Run("bucket_creation_returns_unexpected_AWS_error", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, awserr.New("foo", "", nil)).Times(1) + + if err := svc.ReconcileBucket(); err == nil { + t.Fatalf("Expected error") + } + }) + + t.Run("generating_bucket_policy_fails", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, nil).Times(1) + + mockCtrl := gomock.NewController(t) + stsMock := mock_stsiface.NewMockSTSAPI(mockCtrl) + stsMock.EXPECT().GetCallerIdentity(gomock.Any()).Return(nil, fmt.Errorf(t.Name())).AnyTimes() + svc.STSClient = stsMock + + if err := svc.ReconcileBucket(); err == nil { + t.Fatalf("Expected error") + } + }) + + t.Run("creating_bucket_policy_fails", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().CreateBucket(gomock.Any()).Return(nil, nil).Times(1) + s3Mock.EXPECT().PutBucketPolicy(gomock.Any()).Return(nil, errors.New("error")).Times(1) + + if err := svc.ReconcileBucket(); err == nil { + t.Fatalf("Expected error") + } + }) + }) +} + +func Test_Delete_bucket(t *testing.T) { + t.Parallel() + + const bucketName = "foo" + + t.Run("does_nothing_when_bucket_management_is_disabled", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, nil) + + if err := svc.DeleteBucket(); err != nil { + t.Fatalf("Unexpected error, got: %v", err) + } + }) + + t.Run("deletes_bucket_with_configured_name", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{ + Name: bucketName, + }) + + input := &s3svc.DeleteBucketInput{ + Bucket: aws.String(bucketName), + } + + s3Mock.EXPECT().DeleteBucket(input).Return(nil, nil).Times(1) + + if err := svc.DeleteBucket(); err != nil { + t.Fatalf("Unexpected error, got: %v", err) + } + }) + + t.Run("returns_error_when_bucket_removal_returns", func(t *testing.T) { + t.Parallel() + t.Run("unexpected_error", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().DeleteBucket(gomock.Any()).Return(nil, errors.New("err")).Times(1) + + if err := svc.DeleteBucket(); err == nil { + t.Fatalf("Expected error") + } + }) + + t.Run("unexpected_AWS_error", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().DeleteBucket(gomock.Any()).Return(nil, awserr.New("foo", "", nil)).Times(1) + + if err := svc.DeleteBucket(); err == nil { + t.Fatalf("Expected error") + } + }) + }) + + t.Run("ignores_when_bucket_has_already_been_removed", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().DeleteBucket(gomock.Any()).Return(nil, awserr.New(s3svc.ErrCodeNoSuchBucket, "", nil)).Times(1) + + if err := svc.DeleteBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("skips_bucket_removal_when_bucket_is_not_empty", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + s3Mock.EXPECT().DeleteBucket(gomock.Any()).Return(nil, awserr.New("BucketNotEmpty", "", nil)).Times(1) + + if err := svc.DeleteBucket(); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) +} + +func Test_Create_object(t *testing.T) { + t.Parallel() + + const ( + bucketName = "foo" + nodeName = "aws-test1" + ) + + t.Run("for_machine", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{ + Name: bucketName, + }) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + bootstrapData := []byte("foobar") + + s3Mock.EXPECT().PutObject(gomock.Any()).Do(func(putObjectInput *s3svc.PutObjectInput) { + t.Run("use_configured_bucket_name_on_cluster_level", func(t *testing.T) { + t.Parallel() + + if *putObjectInput.Bucket != bucketName { + t.Fatalf("Expected object to be created in bucket %q, got %q", bucketName, *putObjectInput.Bucket) + } + }) + + t.Run("use_machine_role_and_machine_name_as_key", func(t *testing.T) { + t.Parallel() + + if !strings.HasPrefix(*putObjectInput.Key, "node") { + t.Errorf("Expected key to start with node role, got: %q", *putObjectInput.Key) + } + + if !strings.HasSuffix(*putObjectInput.Key, nodeName) { + t.Errorf("Expected key to end with node name, got: %q", *putObjectInput.Key) + } + }) + + t.Run("puts_given_bootstrap_data_untouched", func(t *testing.T) { + t.Parallel() + + data, err := ioutil.ReadAll(putObjectInput.Body) + if err != nil { + t.Fatalf("Reading put object body: %v", err) + } + + if !reflect.DeepEqual(data, bootstrapData) { + t.Fatalf("Unexpected request body %q, expected %q", string(data), string(bootstrapData)) + } + }) + }).Return(nil, nil).Times(1) + + bootstrapDataURL, err := svc.Create(machineScope, bootstrapData) + if err != nil { + t.Fatalf("Unexpected error, got: %v", err) + } + + t.Run("returns_s3_url_for_created_object", func(t *testing.T) { + t.Parallel() + + parsedURL, err := url.Parse(bootstrapDataURL) + if err != nil { + t.Fatalf("Parsing URL %q: %v", bootstrapDataURL, err) + } + + expectedScheme := "s3" + if parsedURL.Scheme != expectedScheme { + t.Errorf("Unexpected URL scheme, expected %q, got %q", expectedScheme, parsedURL.Scheme) + } + + if !strings.Contains(parsedURL.Host, bucketName) { + t.Errorf("URL Host should include bucket %q reference, got %q", bucketName, parsedURL.Host) + } + + if !strings.HasSuffix(parsedURL.Path, nodeName) { + t.Errorf("URL Path should end with node name %q, got: %q", nodeName, parsedURL.Path) + } + }) + }) + + t.Run("is_idempotent", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + s3Mock.EXPECT().PutObject(gomock.Any()).Return(nil, nil).Times(2) + + boostrapData := []byte("foo") + + if _, err := svc.Create(machineScope, boostrapData); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if _, err := svc.Create(machineScope, boostrapData); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) + + t.Run("returns_error_when", func(t *testing.T) { + t.Parallel() + + t.Run("object_creation_fails", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + s3Mock.EXPECT().PutObject(gomock.Any()).Return(nil, errors.New("foo")).Times(1) + + bootstrapDataURL, err := svc.Create(machineScope, []byte("foo")) + if err == nil { + t.Fatalf("Expected error") + } + + if bootstrapDataURL != "" { + t.Fatalf("Expected empty bootstrap data URL when creation error occurs") + } + }) + + t.Run("given_empty_machine_scope", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, &infrav1.S3Bucket{}) + + bootstrapDataURL, err := svc.Create(nil, []byte("foo")) + if err == nil { + t.Fatalf("Expected error") + } + + if bootstrapDataURL != "" { + t.Fatalf("Expected empty bootstrap data URL when creation error occurs") + } + }) + + // If one tries to put empty bootstrap data into S3, most likely something is wrong. + t.Run("given_empty_bootstrap_data", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, &infrav1.S3Bucket{}) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + bootstrapDataURL, err := svc.Create(machineScope, []byte{}) + if err == nil { + t.Fatalf("Expected error") + } + + if bootstrapDataURL != "" { + t.Fatalf("Expected empty bootstrap data URL when creation error occurs") + } + }) + + t.Run("bucket_management_is_disabled_clusterwide", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, nil) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + bootstrapDataURL, err := svc.Create(machineScope, []byte("foo")) + if err == nil { + t.Fatalf("Expected error") + } + + if bootstrapDataURL != "" { + t.Fatalf("Expected empty bootstrap data URL when creation error occurs") + } + }) + }) +} + +func Test_Delete_object(t *testing.T) { + t.Parallel() + + const nodeName = "aws-test1" + + t.Run("for_machine", func(t *testing.T) { + t.Parallel() + + expectedBucketName := "foo" + + svc, s3Mock := testService(t, &infrav1.S3Bucket{ + Name: expectedBucketName, + }) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + clusterv1.MachineControlPlaneLabelName: "", + }, + }, + }, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + s3Mock.EXPECT().DeleteObject(gomock.Any()).Do(func(deleteObjectInput *s3svc.DeleteObjectInput) { + t.Run("use_configured_bucket_name_on_cluster_level", func(t *testing.T) { + t.Parallel() + + if *deleteObjectInput.Bucket != expectedBucketName { + t.Fatalf("Expected object to be deleted from bucket %q, got %q", expectedBucketName, *deleteObjectInput.Bucket) + } + }) + + t.Run("use_machine_role_and_machine_name_as_key", func(t *testing.T) { + t.Parallel() + + if !strings.HasPrefix(*deleteObjectInput.Key, "control-plane") { + t.Errorf("Expected key to start with control-plane role, got: %q", *deleteObjectInput.Key) + } + + if !strings.HasSuffix(*deleteObjectInput.Key, nodeName) { + t.Errorf("Expected key to end with node name, got: %q", *deleteObjectInput.Key) + } + }) + }).Return(nil, nil).Times(1) + + if err := svc.Delete(machineScope); err != nil { + t.Fatalf("Unexpected error, got: %v", err) + } + }) + + t.Run("succeeds_when_bucket_has_already_been_removed", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + s3Mock.EXPECT().DeleteObject(gomock.Any()).Return(nil, awserr.New(s3svc.ErrCodeNoSuchBucket, "", nil)).Times(1) + + if err := svc.Delete(machineScope); err != nil { + t.Fatalf("Unexpected error, got: %v", err) + } + }) + + t.Run("returns_error_when", func(t *testing.T) { + t.Parallel() + + t.Run("object_deletion_fails", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + s3Mock.EXPECT().DeleteObject(gomock.Any()).Return(nil, errors.New("foo")).Times(1) + + if err := svc.Delete(machineScope); err == nil { + t.Fatalf("Expected error") + } + }) + + t.Run("given_empty_machine_scope", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, &infrav1.S3Bucket{}) + + if err := svc.Delete(nil); err == nil { + t.Fatalf("Expected error") + } + }) + + t.Run("bucket_management_is_disabled_clusterwide", func(t *testing.T) { + t.Parallel() + + svc, _ := testService(t, nil) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + if err := svc.Delete(machineScope); err == nil { + t.Fatalf("Expected error") + } + }) + }) + + t.Run("is_idempotent", func(t *testing.T) { + t.Parallel() + + svc, s3Mock := testService(t, &infrav1.S3Bucket{}) + + machineScope := &scope.MachineScope{ + Machine: &clusterv1.Machine{}, + AWSMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + }, + } + + s3Mock.EXPECT().DeleteObject(gomock.Any()).Return(nil, nil).Times(2) + + if err := svc.Delete(machineScope); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if err := svc.Delete(machineScope); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + }) +} + +func testService(t *testing.T, bucket *infrav1.S3Bucket) (*s3.Service, *mock_s3iface.MockS3API) { + t.Helper() + + mockCtrl := gomock.NewController(t) + s3Mock := mock_s3iface.NewMockS3API(mockCtrl) + stsMock := mock_stsiface.NewMockSTSAPI(mockCtrl) + + getCallerIdentityResult := &sts.GetCallerIdentityOutput{Account: aws.String("foo")} + stsMock.EXPECT().GetCallerIdentity(gomock.Any()).Return(getCallerIdentityResult, nil).AnyTimes() + + scheme := runtime.NewScheme() + _ = infrav1.AddToScheme(scheme) + client := fake.NewClientBuilder().WithScheme(scheme).Build() + + scope, err := scope.NewClusterScope(scope.ClusterScopeParams{ + Client: client, + Cluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: testClusterName, + Namespace: testClusterNamespace, + }, + }, + AWSCluster: &infrav1.AWSCluster{ + Spec: infrav1.AWSClusterSpec{ + S3Bucket: bucket, + }, + }, + }) + if err != nil { + t.Fatalf("Failed to create test context: %v", err) + } + + svc := s3.NewService(scope) + svc.S3Client = s3Mock + svc.STSClient = stsMock + + return svc, s3Mock +} From aa4f25e5be9264b3ae9fc3e19c335adb49530732 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 16 Feb 2021 09:52:13 +0100 Subject: [PATCH 04/12] controllers: reconcile S3Bucket as part of reconciliation loop When S3Bucket.Enabled is true, cluster controller will create an S3 bucket, by default with cluster name as a bucket name, where machine controller will be able to put userdata for systems, which do not support pulling them from Secret Manager, like Ignition. When cluster is deleted, bucket will be removed as well. Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- .../v1alpha1/zz_generated.conversion.go | 1 + .../api/bootstrap/v1beta1/defaults.go | 6 + .../api/bootstrap/v1beta1/types.go | 17 + .../v1beta1/zz_generated.deepcopy.go | 16 + .../bootstrap/cluster_api_controller.go | 15 + .../bootstrap/fixtures/with_s3_bucket.yaml | 427 ++++++++++++++++++ .../cloudformation/bootstrap/template_test.go | 8 + controllers/awscluster_controller.go | 12 + 8 files changed, 502 insertions(+) create mode 100644 cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml diff --git a/cmd/clusterawsadm/api/bootstrap/v1alpha1/zz_generated.conversion.go b/cmd/clusterawsadm/api/bootstrap/v1alpha1/zz_generated.conversion.go index 61a6059880..39a1e1b78f 100644 --- a/cmd/clusterawsadm/api/bootstrap/v1alpha1/zz_generated.conversion.go +++ b/cmd/clusterawsadm/api/bootstrap/v1alpha1/zz_generated.conversion.go @@ -206,6 +206,7 @@ func autoConvert_v1beta1_AWSIAMConfigurationSpec_To_v1alpha1_AWSIAMConfiguration out.EventBridge = (*EventBridgeConfig)(unsafe.Pointer(in.EventBridge)) out.Partition = in.Partition out.SecureSecretsBackends = *(*[]apiv1beta1.SecretBackend)(unsafe.Pointer(&in.SecureSecretsBackends)) + // WARNING: in.S3Buckets requires manual conversion: does not exist in peer-type return nil } diff --git a/cmd/clusterawsadm/api/bootstrap/v1beta1/defaults.go b/cmd/clusterawsadm/api/bootstrap/v1beta1/defaults.go index 76dd68fc1a..e18f1b26e6 100644 --- a/cmd/clusterawsadm/api/bootstrap/v1beta1/defaults.go +++ b/cmd/clusterawsadm/api/bootstrap/v1beta1/defaults.go @@ -33,6 +33,8 @@ const ( DefaultPartitionName = "aws" // DefaultKMSAliasPattern is the default KMS alias. DefaultKMSAliasPattern = "cluster-api-provider-aws-*" + // DefaultS3BucketPrefix is the default S3 bucket prefix. + DefaultS3BucketPrefix = "cluster-api-provider-aws-" ) func addDefaultingFuncs(scheme *runtime.Scheme) error { @@ -91,6 +93,10 @@ func SetDefaults_AWSIAMConfigurationSpec(obj *AWSIAMConfigurationSpec) { //nolin if len(obj.EKS.KMSAliasPrefix) == 0 { obj.EKS.KMSAliasPrefix = DefaultKMSAliasPattern } + + if obj.S3Buckets.NamePrefix == "" { + obj.S3Buckets.NamePrefix = DefaultS3BucketPrefix + } } // SetDefaults_AWSIAMConfiguration is used by defaulter-gen. diff --git a/cmd/clusterawsadm/api/bootstrap/v1beta1/types.go b/cmd/clusterawsadm/api/bootstrap/v1beta1/types.go index 8c228cf781..9f1bdf7514 100644 --- a/cmd/clusterawsadm/api/bootstrap/v1beta1/types.go +++ b/cmd/clusterawsadm/api/bootstrap/v1beta1/types.go @@ -159,6 +159,17 @@ type AWSIAMConfiguration struct { Spec AWSIAMConfigurationSpec `json:"spec,omitempty"` } +// S3Buckets controls the configuration of the AWS IAM role for S3 buckets +// which can be created for storing bootstrap data for nodes requiring it. +type S3Buckets struct { + // Enable controls whether permissions are granted to manage S3 buckets. + Enable bool `json:"enable"` + + // NamePrefix will be prepended to every AWS IAM role bucket name. Defaults to "cluster-api-provider-aws-". + // AWSCluster S3 Bucket name must be prefixed with the same prefix. + NamePrefix string `json:"namePrefix"` +} + // AWSIAMConfigurationSpec defines the specification of the AWSIAMConfiguration. type AWSIAMConfigurationSpec struct { // NamePrefix will be prepended to every AWS IAM role, user and policy created by clusterawsadm. Defaults to "". @@ -207,6 +218,12 @@ type AWSIAMConfigurationSpec struct { // will generate AWS Secrets Manager policies instead. // +kubebuilder:validation:Enum=secrets-manager;ssm-parameter-store SecureSecretsBackends []infrav1.SecretBackend `json:"secureSecretBackends,omitempty"` + + // S3Buckets, when enabled, will add controller nodes permissions to + // create S3 Buckets for workload clusters. + // TODO: This field could be a pointer, but it seems it breaks setting default values? + // +optional + S3Buckets S3Buckets `json:"s3Buckets,omitempty"` } // GetObjectKind returns the AAWSIAMConfiguration's TypeMeta. diff --git a/cmd/clusterawsadm/api/bootstrap/v1beta1/zz_generated.deepcopy.go b/cmd/clusterawsadm/api/bootstrap/v1beta1/zz_generated.deepcopy.go index 55f43129bb..c318c00061 100644 --- a/cmd/clusterawsadm/api/bootstrap/v1beta1/zz_generated.deepcopy.go +++ b/cmd/clusterawsadm/api/bootstrap/v1beta1/zz_generated.deepcopy.go @@ -86,6 +86,7 @@ func (in *AWSIAMConfigurationSpec) DeepCopyInto(out *AWSIAMConfigurationSpec) { *out = make([]cluster_api_provider_awsapiv1beta1.SecretBackend, len(*in)) copy(*out, *in) } + out.S3Buckets = in.S3Buckets } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSIAMConfigurationSpec. @@ -271,3 +272,18 @@ func (in *Nodes) DeepCopy() *Nodes { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *S3Buckets) DeepCopyInto(out *S3Buckets) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3Buckets. +func (in *S3Buckets) DeepCopy() *S3Buckets { + if in == nil { + return nil + } + out := new(S3Buckets) + in.DeepCopyInto(out) + return out +} diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go b/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go index 9c514ddf1d..9e942671b8 100644 --- a/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go +++ b/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go @@ -236,6 +236,21 @@ func (t Template) ControllersPolicy() *iamv1.PolicyDocument { }) } } + if t.Spec.S3Buckets.Enable { + statement = append(statement, iamv1.StatementEntry{ + Effect: iamv1.EffectAllow, + Resource: iamv1.Resources{ + fmt.Sprintf("arn:*:s3:::%s*", t.Spec.S3Buckets.NamePrefix), + }, + Action: iamv1.Actions{ + "s3:CreateBucket", + "s3:DeleteBucket", + "s3:PutObject", + "s3:DeleteObject", + "s3:PutBucketPolicy", + }, + }) + } if t.Spec.EventBridge.Enable { statement = append(statement, iamv1.StatementEntry{ Effect: iamv1.EffectAllow, diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml new file mode 100644 index 0000000000..b9f9bcd9a5 --- /dev/null +++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml @@ -0,0 +1,427 @@ +AWSTemplateFormatVersion: 2010-09-09 +Resources: + AWSIAMInstanceProfileControlPlane: + Properties: + InstanceProfileName: control-plane.cluster-api-provider-aws.sigs.k8s.io + Roles: + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::InstanceProfile + AWSIAMInstanceProfileControllers: + Properties: + InstanceProfileName: controllers.cluster-api-provider-aws.sigs.k8s.io + Roles: + - Ref: AWSIAMRoleControllers + Type: AWS::IAM::InstanceProfile + AWSIAMInstanceProfileNodes: + Properties: + InstanceProfileName: nodes.cluster-api-provider-aws.sigs.k8s.io + Roles: + - Ref: AWSIAMRoleNodes + Type: AWS::IAM::InstanceProfile + AWSIAMManagedPolicyCloudProviderControlPlane: + Properties: + Description: For the Kubernetes Cloud Provider AWS Control Plane + ManagedPolicyName: control-plane.cluster-api-provider-aws.sigs.k8s.io + PolicyDocument: + Statement: + - Action: + - autoscaling:DescribeAutoScalingGroups + - autoscaling:DescribeLaunchConfigurations + - autoscaling:DescribeTags + - ec2:DescribeInstances + - ec2:DescribeImages + - ec2:DescribeRegions + - ec2:DescribeRouteTables + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVolumes + - ec2:CreateSecurityGroup + - ec2:CreateTags + - ec2:CreateVolume + - ec2:ModifyInstanceAttribute + - ec2:ModifyVolume + - ec2:AttachVolume + - ec2:AuthorizeSecurityGroupIngress + - ec2:CreateRoute + - ec2:DeleteRoute + - ec2:DeleteSecurityGroup + - ec2:DeleteVolume + - ec2:DetachVolume + - ec2:RevokeSecurityGroupIngress + - ec2:DescribeVpcs + - elasticloadbalancing:AddTags + - elasticloadbalancing:AttachLoadBalancerToSubnets + - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer + - elasticloadbalancing:CreateLoadBalancer + - elasticloadbalancing:CreateLoadBalancerPolicy + - elasticloadbalancing:CreateLoadBalancerListeners + - elasticloadbalancing:ConfigureHealthCheck + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:DeleteLoadBalancerListeners + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:DetachLoadBalancerFromSubnets + - elasticloadbalancing:DeregisterInstancesFromLoadBalancer + - elasticloadbalancing:ModifyLoadBalancerAttributes + - elasticloadbalancing:RegisterInstancesWithLoadBalancer + - elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer + - elasticloadbalancing:CreateListener + - elasticloadbalancing:CreateTargetGroup + - elasticloadbalancing:DeleteListener + - elasticloadbalancing:DeleteTargetGroup + - elasticloadbalancing:DescribeListeners + - elasticloadbalancing:DescribeLoadBalancerPolicies + - elasticloadbalancing:DescribeTargetGroups + - elasticloadbalancing:DescribeTargetHealth + - elasticloadbalancing:ModifyListener + - elasticloadbalancing:ModifyTargetGroup + - elasticloadbalancing:RegisterTargets + - elasticloadbalancing:SetLoadBalancerPoliciesOfListener + - iam:CreateServiceLinkedRole + - kms:DescribeKey + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyCloudProviderNodes: + Properties: + Description: For the Kubernetes Cloud Provider AWS nodes + ManagedPolicyName: nodes.cluster-api-provider-aws.sigs.k8s.io + PolicyDocument: + Statement: + - Action: + - ec2:DescribeInstances + - ec2:DescribeRegions + - ecr:GetAuthorizationToken + - ecr:BatchCheckLayerAvailability + - ecr:GetDownloadUrlForLayer + - ecr:GetRepositoryPolicy + - ecr:DescribeRepositories + - ecr:ListImages + - ecr:BatchGetImage + Effect: Allow + Resource: + - '*' + - Action: + - secretsmanager:DeleteSecret + - secretsmanager:GetSecretValue + Effect: Allow + Resource: + - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/* + - Action: + - ssm:UpdateInstanceInformation + - ssmmessages:CreateControlChannel + - ssmmessages:CreateDataChannel + - ssmmessages:OpenControlChannel + - ssmmessages:OpenDataChannel + - s3:GetEncryptionConfiguration + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControlPlane + - Ref: AWSIAMRoleNodes + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyControllers: + Properties: + Description: For the Kubernetes Cluster API Provider AWS Controllers + ManagedPolicyName: controllers.cluster-api-provider-aws.sigs.k8s.io + PolicyDocument: + Statement: + - Action: + - ec2:AllocateAddress + - ec2:AssociateRouteTable + - ec2:AttachInternetGateway + - ec2:AuthorizeSecurityGroupIngress + - ec2:CreateInternetGateway + - ec2:CreateNatGateway + - ec2:CreateRoute + - ec2:CreateRouteTable + - ec2:CreateSecurityGroup + - ec2:CreateSubnet + - ec2:CreateTags + - ec2:CreateVpc + - ec2:ModifyVpcAttribute + - ec2:DeleteInternetGateway + - ec2:DeleteNatGateway + - ec2:DeleteRouteTable + - ec2:DeleteSecurityGroup + - ec2:DeleteSubnet + - ec2:DeleteTags + - ec2:DeleteVpc + - ec2:DescribeAccountAttributes + - ec2:DescribeAddresses + - ec2:DescribeAvailabilityZones + - ec2:DescribeInstances + - ec2:DescribeInternetGateways + - ec2:DescribeImages + - ec2:DescribeNatGateways + - ec2:DescribeNetworkInterfaces + - ec2:DescribeNetworkInterfaceAttribute + - ec2:DescribeRouteTables + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + - ec2:DescribeVpcAttribute + - ec2:DescribeVolumes + - ec2:DetachInternetGateway + - ec2:DisassociateRouteTable + - ec2:DisassociateAddress + - ec2:ModifyInstanceAttribute + - ec2:ModifyNetworkInterfaceAttribute + - ec2:ModifySubnetAttribute + - ec2:ReleaseAddress + - ec2:RevokeSecurityGroupIngress + - ec2:RunInstances + - ec2:TerminateInstances + - tag:GetResources + - elasticloadbalancing:AddTags + - elasticloadbalancing:CreateLoadBalancer + - elasticloadbalancing:ConfigureHealthCheck + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer + - elasticloadbalancing:DescribeTags + - elasticloadbalancing:ModifyLoadBalancerAttributes + - elasticloadbalancing:RegisterInstancesWithLoadBalancer + - elasticloadbalancing:DeregisterInstancesFromLoadBalancer + - elasticloadbalancing:RemoveTags + - autoscaling:DescribeAutoScalingGroups + - autoscaling:DescribeInstanceRefreshes + - ec2:CreateLaunchTemplate + - ec2:CreateLaunchTemplateVersion + - ec2:DescribeLaunchTemplates + - ec2:DescribeLaunchTemplateVersions + - ec2:DeleteLaunchTemplate + - ec2:DeleteLaunchTemplateVersions + - ec2:DescribeKeyPairs + Effect: Allow + Resource: + - '*' + - Action: + - autoscaling:CreateAutoScalingGroup + - autoscaling:UpdateAutoScalingGroup + - autoscaling:CreateOrUpdateTags + - autoscaling:StartInstanceRefresh + - autoscaling:DeleteAutoScalingGroup + - autoscaling:DeleteTags + Effect: Allow + Resource: + - arn:*:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/* + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: autoscaling.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: elasticloadbalancing.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: spot.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot + - Action: + - iam:PassRole + Effect: Allow + Resource: + - arn:*:iam::*:role/*.cluster-api-provider-aws.sigs.k8s.io + - Action: + - secretsmanager:CreateSecret + - secretsmanager:DeleteSecret + - secretsmanager:TagResource + Effect: Allow + Resource: + - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/* + - Action: + - s3:CreateBucket + - s3:DeleteBucket + - s3:PutObject + - s3:DeleteObject + - s3:PutBucketPolicy + Effect: Allow + Resource: + - arn:*:s3:::cluster-api-provider-aws-* + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControllers + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyControllersEKS: + Properties: + Description: For the Kubernetes Cluster API Provider AWS Controllers + ManagedPolicyName: controllers-eks.cluster-api-provider-aws.sigs.k8s.io + PolicyDocument: + Statement: + - Action: + - ssm:GetParameter + Effect: Allow + Resource: + - arn:*:ssm:*:*:parameter/aws/service/eks/optimized-ami/* + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: eks.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: eks-nodegroup.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: eks-fargate.amazonaws.com + Effect: Allow + Resource: + - arn:aws:iam::*:role/aws-service-role/eks-fargate-pods.amazonaws.com/AWSServiceRoleForAmazonEKSForFargate + - Action: + - iam:GetRole + - iam:ListAttachedRolePolicies + Effect: Allow + Resource: + - arn:*:iam::*:role/* + - Action: + - iam:GetPolicy + Effect: Allow + Resource: + - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy + - Action: + - eks:DescribeCluster + - eks:ListClusters + - eks:CreateCluster + - eks:TagResource + - eks:UpdateClusterVersion + - eks:DeleteCluster + - eks:UpdateClusterConfig + - eks:UntagResource + - eks:UpdateNodegroupVersion + - eks:DescribeNodegroup + - eks:DeleteNodegroup + - eks:UpdateNodegroupConfig + - eks:CreateNodegroup + - eks:AssociateEncryptionConfig + - eks:ListIdentityProviderConfigs + - eks:AssociateIdentityProviderConfig + - eks:DescribeIdentityProviderConfig + - eks:DisassociateIdentityProviderConfig + Effect: Allow + Resource: + - arn:*:eks:*:*:cluster/* + - arn:*:eks:*:*:nodegroup/*/*/* + - Action: + - eks:ListAddons + - eks:CreateAddon + - eks:DescribeAddonVersions + - eks:DescribeAddon + - eks:DeleteAddon + - eks:UpdateAddon + - eks:TagResource + - eks:DescribeFargateProfile + - eks:CreateFargateProfile + - eks:DeleteFargateProfile + Effect: Allow + Resource: + - '*' + - Action: + - iam:PassRole + Condition: + StringEquals: + iam:PassedToService: eks.amazonaws.com + Effect: Allow + Resource: + - '*' + - Action: + - kms:CreateGrant + - kms:DescribeKey + Condition: + ForAnyValue:StringLike: + kms:ResourceAliases: alias/cluster-api-provider-aws-* + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControllers + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMRoleControlPlane: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + RoleName: control-plane.cluster-api-provider-aws.sigs.k8s.io + Type: AWS::IAM::Role + AWSIAMRoleControllers: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + RoleName: controllers.cluster-api-provider-aws.sigs.k8s.io + Type: AWS::IAM::Role + AWSIAMRoleEKSControlPlane: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - eks.amazonaws.com + Version: 2012-10-17 + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy + RoleName: eks-controlplane.cluster-api-provider-aws.sigs.k8s.io + Type: AWS::IAM::Role + AWSIAMRoleNodes: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy + - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy + RoleName: nodes.cluster-api-provider-aws.sigs.k8s.io + Type: AWS::IAM::Role diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/template_test.go b/cmd/clusterawsadm/cloudformation/bootstrap/template_test.go index b2818d07fc..6a50aa7539 100644 --- a/cmd/clusterawsadm/cloudformation/bootstrap/template_test.go +++ b/cmd/clusterawsadm/cloudformation/bootstrap/template_test.go @@ -61,6 +61,14 @@ func Test_RenderCloudformation(t *testing.T) { return t }, }, + { + fixture: "with_s3_bucket", + template: func() Template { + t := NewTemplate() + t.Spec.S3Buckets.Enable = true + return t + }, + }, { fixture: "customsuffix", template: func() Template { diff --git a/controllers/awscluster_controller.go b/controllers/awscluster_controller.go index 097b9cb098..6a8f491650 100644 --- a/controllers/awscluster_controller.go +++ b/controllers/awscluster_controller.go @@ -46,6 +46,7 @@ import ( "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/elb" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/instancestate" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/network" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/s3" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/securitygroup" infrautilconditions "sigs.k8s.io/cluster-api-provider-aws/util/conditions" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" @@ -200,6 +201,7 @@ func (r *AWSClusterReconciler) reconcileDelete(clusterScope *scope.ClusterScope) elbsvc := r.getELBService(clusterScope) networkSvc := r.getNetworkService(*clusterScope) sgService := r.getSecurityGroupService(*clusterScope) + s3Service := s3.NewService(clusterScope) if feature.Gates.Enabled(feature.EventBridgeInstanceState) { instancestateSvc := instancestate.NewService(clusterScope) @@ -229,6 +231,10 @@ func (r *AWSClusterReconciler) reconcileDelete(clusterScope *scope.ClusterScope) return reconcile.Result{}, err } + if err := s3Service.DeleteBucket(); err != nil { + return reconcile.Result{}, errors.Wrapf(err, "error deleting S3 Bucket") + } + // Cluster is deleted so remove the finalizer. controllerutil.RemoveFinalizer(clusterScope.AWSCluster, infrav1.ClusterFinalizer) @@ -251,6 +257,7 @@ func (r *AWSClusterReconciler) reconcileNormal(clusterScope *scope.ClusterScope) elbService := r.getELBService(clusterScope) networkSvc := r.getNetworkService(*clusterScope) sgService := r.getSecurityGroupService(*clusterScope) + s3Service := s3.NewService(clusterScope) if err := networkSvc.ReconcileNetwork(); err != nil { clusterScope.Error(err, "failed to reconcile network") @@ -288,6 +295,11 @@ func (r *AWSClusterReconciler) reconcileNormal(clusterScope *scope.ClusterScope) return reconcile.Result{}, err } + if err := s3Service.ReconcileBucket(); err != nil { + conditions.MarkFalse(awsCluster, infrav1.S3BucketReadyCondition, infrav1.S3BucketFailedReason, clusterv1.ConditionSeverityError, err.Error()) + return reconcile.Result{}, errors.Wrapf(err, "failed to reconcile S3 Bucket for AWSCluster %s/%s", awsCluster.Namespace, awsCluster.Name) + } + if awsCluster.Status.Network.APIServerELB.DNSName == "" { conditions.MarkFalse(awsCluster, infrav1.LoadBalancerReadyCondition, infrav1.WaitForDNSNameReason, clusterv1.ConditionSeverityInfo, "") clusterScope.Info("Waiting on API server ELB DNS name") From 258b768f536423be3e64f0273abb067f32cd5ab7 Mon Sep 17 00:00:00 2001 From: Suraj Deshmukh Date: Mon, 18 Oct 2021 14:28:09 +0530 Subject: [PATCH 05/12] api/v1beta1: add Ignition field to AWSMachineSpec This commit adds new Ignition block to AWSMachineSpec struct, which will allow different way of handling user data. If either bootstrap data has format defined as Ignition or user explicitly specify to use Ignition as a bootstrap format, machine controller will handle things accordingly. Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- api/v1alpha3/awsmachine_conversion.go | 3 ++ api/v1alpha3/zz_generated.conversion.go | 1 + api/v1alpha4/awsmachine_conversion.go | 27 ++++++++++++-- api/v1beta1/awsmachine_types.go | 17 +++++++++ api/v1beta1/awsmachine_webhook.go | 36 ++++++++++++++++++- api/v1beta1/awsmachinetemplate_webhook.go | 6 ++++ ...tructure.cluster.x-k8s.io_awsmachines.yaml | 12 +++++++ ....cluster.x-k8s.io_awsmachinetemplates.yaml | 12 +++++++ 8 files changed, 111 insertions(+), 3 deletions(-) diff --git a/api/v1alpha3/awsmachine_conversion.go b/api/v1alpha3/awsmachine_conversion.go index 6bb4010632..84bf113f31 100644 --- a/api/v1alpha3/awsmachine_conversion.go +++ b/api/v1alpha3/awsmachine_conversion.go @@ -40,6 +40,8 @@ func (r *AWSMachine) ConvertTo(dstRaw conversion.Hub) error { restoreSpec(&restored.Spec, &dst.Spec) + dst.Spec.Ignition = restored.Spec.Ignition + return nil } @@ -100,6 +102,7 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error { } dst.Spec.Template.ObjectMeta = restored.Spec.Template.ObjectMeta + dst.Spec.Template.Spec.Ignition = restored.Spec.Template.Spec.Ignition restoreSpec(&restored.Spec.Template.Spec, &dst.Spec.Template.Spec) diff --git a/api/v1alpha3/zz_generated.conversion.go b/api/v1alpha3/zz_generated.conversion.go index 1cc3372f03..149a9c37a8 100644 --- a/api/v1alpha3/zz_generated.conversion.go +++ b/api/v1alpha3/zz_generated.conversion.go @@ -1225,6 +1225,7 @@ func autoConvert_v1beta1_AWSMachineSpec_To_v1alpha3_AWSMachineSpec(in *v1beta1.A if err := Convert_v1beta1_CloudInit_To_v1alpha3_CloudInit(&in.CloudInit, &out.CloudInit, s); err != nil { return err } + // WARNING: in.Ignition requires manual conversion: does not exist in peer-type out.SpotMarketOptions = (*SpotMarketOptions)(unsafe.Pointer(in.SpotMarketOptions)) out.Tenancy = in.Tenancy return nil diff --git a/api/v1alpha4/awsmachine_conversion.go b/api/v1alpha4/awsmachine_conversion.go index ff4feadb4f..4416b55761 100644 --- a/api/v1alpha4/awsmachine_conversion.go +++ b/api/v1alpha4/awsmachine_conversion.go @@ -18,6 +18,7 @@ package v1alpha4 import ( apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" utilconversion "sigs.k8s.io/cluster-api/util/conversion" "sigs.k8s.io/controller-runtime/pkg/conversion" @@ -26,14 +27,31 @@ import ( // ConvertTo converts the v1alpha4 AWSMachine receiver to a v1beta1 AWSMachine. func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*infrav1.AWSMachine) - return Convert_v1alpha4_AWSMachine_To_v1beta1_AWSMachine(src, dst, nil) + if err := Convert_v1alpha4_AWSMachine_To_v1beta1_AWSMachine(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &v1beta1.AWSMachine{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.Ignition = restored.Spec.Ignition + + return nil } // ConvertFrom converts the v1beta1 AWSMachine to a v1alpha4 AWSMachine. func (dst *AWSMachine) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*infrav1.AWSMachine) - return Convert_v1beta1_AWSMachine_To_v1alpha4_AWSMachine(src, dst, nil) + if err := Convert_v1beta1_AWSMachine_To_v1alpha4_AWSMachine(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata. + return utilconversion.MarshalData(src, dst) } // ConvertTo converts the v1alpha4 AWSMachineList receiver to a v1beta1 AWSMachineList. @@ -64,6 +82,7 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error { } dst.Spec.Template.ObjectMeta = restored.Spec.Template.ObjectMeta + dst.Spec.Template.Spec.Ignition = restored.Spec.Template.Spec.Ignition return nil } @@ -100,3 +119,7 @@ func (dst *AWSMachineTemplateList) ConvertFrom(srcRaw conversion.Hub) error { func Convert_v1beta1_AWSMachineTemplateResource_To_v1alpha4_AWSMachineTemplateResource(in *infrav1.AWSMachineTemplateResource, out *AWSMachineTemplateResource, s apiconversion.Scope) error { return autoConvert_v1beta1_AWSMachineTemplateResource_To_v1alpha4_AWSMachineTemplateResource(in, out, s) } + +func Convert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(in *v1beta1.AWSMachineSpec, out *AWSMachineSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_AWSMachineSpec_To_v1alpha4_AWSMachineSpec(in, out, s) +} diff --git a/api/v1beta1/awsmachine_types.go b/api/v1beta1/awsmachine_types.go index 475cab8893..5c94ca132c 100644 --- a/api/v1beta1/awsmachine_types.go +++ b/api/v1beta1/awsmachine_types.go @@ -27,6 +27,9 @@ const ( // MachineFinalizer allows ReconcileAWSMachine to clean up AWS resources associated with AWSMachine before // removing it from the apiserver. MachineFinalizer = "awsmachine.infrastructure.cluster.x-k8s.io" + + // DefaultIgnitionVersion represents default Ignition version generated for machine userdata. + DefaultIgnitionVersion = "2.3" ) // SecretBackend defines variants for backend secret storage. @@ -142,6 +145,10 @@ type AWSMachineSpec struct { // +optional CloudInit CloudInit `json:"cloudInit,omitempty"` + // Ignition defined options related to the bootstrapping systems where Ignition is used. + // +optional + Ignition *Ignition `json:"ignition,omitempty"` + // SpotMarketOptions allows users to configure instances to be run using AWS Spot instances. // +optional SpotMarketOptions *SpotMarketOptions `json:"spotMarketOptions,omitempty"` @@ -179,6 +186,16 @@ type CloudInit struct { SecureSecretsBackend SecretBackend `json:"secureSecretsBackend,omitempty"` } +// Ignition defines options related to the bootstrapping systems where Ignition is used. +type Ignition struct { + // Version defines which version of Ignition will be used to generate bootstrap data. + // + // +optional + // +kubebuilder:default="2.3" + // +kubebuilder:validation:Enum="2.3" + Version string `json:"version,omitempty"` +} + // AWSMachineStatus defines the observed state of AWSMachine. type AWSMachineStatus struct { // Ready is true when the provider resource is ready. diff --git a/api/v1beta1/awsmachine_webhook.go b/api/v1beta1/awsmachine_webhook.go index 5aa64157f6..e08b81216e 100644 --- a/api/v1beta1/awsmachine_webhook.go +++ b/api/v1beta1/awsmachine_webhook.go @@ -50,6 +50,7 @@ func (r *AWSMachine) ValidateCreate() error { var allErrs field.ErrorList allErrs = append(allErrs, r.validateCloudInitSecret()...) + allErrs = append(allErrs, r.validateIgnitionAndCloudInit()...) allErrs = append(allErrs, r.validateRootVolume()...) allErrs = append(allErrs, r.validateNonRootVolumes()...) allErrs = append(allErrs, r.validateSSHKeyName()...) @@ -140,6 +141,31 @@ func (r *AWSMachine) validateCloudInitSecret() field.ErrorList { return allErrs } +func (r *AWSMachine) cloudInitConfigured() bool { + configured := false + + configured = configured || r.Spec.CloudInit.SecretPrefix != "" + configured = configured || r.Spec.CloudInit.SecretCount != 0 + configured = configured || r.Spec.CloudInit.SecureSecretsBackend != "" + configured = configured || r.Spec.CloudInit.InsecureSkipSecretsManager + + return configured +} + +func (r *AWSMachine) ignitionEnabled() bool { + return r.Spec.Ignition != nil +} + +func (r *AWSMachine) validateIgnitionAndCloudInit() field.ErrorList { + var allErrs field.ErrorList + + if r.ignitionEnabled() && r.cloudInitConfigured() { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "cloudInit"), "cannot be set if spec.ignition is set")) + } + + return allErrs +} + func (r *AWSMachine) validateRootVolume() field.ErrorList { var allErrs field.ErrorList @@ -200,9 +226,17 @@ func (r *AWSMachine) ValidateDelete() error { // Default implements webhook.Defaulter such that an empty CloudInit will be defined with a default // SecureSecretsBackend as SecretBackendSecretsManager iff InsecureSkipSecretsManager is unset. func (r *AWSMachine) Default() { - if !r.Spec.CloudInit.InsecureSkipSecretsManager && r.Spec.CloudInit.SecureSecretsBackend == "" { + if !r.Spec.CloudInit.InsecureSkipSecretsManager && r.Spec.CloudInit.SecureSecretsBackend == "" && !r.ignitionEnabled() { r.Spec.CloudInit.SecureSecretsBackend = SecretBackendSecretsManager } + + if r.ignitionEnabled() && r.Spec.Ignition.Version == "" { + if r.Spec.Ignition == nil { + r.Spec.Ignition = &Ignition{} + } + + r.Spec.Ignition.Version = DefaultIgnitionVersion + } } func (r *AWSMachine) validateAdditionalSecurityGroups() field.ErrorList { diff --git a/api/v1beta1/awsmachinetemplate_webhook.go b/api/v1beta1/awsmachinetemplate_webhook.go index 95af5d7e6d..3d38e023a8 100644 --- a/api/v1beta1/awsmachinetemplate_webhook.go +++ b/api/v1beta1/awsmachinetemplate_webhook.go @@ -113,6 +113,12 @@ func (r *AWSMachineTemplate) ValidateCreate() error { allErrs = append(allErrs, r.validateRootVolume()...) allErrs = append(allErrs, r.validateNonRootVolumes()...) + cloudInitConfigured := spec.CloudInit.SecureSecretsBackend != "" || spec.CloudInit.InsecureSkipSecretsManager + if cloudInitConfigured && spec.Ignition != nil { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "cloudInit"), + "cannot be set if spec.template.spec.ignition is set")) + } + return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) } diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml index 9a03295aaf..10927471c7 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml @@ -1085,6 +1085,18 @@ spec: description: IAMInstanceProfile is a name of an IAM instance profile to assign to the instance type: string + ignition: + description: Ignition defined options related to the bootstrapping + systems where Ignition is used. + properties: + version: + default: "2.3" + description: Version defines which version of Ignition will be + used to generate bootstrap data. + enum: + - "2.3" + type: string + type: object imageLookupBaseOS: description: ImageLookupBaseOS is the name of the base operating system to use for image lookup the AMI is not set. diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml index 1b5e1ae265..f4cfa3d152 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml @@ -891,6 +891,18 @@ spec: description: IAMInstanceProfile is a name of an IAM instance profile to assign to the instance type: string + ignition: + description: Ignition defined options related to the bootstrapping + systems where Ignition is used. + properties: + version: + default: "2.3" + description: Version defines which version of Ignition + will be used to generate bootstrap data. + enum: + - "2.3" + type: string + type: object imageLookupBaseOS: description: ImageLookupBaseOS is the name of the base operating system to use for image lookup the AMI is not set. From a37ebbe1d48b916900c927bd8468ad5a1cd5b3bf Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 16 Feb 2021 10:26:20 +0100 Subject: [PATCH 06/12] controllers: add Ignition support This commit finalizes addition of Ignition support as bootstrap data format. Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- controllers/awsmachine_controller.go | 158 ++++- controllers/awsmachine_controller_test.go | 8 +- .../awsmachine_controller_unit_test.go | 567 +++++++++++++----- go.mod | 4 + go.sum | 4 + pkg/cloud/scope/machine.go | 32 +- pkg/cloud/scope/machine_test.go | 119 +++- pkg/cloud/scope/machinepool.go | 18 +- pkg/cloud/services/ec2/instances.go | 5 +- pkg/cloud/services/ec2/instances_test.go | 152 ++++- pkg/cloud/services/interfaces.go | 2 +- .../mock_services/ec2_interface_mock.go | 8 +- 12 files changed, 872 insertions(+), 205 deletions(-) diff --git a/controllers/awsmachine_controller.go b/controllers/awsmachine_controller.go index 2b3fe7576b..58d49e454e 100644 --- a/controllers/awsmachine_controller.go +++ b/controllers/awsmachine_controller.go @@ -18,10 +18,12 @@ package controllers import ( "context" + "encoding/json" "fmt" "reflect" "github.com/aws/aws-sdk-go/aws" + ignTypes "github.com/flatcar-linux/ignition/config/v2_3/types" "github.com/go-logr/logr" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" @@ -46,6 +48,7 @@ import ( "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/ec2" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/elb" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/instancestate" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/s3" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/secretsmanager" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/ssm" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/userdata" @@ -70,6 +73,7 @@ type AWSMachineReconciler struct { elbServiceFactory func(scope.ELBScope) services.ELBInterface secretsManagerServiceFactory func(cloud.ClusterScoper) services.SecretInterface SSMServiceFactory func(cloud.ClusterScoper) services.SecretInterface + objectStoreServiceFactory func(cloud.ClusterScoper) services.ObjectStoreInterface Endpoints []scope.ServiceEndpoint WatchFilterValue string } @@ -119,6 +123,14 @@ func (r *AWSMachineReconciler) getELBService(elbScope scope.ELBScope) services.E return elb.NewService(elbScope) } +func (r *AWSMachineReconciler) getObjectStoreService(scope scope.S3Scope) services.ObjectStoreInterface { + if r.objectStoreServiceFactory != nil { + return r.objectStoreServiceFactory(scope) + } + + return s3.NewService(scope) +} + // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachines,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachines/status,verbs=get;update;patch // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines;machines/status,verbs=get;list;watch @@ -197,16 +209,16 @@ func (r *AWSMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request) switch infraScope := infraCluster.(type) { case *scope.ManagedControlPlaneScope: if !awsMachine.ObjectMeta.DeletionTimestamp.IsZero() { - return r.reconcileDelete(machineScope, infraScope, infraScope, nil) + return r.reconcileDelete(machineScope, infraScope, infraScope, nil, nil) } - return r.reconcileNormal(ctx, machineScope, infraScope, infraScope, nil) + return r.reconcileNormal(ctx, machineScope, infraScope, infraScope, nil, nil) case *scope.ClusterScope: if !awsMachine.ObjectMeta.DeletionTimestamp.IsZero() { - return r.reconcileDelete(machineScope, infraScope, infraScope, infraScope) + return r.reconcileDelete(machineScope, infraScope, infraScope, infraScope, infraScope) } - return r.reconcileNormal(ctx, machineScope, infraScope, infraScope, infraScope) + return r.reconcileNormal(ctx, machineScope, infraScope, infraScope, infraScope, infraScope) default: return ctrl.Result{}, errors.New("infraCluster has unknown type") } @@ -271,16 +283,14 @@ func (r *AWSMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma ) } -func (r *AWSMachineReconciler) reconcileDelete(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, ec2Scope scope.EC2Scope, elbScope scope.ELBScope) (ctrl.Result, error) { +func (r *AWSMachineReconciler) reconcileDelete(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, ec2Scope scope.EC2Scope, elbScope scope.ELBScope, objectStoreScope scope.S3Scope) (ctrl.Result, error) { machineScope.Info("Handling deleted AWSMachine") ec2Service := r.getEC2Service(ec2Scope) - if machineScope.UseSecretsManager() { - if err := r.deleteEncryptedBootstrapDataSecret(machineScope, clusterScope); err != nil { - machineScope.Error(err, "unable to delete machine") - return ctrl.Result{}, err - } + if err := r.deleteBootstrapData(machineScope, clusterScope, objectStoreScope); err != nil { + machineScope.Error(err, "unable to delete machine") + return ctrl.Result{}, err } instance, err := r.findInstance(machineScope, ec2Service) @@ -418,19 +428,17 @@ func (r *AWSMachineReconciler) findInstance(scope *scope.MachineScope, ec2svc se return instance, nil } -func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, ec2Scope scope.EC2Scope, elbScope scope.ELBScope) (ctrl.Result, error) { +func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, ec2Scope scope.EC2Scope, elbScope scope.ELBScope, objectStoreScope scope.S3Scope) (ctrl.Result, error) { machineScope.Info("Reconciling AWSMachine") // If the AWSMachine is in an error state, return early. if machineScope.HasFailed() { machineScope.Info("Error state detected, skipping reconciliation") - if machineScope.UseSecretsManager() { - // If we are in a failed state, delete the secret regardless of instance state - if err := r.deleteEncryptedBootstrapDataSecret(machineScope, clusterScope); err != nil { - machineScope.Error(err, "unable to reconcile machine") - return ctrl.Result{}, err - } + // If we are in a failed state, delete the secret regardless of instance state. + if err := r.deleteBootstrapData(machineScope, clusterScope, objectStoreScope); err != nil { + machineScope.Error(err, "unable to reconcile machine") + return ctrl.Result{}, err } return ctrl.Result{}, nil @@ -477,7 +485,14 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope * return ctrl.Result{}, patchErr } } - instance, err = r.createInstance(ec2svc, machineScope, clusterScope) + + var objectStoreSvc services.ObjectStoreInterface + + if objectStoreScope != nil { + objectStoreSvc = r.getObjectStoreService(objectStoreScope) + } + + instance, err = r.createInstance(ec2svc, machineScope, clusterScope, objectStoreSvc) if err != nil { machineScope.Error(err, "unable to create instance") conditions.MarkFalse(machineScope.AWSMachine, infrav1.InstanceReadyCondition, infrav1.InstanceProvisionFailedReason, clusterv1.ConditionSeverityError, err.Error()) @@ -533,7 +548,7 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope * } // reconcile the deletion of the bootstrap data secret now that we have updated instance state - if deleteSecretErr := r.deleteEncryptedBootstrapDataSecret(machineScope, clusterScope); deleteSecretErr != nil { + if deleteSecretErr := r.deleteBootstrapData(machineScope, clusterScope, objectStoreScope); deleteSecretErr != nil { r.Log.Error(deleteSecretErr, "unable to delete secrets") return ctrl.Result{}, deleteSecretErr } @@ -585,10 +600,6 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope * } func (r *AWSMachineReconciler) deleteEncryptedBootstrapDataSecret(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper) error { - if !machineScope.UseSecretsManager() { - return nil - } - secretSvc, secretBackendErr := r.getSecretService(machineScope, clusterScope) if secretBackendErr != nil { machineScope.Error(secretBackendErr, "unable to get secret service backend") @@ -621,15 +632,15 @@ func (r *AWSMachineReconciler) deleteEncryptedBootstrapDataSecret(machineScope * return nil } -func (r *AWSMachineReconciler) createInstance(ec2svc services.EC2Interface, machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper) (*infrav1.Instance, error) { +func (r *AWSMachineReconciler) createInstance(ec2svc services.EC2Interface, machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, objectStoreSvc services.ObjectStoreInterface) (*infrav1.Instance, error) { machineScope.Info("Creating EC2 instance") - userData, userDataErr := r.resolveUserData(machineScope, clusterScope) + userData, userDataFormat, userDataErr := r.resolveUserData(machineScope, clusterScope, objectStoreSvc) if userDataErr != nil { return nil, errors.Wrapf(userDataErr, "failed to resolve userdata") } - instance, err := ec2svc.CreateInstance(machineScope, userData) + instance, err := ec2svc.CreateInstance(machineScope, userData, userDataFormat) if err != nil { return nil, errors.Wrapf(err, "failed to create AWSMachine instance") } @@ -637,17 +648,25 @@ func (r *AWSMachineReconciler) createInstance(ec2svc services.EC2Interface, mach return instance, nil } -func (r *AWSMachineReconciler) resolveUserData(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper) ([]byte, error) { - userData, err := machineScope.GetRawBootstrapData() +func (r *AWSMachineReconciler) resolveUserData(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, objectStoreSvc services.ObjectStoreInterface) ([]byte, string, error) { + userData, userDataFormat, err := machineScope.GetRawBootstrapDataWithFormat() if err != nil { r.Recorder.Eventf(machineScope.AWSMachine, corev1.EventTypeWarning, "FailedGetBootstrapData", err.Error()) - return nil, err + return nil, "", err + } + + if machineScope.UseSecretsManager(userDataFormat) { + userData, err = r.cloudInitUserData(machineScope, clusterScope, userData) } - if !machineScope.UseSecretsManager() { - return userData, nil + if machineScope.UseIgnition(userDataFormat) { + userData, err = r.ignitionUserData(machineScope, objectStoreSvc, userData) } + return userData, userDataFormat, err +} + +func (r *AWSMachineReconciler) cloudInitUserData(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, userData []byte) ([]byte, error) { secretSvc, secretBackendErr := r.getSecretService(machineScope, clusterScope) if secretBackendErr != nil { machineScope.Error(secretBackendErr, "unable to reconcile machine") @@ -681,6 +700,83 @@ func (r *AWSMachineReconciler) resolveUserData(machineScope *scope.MachineScope, return encryptedCloudInit, nil } +func (r *AWSMachineReconciler) ignitionUserData(scope *scope.MachineScope, objectStoreSvc services.ObjectStoreInterface, userData []byte) ([]byte, error) { + if objectStoreSvc == nil { + return nil, errors.New("object store service not available") + } + + objectURL, err := objectStoreSvc.Create(scope, userData) + if err != nil { + return nil, errors.Wrap(err, "creating userdata object") + } + + ignData := &ignTypes.Config{ + Ignition: ignTypes.Ignition{ + Version: "2.3.0", + Config: ignTypes.IgnitionConfig{ + Append: []ignTypes.ConfigReference{ + { + Source: objectURL, + }, + }, + }, + }, + } + + ignitionUserData, err := json.Marshal(ignData) + if err != nil { + r.Recorder.Eventf(scope.AWSMachine, corev1.EventTypeWarning, "FailedGenerateIgnition", err.Error()) + return nil, errors.Wrap(err, "serializing generated data") + } + + return ignitionUserData, nil +} + +func (r *AWSMachineReconciler) deleteBootstrapData(machineScope *scope.MachineScope, clusterScope cloud.ClusterScoper, objectStoreScope scope.S3Scope) error { + if err := r.deleteEncryptedBootstrapDataSecret(machineScope, clusterScope); err != nil { + return err + } + + if objectStoreScope != nil { + // Bootstrap data will be removed from S3 if it is already populated. + if err := r.deleteIgnitionBootstrapDataFromS3(machineScope, r.getObjectStoreService(objectStoreScope)); err != nil { + return err + } + } + + return nil +} + +func (r *AWSMachineReconciler) deleteIgnitionBootstrapDataFromS3(machineScope *scope.MachineScope, objectStoreSvc services.ObjectStoreInterface) error { + // Do nothing if the AWSMachine is not in a failed state, and is operational from an EC2 perspective, but does not have a node reference + if !machineScope.HasFailed() && machineScope.InstanceIsOperational() && machineScope.Machine.Status.NodeRef == nil && !machineScope.AWSMachineIsDeleted() { + return nil + } + + // If bootstrap data has not been populated yet, we cannot determine it's format, so there is probably nothing to do. + if machineScope.Machine.Spec.Bootstrap.DataSecretName == nil { + return nil + } + + machineScope.Info("Deleting unneeded entry from AWS S3", "secretPrefix", machineScope.GetSecretPrefix()) + + _, userDataFormat, err := machineScope.GetRawBootstrapDataWithFormat() + if err != nil { + r.Recorder.Eventf(machineScope.AWSMachine, corev1.EventTypeWarning, "FailedGetBootstrapData", err.Error()) + return err + } + + if !machineScope.UseIgnition(userDataFormat) { + return nil + } + + if err := objectStoreSvc.Delete(machineScope); err != nil { + return errors.Wrap(err, "deleting bootstrap data object") + } + + return nil +} + func (r *AWSMachineReconciler) reconcileLBAttachment(machineScope *scope.MachineScope, elbScope scope.ELBScope, i *infrav1.Instance) error { if !machineScope.IsControlPlane() { return nil diff --git a/controllers/awsmachine_controller_test.go b/controllers/awsmachine_controller_test.go index 0965534256..5927dd28cb 100644 --- a/controllers/awsmachine_controller_test.go +++ b/controllers/awsmachine_controller_test.go @@ -151,7 +151,7 @@ func TestAWSMachineReconciler_IntegrationTests(t *testing.T) { return secretMock } - _, err = reconciler.reconcileNormal(ctx, ms, cs, cs, cs) + _, err = reconciler.reconcileNormal(ctx, ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.SecurityGroupsReadyCondition, corev1.ConditionTrue, "", ""}, {infrav1.InstanceReadyCondition, corev1.ConditionTrue, "", ""}, @@ -207,7 +207,7 @@ func TestAWSMachineReconciler_IntegrationTests(t *testing.T) { return elbSvc } - _, err = reconciler.reconcileDelete(ms, cs, cs, cs) + _, err = reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) expectConditions(g, ms.AWSMachine, []conditionAssertion{ {infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityInfo, clusterv1.DeletedReason}, @@ -300,7 +300,7 @@ func TestAWSMachineReconciler_IntegrationTests(t *testing.T) { return secretMock } - _, err = reconciler.reconcileNormal(ctx, ms, cs, cs, cs) + _, err = reconciler.reconcileNormal(ctx, ms, cs, cs, cs, cs) g.Expect(err).Should(HaveOccurred()) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionTrue, "", ""}}) g.Expect(ms.AWSMachine.Finalizers).Should(ContainElement(infrav1.MachineFinalizer)) @@ -359,7 +359,7 @@ func TestAWSMachineReconciler_IntegrationTests(t *testing.T) { return elbSvc } - _, err = reconciler.reconcileDelete(ms, cs, cs, cs) + _, err = reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).Should(HaveOccurred()) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityWarning, "DeletingFailed"}, {infrav1.ELBAttachedCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityInfo, clusterv1.DeletedReason}}) diff --git a/controllers/awsmachine_controller_unit_test.go b/controllers/awsmachine_controller_unit_test.go index 284073b9cd..3ebea82996 100644 --- a/controllers/awsmachine_controller_unit_test.go +++ b/controllers/awsmachine_controller_unit_test.go @@ -57,14 +57,15 @@ const providerID = "aws:////myMachine" func TestAWSMachineReconciler(t *testing.T) { var ( - reconciler AWSMachineReconciler - cs *scope.ClusterScope - ms *scope.MachineScope - mockCtrl *gomock.Controller - ec2Svc *mock_services.MockEC2Interface - elbSvc *mock_services.MockELBInterface - secretSvc *mock_services.MockSecretInterface - recorder *record.FakeRecorder + reconciler AWSMachineReconciler + cs *scope.ClusterScope + ms *scope.MachineScope + mockCtrl *gomock.Controller + ec2Svc *mock_services.MockEC2Interface + elbSvc *mock_services.MockELBInterface + secretSvc *mock_services.MockSecretInterface + objectStoreSvc *mock_services.MockObjectStoreInterface + recorder *record.FakeRecorder ) setup := func(t *testing.T, g *WithT, awsMachine *infrav1.AWSMachine) { @@ -91,7 +92,17 @@ func TestAWSMachineReconciler(t *testing.T) { }, } - client := fake.NewClientBuilder().WithObjects(awsMachine, secret).Build() + secretIgnition := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bootstrap-data-ignition", + }, + Data: map[string][]byte{ + "value": []byte("ignitionJSON"), + "format": []byte("ignition"), + }, + } + + client := fake.NewClientBuilder().WithObjects(awsMachine, secret, secretIgnition).Build() ms, err = scope.NewMachineScope( scope.MachineScopeParams{ Client: client, @@ -153,6 +164,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc = mock_services.NewMockEC2Interface(mockCtrl) secretSvc = mock_services.NewMockSecretInterface(mockCtrl) elbSvc = mock_services.NewMockELBInterface(mockCtrl) + objectStoreSvc = mock_services.NewMockObjectStoreInterface(mockCtrl) // If your test hangs for 9 minutes, increase the value here to the number of events during a reconciliation loop recorder = record.NewFakeRecorder(2) @@ -164,6 +176,9 @@ func TestAWSMachineReconciler(t *testing.T) { secretsManagerServiceFactory: func(cloud.ClusterScoper) services.SecretInterface { return secretSvc }, + objectStoreServiceFactory: func(cloud.ClusterScoper) services.ObjectStoreInterface { + return objectStoreSvc + }, Recorder: recorder, Log: klogr.New(), } @@ -195,7 +210,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(buf).To(ContainSubstring("Error state detected, skipping reconciliation")) }) @@ -210,7 +225,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(buf.String()).To(ContainSubstring("Cluster infrastructure is not ready yet")) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityInfo, infrav1.WaitingForClusterInfrastructureReason}}) @@ -227,7 +242,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(buf.String()).To(ContainSubstring("Bootstrap data secret reference is not yet available")) @@ -240,7 +255,7 @@ func TestAWSMachineReconciler(t *testing.T) { setup(t, g, awsMachine) defer teardown(t, g) runningInstance(t, g) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(errors.Cause(err)).To(MatchError(expectedErr)) }) @@ -250,7 +265,7 @@ func TestAWSMachineReconciler(t *testing.T) { setup(t, g, awsMachine) defer teardown(t, g) runningInstance(t, g) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(len(ms.AWSMachine.Finalizers)).To(Equal(0)) }) @@ -276,7 +291,7 @@ func TestAWSMachineReconciler(t *testing.T) { expectedErr := errors.New("no connection available ") ec2Svc.EXPECT().InstanceIfExists(PointsTo("myMachine")).Return(nil, expectedErr) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(errors.Cause(err)).To(MatchError(expectedErr)) }) @@ -290,10 +305,10 @@ func TestAWSMachineReconciler(t *testing.T) { expectedErr := errors.New("Invalid instance") ec2Svc.EXPECT().InstanceIfExists(gomock.Any()).Return(nil, nil) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil).Times(1) - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(nil, expectedErr) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, expectedErr) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) g.Expect(errors.Cause(err)).To(MatchError(expectedErr)) }) @@ -309,7 +324,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.AWSMachine.Spec.ProviderID = &id expectedErr := "providerID must be of the form :////" - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err.Error()).To(ContainSubstring(expectedErr)) }) @@ -326,7 +341,7 @@ func TestAWSMachineReconciler(t *testing.T) { instance.State = infrav1.InstanceStatePending ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, nil) - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil) } t.Run("instance security group errors", func(t *testing.T) { @@ -349,7 +364,7 @@ func TestAWSMachineReconciler(t *testing.T) { getInstanceSecurityGroups(t, g) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Spec.ProviderID).To(PointTo(Equal(providerID))) }) @@ -363,7 +378,7 @@ func TestAWSMachineReconciler(t *testing.T) { secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) instance.State = infrav1.InstanceStatePending - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.InstanceState).To(PointTo(Equal(infrav1.InstanceStatePending))) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(false)) g.Expect(buf.String()).To(ContainSubstring(("EC2 instance state changed"))) @@ -382,7 +397,7 @@ func TestAWSMachineReconciler(t *testing.T) { secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) instance.State = infrav1.InstanceStateRunning - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.InstanceState).To(PointTo(Equal(infrav1.InstanceStateRunning))) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(true)) g.Expect(buf.String()).To(ContainSubstring(("EC2 instance state changed"))) @@ -404,7 +419,7 @@ func TestAWSMachineReconciler(t *testing.T) { secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil).Times(1) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(false)) g.Expect(buf.String()).To(ContainSubstring(("EC2 instance state is undefined"))) g.Eventually(recorder.Events).Should(Receive(ContainSubstring("InstanceUnhandledState"))) @@ -436,7 +451,7 @@ func TestAWSMachineReconciler(t *testing.T) { } ec2Svc.EXPECT().UpdateInstanceSecurityGroups(instance.ID, []string{"sg-2345"}) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) expectConditions(g, ms.AWSMachine, []conditionAssertion{{conditionType: infrav1.SecurityGroupsReadyCondition, status: corev1.ConditionTrue}}) }) @@ -449,7 +464,7 @@ func TestAWSMachineReconciler(t *testing.T) { getCoreSecurityGroups(t, g) ec2Svc.EXPECT().UpdateInstanceSecurityGroups(gomock.Any(), gomock.Any()).Times(0) - if _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs); err != nil { + if _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs); err != nil { _ = fmt.Errorf("reconcileNormal reutrned an error during test") } }) @@ -482,7 +497,7 @@ func TestAWSMachineReconciler(t *testing.T) { map[string]string{}, ).Return(nil) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) }) t.Run("should tag instances volume tags", func(t *testing.T) { @@ -504,7 +519,7 @@ func TestAWSMachineReconciler(t *testing.T) { map[string]string{}, ).Return(nil).Times(3) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) }) }) @@ -532,7 +547,7 @@ func TestAWSMachineReconciler(t *testing.T) { getCoreSecurityGroups(t, g) instance.State = infrav1.InstanceStateStopping - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.InstanceState).To(PointTo(Equal(infrav1.InstanceStateStopping))) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(false)) g.Expect(buf.String()).To(ContainSubstring(("EC2 instance state changed"))) @@ -548,7 +563,7 @@ func TestAWSMachineReconciler(t *testing.T) { getCoreSecurityGroups(t, g) instance.State = infrav1.InstanceStateStopped - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.InstanceState).To(PointTo(Equal(infrav1.InstanceStateStopped))) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(false)) g.Expect(buf.String()).To(ContainSubstring(("EC2 instance state changed"))) @@ -564,7 +579,7 @@ func TestAWSMachineReconciler(t *testing.T) { getCoreSecurityGroups(t, g) instance.State = infrav1.InstanceStateRunning - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.InstanceState).To(PointTo(Equal(infrav1.InstanceStateRunning))) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(true)) g.Expect(buf.String()).To(ContainSubstring(("EC2 instance state changed"))) @@ -590,7 +605,7 @@ func TestAWSMachineReconciler(t *testing.T) { instanceCreate(t, g) deleteMachine(t, g) instance.State = infrav1.InstanceStateShuttingDown - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(false)) g.Expect(buf.String()).To(ContainSubstring(("Unexpected EC2 instance termination"))) g.Eventually(recorder.Events).Should(Receive(ContainSubstring("UnexpectedTermination"))) @@ -605,7 +620,7 @@ func TestAWSMachineReconciler(t *testing.T) { deleteMachine(t, g) instance.State = infrav1.InstanceStateTerminated - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(ms.AWSMachine.Status.Ready).To(Equal(false)) g.Expect(buf.String()).To(ContainSubstring(("Unexpected EC2 instance termination"))) g.Eventually(recorder.Events).Should(Receive(ContainSubstring("UnexpectedTermination"))) @@ -632,7 +647,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityWarning, infrav1.InstanceNotReadyReason}}) @@ -657,7 +672,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.ELBAttachedCondition, corev1.ConditionTrue, "", ""}}) @@ -677,7 +692,7 @@ func TestAWSMachineReconciler(t *testing.T) { return elbSvc } - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityWarning, infrav1.InstanceNotReadyReason}}) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) @@ -697,7 +712,7 @@ func TestAWSMachineReconciler(t *testing.T) { secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil).Times(1) secretSvc.EXPECT().Delete(gomock.Any()).Return(errors.New("failed to delete entries from AWS Secret")).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityWarning, infrav1.InstanceNotReadyReason}}) g.Expect(err).To(MatchError(ContainSubstring("failed to delete entries from AWS Secret"))) }) @@ -725,7 +740,7 @@ func TestAWSMachineReconciler(t *testing.T) { secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil).Times(1) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New(expectedError)).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err.Error()).To(ContainSubstring(expectedError)) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) @@ -744,13 +759,13 @@ func TestAWSMachineReconciler(t *testing.T) { return elbSvc } - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil) ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, nil) elbSvc.EXPECT().IsInstanceRegisteredWithAPIServerELB(gomock.Any()).Return(false, errors.New("error describing ELB")) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(err.Error()).To(ContainSubstring("error describing ELB")) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) @@ -770,14 +785,14 @@ func TestAWSMachineReconciler(t *testing.T) { return elbSvc } - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil) ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, nil) elbSvc.EXPECT().IsInstanceRegisteredWithAPIServerELB(gomock.Any()).Return(false, nil) elbSvc.EXPECT().RegisterInstanceWithAPIServerELB(gomock.Any()).Return(errors.New("failed to attach ELB")) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil).Times(1) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(err.Error()).To(ContainSubstring("failed to attach ELB")) g.Eventually(recorder.Events).Should(Receive(ContainSubstring("FailedAttachControlPlaneELB"))) @@ -793,7 +808,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.AWSMachine.Status.FailureReason = (*capierrors.MachineStatusError)(aws.String("error in AWSMachine")) ms.SetSecretCount(0) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(MatchError(ContainSubstring("secretPrefix present, but secretCount is not set"))) }) t.Run("Should fail in ensureTag", func(t *testing.T) { @@ -801,7 +816,7 @@ func TestAWSMachineReconciler(t *testing.T) { ensureTag := func(t *testing.T, g *WithT) { t.Helper() ec2Svc.EXPECT().InstanceIfExists(gomock.Any()).Return(nil, nil) - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) } @@ -817,7 +832,7 @@ func TestAWSMachineReconciler(t *testing.T) { ensureTag(t, g) ms.AWSMachine.Annotations = map[string]string{TagsLastAppliedAnnotation: "12345"} - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err.Error()).To(ContainSubstring("json: cannot unmarshal number into Go value of type map[string]interface {}")) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityWarning, infrav1.InstanceNotReadyReason}}) @@ -836,7 +851,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().UpdateResourceTags(gomock.Any(), gomock.Any(), map[string]string{"tag": "tag1"}).Return(errors.New("failed to update resource tag")) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.InstanceReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityWarning, infrav1.InstanceNotReadyReason}}) @@ -847,7 +862,7 @@ func TestAWSMachineReconciler(t *testing.T) { ensureSecurityGroups := func(t *testing.T, g *WithT) { t.Helper() ec2Svc.EXPECT().InstanceIfExists(gomock.Any()).Return(nil, nil) - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("test", int32(1), nil) secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil) ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil) @@ -867,7 +882,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().UpdateResourceTags(gomock.Any(), map[string]string{"tag": "\"old_tag\"\"\""}, gomock.Any()).Return(nil).AnyTimes() - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.SecurityGroupsReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityError, infrav1.SecurityGroupsFailedReason}}) @@ -885,7 +900,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, errors.New("failed to get core security groups")).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.SecurityGroupsReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityError, infrav1.SecurityGroupsFailedReason}}) @@ -917,7 +932,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil) ec2Svc.EXPECT().GetFilteredSecurityGroupID(gomock.Any()).Return("sg-1", errors.New("failed to get filtered SGs")) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.SecurityGroupsReadyCondition, corev1.ConditionTrue, "", ""}}) @@ -950,7 +965,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil) ec2Svc.EXPECT().UpdateInstanceSecurityGroups(gomock.Any(), gomock.Any()).Return(errors.New("failed to update security groups")) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(infrav1.MachineFinalizer)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.SecurityGroupsReadyCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityError, infrav1.SecurityGroupsFailedReason}}) @@ -977,7 +992,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, nil).AnyTimes() secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return(secretPrefix, int32(1), nil).Times(1) - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil).AnyTimes() + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil).AnyTimes() secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) @@ -985,7 +1000,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.AWSMachine.ObjectMeta.Labels = map[string]string{ clusterv1.MachineControlPlaneLabelName: "", } - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) }) }) @@ -1024,7 +1039,7 @@ func TestAWSMachineReconciler(t *testing.T) { Return(map[string][]string{"eid": {}}, nil).Times(1) secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) }) t.Run("should delete the secret if the instance is terminated", func(t *testing.T) { @@ -1036,7 +1051,7 @@ func TestAWSMachineReconciler(t *testing.T) { instance.State = infrav1.InstanceStateTerminated secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) }) t.Run("should delete the secret if the AWSMachine is deleted", func(t *testing.T) { @@ -1049,7 +1064,7 @@ func TestAWSMachineReconciler(t *testing.T) { instance.State = infrav1.InstanceStateRunning secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() - _, _ = reconciler.reconcileDelete(ms, cs, cs, cs) + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) }) t.Run("should delete the secret if the AWSMachine is in a failure condition", func(t *testing.T) { @@ -1062,7 +1077,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.AWSMachine.Status.FailureReason = capierrors.MachineStatusErrorPtr(capierrors.UpdateMachineError) secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() - _, _ = reconciler.reconcileDelete(ms, cs, cs, cs) + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) }) }) @@ -1095,7 +1110,7 @@ func TestAWSMachineReconciler(t *testing.T) { Return(map[string][]string{"eid": {}}, nil).Times(1) ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).MaxTimes(0) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) }) t.Run("should delete the secret if the instance is terminated", func(t *testing.T) { @@ -1107,7 +1122,7 @@ func TestAWSMachineReconciler(t *testing.T) { instance.State = infrav1.InstanceStateTerminated secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) - _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) }) t.Run("should delete the secret if the AWSMachine is deleted", func(t *testing.T) { @@ -1120,7 +1135,7 @@ func TestAWSMachineReconciler(t *testing.T) { instance.State = infrav1.InstanceStateRunning secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() - _, _ = reconciler.reconcileDelete(ms, cs, cs, cs) + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) }) t.Run("should delete the secret if the AWSMachine is in a failure condition", func(t *testing.T) { @@ -1133,7 +1148,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.AWSMachine.Status.FailureReason = capierrors.MachineStatusErrorPtr(capierrors.UpdateMachineError) secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() - _, _ = reconciler.reconcileDelete(ms, cs, cs, cs) + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) }) }) @@ -1154,7 +1169,7 @@ func TestAWSMachineReconciler(t *testing.T) { getInstances(t, g) secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return(secretPrefix, int32(0), errors.New("connection error")).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(err.Error()).To(ContainSubstring("connection error")) g.Expect(ms.GetSecretPrefix()).To(Equal("prefix")) @@ -1172,12 +1187,12 @@ func TestAWSMachineReconciler(t *testing.T) { } instance.State = infrav1.InstanceStatePending secretSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return(secretPrefix, int32(1), nil).Times(1) - ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any()).Return(instance, nil).AnyTimes() + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil).AnyTimes() secretSvc.EXPECT().UserData(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) - _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.GetSecretPrefix()).To(Equal(secretPrefix)) @@ -1186,6 +1201,242 @@ func TestAWSMachineReconciler(t *testing.T) { }) }) + t.Run("Object storage lifecycle", func(t *testing.T) { + t.Run("creating EC2 instances", func(t *testing.T) { + var instance *infrav1.Instance + + getInstances := func(t *testing.T, g *WithT) { + t.Helper() + + ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, nil).AnyTimes() + } + + useIgnition := func(t *testing.T, g *WithT) { + t.Helper() + + ms.Machine.Spec.Bootstrap.DataSecretName = pointer.StringPtr("bootstrap-data-ignition") + ms.AWSMachine.Spec.CloudInit.SecretCount = 0 + ms.AWSMachine.Spec.CloudInit.SecretPrefix = "" + } + + t.Run("should leverage AWS S3", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + getInstances(t, g) + useIgnition(t, g) + + instance = &infrav1.Instance{ + ID: "myMachine", + State: infrav1.InstanceStatePending, + } + fakeS3URL := "s3://foo" + + objectStoreSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return(fakeS3URL, nil).Times(1) + ec2Svc.EXPECT().CreateInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(instance, nil).AnyTimes() + ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) + ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) + + ms.AWSMachine.ObjectMeta.Labels = map[string]string{ + clusterv1.MachineControlPlaneLabelName: "", + } + + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) + g.Expect(err).To(BeNil()) + }) + }) + + t.Run("there's a node ref and a secret ARN", func(t *testing.T) { + var instance *infrav1.Instance + setNodeRef := func(t *testing.T, g *WithT) { + t.Helper() + + instance = &infrav1.Instance{ + ID: "myMachine", + } + + ms.Machine.Status.NodeRef = &corev1.ObjectReference{ + Kind: "Node", + Name: "myMachine", + APIVersion: "v1", + } + + ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(instance, nil).AnyTimes() + } + useIgnition := func(t *testing.T, g *WithT) { + t.Helper() + + ms.Machine.Spec.Bootstrap.DataSecretName = pointer.StringPtr("bootstrap-data-ignition") + ms.AWSMachine.Spec.CloudInit.SecretCount = 0 + ms.AWSMachine.Spec.CloudInit.SecretPrefix = "" + } + + t.Run("should delete the object if the instance is running", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + setNodeRef(t, g) + useIgnition(t, g) + + instance.State = infrav1.InstanceStateRunning + ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) + + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) + }) + + t.Run("should delete the object if the instance is terminated", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + setNodeRef(t, g) + useIgnition(t, g) + + instance.State = infrav1.InstanceStateTerminated + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) + }) + + t.Run("should delete the object if the instance is deleted", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + setNodeRef(t, g) + useIgnition(t, g) + + instance.State = infrav1.InstanceStateRunning + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() + + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) + }) + + t.Run("should delete the object if the AWSMachine is in a failure condition", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + setNodeRef(t, g) + useIgnition(t, g) + + // TODO: This seems to have no effect on the test result. + ms.AWSMachine.Status.FailureReason = capierrors.MachineStatusErrorPtr(capierrors.UpdateMachineError) + + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() + + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) + }) + }) + + t.Run("there's only a secret ARN and no node ref", func(t *testing.T) { + var instance *infrav1.Instance + + getInstances := func(t *testing.T, g *WithT) { + t.Helper() + + instance = &infrav1.Instance{ + ID: "myMachine", + } + ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(instance, nil).AnyTimes() + } + + useIgnition := func(t *testing.T, g *WithT) { + t.Helper() + + ms.Machine.Spec.Bootstrap.DataSecretName = pointer.StringPtr("bootstrap-data-ignition") + ms.AWSMachine.Spec.CloudInit.SecretCount = 0 + ms.AWSMachine.Spec.CloudInit.SecretPrefix = "" + } + + t.Run("should not delete the object if the instance is running", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + getInstances(t, g) + + instance.State = infrav1.InstanceStateRunning + ec2Svc.EXPECT().GetInstanceSecurityGroups(gomock.Any()).Return(map[string][]string{"eid": {}}, nil).Times(1) + ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{}, nil).Times(1) + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).MaxTimes(0) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) + }) + + t.Run("should delete the object if the instance is terminated", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + getInstances(t, g) + useIgnition(t, g) + + instance.State = infrav1.InstanceStateTerminated + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + _, _ = reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) + }) + + t.Run("should delete the object if the AWSMachine is deleted", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + getInstances(t, g) + useIgnition(t, g) + + instance.State = infrav1.InstanceStateRunning + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) + }) + + t.Run("should delete the object if the AWSMachine is in a failure condition", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + getInstances(t, g) + useIgnition(t, g) + + // TODO: This seems to have no effect on the test result. + ms.AWSMachine.Status.FailureReason = capierrors.MachineStatusErrorPtr(capierrors.UpdateMachineError) + objectStoreSvc.EXPECT().Delete(gomock.Any()).Return(nil).Times(1) + ec2Svc.EXPECT().TerminateInstanceAndWait(gomock.Any()).Return(nil).AnyTimes() + _, _ = reconciler.reconcileDelete(ms, cs, cs, cs, cs) + }) + }) + + t.Run("there is an intermittent connection issue and no object could be created", func(t *testing.T) { + useIgnition := func(t *testing.T, g *WithT) { + t.Helper() + + ms.Machine.Spec.Bootstrap.DataSecretName = pointer.StringPtr("bootstrap-data-ignition") + ms.AWSMachine.Spec.CloudInit.SecretCount = 0 + ms.AWSMachine.Spec.CloudInit.SecretPrefix = "" + } + + t.Run("should error if object could not be created", func(t *testing.T) { + g := NewWithT(t) + awsMachine := getAWSMachine() + setup(t, g, awsMachine) + defer teardown(t, g) + useIgnition(t, g) + + ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, nil).AnyTimes() + objectStoreSvc.EXPECT().Create(gomock.Any(), gomock.Any()).Return("", errors.New("connection error")).Times(1) + _, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs, cs, cs) + g.Expect(err).ToNot(BeNil()) + g.Expect(err.Error()).To(ContainSubstring("connection error")) + }) + }) + }) + t.Run("Deleting an AWSMachine", func(t *testing.T) { finalizer := func(t *testing.T, g *WithT) { t.Helper() @@ -1206,7 +1457,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetRunningInstanceByTags(gomock.Any()).Return(nil, expectedErr).AnyTimes() secretSvc.EXPECT().Delete(gomock.Any()).Return(nil).AnyTimes() - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(errors.Cause(err)).To(MatchError(expectedErr)) }) t.Run("should log and remove finalizer when no machine exists", func(t *testing.T) { @@ -1222,7 +1473,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(buf.String()).To(ContainSubstring("Unable to locate EC2 instance by ID or tags")) g.Expect(ms.AWSMachine.Finalizers).To(ConsistOf(metav1.FinalizerDeleteDependents)) @@ -1243,7 +1494,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(buf.String()).To(ContainSubstring("EC2 instance is shutting down or already terminated")) g.Expect(ms.AWSMachine.Finalizers).To(ConsistOf(metav1.FinalizerDeleteDependents)) @@ -1263,7 +1514,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(buf.String()).To(ContainSubstring("EC2 instance is shutting down or already terminated")) g.Expect(ms.AWSMachine.Finalizers).To(ConsistOf(metav1.FinalizerDeleteDependents)) @@ -1289,7 +1540,7 @@ func TestAWSMachineReconciler(t *testing.T) { buf := new(bytes.Buffer) klog.SetOutput(buf) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(errors.Cause(err)).To(MatchError(expected)) g.Expect(buf.String()).To(ContainSubstring("Terminating EC2 instance")) g.Eventually(recorder.Events).Should(Receive(ContainSubstring("FailedTerminate"))) @@ -1317,7 +1568,7 @@ func TestAWSMachineReconciler(t *testing.T) { expected := errors.New("can't reach AWS to list security groups") ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return(nil, expected) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(errors.Cause(err)).To(MatchError(expected)) }) @@ -1338,7 +1589,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().GetCoreSecurityGroups(gomock.Any()).Return([]string{"sg0", "sg1"}, nil) ec2Svc.EXPECT().DetachSecurityGroupsFromNetworkInterface(gomock.Any(), gomock.Any()).Return(expected) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(errors.Cause(err)).To(MatchError(expected)) }) @@ -1360,7 +1611,7 @@ func TestAWSMachineReconciler(t *testing.T) { ec2Svc.EXPECT().DetachSecurityGroupsFromNetworkInterface(groups, "eth0").Return(nil) ec2Svc.EXPECT().DetachSecurityGroupsFromNetworkInterface(groups, "eth1").Return(nil) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) }) @@ -1373,7 +1624,7 @@ func TestAWSMachineReconciler(t *testing.T) { getRunningInstance(t, g) terminateInstance(t, g) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ConsistOf(metav1.FinalizerDeleteDependents)) }) @@ -1395,7 +1646,7 @@ func TestAWSMachineReconciler(t *testing.T) { }, nil) elbSvc.EXPECT().IsInstanceRegisteredWithAPIServerELB(gomock.Any()).Return(false, errors.New("error describing ELB")) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(err.Error()).To(ContainSubstring("error describing ELB")) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) @@ -1420,7 +1671,7 @@ func TestAWSMachineReconciler(t *testing.T) { }, nil) elbSvc.EXPECT().IsInstanceRegisteredWithAPIServerELB(gomock.Any()).Return(false, nil) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.ELBAttachedCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityInfo, clusterv1.DeletedReason}}) @@ -1446,7 +1697,7 @@ func TestAWSMachineReconciler(t *testing.T) { elbSvc.EXPECT().IsInstanceRegisteredWithAPIServerELB(gomock.Any()).Return(true, nil) elbSvc.EXPECT().DeregisterInstanceFromAPIServerELB(gomock.Any()).Return(nil) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(BeNil()) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) expectConditions(g, ms.AWSMachine, []conditionAssertion{{infrav1.ELBAttachedCondition, corev1.ConditionFalse, clusterv1.ConditionSeverityInfo, clusterv1.DeletedReason}}) @@ -1469,7 +1720,7 @@ func TestAWSMachineReconciler(t *testing.T) { elbSvc.EXPECT().IsInstanceRegisteredWithAPIServerELB(gomock.Any()).Return(true, nil) elbSvc.EXPECT().DeregisterInstanceFromAPIServerELB(gomock.Any()).Return(errors.New("Duplicate access point name for load balancer")) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).ToNot(BeNil()) g.Expect(err.Error()).To(ContainSubstring("Duplicate access point name for load balancer")) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) @@ -1484,7 +1735,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.SetSecretPrefix("test") ms.SetSecretCount(0) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(MatchError(ContainSubstring("secretPrefix present, but secretCount is not set"))) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) }) @@ -1496,7 +1747,7 @@ func TestAWSMachineReconciler(t *testing.T) { finalizer(t, g) ms.AWSMachine.Spec.CloudInit.SecureSecretsBackend = "InvalidSecretBackend" - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(MatchError(ContainSubstring("invalid secret backend"))) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) }) @@ -1510,7 +1761,7 @@ func TestAWSMachineReconciler(t *testing.T) { ms.SetSecretCount(1) secretSvc.EXPECT().Delete(gomock.Any()).Return(errors.New("Hierarchy Type Mismatch Exception")) - _, err := reconciler.reconcileDelete(ms, cs, cs, cs) + _, err := reconciler.reconcileDelete(ms, cs, cs, cs, cs) g.Expect(err).To(MatchError(ContainSubstring("Hierarchy Type Mismatch Exception"))) g.Expect(ms.AWSMachine.Finalizers).To(ContainElement(metav1.FinalizerDeleteDependents)) }) @@ -1541,7 +1792,8 @@ func TestAWSMachineReconciler_AWSClusterToAWSMachines(t *testing.T) { Kind: "AWSMachine", Name: "aws-machine-6", APIVersion: infrav1.GroupVersion.String(), - }}, + }, + }, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -1579,7 +1831,8 @@ func TestAWSMachineReconciler_AWSClusterToAWSMachines(t *testing.T) { Kind: "AWSMachine", Name: "aws-machine-1", APIVersion: infrav1.GroupVersion.String(), - }}, + }, + }, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -1609,7 +1862,8 @@ func TestAWSMachineReconciler_AWSClusterToAWSMachines(t *testing.T) { Kind: "AWSMachine", Name: "aws-machine-2", APIVersion: infrav1.GroupVersion.String(), - }}, + }, + }, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -1636,7 +1890,8 @@ func TestAWSMachineReconciler_AWSClusterToAWSMachines(t *testing.T) { Kind: "AWSMachine", Name: "aws-machine-3", APIVersion: infrav1.GroupVersion.String(), - }}, + }, + }, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -1671,7 +1926,8 @@ func TestAWSMachineReconciler_AWSClusterToAWSMachines(t *testing.T) { Kind: "Machine", Name: "aws-machine-4", APIVersion: infrav1.GroupVersion.String(), - }}, + }, + }, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -1701,7 +1957,8 @@ func TestAWSMachineReconciler_AWSClusterToAWSMachines(t *testing.T) { InfrastructureRef: corev1.ObjectReference{ Kind: "AWSMachine", APIVersion: infrav1.GroupVersion.String(), - }}, + }, + }, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -1840,29 +2097,35 @@ func TestAWSMachineReconciler_Reconcile(t *testing.T) { }, { name: "Should fail Reconcile with GetOwnerMachine failure", - awsMachine: &infrav1.AWSMachine{ObjectMeta: metav1.ObjectMeta{Name: "aws-test-2", - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: clusterv1.GroupVersion.String(), - Kind: "Machine", - Name: "capi-test-machine", - UID: "1", - }}}, + awsMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-test-2", + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: clusterv1.GroupVersion.String(), + Kind: "Machine", + Name: "capi-test-machine", + UID: "1", + }, + }, + }, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, }, expectError: true, }, { name: "Should not Reconcile if machine does not contain cluster label", - awsMachine: &infrav1.AWSMachine{ObjectMeta: metav1.ObjectMeta{ - Name: "aws-test-3", Annotations: map[string]string{clusterv1.PausedAnnotation: ""}, OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: clusterv1.GroupVersion.String(), - Kind: "Machine", - Name: "capi-test-machine", - UID: "1", + awsMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-test-3", Annotations: map[string]string{clusterv1.PausedAnnotation: ""}, OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: clusterv1.GroupVersion.String(), + Kind: "Machine", + Name: "capi-test-machine", + UID: "1", + }, }, - }}, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, + }, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, }, ownerMachine: &clusterv1.Machine{ObjectMeta: metav1.ObjectMeta{Name: "capi-test-machine"}}, ownerCluster: &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}}, @@ -1870,91 +2133,109 @@ func TestAWSMachineReconciler_Reconcile(t *testing.T) { }, { name: "Should not Reconcile if cluster is paused", - awsMachine: &infrav1.AWSMachine{ObjectMeta: metav1.ObjectMeta{ - Name: "aws-test-4", Annotations: map[string]string{clusterv1.PausedAnnotation: ""}, OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: clusterv1.GroupVersion.String(), - Kind: "Machine", - Name: "capi-test-machine", - UID: "1", + awsMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-test-4", Annotations: map[string]string{clusterv1.PausedAnnotation: ""}, OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: clusterv1.GroupVersion.String(), + Kind: "Machine", + Name: "capi-test-machine", + UID: "1", + }, }, - }}, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, + }, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, }, ownerMachine: &clusterv1.Machine{ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ clusterv1.ClusterLabelName: "capi-test-1", }, - Name: "capi-test-machine", Namespace: "default"}}, + Name: "capi-test-machine", Namespace: "default", + }}, ownerCluster: &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}}, expectError: false, }, { name: "Should not Reconcile if AWSManagedControlPlane is not ready", - awsMachine: &infrav1.AWSMachine{ObjectMeta: metav1.ObjectMeta{ - Name: "aws-test-5", OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: clusterv1.GroupVersion.String(), - Kind: "Machine", - Name: "capi-test-machine", - UID: "1", + awsMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-test-5", OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: clusterv1.GroupVersion.String(), + Kind: "Machine", + Name: "capi-test-machine", + UID: "1", + }, }, - }}, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, + }, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, }, ownerMachine: &clusterv1.Machine{ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ clusterv1.ClusterLabelName: "capi-test-1", }, - Name: "capi-test-machine", Namespace: "default"}}, - ownerCluster: &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}, + Name: "capi-test-machine", Namespace: "default", + }}, + ownerCluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}, Spec: clusterv1.ClusterSpec{ ControlPlaneRef: &corev1.ObjectReference{Kind: AWSManagedControlPlaneRefKind}, - }}, + }, + }, expectError: false, }, { name: "Should not Reconcile if AWSCluster is not ready", - awsMachine: &infrav1.AWSMachine{ObjectMeta: metav1.ObjectMeta{ - Name: "aws-test-5", OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: clusterv1.GroupVersion.String(), - Kind: "Machine", - Name: "capi-test-machine", - UID: "1", + awsMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-test-5", OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: clusterv1.GroupVersion.String(), + Kind: "Machine", + Name: "capi-test-machine", + UID: "1", + }, }, - }}, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, + }, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, }, ownerMachine: &clusterv1.Machine{ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ clusterv1.ClusterLabelName: "capi-test-1", }, - Name: "capi-test-machine", Namespace: "default"}}, - ownerCluster: &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}, + Name: "capi-test-machine", Namespace: "default", + }}, + ownerCluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}, Spec: clusterv1.ClusterSpec{ InfrastructureRef: &corev1.ObjectReference{Name: "aws-test-5"}, - }}, + }, + }, expectError: false, }, { name: "Should fail to reconcile while fetching infra cluster", - awsMachine: &infrav1.AWSMachine{ObjectMeta: metav1.ObjectMeta{ - Name: "aws-test-5", OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: clusterv1.GroupVersion.String(), - Kind: "Machine", - Name: "capi-test-machine", - UID: "1", + awsMachine: &infrav1.AWSMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-test-5", OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: clusterv1.GroupVersion.String(), + Kind: "Machine", + Name: "capi-test-machine", + UID: "1", + }, }, - }}, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, + }, Spec: infrav1.AWSMachineSpec{InstanceType: "test"}, }, ownerMachine: &clusterv1.Machine{ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ clusterv1.ClusterLabelName: "capi-test-1", }, - Name: "capi-test-machine", Namespace: "default"}}, - ownerCluster: &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}, + Name: "capi-test-machine", Namespace: "default", + }}, + ownerCluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{Name: "capi-test-1"}, Spec: clusterv1.ClusterSpec{ InfrastructureRef: &corev1.ObjectReference{Name: "aws-test-5"}, - }}, + }, + }, awsCluster: &infrav1.AWSCluster{ObjectMeta: metav1.ObjectMeta{Name: "aws-test-5"}}, expectError: true, }, diff --git a/go.mod b/go.mod index 5d7f462913..7cf77993a6 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/aws/aws-sdk-go v1.40.56 github.com/awslabs/goformation/v4 v4.19.5 github.com/blang/semver v3.5.1+incompatible + github.com/flatcar-linux/ignition v0.36.1 github.com/go-logr/logr v1.2.3 github.com/gofrs/flock v0.8.1 github.com/golang/mock v1.6.0 @@ -57,6 +58,8 @@ require ( github.com/containerd/containerd v1.5.9 // indirect github.com/coredns/caddy v1.1.0 // indirect github.com/coredns/corefile-migration v1.0.14 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/distribution v2.7.1+incompatible // indirect @@ -122,6 +125,7 @@ require ( github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/valyala/fastjson v1.6.3 // indirect + github.com/vincent-petithory/dataurl v1.0.0 // indirect golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect diff --git a/go.sum b/go.sum index cba5125f1f..d6ab1323a2 100644 --- a/go.sum +++ b/go.sum @@ -309,11 +309,13 @@ github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.1.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= @@ -401,6 +403,7 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flatcar-linux/container-linux-config-transpiler v0.9.2/go.mod h1:AGVTulMzeIKwurV9ExYH3UiokET1Ur65g+EIeRDMwzM= +github.com/flatcar-linux/ignition v0.36.1 h1:yNvS9sQvm9HJ8VgxXskx88DsF73qdF35ALJkbTwcYhY= github.com/flatcar-linux/ignition v0.36.1/go.mod h1:0jS5n4AopgOdwgi7QDo5MFgkMx/fQUDYjuxlGJC1Txg= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -1070,6 +1073,7 @@ github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2 github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= diff --git a/pkg/cloud/scope/machine.go b/pkg/cloud/scope/machine.go index 0f2ebb8318..8a8f4f3a4b 100644 --- a/pkg/cloud/scope/machine.go +++ b/pkg/cloud/scope/machine.go @@ -192,8 +192,12 @@ func (m *MachineScope) SetAnnotation(key, value string) { // UseSecretsManager returns the computed value of whether or not // userdata should be stored using AWS Secrets Manager. -func (m *MachineScope) UseSecretsManager() bool { - return !m.AWSMachine.Spec.CloudInit.InsecureSkipSecretsManager +func (m *MachineScope) UseSecretsManager(userDataFormat string) bool { + return !m.AWSMachine.Spec.CloudInit.InsecureSkipSecretsManager && !m.UseIgnition(userDataFormat) +} + +func (m *MachineScope) UseIgnition(userDataFormat string) bool { + return userDataFormat == "ignition" || (m.AWSMachine.Spec.Ignition != nil) } // SecureSecretsBackend returns the chosen secret backend. @@ -201,10 +205,14 @@ func (m *MachineScope) SecureSecretsBackend() infrav1.SecretBackend { return m.AWSMachine.Spec.CloudInit.SecureSecretsBackend } -// UserDataIsUncompressed returns the computed value of whether or not +// CompressUserData returns the computed value of whether or not // userdata should be compressed using gzip. -func (m *MachineScope) UserDataIsUncompressed() bool { - return m.AWSMachine.Spec.UncompressedUserData != nil && *m.AWSMachine.Spec.UncompressedUserData +func (m *MachineScope) CompressUserData(userDataFormat string) bool { + if m.UseIgnition(userDataFormat) { + return false + } + + return m.AWSMachine.Spec.UncompressedUserData != nil && !*m.AWSMachine.Spec.UncompressedUserData } // GetSecretPrefix returns the prefix for the secrets belonging @@ -253,22 +261,28 @@ func (m *MachineScope) GetBootstrapData() (string, error) { // GetRawBootstrapData returns the bootstrap data from the secret in the Machine's bootstrap.dataSecretName. func (m *MachineScope) GetRawBootstrapData() ([]byte, error) { + data, _, err := m.GetRawBootstrapDataWithFormat() + + return data, err +} + +func (m *MachineScope) GetRawBootstrapDataWithFormat() ([]byte, string, error) { if m.Machine.Spec.Bootstrap.DataSecretName == nil { - return nil, errors.New("error retrieving bootstrap data: linked Machine's bootstrap.dataSecretName is nil") + return nil, "", errors.New("error retrieving bootstrap data: linked Machine's bootstrap.dataSecretName is nil") } secret := &corev1.Secret{} key := types.NamespacedName{Namespace: m.Namespace(), Name: *m.Machine.Spec.Bootstrap.DataSecretName} if err := m.client.Get(context.TODO(), key, secret); err != nil { - return nil, errors.Wrapf(err, "failed to retrieve bootstrap data secret for AWSMachine %s/%s", m.Namespace(), m.Name()) + return nil, "", errors.Wrapf(err, "failed to retrieve bootstrap data secret for AWSMachine %s/%s", m.Namespace(), m.Name()) } value, ok := secret.Data["value"] if !ok { - return nil, errors.New("error retrieving bootstrap data: secret value key is missing") + return nil, "", errors.New("error retrieving bootstrap data: secret value key is missing") } - return value, nil + return value, string(secret.Data["format"]), nil } // PatchObject persists the machine spec and status. diff --git a/pkg/cloud/scope/machine_test.go b/pkg/cloud/scope/machine_test.go index f8eddbe655..a79b370381 100644 --- a/pkg/cloud/scope/machine_test.go +++ b/pkg/cloud/scope/machine_test.go @@ -170,17 +170,134 @@ func TestGetRawBootstrapDataIsNotBase64Encoded(t *testing.T) { } } +func Test_GetRawBootstrapDataWithFormat(t *testing.T) { + t.Run("returns_empty_format_when_format_is_not_set_in_bootstrap_data", func(t *testing.T) { + scope, err := setupMachineScope() + if err != nil { + t.Fatal(err) + } + + _, format, err := scope.GetRawBootstrapDataWithFormat() + if err != nil { + t.Fatalf("Getting raw bootstrap data with format: %v", err) + } + + if format != "" { + t.Fatalf("Fromat should be empty when it's not defined in bootstrap data, got: %q", format) + } + }) + + t.Run("returns_format_defined_in_bootstrap_data_when_available", func(t *testing.T) { + scheme, err := setupScheme() + if err != nil { + t.Fatalf("Configuring schema: %v", err) + } + + clusterName := "my-cluster" + machineName := "my-machine-0" + cluster := newCluster(clusterName) + machine := newMachine(clusterName, machineName) + awsMachine := newAWSMachine(clusterName, machineName) + awsCluster := newAWSCluster(clusterName) + + expectedBootstrapDataFormat := "ignition" + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + clusterv1.ClusterLabelName: clusterName, + }, + Name: machineName, + Namespace: "default", + }, + Data: map[string][]byte{ + "value": []byte("user data"), + "format": []byte(expectedBootstrapDataFormat), + }, + } + + initObjects := []client.Object{ + cluster, machine, secret, awsMachine, awsCluster, + } + + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjects...).Build() + + machineScope, err := NewMachineScope( + MachineScopeParams{ + Client: client, + Machine: machine, + Cluster: cluster, + InfraCluster: &ClusterScope{ + AWSCluster: awsCluster, + }, + AWSMachine: awsMachine, + }, + ) + if err != nil { + t.Fatalf("Creating machine scope: %v", err) + } + + _, format, err := machineScope.GetRawBootstrapDataWithFormat() + if err != nil { + t.Fatalf("Getting raw bootstrap data with format: %v", err) + } + + if format != expectedBootstrapDataFormat { + t.Fatalf("Unexpected bootstrap data format, expected %q, got %q", expectedBootstrapDataFormat, format) + } + }) +} + func TestUseSecretsManagerTrue(t *testing.T) { scope, err := setupMachineScope() if err != nil { t.Fatal(err) } - if !scope.UseSecretsManager() { + if !scope.UseSecretsManager("cloud-config") { t.Fatalf("UseSecretsManager should be true") } } +func Test_UseIgnition(t *testing.T) { + t.Run("returns_true_when_given_bootstrap_data_format_is_ignition", func(t *testing.T) { + scope, err := setupMachineScope() + if err != nil { + t.Fatal(err) + } + + if !scope.UseIgnition("ignition") { + t.Fatalf("UseIgnition should be true") + } + }) + + // To retain backward compatibility, where KAPBK does not produce format field. + t.Run("returns_false_when_given_bootstrap_data_format_is_empty", func(t *testing.T) { + scope, err := setupMachineScope() + if err != nil { + t.Fatal(err) + } + + if scope.UseIgnition("") { + t.Fatalf("UseIgnition should be false") + } + }) +} + +func Test_CompressUserData(t *testing.T) { + // Ignition does not support compressed data in S3. + t.Run("returns_false_when_bootstrap_data_is_in_ignition_format", func(t *testing.T) { + scope, err := setupMachineScope() + if err != nil { + t.Fatal(err) + } + + if scope.CompressUserData("ignition") { + t.Fatalf("User data would be compressed despite Ignition format") + } + }) +} + func TestGetSecretARNDefaultIsNil(t *testing.T) { scope, err := setupMachineScope() if err != nil { diff --git a/pkg/cloud/scope/machinepool.go b/pkg/cloud/scope/machinepool.go index c014db1549..baf007fd16 100644 --- a/pkg/cloud/scope/machinepool.go +++ b/pkg/cloud/scope/machinepool.go @@ -124,23 +124,33 @@ func (m *MachinePoolScope) Namespace() string { // GetRawBootstrapData returns the bootstrap data from the secret in the Machine's bootstrap.dataSecretName. // todo(rudoi): stolen from MachinePool - any way to reuse? func (m *MachinePoolScope) GetRawBootstrapData() ([]byte, error) { + data, _, err := m.getBootstrapData() + + return data, err +} + +func (m *MachinePoolScope) GetRawBootstrapDataWithFormat() ([]byte, string, error) { + return m.getBootstrapData() +} + +func (m *MachinePoolScope) getBootstrapData() ([]byte, string, error) { if m.MachinePool.Spec.Template.Spec.Bootstrap.DataSecretName == nil { - return nil, errors.New("error retrieving bootstrap data: linked Machine's bootstrap.dataSecretName is nil") + return nil, "", errors.New("error retrieving bootstrap data: linked Machine's bootstrap.dataSecretName is nil") } secret := &corev1.Secret{} key := types.NamespacedName{Namespace: m.Namespace(), Name: *m.MachinePool.Spec.Template.Spec.Bootstrap.DataSecretName} if err := m.client.Get(context.TODO(), key, secret); err != nil { - return nil, errors.Wrapf(err, "failed to retrieve bootstrap data secret for AWSMachine %s/%s", m.Namespace(), m.Name()) + return nil, "", errors.Wrapf(err, "failed to retrieve bootstrap data secret for AWSMachine %s/%s", m.Namespace(), m.Name()) } value, ok := secret.Data["value"] if !ok { - return nil, errors.New("error retrieving bootstrap data: secret value key is missing") + return nil, "", errors.New("error retrieving bootstrap data: secret value key is missing") } - return value, nil + return value, string(secret.Data["format"]), nil } // AdditionalTags merges AdditionalTags from the scope's AWSCluster and AWSMachinePool. If the same key is present in both, diff --git a/pkg/cloud/services/ec2/instances.go b/pkg/cloud/services/ec2/instances.go index bf7e5ce212..a7c2f2b0d5 100644 --- a/pkg/cloud/services/ec2/instances.go +++ b/pkg/cloud/services/ec2/instances.go @@ -110,7 +110,7 @@ func (s *Service) InstanceIfExists(id *string) (*infrav1.Instance, error) { } // CreateInstance runs an ec2 instance. -func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte) (*infrav1.Instance, error) { +func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte, userDataFormat string) (*infrav1.Instance, error) { s.scope.V(2).Info("Creating an instance for a machine") input := &infrav1.Instance{ @@ -183,7 +183,8 @@ func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte) (*i return nil, awserrors.NewFailedDependency("failed to run controlplane, APIServer ELB not available") } - if !scope.UserDataIsUncompressed() { + + if scope.CompressUserData(userDataFormat) { userData, err = userdata.GzipBytes(userData) if err != nil { return nil, errors.New("failed to gzip userdata") diff --git a/pkg/cloud/services/ec2/instances_test.go b/pkg/cloud/services/ec2/instances_test.go index 91be58fe7f..fc755487ac 100644 --- a/pkg/cloud/services/ec2/instances_test.go +++ b/pkg/cloud/services/ec2/instances_test.go @@ -286,11 +286,14 @@ func TestCreateInstance(t *testing.T) { data := []byte("userData") - userData, err := userdata.GzipBytes(data) + userDataCompressed, err := userdata.GzipBytes(data) if err != nil { t.Fatal("Failed to gzip test user data") } + isUncompressedFalse := false + isUncompressedTrue := true + testcases := []struct { name string machine clusterv1.Machine @@ -2008,7 +2011,7 @@ func TestCreateInstance(t *testing.T) { }, }, { - name: "with dedicated tenancy", + name: "with dedicated tenancy cloud-config", machine: clusterv1.Machine{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"set": "node"}, @@ -2025,8 +2028,145 @@ func TestCreateInstance(t *testing.T) { AMI: infrav1.AMIReference{ ID: aws.String("abc"), }, - InstanceType: "m5.large", - Tenancy: "dedicated", + InstanceType: "m5.large", + Tenancy: "dedicated", + UncompressedUserData: &isUncompressedFalse, + }, + awsCluster: &infrav1.AWSCluster{ + Spec: infrav1.AWSClusterSpec{ + NetworkSpec: infrav1.NetworkSpec{ + Subnets: infrav1.Subnets{ + infrav1.SubnetSpec{ + ID: "subnet-1", + IsPublic: false, + }, + infrav1.SubnetSpec{ + IsPublic: false, + }, + }, + }, + }, + Status: infrav1.AWSClusterStatus{ + Network: infrav1.NetworkStatus{ + SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{ + infrav1.SecurityGroupControlPlane: { + ID: "1", + }, + infrav1.SecurityGroupNode: { + ID: "2", + }, + infrav1.SecurityGroupLB: { + ID: "3", + }, + }, + APIServerELB: infrav1.ClassicELB{ + DNSName: "test-apiserver.us-east-1.aws", + }, + }, + }, + }, + expect: func(m *mock_ec2iface.MockEC2APIMockRecorder) { + m. // TODO: Restore these parameters, but with the tags as well + RunInstances(gomock.Eq(&ec2.RunInstancesInput{ + ImageId: aws.String("abc"), + InstanceType: aws.String("m5.large"), + KeyName: aws.String("default"), + MaxCount: aws.Int64(1), + MinCount: aws.Int64(1), + Placement: &ec2.Placement{ + Tenancy: &tenancy, + }, + SecurityGroupIds: []*string{aws.String("2"), aws.String("3")}, + SubnetId: aws.String("subnet-1"), + TagSpecifications: []*ec2.TagSpecification{ + { + ResourceType: aws.String("instance"), + Tags: []*ec2.Tag{ + { + Key: aws.String("MachineName"), + Value: aws.String("default/machine-aws-test1"), + }, + { + Key: aws.String("Name"), + Value: aws.String("aws-test1"), + }, + { + Key: aws.String("kubernetes.io/cluster/test1"), + Value: aws.String("owned"), + }, + { + Key: aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test1"), + Value: aws.String("owned"), + }, + { + Key: aws.String("sigs.k8s.io/cluster-api-provider-aws/role"), + Value: aws.String("node"), + }, + }, + }, + }, + UserData: aws.String(base64.StdEncoding.EncodeToString(userDataCompressed)), + })). + Return(&ec2.Reservation{ + Instances: []*ec2.Instance{ + { + State: &ec2.InstanceState{ + Name: aws.String(ec2.InstanceStateNamePending), + }, + IamInstanceProfile: &ec2.IamInstanceProfile{ + Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"), + }, + InstanceId: aws.String("two"), + InstanceType: aws.String("m5.large"), + SubnetId: aws.String("subnet-1"), + ImageId: aws.String("ami-1"), + RootDeviceName: aws.String("device-1"), + BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{ + { + DeviceName: aws.String("device-1"), + Ebs: &ec2.EbsInstanceBlockDevice{ + VolumeId: aws.String("volume-1"), + }, + }, + }, + Placement: &ec2.Placement{ + AvailabilityZone: &az, + Tenancy: &tenancy, + }, + }, + }, + }, nil) + m.WaitUntilInstanceRunningWithContext(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + }, + check: func(instance *infrav1.Instance, err error) { + if err != nil { + t.Fatalf("did not expect error: %v", err) + } + }, + }, + { + name: "with dedicated tenancy ignition", + machine: clusterv1.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"set": "node"}, + Namespace: "default", + Name: "machine-aws-test1", + }, + Spec: clusterv1.MachineSpec{ + Bootstrap: clusterv1.Bootstrap{ + DataSecretName: pointer.StringPtr("bootstrap-data"), + }, + }, + }, + machineConfig: &infrav1.AWSMachineSpec{ + AMI: infrav1.AMIReference{ + ID: aws.String("abc"), + }, + InstanceType: "m5.large", + Tenancy: "dedicated", + UncompressedUserData: &isUncompressedTrue, + Ignition: &infrav1.Ignition{}, }, awsCluster: &infrav1.AWSCluster{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, @@ -2102,7 +2242,7 @@ func TestCreateInstance(t *testing.T) { }, }, }, - UserData: aws.String(base64.StdEncoding.EncodeToString(userData)), + UserData: aws.String(base64.StdEncoding.EncodeToString(data)), })). Return(&ec2.Reservation{ Instances: []*ec2.Instance{ @@ -2860,7 +3000,7 @@ func TestCreateInstance(t *testing.T) { s := NewService(clusterScope) s.EC2Client = ec2Mock - instance, err := s.CreateInstance(machineScope, data) + instance, err := s.CreateInstance(machineScope, data, "") tc.check(instance, err) }) } diff --git a/pkg/cloud/services/interfaces.go b/pkg/cloud/services/interfaces.go index b71abeca14..d532cd019d 100644 --- a/pkg/cloud/services/interfaces.go +++ b/pkg/cloud/services/interfaces.go @@ -47,7 +47,7 @@ type ASGInterface interface { type EC2Interface interface { InstanceIfExists(id *string) (*infrav1.Instance, error) TerminateInstance(id string) error - CreateInstance(scope *scope.MachineScope, userData []byte) (*infrav1.Instance, error) + CreateInstance(scope *scope.MachineScope, userData []byte, userDataFormat string) (*infrav1.Instance, error) GetRunningInstanceByTags(scope *scope.MachineScope) (*infrav1.Instance, error) GetCoreSecurityGroups(machine *scope.MachineScope) ([]string, error) diff --git a/pkg/cloud/services/mock_services/ec2_interface_mock.go b/pkg/cloud/services/mock_services/ec2_interface_mock.go index d0986f39df..b1b5de1eb0 100644 --- a/pkg/cloud/services/mock_services/ec2_interface_mock.go +++ b/pkg/cloud/services/mock_services/ec2_interface_mock.go @@ -53,18 +53,18 @@ func (m *MockEC2Interface) EXPECT() *MockEC2InterfaceMockRecorder { } // CreateInstance mocks base method. -func (m *MockEC2Interface) CreateInstance(arg0 *scope.MachineScope, arg1 []byte) (*v1beta1.Instance, error) { +func (m *MockEC2Interface) CreateInstance(arg0 *scope.MachineScope, arg1 []byte, arg2 string) (*v1beta1.Instance, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateInstance", arg0, arg1) + ret := m.ctrl.Call(m, "CreateInstance", arg0, arg1, arg2) ret0, _ := ret[0].(*v1beta1.Instance) ret1, _ := ret[1].(error) return ret0, ret1 } // CreateInstance indicates an expected call of CreateInstance. -func (mr *MockEC2InterfaceMockRecorder) CreateInstance(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockEC2InterfaceMockRecorder) CreateInstance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInstance", reflect.TypeOf((*MockEC2Interface)(nil).CreateInstance), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInstance", reflect.TypeOf((*MockEC2Interface)(nil).CreateInstance), arg0, arg1, arg2) } // CreateLaunchTemplate mocks base method. From bdc7ade6f376289bf9dff921c757e3b706e3288a Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 16 Feb 2021 10:27:35 +0100 Subject: [PATCH 07/12] templates: add Flatcar Container Linux template Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- templates/cluster-template-flatcar.yaml | 163 ++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 templates/cluster-template-flatcar.yaml diff --git a/templates/cluster-template-flatcar.yaml b/templates/cluster-template-flatcar.yaml new file mode 100644 index 0000000000..24cc55b041 --- /dev/null +++ b/templates/cluster-template-flatcar.yaml @@ -0,0 +1,163 @@ +--- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Cluster +metadata: + name: "${CLUSTER_NAME}" +spec: + clusterNetwork: + pods: + cidrBlocks: ["192.168.0.0/16"] + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: AWSCluster + name: "${CLUSTER_NAME}" + controlPlaneRef: + kind: KubeadmControlPlane + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + name: "${CLUSTER_NAME}-control-plane" +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSCluster +metadata: + name: "${CLUSTER_NAME}" +spec: + region: "${AWS_REGION}" + sshKeyName: "${AWS_SSH_KEY_NAME}" + s3Bucket: + controlPlaneIAMInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io + name: "${AWS_S3_BUCKET_NAME}" + nodesIAMInstanceProfiles: + - nodes.cluster-api-provider-aws.sigs.k8s.io +--- +apiVersion: controlplane.cluster.x-k8s.io/v1beta1 +kind: KubeadmControlPlane +metadata: + name: ${CLUSTER_NAME}-control-plane +spec: + replicas: ${CONTROL_PLANE_MACHINE_COUNT} + machineTemplate: + infrastructureRef: + kind: AWSMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + name: "${CLUSTER_NAME}-control-plane" + kubeadmConfigSpec: + initConfiguration: + nodeRegistration: + name: $${COREOS_EC2_HOSTNAME} + kubeletExtraArgs: + cloud-provider: aws + clusterConfiguration: + apiServer: + extraArgs: + cloud-provider: aws + controllerManager: + extraArgs: + cloud-provider: aws + joinConfiguration: + nodeRegistration: + name: $${COREOS_EC2_HOSTNAME} + kubeletExtraArgs: + cloud-provider: aws + format: ignition + ignition: + containerLinuxConfig: + additionalConfig: | + systemd: + units: + - name: kubeadm.service + enabled: true + dropins: + - name: 10-flatcar.conf + contents: | + [Unit] + # kubeadm must run after coreos-metadata populated /run/metadata directory. + Requires=coreos-metadata.service + After=coreos-metadata.service + [Service] + # To make metadata environment variables available for pre-kubeadm commands. + EnvironmentFile=/run/metadata/* + preKubeadmCommands: + - envsubst < /etc/kubeadm.yml > /etc/kubeadm.yml.tmp + - mv /etc/kubeadm.yml.tmp /etc/kubeadm.yml + version: ${KUBERNETES_VERSION} +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSMachineTemplate +metadata: + name: ${CLUSTER_NAME}-control-plane +spec: + template: + spec: + instanceType: ${AWS_CONTROL_PLANE_MACHINE_TYPE} + iamInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io + imageLookupBaseOS: flatcar-stable + sshKeyName: ${AWS_SSH_KEY_NAME} +--- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineDeployment +metadata: + name: ${CLUSTER_NAME}-md-0 +spec: + clusterName: ${CLUSTER_NAME} + replicas: ${WORKER_MACHINE_COUNT} + selector: + matchLabels: + template: + spec: + clusterName: ${CLUSTER_NAME} + version: ${KUBERNETES_VERSION} + bootstrap: + configRef: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: ${CLUSTER_NAME}-md-0 + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: AWSMachineTemplate + name: ${CLUSTER_NAME}-md-0 +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSMachineTemplate +metadata: + name: ${CLUSTER_NAME}-md-0 +spec: + template: + spec: + instanceType: ${AWS_NODE_MACHINE_TYPE} + iamInstanceProfile: nodes.cluster-api-provider-aws.sigs.k8s.io + imageLookupBaseOS: flatcar-stable + sshKeyName: ${AWS_SSH_KEY_NAME} +--- +apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 +kind: KubeadmConfigTemplate +metadata: + name: ${CLUSTER_NAME}-md-0 +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + kubeletExtraArgs: + cloud-provider: aws + name: $${COREOS_EC2_HOSTNAME} + format: ignition + ignition: + containerLinuxConfig: + additionalConfig: | + systemd: + units: + - name: kubeadm.service + enabled: true + dropins: + - name: 10-flatcar.conf + contents: | + [Unit] + # kubeadm must run after coreos-metadata populated /run/metadata directory. + Requires=coreos-metadata.service + After=coreos-metadata.service + [Service] + # To make metadata environment variables available for pre-kubeadm commands. + EnvironmentFile=/run/metadata/* + preKubeadmCommands: + - envsubst < /etc/kubeadm.yml > /etc/kubeadm.yml.tmp + - mv /etc/kubeadm.yml.tmp /etc/kubeadm.yml From 3156e2e0e48ef707ef015c3af1a8881e5049196a Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Thu, 11 Mar 2021 12:43:24 +0100 Subject: [PATCH 08/12] test/e2e: add tests for S3 Bucket and Flatcar support Co-authored-by: Dongsu Park Signed-off-by: Mateusz Gozdek --- test/e2e/data/e2e_conf.yaml | 1 + .../ignition/kustomization.yaml | 8 ++++ .../ignition/patches/control-plane-ami.yaml | 8 ++++ .../patches/control-plane-ignition.yaml | 37 +++++++++++++++++++ .../ignition/patches/s3bucket.yaml | 11 ++++++ .../ignition/patches/worker-ami.yaml | 8 ++++ .../ignition/patches/worker-ignition.yaml | 33 +++++++++++++++++ test/e2e/shared/defaults.go | 1 + test/e2e/shared/template.go | 1 + .../unmanaged/unmanaged_functional_test.go | 28 ++++++++++++++ 10 files changed, 136 insertions(+) create mode 100644 test/e2e/data/infrastructure-aws/kustomize_sources/ignition/kustomization.yaml create mode 100644 test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ami.yaml create mode 100644 test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ignition.yaml create mode 100644 test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/s3bucket.yaml create mode 100644 test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ami.yaml create mode 100644 test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ignition.yaml diff --git a/test/e2e/data/e2e_conf.yaml b/test/e2e/data/e2e_conf.yaml index d5b5a0a1c6..81334aa65f 100644 --- a/test/e2e/data/e2e_conf.yaml +++ b/test/e2e/data/e2e_conf.yaml @@ -232,6 +232,7 @@ providers: - sourcePath: "./infrastructure-aws/generated/cluster-template-internal-elb.yaml" - sourcePath: "./infrastructure-aws/kustomize_sources/topology/clusterclass-quick-start.yaml" - sourcePath: "./shared/v1beta1_provider/metadata.yaml" + - sourcePath: "./infrastructure-aws/generated/cluster-template-ignition.yaml" replacements: # To allow bugs to be catched. - old: "failureThreshold: 3" diff --git a/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/kustomization.yaml b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/kustomization.yaml new file mode 100644 index 0000000000..f110b7516e --- /dev/null +++ b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/kustomization.yaml @@ -0,0 +1,8 @@ +resources: +- ../default +patchesStrategicMerge: +- patches/control-plane-ami.yaml +- patches/control-plane-ignition.yaml +- patches/s3bucket.yaml +- patches/worker-ami.yaml +- patches/worker-ignition.yaml diff --git a/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ami.yaml b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ami.yaml new file mode 100644 index 0000000000..e2dfa7c92e --- /dev/null +++ b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ami.yaml @@ -0,0 +1,8 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSMachineTemplate +metadata: + name: "${CLUSTER_NAME}-control-plane" +spec: + template: + spec: + imageLookupBaseOS: flatcar-stable diff --git a/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ignition.yaml b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ignition.yaml new file mode 100644 index 0000000000..5fca54cb27 --- /dev/null +++ b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/control-plane-ignition.yaml @@ -0,0 +1,37 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta1 +kind: KubeadmControlPlane +metadata: + name: "${CLUSTER_NAME}-control-plane" +spec: + kubeadmConfigSpec: + initConfiguration: + nodeRegistration: + kubeletExtraArgs: + cloud-provider: aws + name: $${COREOS_EC2_HOSTNAME} + joinConfiguration: + nodeRegistration: + kubeletExtraArgs: + cloud-provider: aws + name: $${COREOS_EC2_HOSTNAME} + format: ignition + ignition: + containerLinuxConfig: + additionalConfig: | + systemd: + units: + - name: kubeadm.service + enabled: true + dropins: + - name: 10-flatcar.conf + contents: | + [Unit] + # kubeadm must run after coreos-metadata populated /run/metadata directory. + Requires=coreos-metadata.service + After=coreos-metadata.service + [Service] + # To make metadata environment variables available for pre-kubeadm commands. + EnvironmentFile=/run/metadata/* + preKubeadmCommands: + - envsubst < /etc/kubeadm.yml > /etc/kubeadm.yml.tmp + - mv /etc/kubeadm.yml.tmp /etc/kubeadm.yml diff --git a/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/s3bucket.yaml b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/s3bucket.yaml new file mode 100644 index 0000000000..070d3e6724 --- /dev/null +++ b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/s3bucket.yaml @@ -0,0 +1,11 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSCluster +metadata: + name: "${CLUSTER_NAME}" +spec: + s3Bucket: + controlPlaneIAMInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io + # Letter at the end ensures bucket name ends with a letter which is a requirement. + name: "cluster-api-provider-aws-${CLUSTER_NAME}a" + nodesIAMInstanceProfiles: + - nodes.cluster-api-provider-aws.sigs.k8s.io diff --git a/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ami.yaml b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ami.yaml new file mode 100644 index 0000000000..b0887da6a3 --- /dev/null +++ b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ami.yaml @@ -0,0 +1,8 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSMachineTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + imageLookupBaseOS: flatcar-stable diff --git a/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ignition.yaml b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ignition.yaml new file mode 100644 index 0000000000..c4f18f21cc --- /dev/null +++ b/test/e2e/data/infrastructure-aws/kustomize_sources/ignition/patches/worker-ignition.yaml @@ -0,0 +1,33 @@ +apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 +kind: KubeadmConfigTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + kubeletExtraArgs: + cloud-provider: aws + name: $${COREOS_EC2_HOSTNAME} + format: ignition + ignition: + containerLinuxConfig: + additionalConfig: | + systemd: + units: + - name: kubeadm.service + enabled: true + dropins: + - name: 10-flatcar.conf + contents: | + [Unit] + # kubeadm must run after coreos-metadata populated /run/metadata directory. + Requires=coreos-metadata.service + After=coreos-metadata.service + [Service] + # To make metadata environment variables available for pre-kubeadm commands. + EnvironmentFile=/run/metadata/* + preKubeadmCommands: + - envsubst < /etc/kubeadm.yml > /etc/kubeadm.yml.tmp + - mv /etc/kubeadm.yml.tmp /etc/kubeadm.yml diff --git a/test/e2e/shared/defaults.go b/test/e2e/shared/defaults.go index e3bca11d74..231fbc3c08 100644 --- a/test/e2e/shared/defaults.go +++ b/test/e2e/shared/defaults.go @@ -54,6 +54,7 @@ const ( SimpleMultitenancyFlavor = "simple-multitenancy" NestedMultitenancyFlavor = "nested-multitenancy" KCPScaleInFlavor = "kcp-scale-in" + IgnitionFlavor = "ignition" StorageClassOutTreeZoneLabel = "topology.ebs.csi.aws.com/zone" GPUFlavor = "gpu" InstanceVcpu = "AWS_MACHINE_TYPE_VCPU_USAGE" diff --git a/test/e2e/shared/template.go b/test/e2e/shared/template.go index 2e4183d3be..9b5a49b788 100644 --- a/test/e2e/shared/template.go +++ b/test/e2e/shared/template.go @@ -105,6 +105,7 @@ func newBootstrapTemplate(e2eCtx *E2EContext) *cfn_bootstrap.Template { t.Spec.EKS.AllowIAMRoleCreation = false t.Spec.EKS.DefaultControlPlaneRole.Disable = false t.Spec.EKS.ManagedMachinePool.Disable = false + t.Spec.S3Buckets.Enable = true str, err := yaml.Marshal(t.Spec) Expect(err).NotTo(HaveOccurred()) Expect(os.WriteFile(path.Join(e2eCtx.Settings.ArtifactFolder, "awsiamconfiguration.yaml"), str, 0644)).To(Succeed()) //nolint:gosec diff --git a/test/e2e/suites/unmanaged/unmanaged_functional_test.go b/test/e2e/suites/unmanaged/unmanaged_functional_test.go index 110db3a3d7..43aeedca83 100644 --- a/test/e2e/suites/unmanaged/unmanaged_functional_test.go +++ b/test/e2e/suites/unmanaged/unmanaged_functional_test.go @@ -1044,6 +1044,34 @@ var _ = ginkgo.Context("[unmanaged] [functional]", func() { } }) }) + + ginkgo.Describe("Workload cluster with AWS S3 and Ignition parameter", func() { + ginkgo.It("It should be creatable and deletable", func() { + specName := "functional-test-ignition-parameter" + namespace := shared.SetupSpecNamespace(ctx, specName, e2eCtx) + ginkgo.By("Creating a cluster") + clusterName := fmt.Sprintf("cluster-%s", util.RandomString(6)) + configCluster := defaultConfigCluster(clusterName, namespace.Name) + configCluster.ControlPlaneMachineCount = pointer.Int64Ptr(1) + configCluster.WorkerMachineCount = pointer.Int64Ptr(1) + configCluster.Flavor = shared.IgnitionFlavor + _, md, _ := createCluster(ctx, configCluster, result) + + workerMachines := framework.GetMachinesByMachineDeployments(ctx, framework.GetMachinesByMachineDeploymentsInput{ + Lister: e2eCtx.Environment.BootstrapClusterProxy.GetClient(), + ClusterName: clusterName, + Namespace: namespace.Name, + MachineDeployment: *md[0], + }) + controlPlaneMachines := framework.GetControlPlaneMachinesByCluster(ctx, framework.GetControlPlaneMachinesByClusterInput{ + Lister: e2eCtx.Environment.BootstrapClusterProxy.GetClient(), + ClusterName: clusterName, + Namespace: namespace.Name, + }) + Expect(len(workerMachines)).To(Equal(1)) + Expect(len(controlPlaneMachines)).To(Equal(1)) + }) + }) }) func createStatefulSetInfo(isIntreeCSI bool, prefix string) statefulSetInfo { From a9d5c1e94e9d0685f0c587d464b58b5bbaeecef5 Mon Sep 17 00:00:00 2001 From: Suraj Deshmukh Date: Tue, 19 Oct 2021 13:56:24 +0530 Subject: [PATCH 09/12] Add feature gate BootstrapFormatIgnition This commit adds the feature gate BootstrapFormatIgnition that will control the usage of field `ignition` in AWSMachine & AWSMachineTemplate and `s3Bucket` in AWSCluster. If user provides `ignition` field and/or `s3Bucket` without setting the feature gate then the webhook rejects the request with a validation error. Signed-off-by: Suraj Deshmukh --- api/v1beta1/awscluster_webhook_test.go | 4 ++++ api/v1beta1/awsmachine_webhook.go | 8 ++++++++ api/v1beta1/awsmachinetemplate_webhook.go | 8 ++++++++ api/v1beta1/s3bucket.go | 8 ++++++++ config/manager/manager.yaml | 2 +- docs/book/src/development/tilt-setup.md | 7 ++++--- feature/feature.go | 4 ++++ main.go | 4 ++++ test/e2e/data/e2e_conf.yaml | 1 + 9 files changed, 42 insertions(+), 4 deletions(-) diff --git a/api/v1beta1/awscluster_webhook_test.go b/api/v1beta1/awscluster_webhook_test.go index 08fbcd0d2f..9ed4f1b3bd 100644 --- a/api/v1beta1/awscluster_webhook_test.go +++ b/api/v1beta1/awscluster_webhook_test.go @@ -25,8 +25,10 @@ import ( "github.com/aws/aws-sdk-go/aws" . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilfeature "k8s.io/component-base/featuregate/testing" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/cluster-api-provider-aws/feature" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" utildefaulting "sigs.k8s.io/cluster-api/util/defaulting" ) @@ -223,6 +225,8 @@ func TestAWSCluster_ValidateCreate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, feature.BootstrapFormatIgnition, true)() + cluster := tt.cluster.DeepCopy() cluster.ObjectMeta = metav1.ObjectMeta{ GenerateName: "cluster-", diff --git a/api/v1beta1/awsmachine_webhook.go b/api/v1beta1/awsmachine_webhook.go index e08b81216e..cd54cbe179 100644 --- a/api/v1beta1/awsmachine_webhook.go +++ b/api/v1beta1/awsmachine_webhook.go @@ -26,6 +26,8 @@ import ( ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" + + "sigs.k8s.io/cluster-api-provider-aws/feature" ) // log is for logging in this package. @@ -159,6 +161,12 @@ func (r *AWSMachine) ignitionEnabled() bool { func (r *AWSMachine) validateIgnitionAndCloudInit() field.ErrorList { var allErrs field.ErrorList + // Feature gate is not enabled but ignition is enabled then send a forbidden error. + if !feature.Gates.Enabled(feature.BootstrapFormatIgnition) && r.ignitionEnabled() { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "ignition"), + "can be set only if the BootstrapFormatIgnition feature gate is enabled")) + } + if r.ignitionEnabled() && r.cloudInitConfigured() { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "cloudInit"), "cannot be set if spec.ignition is set")) } diff --git a/api/v1beta1/awsmachinetemplate_webhook.go b/api/v1beta1/awsmachinetemplate_webhook.go index 3d38e023a8..85fe8b38fc 100644 --- a/api/v1beta1/awsmachinetemplate_webhook.go +++ b/api/v1beta1/awsmachinetemplate_webhook.go @@ -24,6 +24,8 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/webhook" + + "sigs.k8s.io/cluster-api-provider-aws/feature" ) func (r *AWSMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error { @@ -113,6 +115,12 @@ func (r *AWSMachineTemplate) ValidateCreate() error { allErrs = append(allErrs, r.validateRootVolume()...) allErrs = append(allErrs, r.validateNonRootVolumes()...) + // Feature gate is not enabled but ignition is enabled then send a forbidden error. + if !feature.Gates.Enabled(feature.BootstrapFormatIgnition) && spec.Ignition != nil { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "ignition"), + "can be set only if the BootstrapFormatIgnition feature gate is enabled")) + } + cloudInitConfigured := spec.CloudInit.SecureSecretsBackend != "" || spec.CloudInit.InsecureSkipSecretsManager if cloudInitConfigured && spec.Ignition != nil { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "cloudInit"), diff --git a/api/v1beta1/s3bucket.go b/api/v1beta1/s3bucket.go index 4a1c0a4358..27cb7c24e0 100644 --- a/api/v1beta1/s3bucket.go +++ b/api/v1beta1/s3bucket.go @@ -21,6 +21,8 @@ import ( "net" "k8s.io/apimachinery/pkg/util/validation/field" + + "sigs.k8s.io/cluster-api-provider-aws/feature" ) // Validate validates S3Bucket fields. @@ -35,6 +37,12 @@ func (b *S3Bucket) Validate() []*field.Error { errs = append(errs, field.Required(field.NewPath("spec", "s3Bucket", "name"), "can't be empty")) } + // Feature gate is not enabled but ignition is enabled then send a forbidden error. + if !feature.Gates.Enabled(feature.BootstrapFormatIgnition) { + errs = append(errs, field.Forbidden(field.NewPath("spec", "s3Bucket"), + "can be set only if the BootstrapFormatIgnition feature gate is enabled")) + } + if b.ControlPlaneIAMInstanceProfile == "" { errs = append(errs, field.Required(field.NewPath("spec", "s3Bucket", "controlPlaneIAMInstanceProfiles"), "can't be empty")) diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 4c7e46503a..e209800fec 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -19,7 +19,7 @@ spec: containers: - args: - "--leader-elect" - - "--feature-gates=EKS=${CAPA_EKS:=true},EKSEnableIAM=${CAPA_EKS_IAM:=false},EKSAllowAddRoles=${CAPA_EKS_ADD_ROLES:=false},EKSFargate=${EXP_EKS_FARGATE:=false},MachinePool=${EXP_MACHINE_POOL:=false},EventBridgeInstanceState=${EVENT_BRIDGE_INSTANCE_STATE:=false},AutoControllerIdentityCreator=${AUTO_CONTROLLER_IDENTITY_CREATOR:=true}" + - "--feature-gates=EKS=${CAPA_EKS:=true},EKSEnableIAM=${CAPA_EKS_IAM:=false},EKSAllowAddRoles=${CAPA_EKS_ADD_ROLES:=false},EKSFargate=${EXP_EKS_FARGATE:=false},MachinePool=${EXP_MACHINE_POOL:=false},EventBridgeInstanceState=${EVENT_BRIDGE_INSTANCE_STATE:=false},AutoControllerIdentityCreator=${AUTO_CONTROLLER_IDENTITY_CREATOR:=true},BootstrapFormatIgnition=${EXP_BOOTSTRAP_FORMAT_IGNITION:=false}" - "--v=${CAPA_LOGLEVEL:=0}" - "--metrics-bind-addr=127.0.0.1:8080" image: controller:latest diff --git a/docs/book/src/development/tilt-setup.md b/docs/book/src/development/tilt-setup.md index c39781e374..49aa573d43 100644 --- a/docs/book/src/development/tilt-setup.md +++ b/docs/book/src/development/tilt-setup.md @@ -56,7 +56,8 @@ Next, create a `tilt-settings.json` file and place it in your local copy of `clu "AWS_B64ENCODED_CREDENTIALS": "W2RlZmFZSZnRg==", "EXP_EKS_FARGATE": "false", "CAPA_EKS_IAM": "false", - "CAPA_EKS_ADD_ROLES": "false" + "CAPA_EKS_ADD_ROLES": "false", + "EXP_BOOTSTRAP_FORMAT_IGNITION": "true" }, "extra_args": { "aws": ["--v=2"] @@ -186,7 +187,7 @@ export EKS_KUBERNETES_VERSION=v1.15 **Create CAPA managed workload cluster:** ```bash -cat templates/cluster-template.yaml +cat templates/cluster-template.yaml cat templates/cluster-template.yaml | $HOME/go/bin/envsubst > test-cluster.yaml kubectl apply -f test-cluster.yaml ``` @@ -194,7 +195,7 @@ kubectl apply -f test-cluster.yaml **Create EKS workload cluster:** ```bash -cat templates/cluster-template-eks.yaml +cat templates/cluster-template-eks.yaml cat templates/cluster-template-eks.yaml | $HOME/go/bin/envsubst > test-cluster.yaml kubectl apply -f test-cluster.yaml ``` diff --git a/feature/feature.go b/feature/feature.go index 0ed4934a7b..7f997b3431 100644 --- a/feature/feature.go +++ b/feature/feature.go @@ -62,6 +62,9 @@ const ( // owner: @sedefsavas // alpha: v0.6 AutoControllerIdentityCreator featuregate.Feature = "AutoControllerIdentityCreator" + + // BootstrapFormatIgnition will allow an user to enable alternate machine bootstrap format, viz. Ignition. + BootstrapFormatIgnition featuregate.Feature = "BootstrapFormatIgnition" ) func init() { @@ -79,4 +82,5 @@ var defaultCAPAFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ EventBridgeInstanceState: {Default: false, PreRelease: featuregate.Alpha}, MachinePool: {Default: false, PreRelease: featuregate.Alpha}, AutoControllerIdentityCreator: {Default: true, PreRelease: featuregate.Alpha}, + BootstrapFormatIgnition: {Default: false, PreRelease: featuregate.Alpha}, } diff --git a/main.go b/main.go index 1149a49069..5d35ff9b8b 100644 --- a/main.go +++ b/main.go @@ -392,6 +392,10 @@ func enableGates(ctx context.Context, mgr ctrl.Manager, awsServiceEndpoints []sc os.Exit(1) } } + + if feature.Gates.Enabled(feature.BootstrapFormatIgnition) { + setupLog.Info("Enabling Ignition support for machine bootstrap data") + } } func initFlags(fs *pflag.FlagSet) { fs.StringVar( diff --git a/test/e2e/data/e2e_conf.yaml b/test/e2e/data/e2e_conf.yaml index 81334aa65f..e5212cb88f 100644 --- a/test/e2e/data/e2e_conf.yaml +++ b/test/e2e/data/e2e_conf.yaml @@ -283,6 +283,7 @@ variables: # INIT_WITH_KUBERNETES_VERSION are only used by the clusterctl upgrade test to initialize # the management cluster to be upgraded. INIT_WITH_KUBERNETES_VERSION: "v1.21.6" + EXP_BOOTSTRAP_FORMAT_IGNITION: "true" intervals: default/wait-cluster: ["30m", "10s"] From 9502110f4bbd6a751abd8cf89c50605d67139f46 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 4 Jan 2022 02:00:44 +0100 Subject: [PATCH 10/12] test/e2e/data/e2e_conf.yaml: enable Ignition feature gate Signed-off-by: Mateusz Gozdek --- test/e2e/data/e2e_conf.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/data/e2e_conf.yaml b/test/e2e/data/e2e_conf.yaml index e5212cb88f..f09f62f65b 100644 --- a/test/e2e/data/e2e_conf.yaml +++ b/test/e2e/data/e2e_conf.yaml @@ -284,6 +284,7 @@ variables: # the management cluster to be upgraded. INIT_WITH_KUBERNETES_VERSION: "v1.21.6" EXP_BOOTSTRAP_FORMAT_IGNITION: "true" + EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION: "true" intervals: default/wait-cluster: ["30m", "10s"] From 933a0e4fa37bc7635e8a2a5d15b63ececbc67676 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Fri, 25 Mar 2022 13:43:19 +0100 Subject: [PATCH 11/12] Add S3 policy as part of the release Mainly so it can be referenced in the book. Signed-off-by: Mateusz Gozdek --- Makefile | 5 ++++- hack/s3-clusterawsadm-config.yaml | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 hack/s3-clusterawsadm-config.yaml diff --git a/Makefile b/Makefile index e6eb4b7cd8..e7e9e36474 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ RELEASE_TAG ?= $(shell git describe --abbrev=0 2>/dev/null) PULL_BASE_REF ?= $(RELEASE_TAG) # PULL_BASE_REF will be provided by Prow RELEASE_ALIAS_TAG ?= $(PULL_BASE_REF) RELEASE_DIR := out -RELEASE_POLICIES := $(RELEASE_DIR)/AWSIAMManagedPolicyControllers.json $(RELEASE_DIR)/AWSIAMManagedPolicyControllersWithEKS.json $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderControlPlane.json $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderNodes.json +RELEASE_POLICIES := $(RELEASE_DIR)/AWSIAMManagedPolicyControllers.json $(RELEASE_DIR)/AWSIAMManagedPolicyControllersWithEKS.json $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderControlPlane.json $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderNodes.json $(RELEASE_DIR)/AWSIAMManagedPolicyControllersWithS3.json BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) # image name used to build the cmd/clusterawsadm @@ -524,6 +524,9 @@ $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderControlPlane.json: $(RELEASE_DIR) $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderNodes.json: $(RELEASE_DIR) $(CLUSTERAWSADM_SRCS) go run ./cmd/clusterawsadm bootstrap iam print-policy --document AWSIAMManagedPolicyCloudProviderNodes > $(RELEASE_DIR)/AWSIAMManagedPolicyCloudProviderNodes.json +$(RELEASE_DIR)/AWSIAMManagedPolicyControllersWithS3.json: $(RELEASE_DIR) $(CLUSTERAWSADM_SRCS) + go run ./cmd/clusterawsadm bootstrap iam print-policy --document AWSIAMManagedPolicyControllers --config hack/s3-clusterawsadm-config.yaml > $@ + .PHONY: release-manifests release-manifests: ## Release manifest files $(MAKE) $(RELEASE_DIR)/$(CORE_MANIFEST_FILE).yaml TAG=$(RELEASE_TAG) PULL_POLICY=IfNotPresent diff --git a/hack/s3-clusterawsadm-config.yaml b/hack/s3-clusterawsadm-config.yaml new file mode 100644 index 0000000000..9cde818d9c --- /dev/null +++ b/hack/s3-clusterawsadm-config.yaml @@ -0,0 +1,5 @@ +apiVersion: bootstrap.aws.infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSIAMConfiguration +spec: + s3Buckets: + enable: true From 0db23d4c94e18c16ef0222399f911599b507f2be Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Fri, 25 Mar 2022 13:44:08 +0100 Subject: [PATCH 12/12] docs/book/src: add Ignition support documentation Signed-off-by: Mateusz Gozdek --- docs/book/src/SUMMARY_PREFIX.md | 1 + docs/book/src/crd/index.md | 249 +++++++++++++++++++++++ docs/book/src/topics/iam-permissions.md | 5 + docs/book/src/topics/ignition-support.md | 130 ++++++++++++ 4 files changed, 385 insertions(+) create mode 100644 docs/book/src/topics/ignition-support.md diff --git a/docs/book/src/SUMMARY_PREFIX.md b/docs/book/src/SUMMARY_PREFIX.md index 0b67fa99a4..d291564027 100644 --- a/docs/book/src/SUMMARY_PREFIX.md +++ b/docs/book/src/SUMMARY_PREFIX.md @@ -31,3 +31,4 @@ - [Userdata Privacy](./topics/userdata-privacy.md) - [Troubleshooting](./topics/troubleshooting.md) - [IAM Permissions Used](./topics/iam-permissions.md) + - [Ignition support](./topics/ignition-support.md) diff --git a/docs/book/src/crd/index.md b/docs/book/src/crd/index.md index 1fa15f1260..7b7e4fef85 100644 --- a/docs/book/src/crd/index.md +++ b/docs/book/src/crd/index.md @@ -1218,6 +1218,22 @@ Parameter Storage policies. By default or with the value of secrets-manager, will generate AWS Secrets Manager policies instead.

+ + +s3Buckets
+ + +S3Buckets + + + + +(Optional) +

S3Buckets, when enabled, will add controller nodes permissions to +create S3 Buckets for workload clusters. +TODO: This field could be a pointer, but it seems it breaks setting default values?

+ + @@ -1401,6 +1417,22 @@ Parameter Storage policies. By default or with the value of secrets-manager, will generate AWS Secrets Manager policies instead.

+ + +s3Buckets
+ + +S3Buckets + + + + +(Optional) +

S3Buckets, when enabled, will add controller nodes permissions to +create S3 Buckets for workload clusters. +TODO: This field could be a pointer, but it seems it breaks setting default values?

+ +

AWSIAMRoleSpec @@ -1891,6 +1923,48 @@ EC2 container registry

+

S3Buckets +

+

+(Appears on:AWSIAMConfigurationSpec) +

+

+

S3Buckets controls the configuration of the AWS IAM role for S3 buckets +which can be created for storing bootstrap data for nodes requiring it.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+enable
+ +bool + +
+

Enable controls whether permissions are granted to manage S3 buckets.

+
+namePrefix
+ +string + +
+

NamePrefix will be prepended to every AWS IAM role bucket name. Defaults to “cluster-api-provider-aws-”. +AWSCluster S3 Bucket name must be prefixed with the same prefix.

+

bootstrap.cluster.x-k8s.io/v1alpha4

Resource Types: @@ -13534,6 +13608,23 @@ AWSIdentityReference

IdentityRef is a reference to a identity to be used when reconciling this cluster

+ + +s3Bucket
+ + +S3Bucket + + + + +(Optional) +

S3Bucket contains options to configure a supporting S3 bucket for this +cluster - currently used for nodes requiring Ignition +(https://coreos.github.io/ignition/) for bootstrapping (requires +BootstrapFormatIgnition feature flag to be enabled).

+ + @@ -14049,6 +14140,23 @@ AWSIdentityReference

IdentityRef is a reference to a identity to be used when reconciling this cluster

+ + +s3Bucket
+ + +S3Bucket + + + + +(Optional) +

S3Bucket contains options to configure a supporting S3 bucket for this +cluster - currently used for nodes requiring Ignition +(https://coreos.github.io/ignition/) for bootstrapping (requires +BootstrapFormatIgnition feature flag to be enabled).

+ +

AWSClusterStaticIdentity @@ -14512,6 +14620,23 @@ AWSIdentityReference

IdentityRef is a reference to a identity to be used when reconciling this cluster

+ + +s3Bucket
+ + +S3Bucket + + + + +(Optional) +

S3Bucket contains options to configure a supporting S3 bucket for this +cluster - currently used for nodes requiring Ignition +(https://coreos.github.io/ignition/) for bootstrapping (requires +BootstrapFormatIgnition feature flag to be enabled).

+ + @@ -15005,6 +15130,20 @@ CloudInit is used.

+ignition
+ + +Ignition + + + + +(Optional) +

Ignition defined options related to the bootstrapping systems where Ignition is used.

+ + + + spotMarketOptions
@@ -15331,6 +15470,20 @@ CloudInit is used.

+ignition
+ +
+Ignition + + + + +(Optional) +

Ignition defined options related to the bootstrapping systems where Ignition is used.

+ + + + spotMarketOptions
@@ -15861,6 +16014,20 @@ CloudInit is used.

+ignition
+ +
+Ignition + + + + +(Optional) +

Ignition defined options related to the bootstrapping systems where Ignition is used.

+ + + + spotMarketOptions
@@ -16834,6 +17001,36 @@ string +

Ignition +

+

+(Appears on:AWSMachineSpec) +

+

+

Ignition defines options related to the bootstrapping systems where Ignition is used.

+

+ + + + + + + + + + + + + +
FieldDescription
+version
+ +string + +
+(Optional) +

Version defines which version of Ignition will be used to generate bootstrap data.

+

IngressRule

@@ -17355,6 +17552,58 @@ string +

S3Bucket +

+

+(Appears on:AWSClusterSpec) +

+

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+controlPlaneIAMInstanceProfile
+ +string + +
+

ControlPlaneIAMInstanceProfile is a name of the IAMInstanceProfile, which will be allowed +to read control-plane node bootstrap data from S3 Bucket.

+
+nodesIAMInstanceProfiles
+ +[]string + +
+

NodesIAMInstanceProfiles is a list of IAM instance profiles, which will be allowed to read +worker nodes bootstrap data from S3 Bucket.

+
+name
+ +string + +
+

Name defines name of S3 Bucket to be created.

+

SecretBackend (string alias)

diff --git a/docs/book/src/topics/iam-permissions.md b/docs/book/src/topics/iam-permissions.md index 3bf7931af5..217b9702fc 100644 --- a/docs/book/src/topics/iam-permissions.md +++ b/docs/book/src/topics/iam-permissions.md @@ -26,6 +26,11 @@ and `control-plane.cluster-api-provider-aws.sigs.k8s.io` IAM roles. {{#include ../../../../out/AWSIAMManagedPolicyControllersWithEKS.json}} ``` +### With S3 Support +``` json +{{#include ../../../../out/AWSIAMManagedPolicyControllersWithS3.json}} +``` + ## Required by the Kubernetes AWS Cloud Provider These permissions are used by the Kubernetes AWS Cloud Provider. If you are diff --git a/docs/book/src/topics/ignition-support.md b/docs/book/src/topics/ignition-support.md new file mode 100644 index 0000000000..12517df6e7 --- /dev/null +++ b/docs/book/src/topics/ignition-support.md @@ -0,0 +1,130 @@ +# Ignition support + +- **Feature status:** Experimental +- **Feature gate:** BootstrapFormatIgnition=true + +The default configuration engine for bootstrapping workload cluster machines is [cloud-init][cloud-init]. +**Ignition** is an alternative engine used by Linux distributions such as [Flatcar Container Linux][flatcar] +and [Fedora CoreOS][fedora-coreos] and therefore should be used when choosing an Ignition-based distribution as +the underlying OS for workload clusters. + +

+ +This document explains how Ignition support works. + +For more generic information, see [Cluster API documentation on Ignition Bootstrap configuration][cabpk]. + +## Overview + +By default machine controller stores EC2 instance user data using SSM to store it encrypted, which underneath +use multi part mime types, which are [unlikely to be supported](https://github.com/coreos/ignition/issues/1072) +by Ignition. + +EC2 user data is also limited to 64 KB, which is often not enough to provision Kubernetes controlplane because +of the size of required certificates and configuration files. + +To address those limitations CAPA can create and use S3 Bucket to store encrypted user data, which will be then +pulled by the instances during provisioning. + +## IAM Permissions + +To manage S3 Buckets and objects inside them, CAPA controllers require additional IAM permissions. + +If you use `clusterawsadm` for managing the IAM roles, you can use the configuration below to create S3-related +IAM permissions. + +``` yaml +apiVersion: bootstrap.aws.infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSIAMConfiguration +spec: + s3Buckets: + enable: true +``` + +See [Using clusterawsadm to fulfill prerequisites](./using-clusterawsadm-to-fulfill-prerequisites.md) for more +details. + +## Enabling EXP_BOOTSTRAP_FORMAT_IGNITION feature gate + +When deploying CAPA using `clusterctl`, make sure you set `BOOTSTRAP_FORMAT_IGNITION=true` and +`EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true `environment variables to enable experimental Ignition bootstrap +support. + +``` sh +# Enable the feature gates controlling Ignition bootstrap. +export EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true # Used by the kubeadm bootstrap provider. +export EXP_BOOTSTRAP_FORMAT_IGNITION=true # Used by the AWS provider. + +# Initialize the management cluster. +clusterctl init --infrastructure aws +``` + +## Bucket and object management + +When you want to use Ignition user data format for you machines, you need to configure your cluster to +specify which S3 bucket to use. Controller will then make sure that the bucket exists and that required policies +are in place. + +See the configuration snippet below to learn how to configure `AWSCluster` to manage S3 bucket. + +``` yaml +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSCluster +spec: + s3Bucket: + controlPlaneIAMInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io + name: cluster-api-provider-aws-unique-suffix + nodesIAMInstanceProfiles: + - nodes.cluster-api-provider-aws.sigs.k8s.io +``` + +Buckets are safe to be reused between clusters. + +After successful machine provisioning, bootstrap data is removed from the bucket. + +During cluster removal, if S3 bucket is empty, it will be removed as well. + +## Bucket naming + +Bucket naming must follow [S3 Bucket naming rules][bucket-naming-rules]. + +In addition, by default `clusterawsadm` creates IAM roles to only allow interacting with buckets with +`cluster-api-provider-aws-` prefix to reduce the permissions of CAPA controller, so all bucket names should +use this prefix. + +To change it, use `spec.s3Buckets.namePrefix` field in `AWSIAMConfiguration`. + +```yaml +apiVersion: bootstrap.aws.infrastructure.cluster.x-k8s.io/v1beta1 +kind: AWSIAMConfiguration +spec: + s3Buckets: + namePrefix: my-custom-secure-bucket-prefix- +``` + +## Supported bootstrap providers + +At the moment only [CABPK][cabpk] is known to support producing bootstrap data in Ignition format. + +## Trying it out + +If you want to test Ignition support, use `flatcar` cluster flavor. + +## Other bootstrap providers + +If you want to use Ignition support with custom bootstrap provider which supports producing Ignition bootstrap +data, ensure that bootstrap provider sets the `format` field in machine bootstrap secret to `ignition`. This +information is used by the machine controller to determine which user data format to use for the instances. + +[bucket-naming-rules]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html +[cloud-init]: https://cloudinit.readthedocs.io/ +[flatcar]: https://www.flatcar-linux.org/docs/latest/provisioning/ignition/ +[fedora-coreos]: https://docs.fedoraproject.org/en-US/fedora-coreos/producing-ign/ +[cabpk]: https://cluster-api.sigs.k8s.io/tasks/experimental-features/ignition.html