diff --git a/deploy/crds/noobaa.io_noobaaaccounts.yaml b/deploy/crds/noobaa.io_noobaaaccounts.yaml index 2015619f2..360905e08 100644 --- a/deploy/crds/noobaa.io_noobaaaccounts.yaml +++ b/deploy/crds/noobaa.io_noobaaaccounts.yaml @@ -50,6 +50,10 @@ spec: description: DefaultResource specifies which backingstore this account will use to create new buckets type: string + force_md5_etag: + description: ForceMd5Etag specifies whether MD5 Etags should be calculated + for the account or not + type: boolean nsfs_account_config: description: NsfsAccountConfig specifies the configurations on Namespace FS diff --git a/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go b/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go index e77def6ea..e54b35969 100644 --- a/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go +++ b/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go @@ -66,6 +66,10 @@ type NooBaaAccountSpec struct { // DefaultResource specifies which backingstore this account will use to create new buckets // +optional DefaultResource string `json:"default_resource,omitempty"` + + // ForceMd5Etag specifies whether MD5 Etags should be calculated for the account or not + // +optional + ForceMd5Etag bool `json:"force_md5_etag,omitempty"` } // AccountNsfsConfig is the configuration of NSFS of CreateAccountParams diff --git a/pkg/bucket/bucket.go b/pkg/bucket/bucket.go index e28c79d36..5b164737d 100644 --- a/pkg/bucket/bucket.go +++ b/pkg/bucket/bucket.go @@ -20,6 +20,7 @@ func Cmd() *cobra.Command { } cmd.AddCommand( CmdCreate(), + CmdUpdate(), CmdDelete(), CmdStatus(), CmdList(), @@ -34,6 +35,18 @@ func CmdCreate() *cobra.Command { Short: "Create a NooBaa bucket", Run: RunCreate, } + cmd.Flags().Bool("force_md5_etag", false, "This flag enables md5 etag calculation for bucket") + return cmd +} + +// CmdUpdate returns a CLI command +func CmdUpdate() *cobra.Command { + cmd := &cobra.Command{ + Use: "update ", + Short: "Update a NooBaa bucket", + Run: RunUpdate, + } + cmd.Flags().Bool("force_md5_etag", false, "This flag enables md5 etag calculation for bucket") return cmd } @@ -82,12 +95,31 @@ func RunCreate(cmd *cobra.Command, args []string) { log.Fatal(fmt.Errorf("Failed to get default bucketclass with error: %v", err)) } - tierName, err := bucketclass.CreateTieringStructure(*bucketClass.Spec.PlacementPolicy, bucketName, nbClient); + tierName, err := bucketclass.CreateTieringStructure(*bucketClass.Spec.PlacementPolicy, bucketName, nbClient) if err != nil { log.Fatal(fmt.Errorf("CreateTieringStructure for PlacementPolicy failed to create policy %q with error: %v", tierName, err)) } - err = nbClient.CreateBucketAPI(nb.CreateBucketParams{Name: bucketName, Tiering: tierName}) + forceMd5Etag, _ := cmd.Flags().GetBool("force_md5_etag") + + err = nbClient.CreateBucketAPI(nb.CreateBucketParams{Name: bucketName, Tiering: tierName, ForceMd5Etag: forceMd5Etag}) + if err != nil { + log.Fatal(err) + } +} + +// RunUpdate runs a CLI command +func RunUpdate(cmd *cobra.Command, args []string) { + log := util.Logger() + if len(args) != 1 || args[0] == "" { + log.Fatalf(`Missing expected arguments: %s`, cmd.UsageString()) + } + bucketName := args[0] + nbClient := system.GetNBClient() + + forceMd5Etag, _ := cmd.Flags().GetBool("force_md5_etag") + + err := nbClient.UpdateBucketAPI(nb.CreateBucketParams{Name: bucketName, ForceMd5Etag: forceMd5Etag}) if err != nil { log.Fatal(err) } @@ -129,6 +161,7 @@ func RunStatus(cmd *cobra.Command, args []string) { } fmt.Printf(" %-22s : %s\n", "Type", b.BucketType) fmt.Printf(" %-22s : %s\n", "Mode", b.Mode) + fmt.Printf(" %-22s : %t\n", "Force Md5 Etag", b.ForceMd5Etag) if b.PolicyModes != nil { fmt.Printf(" %-22s : %s\n", "ResiliencyStatus", b.PolicyModes.ResiliencyStatus) fmt.Printf(" %-22s : %s\n", "QuotaStatus", b.PolicyModes.QuotaStatus) diff --git a/pkg/bundle/deploy.go b/pkg/bundle/deploy.go index 19f6c3841..9ccbd02e0 100644 --- a/pkg/bundle/deploy.go +++ b/pkg/bundle/deploy.go @@ -1282,7 +1282,7 @@ spec: status: {} ` -const Sha256_deploy_crds_noobaa_io_noobaaaccounts_yaml = "3149151150a7deefb0922e2dc20988c292935c9adbc2deda65b191cc44909a38" +const Sha256_deploy_crds_noobaa_io_noobaaaccounts_yaml = "27b83df8c18c92d9ad5d1d759234dba67011ec003c02323464ebd8569a7d548d" const File_deploy_crds_noobaa_io_noobaaaccounts_yaml = `--- apiVersion: apiextensions.k8s.io/v1 @@ -1336,6 +1336,10 @@ spec: description: DefaultResource specifies which backingstore this account will use to create new buckets type: string + force_md5_etag: + description: ForceMd5Etag specifies whether MD5 Etags should be calculated + for the account or not + type: boolean nsfs_account_config: description: NsfsAccountConfig specifies the configurations on Namespace FS diff --git a/pkg/nb/types.go b/pkg/nb/types.go index 3b21925e5..0d3a49c3b 100644 --- a/pkg/nb/types.go +++ b/pkg/nb/types.go @@ -66,10 +66,11 @@ type AccountInfo struct { // BucketInfo is a struct of bucket info returned by the API type BucketInfo struct { - Name string `json:"name"` - BucketType string `json:"bucket_type"` - Mode string `json:"mode"` - Undeletable string `json:"undeletable"` + Name string `json:"name"` + BucketType string `json:"bucket_type"` + Mode string `json:"mode"` + Undeletable string `json:"undeletable"` + ForceMd5Etag bool `json:"force_md5_etag"` BucketClaim *BucketClaimInfo `json:"bucket_claim,omitempty"` Tiering *TieringPolicyInfo `json:"tiering,omitempty"` @@ -337,11 +338,12 @@ type CreateSystemReply struct { // CreateBucketParams is the params of bucket_api.create_bucket() type CreateBucketParams struct { - Name string `json:"name"` - Tiering string `json:"tiering,omitempty"` - BucketClaim *BucketClaimInfo `json:"bucket_claim,omitempty"` - Namespace *NamespaceBucketInfo `json:"namespace,omitempty"` - Quota *QuotaConfig `json:"quota,omitempty"` + Name string `json:"name"` + Tiering string `json:"tiering,omitempty"` + ForceMd5Etag bool `json:"force_md5_etag,omitempty"` + BucketClaim *BucketClaimInfo `json:"bucket_claim,omitempty"` + Namespace *NamespaceBucketInfo `json:"namespace,omitempty"` + Quota *QuotaConfig `json:"quota,omitempty"` } // QuotaConfig quota configuration @@ -409,6 +411,7 @@ type CreateAccountParams struct { S3Access bool `json:"s3_access"` AllowBucketCreate bool `json:"allow_bucket_creation"` DefaultResource string `json:"default_resource,omitempty"` + ForceMd5Etag bool `json:"force_md5_etag,omitempty"` BucketClaimOwner string `json:"bucket_claim_owner,omitempty"` NsfsAccountConfig *nbv1.AccountNsfsConfig `json:"nsfs_account_config,omitempty"` } @@ -573,6 +576,7 @@ type UpdateAccountS3AccessParams struct { Email string `json:"email"` S3Access bool `json:"s3_access"` DefaultResource *string `json:"default_resource,omitempty"` + ForceMd5Etag bool `json:"force_md5_etag,omitempty"` AllowBucketCreation *bool `json:"allow_bucket_creation,omitempty"` NsfsAccountConfig *nbv1.AccountNsfsConfig `json:"nsfs_account_config,omitempty"` } diff --git a/pkg/noobaaaccount/noobaaaccount.go b/pkg/noobaaaccount/noobaaaccount.go index 795173e29..32628de82 100644 --- a/pkg/noobaaaccount/noobaaaccount.go +++ b/pkg/noobaaaccount/noobaaaccount.go @@ -56,6 +56,7 @@ func CmdCreate() *cobra.Command { "Should this account be allowed to create new buckets") cmd.Flags().String("default_resource", "", "Set the default resource, on which new buckets will be created") cmd.Flags().Bool("nsfs_account_config", false, "This flag is for creating nsfs account") + cmd.Flags().Bool("force_md5_etag", false, "This flag enables md5 etag calculation for account") cmd.Flags().Int("uid", -1, "Set the nsfs uid") cmd.Flags().Int("gid", -1, "Set the nsfs gid") cmd.Flags().String("new_buckets_path", "/", "Change the path where new buckets will be created") @@ -161,6 +162,7 @@ func RunCreate(cmd *cobra.Command, args []string) { defaultResource, _ := cmd.Flags().GetString("default_resource") nsfsAccountConfig, _ := cmd.Flags().GetBool("nsfs_account_config") + forceMd5Etag, _ := cmd.Flags().GetBool("force_md5_etag") newBucketsPath, _ := cmd.Flags().GetString("new_buckets_path") nsfsOnly, _ := cmd.Flags().GetBool("nsfs_only") @@ -176,6 +178,7 @@ func RunCreate(cmd *cobra.Command, args []string) { noobaaAccount.Name = name noobaaAccount.Namespace = options.Namespace noobaaAccount.Spec.AllowBucketCreate = allowBucketCreate + noobaaAccount.Spec.ForceMd5Etag = forceMd5Etag if nsfsAccountConfig { nsfsUID := util.GetFlagIntOrPrompt(cmd, "uid") @@ -249,6 +252,7 @@ func RunUpdate(cmd *cobra.Command, args []string) { name := args[0] newDefaultResource := util.GetFlagStringOrPrompt(cmd, "new_default_resource") + forceMd5Etag, _ := cmd.Flags().GetBool("force_md5_etag") o := util.KubeObject(bundle.File_deploy_crds_noobaa_io_v1alpha1_noobaaaccount_cr_yaml) noobaaAccount := o.(*nbv1.NooBaaAccount) @@ -276,6 +280,7 @@ func RunUpdate(cmd *cobra.Command, args []string) { } noobaaAccount.Spec.DefaultResource = newDefaultResource + noobaaAccount.Spec.ForceMd5Etag = forceMd5Etag if !util.KubeUpdate(noobaaAccount) { log.Fatalf(`❌ Unable to update account`) @@ -306,6 +311,7 @@ func RunUpdate(cmd *cobra.Command, args []string) { updateAccountS3AccessParams := nb.UpdateAccountS3AccessParams{ Email: name, DefaultResource: &newDefaultResource, + ForceMd5Etag: forceMd5Etag, S3Access: accountInfo.HasS3Access, } @@ -579,7 +585,7 @@ func RunReconcile(cmd *cobra.Command, args []string) { noobaaAccountName := args[0] klient := util.KubeClient() interval := time.Duration(3) - util.Panic(wait.PollUntilContextCancel(ctx,interval*time.Second, true, func(ctx context.Context) (bool, error) { + util.Panic(wait.PollUntilContextCancel(ctx, interval*time.Second, true, func(ctx context.Context) (bool, error) { req := reconcile.Request{ NamespacedName: types.NamespacedName{ Namespace: options.Namespace, diff --git a/pkg/options/options.go b/pkg/options/options.go index 6f1c88c4c..98f8ebbb0 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -30,7 +30,7 @@ const ( // ContainerImageRepo is the repo of the default image url ContainerImageRepo = "noobaa-core" // ContainerImageTag is the tag of the default image url - ContainerImageTag = "master-20230830" + ContainerImageTag = "master-20230920" // ContainerImageSemverLowerBound is the lower bound for supported image versions ContainerImageSemverLowerBound = "5.0.0" // ContainerImageSemverUpperBound is the upper bound for supported image versions