diff --git a/docs/resources/obs_bucket.md b/docs/resources/obs_bucket.md index 705bc84e..7758dd3f 100644 --- a/docs/resources/obs_bucket.md +++ b/docs/resources/obs_bucket.md @@ -33,6 +33,9 @@ resource "flexibleengine_obs_bucket" "b" { ### Enable Logging ```hcl +# The agency must be an OBS cloud service agency with the `PutObject` permission. +variable "agency_name" {} + resource "flexibleengine_obs_bucket" "log_bucket" { bucket = "my-tf-log-bucket" acl = "log-delivery-write" @@ -45,6 +48,7 @@ resource "flexibleengine_obs_bucket" "b" { logging { target_bucket = flexibleengine_obs_bucket.log_bucket.id target_prefix = "log/" + agency = var.agency_name } } ``` @@ -165,7 +169,10 @@ The following arguments are supported: * `encryption` - (Optional, Bool) Whether enable default server-side encryption of the bucket in SSE-KMS mode. -* `kms_key_id` - (Optional, String) Specifies the ID of a kms key. If omitted, the default master key will be used. +* `kms_key_id` - (Optional, String) Specifies the ID of a KMS key. If omitted, the default master key will be used. + +* `kms_key_project_id` - (Optional, String) Specifies the project ID to which the KMS key belongs. This field is valid + only when `kms_key_id` is specified. * `logging` - (Optional, List) A settings of bucket logging. The [logging](#obs_logging) object structure is documented below. @@ -192,8 +199,15 @@ The `logging` object supports: * `target_bucket` - (Required, String) The name of the bucket that will receive the log objects. The acl policy of the target bucket should be `log-delivery-write`. + * `target_prefix` - (Optional, String) To specify a key prefix for log objects. +* `agency` - (Required, String) Specifies the IAM agency of OBS cloud service. + + -> The IAM agency requires the `PutObject` permission for the target bucket. If default encryption is enabled for the + target bucket, the agency also requires the `KMS Administrator` permission in the region where the target bucket is + located. + The `website` object supports: diff --git a/flexibleengine/resource_flexibleengine_obs_bucket.go b/flexibleengine/resource_flexibleengine_obs_bucket.go index 4dda4487..5b8508f6 100644 --- a/flexibleengine/resource_flexibleengine_obs_bucket.go +++ b/flexibleengine/resource_flexibleengine_obs_bucket.go @@ -64,6 +64,12 @@ func resourceObsBucket() *schema.Resource { Optional: true, Default: "logs/", }, + "agency": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "schema: Required", + }, }, }, }, @@ -239,6 +245,11 @@ func resourceObsBucket() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "kms_key_project_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, "multi_az": { Type: schema.TypeBool, Optional: true, @@ -293,10 +304,15 @@ func resourceObsBucketCreate(d *schema.ResourceData, meta interface{}) error { } func resourceObsBucketUpdate(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) - obsClient, err := config.ObjectStorageClient(GetRegion(d, config)) + conf := meta.(*Config) + region := conf.GetRegion(d) + obsClient, err := conf.ObjectStorageClient(region) if err != nil { - return fmt.Errorf("Error creating FlexibleEngine OBS client: %s", err) + return fmt.Errorf("error creating OBS client: %s", err) + } + obsClientWithSignature, err := conf.ObjectStorageClientWithSignature(region) + if err != nil { + return fmt.Errorf("error creating OBS client with signature: %s", err) } log.Printf("[DEBUG] Update OBS bucket %s", d.Id()) @@ -318,14 +334,14 @@ func resourceObsBucketUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChanges("encryption", "kms_key_id") { - if err := resourceObsBucketEncryptionUpdate(obsClient, d); err != nil { + if d.HasChanges("encryption", "kms_key_id", "kms_key_project_id") { + if err := resourceObsBucketEncryptionUpdate(obsClientWithSignature, d); err != nil { return err } } if d.HasChange("logging") { - if err := resourceObsBucketLoggingUpdate(obsClient, d); err != nil { + if err := resourceObsBucketLoggingUpdate(obsClientWithSignature, d); err != nil { return err } } @@ -352,11 +368,15 @@ func resourceObsBucketUpdate(d *schema.ResourceData, meta interface{}) error { } func resourceObsBucketRead(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) - region := GetRegion(d, config) - obsClient, err := config.ObjectStorageClient(region) + conf := meta.(*Config) + region := conf.GetRegion(d) + obsClient, err := conf.ObjectStorageClient(region) if err != nil { - return fmt.Errorf("Error creating FlexibleEngine OBS client: %s", err) + return fmt.Errorf("error creating OBS client: %s", err) + } + obsClientWithSignature, err := conf.ObjectStorageClientWithSignature(region) + if err != nil { + return fmt.Errorf("error creating OBS client with signature: %s", err) } log.Printf("[DEBUG] Read OBS bucket: %s", d.Id()) @@ -394,12 +414,12 @@ func resourceObsBucketRead(d *schema.ResourceData, meta interface{}) error { } // Read the encryption configuration - if err := setObsBucketEncryption(obsClient, d); err != nil { + if err := setObsBucketEncryption(obsClientWithSignature, d); err != nil { return err } // Read the logging configuration - if err := setObsBucketLogging(obsClient, d); err != nil { + if err := setObsBucketLogging(obsClientWithSignature, d); err != nil { return err } @@ -548,6 +568,10 @@ func resourceObsBucketLoggingUpdate(obsClient *obs.ObsClient, d *schema.Resource if val := c["target_prefix"].(string); val != "" { loggingStatus.TargetPrefix = val } + + if val := c["agency"].(string); val != "" { + loggingStatus.Agency = val + } } log.Printf("[DEBUG] set logging of OBS bucket %s: %#v", bucket, loggingStatus) @@ -565,8 +589,11 @@ func resourceObsBucketEncryptionUpdate(obsClient *obs.ObsClient, d *schema.Resou if d.Get("encryption").(bool) { input := &obs.SetBucketEncryptionInput{} input.Bucket = bucket - input.SSEAlgorithm = obs.DEFAULT_SSE_KMS_ENCRYPTION - input.KMSMasterKeyID = d.Get("kms_key_id").(string) + input.SSEAlgorithm = obs.DEFAULT_SSE_KMS_ENCRYPTION_OBS + if raw, ok := d.GetOk("kms_key_id"); ok { + input.KMSMasterKeyID = raw.(string) + input.ProjectID = d.Get("kms_key_project_id").(string) + } log.Printf("[DEBUG] enable default encryption of OBS bucket %s: %#v", bucket, input) _, err := obsClient.SetBucketEncryption(input) @@ -905,6 +932,7 @@ func setObsBucketEncryption(obsClient *obs.ObsClient, d *schema.ResourceData) er if obsError.Code == "NoSuchEncryptionConfiguration" || obsError.Code == "FsNotSupport" { d.Set("encryption", false) d.Set("kms_key_id", nil) + d.Set("kms_key_project_id", nil) return nil } return fmt.Errorf("Error getting encryption configuration of OBS bucket %s: %s,\n Reason: %s", @@ -916,9 +944,11 @@ func setObsBucketEncryption(obsClient *obs.ObsClient, d *schema.ResourceData) er if output.SSEAlgorithm != "" { d.Set("encryption", true) d.Set("kms_key_id", output.KMSMasterKeyID) + d.Set("kms_key_project_id", output.ProjectID) } else { d.Set("encryption", false) d.Set("kms_key_id", nil) + d.Set("kms_key_project_id", nil) } return nil @@ -939,6 +969,9 @@ func setObsBucketLogging(obsClient *obs.ObsClient, d *schema.ResourceData) error if output.TargetPrefix != "" { logging["target_prefix"] = output.TargetPrefix } + if output.Agency != "" { + logging["agency"] = output.Agency + } lcList = append(lcList, logging) } log.Printf("[DEBUG] saving logging configuration of OBS bucket: %s: %#v", bucket, lcList) diff --git a/flexibleengine/resource_flexibleengine_obs_bucket_test.go b/flexibleengine/resource_flexibleengine_obs_bucket_test.go index a4b3b1db..5d5f590f 100644 --- a/flexibleengine/resource_flexibleengine_obs_bucket_test.go +++ b/flexibleengine/resource_flexibleengine_obs_bucket_test.go @@ -143,7 +143,7 @@ func TestAccObsBucket_logging(t *testing.T) { Config: testAccObsBucketConfigWithLogging(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckObsBucketExists(resourceName), - testAccCheckObsBucketLogging(resourceName, target_bucket, "log/"), + testAccCheckObsBucketLogging(resourceName, target_bucket, "log/", "OBS"), ), }, }, @@ -311,7 +311,7 @@ func testAccCheckObsBucketExists(n string) resource.TestCheckFunc { } } -func testAccCheckObsBucketLogging(name, target, prefix string) resource.TestCheckFunc { +func testAccCheckObsBucketLogging(name, target, prefix, agency string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -319,9 +319,9 @@ func testAccCheckObsBucketLogging(name, target, prefix string) resource.TestChec } config := testAccProvider.Meta().(*Config) - obsClient, err := config.ObjectStorageClient(OS_REGION_NAME) + obsClient, err := config.ObjectStorageClientWithSignature(OS_REGION_NAME) if err != nil { - return fmt.Errorf("Error creating FlexibleEngine OBS client: %s", err) + return fmt.Errorf("error creating OBS client with signature: %s", err) } output, err := obsClient.GetBucketLoggingConfiguration(rs.Primary.ID) @@ -337,6 +337,10 @@ func testAccCheckObsBucketLogging(name, target, prefix string) resource.TestChec return fmt.Errorf("%s.logging: Attribute 'target_prefix' expected %s, got %s", name, output.TargetPrefix, prefix) } + if output.Agency != agency { + return fmt.Errorf("%s.logging: Attribute 'agency' expected %s, got %s", + name, output.Agency, agency) + } return nil } @@ -430,6 +434,7 @@ resource "flexibleengine_obs_bucket" "bucket" { logging { target_bucket = flexibleengine_obs_bucket.log_bucket.id target_prefix = "log/" + agency = "OBS" # Make sure that the agency has the 'PutObject' permission. } } `, randInt, randInt)