diff --git a/docs/resources/cbr_policy_v3.md b/docs/resources/cbr_policy_v3.md index 7adb081e1..00b68ab99 100644 --- a/docs/resources/cbr_policy_v3.md +++ b/docs/resources/cbr_policy_v3.md @@ -37,54 +37,86 @@ resource "opentelekomcloud_cbr_policy_v3" "policy" { } ``` +### Create a replication policy (periodic backup) + +```hcl +variable "policy_name" {} +variable "destination_region" {} +variable "destination_project_id" {} + +resource "opentelekomcloud_cbr_policy_v3" "policy" { + name = var.policy_name + operation_type = "replication" + destination_region = var.destination_region + destination_project_id = var.destination_project_id + + trigger_pattern = ["FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU;BYHOUR=14;BYMINUTE=00"] + + operation_definition { + day_backups = 1 + week_backups = 2 + year_backups = 3 + month_backups = 4 + max_backups = 10 + timezone = "UTC+03:00" + } +} +``` + ## Argument reference The following arguments are supported: -* `enabled` - (Optional) Whether to enable the policy. Default value is `true`. +* `enabled` - (Optional, Bool) Whether to enable the policy. Default value is `true`. -* `name` - (Required) Specifies the policy name. The value consists of 1 to 64 characters +* `name` - (Required, String) Specifies the policy name. The value consists of 1 to 64 characters and can contain only letters, digits, underscores (_), and hyphens (-). -* `operation_definition` - (Optional) Scheduling parameter. See reference below. +* `destination_region` - (Optional, String) Specifies the name of the replication destination region, which is mandatory + for cross-region replication. Required if `operation_type` is `replication`. + +* `destination_project_id` - (Optional, String) Specifies the ID of the replication destination project, which is + mandatory for cross-region replication. Required if `operation_type` is `replication`. -* `operation_type` - (Required) Policy type. Enumeration values: `backup`, `replication`. +* `operation_definition` - (Optional, List) Scheduling parameter. See reference below. -* `trigger_pattern` - (Required) Scheduling rule. In the replication policy, you are advised +* `operation_type` - (Required, String) Policy type. Enumeration values: `backup`, `replication`. + +* `trigger_pattern` - (Required, String) Scheduling rule. In the replication policy, you are advised to set one time point for one day. A maximum of 24 rules can be configured. The scheduling rule complies with iCalendar RFC 2445, but it supports only parameters `FREQ`, `BYDAY`, `BYHOUR`, `BYMINUTE`, and `INTERVAL`. `FREQ` can be set only to `WEEKLY` and `DAILY`. The `operation_definition` block contains: -* `day_backups` - (Optional) Specifies the number of retained daily backups. The latest +* `day_backups` - (Optional, Int) Specifies the number of retained daily backups. The latest backup of each day is saved in the long term. This parameter can be effective together with the maximum number of retained backups specified by `max_backups`. The value ranges from `0` to `100`. If this parameter is configured, `timezone` is mandatory. -* `week_backups` - (Optional) Specifies the number of retained weekly backups. The latest +* `week_backups` - (Optional, Int) Specifies the number of retained weekly backups. The latest backup of each week is saved in the long term. This parameter can be effective together with the maximum number of retained backups specified by `max_backups`. The value ranges from `0` to `100`. If this parameter is configured, `timezone` is mandatory. -* `month_backups` - (Optional) Specifies the number of retained monthly backups. The latest +* `month_backups` - (Optional, Int) Specifies the number of retained monthly backups. The latest backup of each month is saved in the long term. This parameter can be effective together with the maximum number of retained backups specified by `max_backups`. The value ranges from `0` to `100`. If this parameter is configured, `timezone` is mandatory. -* `year_backups` - (Optional) Specifies the number of retained yearly backups. The latest +* `year_backups` - (Optional, Int) Specifies the number of retained yearly backups. The latest backup of each year is saved in the long term. This parameter can be effective together with the maximum number of retained backups specified by `max_backups`. The value ranges from `0` to `100`. If this parameter is configured, `timezone` is mandatory. -* `timezone` - (Required) Time zone where the user is located, for example, `UTC+00:00`. +* `timezone` - (Required, String) Time zone where the user is located, for example, `UTC+00:00`. -* `max_backups` - (Optional) Maximum number of retained backups. The value can be `-1` or ranges +* `max_backups` - (Optional, Int) Maximum number of retained backups. The value can be `-1` or ranges from `0` to `99999`. If the value is set to `-1`, the backups will not be cleared even though the configured retained backup quantity is exceeded. If this parameter and `retention_duration_days` are both left blank, the backups will be retained permanently. -* `retention_duration_days` - (Optional) Duration of retaining a backup, in days. +* `retention_duration_days` - (Optional, Int) Duration of retaining a backup, in days. The maximum value is `99999`. `-1` indicates that the backups will not be cleared based on the retention duration. If this parameter and `max_backups` are left blank at the same time, the backups will be retained permanently. @@ -102,3 +134,11 @@ The following attributes are exported: * `trigger_pattern` - See Argument Reference above. * `region` - Specifies the region of the CBRv3 policy. + +## Import + +Volumes can be imported using the `id`, e.g. + +```sh +terraform import opentelekomcloud_cbr_policy_v3.policy ea257959-eeb1-4c10-8d33-26f0409a766a +``` diff --git a/docs/resources/cbr_vault_v3.md b/docs/resources/cbr_vault_v3.md index d84a80b32..85ab1479f 100644 --- a/docs/resources/cbr_vault_v3.md +++ b/docs/resources/cbr_vault_v3.md @@ -265,8 +265,6 @@ The following arguments are supported: * `tags` - (Optional) Tag map. -* `enterprise_project_id` - (Optional) Enterprise project ID. The default value is `"0"`. - * `auto_bind` - (Optional) Whether automatic association is supported. * `bind_rules` - (Optional) Tag map, a rules for automatic association. You can only select tag keys and values from @@ -296,3 +294,11 @@ All above argument parameters can be exported as attribute parameters along with * `frozen_scene` - Scenario when an account is frozen. * `status` - Vault status. + +## Import + +Volumes can be imported using the `id`, e.g. + +```sh +terraform import opentelekomcloud_cbr_vault_v3.vault ea257959-eeb1-4c10-8d33-26f0409a766b +``` diff --git a/go.mod b/go.mod index 8f755e1a0..6fe233f90 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 github.com/mitchellh/go-homedir v1.1.0 - github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20240822122521-1a6812350bb6 + github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20240917133530-6be3493c387e github.com/unknwon/com v1.0.1 golang.org/x/crypto v0.21.0 golang.org/x/sync v0.1.0 diff --git a/go.sum b/go.sum index 5b5f26be5..0b35c9d23 100644 --- a/go.sum +++ b/go.sum @@ -158,6 +158,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20240822122521-1a6812350bb6 h1:PWNaTF7gibUvW2XtHzAn/GcT+6eZkRri3J68t9B7JI4= github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20240822122521-1a6812350bb6/go.mod h1:M1F6OfSRZRzAmAFKQqSLClX952at5hx5rHe4UTEykgg= +github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20240917133530-6be3493c387e h1:+P0HGo3zkkfCcnBGwecoLcqQZi3EsyKOaQZB2kXDn/g= +github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20240917133530-6be3493c387e/go.mod h1:M1F6OfSRZRzAmAFKQqSLClX952at5hx5rHe4UTEykgg= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_policy_v3_test.go b/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_policy_v3_test.go index b875ed619..8627a7a33 100644 --- a/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_policy_v3_test.go +++ b/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_policy_v3_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/opentelekomcloud/gophertelekomcloud/openstack/cbr/v3/policies" @@ -16,8 +17,17 @@ import ( const resourcePolicyName = "opentelekomcloud_cbr_policy_v3.policy" +func getPolicyResourceFunc(conf *cfg.Config, state *terraform.ResourceState) (interface{}, error) { + c, err := conf.CbrV3Client(env.OS_REGION_NAME) + if err != nil { + return nil, fmt.Errorf("error creating CBR v3 client: %s", err) + } + return policies.Get(c, state.Primary.ID) +} + func TestAccCBRPolicyV3_basic(t *testing.T) { var cbrPolicy policies.Policy + rc := common.InitResourceCheck(resourcePolicyName, &cbrPolicy, getPolicyResourceFunc) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -25,12 +35,12 @@ func TestAccCBRPolicyV3_basic(t *testing.T) { quotas.BookOne(t, quotas.CBRPolicy) }, ProviderFactories: common.TestAccProviderFactories, - CheckDestroy: testAccCheckCBRPolicyV3Destroy, + CheckDestroy: rc.CheckResourceDestroy(), Steps: []resource.TestStep{ { Config: testAccCBRPolicyV3Basic, Check: resource.ComposeTestCheckFunc( - testAccCheckCBRPolicyV3Exists(resourcePolicyName, &cbrPolicy), + rc.CheckResourceExists(), resource.TestCheckResourceAttr(resourcePolicyName, "name", "test-policy"), resource.TestCheckResourceAttr(resourcePolicyName, "operation_type", "backup"), resource.TestCheckResourceAttr(resourcePolicyName, "enabled", "true"), @@ -39,7 +49,7 @@ func TestAccCBRPolicyV3_basic(t *testing.T) { { Config: testAccCBRPolicyV3Update, Check: resource.ComposeTestCheckFunc( - testAccCheckCBRPolicyV3Exists(resourcePolicyName, &cbrPolicy), + rc.CheckResourceExists(), resource.TestCheckResourceAttr(resourcePolicyName, "name", "name2"), resource.TestCheckResourceAttr(resourcePolicyName, "enabled", "false"), ), @@ -50,6 +60,7 @@ func TestAccCBRPolicyV3_basic(t *testing.T) { func TestAccCBRPolicyV3_minConfig(t *testing.T) { var cbrPolicy policies.Policy + rc := common.InitResourceCheck(resourcePolicyName, &cbrPolicy, getPolicyResourceFunc) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -57,12 +68,12 @@ func TestAccCBRPolicyV3_minConfig(t *testing.T) { quotas.BookOne(t, quotas.CBRPolicy) }, ProviderFactories: common.TestAccProviderFactories, - CheckDestroy: testAccCheckCBRPolicyV3Destroy, + CheckDestroy: rc.CheckResourceDestroy(), Steps: []resource.TestStep{ { Config: testAccCBRPolicyV3MinConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckCBRPolicyV3Exists(resourcePolicyName, &cbrPolicy), + rc.CheckResourceExists(), resource.TestCheckResourceAttr(resourcePolicyName, "name", "some-policy-min"), resource.TestCheckResourceAttr(resourcePolicyName, "operation_type", "backup"), resource.TestCheckResourceAttr(resourcePolicyName, "enabled", "true"), @@ -78,6 +89,40 @@ func TestAccCBRPolicyV3_minConfig(t *testing.T) { }) } +func TestAccPolicy_replication(t *testing.T) { + var policy policies.Policy + name := fmt.Sprintf("cbr_acc_policy_%s", acctest.RandString(5)) + + rc := common.InitResourceCheck(resourcePolicyName, &policy, getPolicyResourceFunc) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + common.TestAccPreCheck(t) + common.TestAccPreCheckReplication(t) + }, + ProviderFactories: common.TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccPolicy_replication(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(resourcePolicyName, "name", name), + resource.TestCheckResourceAttr(resourcePolicyName, "enabled", "true"), + resource.TestCheckResourceAttr(resourcePolicyName, "operation_type", "replication"), + resource.TestCheckResourceAttr(resourcePolicyName, "destination_region", env.OS_DEST_REGION), + resource.TestCheckResourceAttr(resourcePolicyName, "destination_project_id", env.OS_DEST_PROJECT_ID), + ), + }, + { + ResourceName: resourcePolicyName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckCBRPolicyV3Destroy(s *terraform.State) error { config := common.TestAccProvider.Meta().(*cfg.Config) client, err := config.CbrV3Client(env.OS_REGION_NAME) @@ -99,36 +144,6 @@ func testAccCheckCBRPolicyV3Destroy(s *terraform.State) error { return nil } -func testAccCheckCBRPolicyV3Exists(n string, group *policies.Policy) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not found: %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("no ID is set") - } - - config := common.TestAccProvider.Meta().(*cfg.Config) - client, err := config.CbrV3Client(env.OS_REGION_NAME) - if err != nil { - return fmt.Errorf("error creating OpenTelekomCloud CBRv3 client: %s", err) - } - - found, err := policies.Get(client, rs.Primary.ID) - if err != nil { - return err - } - if found.ID != rs.Primary.ID { - return fmt.Errorf("CBRv3 policy not found") - } - group = found - - return nil - } -} - const ( testAccCBRPolicyV3Basic = ` resource opentelekomcloud_cbr_policy_v3 policy { @@ -182,3 +197,25 @@ resource opentelekomcloud_cbr_policy_v3 policy { } ` ) + +func testAccPolicy_replication(name string) string { + return fmt.Sprintf(` +resource "opentelekomcloud_cbr_policy_v3" "policy" { + name = "%[1]s" + operation_type = "replication" + destination_region = "%[2]s" + destination_project_id = "%[3]s" + + trigger_pattern = ["FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU;BYHOUR=14;BYMINUTE=00"] + + operation_definition { + day_backups = 1 + week_backups = 2 + year_backups = 3 + month_backups = 4 + max_backups = 10 + timezone = "UTC+03:00" + } +} +`, name, env.OS_DEST_REGION, env.OS_DEST_PROJECT_ID) +} diff --git a/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_vault_v3_test.go b/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_vault_v3_test.go index 0491bd0a1..1326412f8 100644 --- a/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_vault_v3_test.go +++ b/opentelekomcloud/acceptance/cbr/resource_opentelekomcloud_cbr_vault_v3_test.go @@ -59,6 +59,12 @@ func TestAccCBRVaultV3_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceVaultName, "billing.0.size", "120"), ), }, + { + ResourceName: resourceVaultName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"billing.0.period_type"}, + }, }, }) } diff --git a/opentelekomcloud/acceptance/common/common.go b/opentelekomcloud/acceptance/common/common.go index acc01bfa1..ff2fd9653 100644 --- a/opentelekomcloud/acceptance/common/common.go +++ b/opentelekomcloud/acceptance/common/common.go @@ -113,6 +113,12 @@ func TestAccPreCheckAdminOnly(t *testing.T) { } } +func TestAccPreCheckReplication(t *testing.T) { + if env.OS_DEST_REGION == "" || env.OS_DEST_PROJECT_ID == "" { + t.Skip("Skipping test because it requires set OS_DEST_REGION and OS_DEST_PROJECT_ID.") + } +} + func TestAccVBSBackupShareCheck(t *testing.T) { TestAccPreCheckRequiredEnvVars(t) if env.OS_TO_TENANT_ID == "" { diff --git a/opentelekomcloud/acceptance/env/vars.go b/opentelekomcloud/acceptance/env/vars.go index 3e63acf95..d7aecea32 100644 --- a/opentelekomcloud/acceptance/env/vars.go +++ b/opentelekomcloud/acceptance/env/vars.go @@ -22,6 +22,8 @@ var ( OS_TO_TENANT_ID = os.Getenv("OS_TO_TENANT_ID") OS_TENANT_NAME = GetTenantName() OS_PROJECT_ID = os.Getenv("OS_PROJECT_ID") + OS_DEST_REGION = os.Getenv("OS_DEST_REGION") + OS_DEST_PROJECT_ID = os.Getenv("OS_DEST_PROJECT_ID") ) func flavorID() string { diff --git a/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_policy_v3.go b/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_policy_v3.go index 03815074e..b57bb9810 100644 --- a/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_policy_v3.go +++ b/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_policy_v3.go @@ -23,6 +23,10 @@ func ResourceCBRPolicyV3() *schema.Resource { UpdateContext: resourceCBRPolicyV3Update, DeleteContext: resourceCBRPolicyV3Delete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ "region": { Type: schema.TypeString, @@ -103,6 +107,15 @@ func ResourceCBRPolicyV3() *schema.Resource { Type: schema.TypeString, }, }, + "destination_region": { + Type: schema.TypeString, + Optional: true, + }, + "destination_project_id": { + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"destination_region"}, + }, }, } } @@ -110,16 +123,20 @@ func ResourceCBRPolicyV3() *schema.Resource { func resourceCBRPolicyV3OpDefinition(d *schema.ResourceData) *policies.PolicyODCreate { opDefinitionRaw := d.Get("operation_definition").([]interface{}) if len(opDefinitionRaw) == 1 { + policyODCreate := policies.PolicyODCreate{} opDefinition := opDefinitionRaw[0].(map[string]interface{}) - return &policies.PolicyODCreate{ - DailyBackups: opDefinition["day_backups"].(int), - WeekBackups: opDefinition["week_backups"].(int), - YearBackups: opDefinition["year_backups"].(int), - MonthBackups: opDefinition["month_backups"].(int), - MaxBackups: opDefinition["max_backups"].(int), - RetentionDurationDays: opDefinition["retention_duration_days"].(int), - Timezone: opDefinition["timezone"].(string), + if destinationProjectID, ok := d.GetOk("destination_project_id"); ok { + policyODCreate.DestinationProjectId = destinationProjectID.(string) + policyODCreate.DestinationRegion = d.Get("destination_region").(string) } + policyODCreate.DailyBackups = opDefinition["day_backups"].(int) + policyODCreate.WeekBackups = opDefinition["week_backups"].(int) + policyODCreate.YearBackups = opDefinition["year_backups"].(int) + policyODCreate.MonthBackups = opDefinition["month_backups"].(int) + policyODCreate.MaxBackups = opDefinition["max_backups"].(int) + policyODCreate.RetentionDurationDays = opDefinition["retention_duration_days"].(int) + policyODCreate.Timezone = opDefinition["timezone"].(string) + return &policyODCreate } return &policies.PolicyODCreate{ Timezone: "UTC+00:00", @@ -193,9 +210,6 @@ func resourceCBRPolicyV3Read(_ context.Context, d *schema.ResourceData, meta int d.Set("trigger_pattern", cbrPolicy.Trigger.Properties.Pattern), d.Set("region", config.GetRegion(d)), ) - if mErr.ErrorOrNil() != nil { - return diag.FromErr(mErr) - } var opDefinitionList []map[string]interface{} opDefinition := make(map[string]interface{}) @@ -211,6 +225,14 @@ func resourceCBRPolicyV3Read(_ context.Context, d *schema.ResourceData, meta int if err := d.Set("operation_definition", opDefinitionList); err != nil { return fmterr.Errorf("error setting operetion_definition: %s", err) } + mErr = multierror.Append(mErr, + d.Set("destination_project_id", cbrPolicyOD.DestinationProjectId), + d.Set("destination_region", cbrPolicyOD.DestinationRegion), + ) + + if mErr.ErrorOrNil() != nil { + return diag.FromErr(mErr) + } return nil } diff --git a/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_vault_v3.go b/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_vault_v3.go index f6fea7c9a..f4462049f 100644 --- a/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_vault_v3.go +++ b/opentelekomcloud/services/cbr/resource_opentelekomcloud_cbr_vault_v3.go @@ -26,6 +26,10 @@ func ResourceCBRVaultV3() *schema.Resource { CustomizeDiff: common.MultipleCustomizeDiffs(cbrVaultRequiredFields), + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ "description": { Type: schema.TypeString, @@ -316,7 +320,6 @@ func resourceCBRVaultV3Read(_ context.Context, d *schema.ResourceData, meta inte d.Set("provider_id", vault.ProviderID), d.Set("resource", resourceInfo), d.Set("tags", tagsMap), - d.Set("enterprise_project_id", vault.EnterpriseProjectID), d.Set("auto_bind", vault.AutoBind), d.Set("auto_expand", vault.AutoExpand), d.Set("bind_rules", bindRules), @@ -345,16 +348,15 @@ func resourceCBRVaultV3Create(ctx context.Context, d *schema.ResourceData, meta } opts := vaults.CreateOpts{ - BackupPolicyID: d.Get("backup_policy_id").(string), - Billing: cbrVaultBillingCreate(d), - Description: d.Get("description").(string), - Name: d.Get("name").(string), - Resources: resources, - Tags: cbrVaultTags(d), - EnterpriseProjectID: d.Get("enterprise_project_id").(string), - AutoBind: d.Get("auto_bind").(bool), - BindRules: cbrVaultBindRules(d), - AutoExpand: d.Get("auto_expand").(bool), + BackupPolicyID: d.Get("backup_policy_id").(string), + Billing: cbrVaultBillingCreate(d), + Description: d.Get("description").(string), + Name: d.Get("name").(string), + Resources: resources, + Tags: cbrVaultTags(d), + AutoBind: d.Get("auto_bind").(bool), + BindRules: cbrVaultBindRules(d), + AutoExpand: d.Get("auto_expand").(bool), } vault, err := vaults.Create(client, opts)