Skip to content

Commit

Permalink
[CBR] include exclude disks support (#1802)
Browse files Browse the repository at this point in the history
[CBR] include exclude disks support

Summary of the Pull Request
PR Checklist

 Refers to: #1776
 Tests added/passed.
 Documentation updated.
 Schema updated.
 Release notes added.

Acceptance Steps Performed
=== RUN   TestAccCBRVaultV3_basic
=== PAUSE TestAccCBRVaultV3_basic
=== CONT  TestAccCBRVaultV3_basic
--- PASS: TestAccCBRVaultV3_basic (126.24s)
=== RUN   TestAccCBRVaultV3_unAssign
=== PAUSE TestAccCBRVaultV3_unAssign
=== CONT  TestAccCBRVaultV3_unAssign
--- PASS: TestAccCBRVaultV3_unAssign (141.70s)
=== RUN   TestAccCBRVaultV3_instance
=== PAUSE TestAccCBRVaultV3_instance
=== CONT  TestAccCBRVaultV3_instance
--- PASS: TestAccCBRVaultV3_instance (166.37s)
=== RUN   TestAccCBRVaultV3_extraInfo
=== PAUSE TestAccCBRVaultV3_extraInfo
=== CONT  TestAccCBRVaultV3_extraInfo
--- PASS: TestAccCBRVaultV3_extraInfo (211.54s)

PASS

Reviewed-by: Artem Lifshits <None>
  • Loading branch information
anton-sidelnikov committed Jul 8, 2022
1 parent 2448495 commit 4160c6b
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 37 deletions.
33 changes: 29 additions & 4 deletions docs/resources/cbr_vault_v3.md
Expand Up @@ -25,7 +25,32 @@ resource "opentelekomcloud_cbr_vault_v3" "vault" {
}
```

### Vault with associated resource
### Vault with associated resource (server)

```hcl
resource "opentelekomcloud_cbr_vault_v3" "vault" {
name = "cbr-vault-test"
description = "CBR vault for terraform provider test"
billing {
size = 100
object_type = "disk"
protect_type = "backup"
charging_mode = "post_paid"
}
resource {
id = opentelekomcloud_ecs_instance_v1.instance.id
type = "OS::Nova::Server"
exclude_volumes = [
opentelekomcloud_ecs_instance_v1.instance_1.data_disks.1.id
]
}
}
```
### Vault with associated resource (volume)

```hcl
resource "opentelekomcloud_blockstorage_volume_v2" "volume" {
Expand All @@ -50,8 +75,6 @@ resource "opentelekomcloud_cbr_vault_v3" "vault" {
resource {
id = opentelekomcloud_blockstorage_volume_v2.volume.id
type = "OS::Cinder::Volume"
extra_info = {}
}
}
```
Expand Down Expand Up @@ -139,7 +162,9 @@ The following arguments are supported:

* `name` - (Optional) Resource name.

* `extra_info` - (Optional) Map of extra info.
* `exclude_volumes` - (Optional) List of excluded volumes.

* `include_volumes` - (Optional) List of included volumes.

* `backup_policy_id` - (Optional) Backup policy ID. If the value of this parameter is empty, automatic backup is not
performed.
Expand Down
Expand Up @@ -5,8 +5,11 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/cbr/v3/vaults"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/common/quotas"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/env"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/common/cfg"

"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/common"
)
Expand Down Expand Up @@ -159,6 +162,57 @@ resource "opentelekomcloud_cbr_vault_v3" "vault" {
`, common.DataSourceImage, common.DataSourceSubnet, env.OsFlavorID)
)

func TestAccCBRVaultV3_extraInfo(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
common.TestAccPreCheck(t)
qts := quotas.MultipleQuotas{
{Q: quotas.Volume, Count: 2},
{Q: quotas.VolumeSize, Count: 20},
{Q: quotas.CBRPolicy, Count: 1},
}
quotas.BookMany(t, qts)
},
ProviderFactories: common.TestAccProviderFactories,
CheckDestroy: testAccCheckCBRVaultV3Destroy,
Steps: []resource.TestStep{
{
Config: testAccCBRVaultV3BasicExtraInfo,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(resourceVaultName, "backup_policy_id"),
),
},
{
Config: testAccCBRVaultV3BasicExtraInfoUpdate,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(resourceVaultName, "resource.#", "1"),
),
},
},
})
}

func testAccCheckCBRVaultV3Destroy(s *terraform.State) error {
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)
}

for _, rs := range s.RootModule().Resources {
if rs.Type != "opentelekomcloud_cbr_vault_v3" {
continue
}

_, err := vaults.Get(client, rs.Primary.ID).Extract()
if err == nil {
return fmt.Errorf("CBRv3 vault still exists")
}
}

return nil
}

const (
testAccCBRVaultV3BasicVolumes = `
resource "opentelekomcloud_blockstorage_volume_v2" "volume" {
Expand Down Expand Up @@ -343,5 +397,109 @@ resource "opentelekomcloud_cbr_vault_v3" "vault" {
charging_mode = "post_paid"
}
}
`
testAccCBRVaultV3BasicExtraInfo = `
resource "opentelekomcloud_cbr_policy_v3" "default_policy" {
name = "cbr-policy"
operation_type = "backup"
trigger_pattern = [
"FREQ=DAILY;INTERVAL=1;BYHOUR=23;BYMINUTE=00"
]
operation_definition {
max_backups = 5
timezone = "UTC+01:00"
}
enabled = "true"
}
resource "opentelekomcloud_cbr_vault_v3" "vault" {
name = "cbr-vault-test"
description = "CBR vault for default backup policy"
backup_policy_id = opentelekomcloud_cbr_policy_v3.default_policy.id
auto_bind = true
auto_expand = true
billing {
size = 10000
object_type = "server"
protect_type = "backup"
charging_mode = "post_paid"
}
}
`
)

var testAccCBRVaultV3BasicExtraInfoUpdate = fmt.Sprintf(`
data "opentelekomcloud_vpc_subnet_v1" "shared_subnet" {
name = "%s"
}
resource "opentelekomcloud_ecs_instance_v1" "instance_1" {
name = "server_1"
image_id = "c0b36460-7aa6-44d2-990d-cc300f3a7e43"
flavor = "s2.medium.1"
vpc_id = data.opentelekomcloud_vpc_subnet_v1.shared_subnet.vpc_id
nics {
network_id = data.opentelekomcloud_vpc_subnet_v1.shared_subnet.network_id
}
data_disks {
type = "SATA"
size = "10"
}
data_disks {
type = "SAS"
size = "10"
}
password = "Password@123"
availability_zone = "%s"
auto_recovery = true
delete_disks_on_termination = true
}
resource "opentelekomcloud_cbr_policy_v3" "default_policy" {
name = "cbr-policy"
operation_type = "backup"
trigger_pattern = [
"FREQ=DAILY;INTERVAL=1;BYHOUR=23;BYMINUTE=00"
]
operation_definition {
max_backups = 5
timezone = "UTC+01:00"
}
enabled = "true"
}
resource "opentelekomcloud_cbr_vault_v3" "vault" {
name = "cbr-vault-test"
description = "CBR vault for default backup policy"
billing {
size = 10000
object_type = "server"
protect_type = "backup"
charging_mode = "post_paid"
}
resource {
id = opentelekomcloud_ecs_instance_v1.instance_1.id
type = "OS::Nova::Server"
exclude_volumes = [
opentelekomcloud_ecs_instance_v1.instance_1.data_disks.1.id
]
}
}
`, env.OsSubnetName, env.OS_AVAILABILITY_ZONE)
Expand Up @@ -2,7 +2,6 @@ package cbr

import (
"context"
"encoding/json"
"fmt"

"github.com/hashicorp/go-multierror"
Expand Down Expand Up @@ -64,10 +63,17 @@ func ResourceCBRVaultV3() *schema.Resource {
"OS::Nova::Server", "OS::Cinder::Volume",
}, false),
},
"extra_info": {
Type: schema.TypeMap,
"exclude_volumes": {
Type: schema.TypeSet,
Optional: true,
Computed: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
},
"include_volumes": {
Type: schema.TypeSet,
Optional: true,
Set: schema.HashString,
Elem: &schema.Schema{Type: schema.TypeString},
},
"protect_status": {
Type: schema.TypeString,
Expand Down Expand Up @@ -279,16 +285,18 @@ func resourceCBRVaultV3Read(_ context.Context, d *schema.ResourceData, meta inte
return fmterr.Errorf("error getting vault details: %s", err)
}

resourceList := make([]interface{}, len(vault.Resources))
for i, resource := range vault.Resources {
data, _ := json.Marshal(resource)
resMap := make(map[string]interface{})
err = json.Unmarshal(data, &resMap)
if err != nil {
return fmterr.Errorf("error converting resource list: %s", err)
var resourceInfo []map[string]interface{}
for _, resource := range vault.Resources {
resourceMap := map[string]interface{}{
"id": resource.ID,
"name": resource.Name,
"type": resource.Type,
"exclude_volumes": resource.ExtraInfo.ExcludeVolumes,
"include_volumes": resource.ExtraInfo.IncludeVolumes,
}
resourceList[i] = resMap
resourceInfo = append(resourceInfo, resourceMap)
}

tagsMap := make(map[string]string)
for _, tag := range vault.Tags {
tagsMap[tag.Key] = tag.Value
Expand All @@ -307,7 +315,7 @@ func resourceCBRVaultV3Read(_ context.Context, d *schema.ResourceData, meta inte
d.Set("name", vault.Name),
d.Set("project_id", vault.ProjectID),
d.Set("provider_id", vault.ProviderID),
d.Set("resource", resourceList),
d.Set("resource", resourceInfo),
d.Set("tags", tagsMap),
d.Set("enterprise_project_id", vault.EnterpriseProjectID),
d.Set("auto_bind", vault.AutoBind),
Expand Down Expand Up @@ -367,37 +375,48 @@ func resourceCBRVaultV3Create(ctx context.Context, d *schema.ResourceData, meta
}

func resourceExtraMapToExtra(src map[string]interface{}) (*vaults.ResourceExtraInfo, error) {
var resExtra *vaults.ResourceExtraInfo
if src == nil {
return nil, nil
}
data, err := json.Marshal(src)
if err != nil {
return nil, err

rawExclude := src["exclude_volumes"].(*schema.Set).List()
exclude := make([]string, len(rawExclude))
for i, raw := range rawExclude {
exclude[i] = raw.(string)
}
extra := new(vaults.ResourceExtraInfo)
err = json.Unmarshal(data, extra)
if err != nil {
return nil, err

rawInclude := src["include_volumes"].(*schema.Set).List()
include := make([]vaults.ResourceExtraInfoIncludeVolumes, len(rawInclude))
for i, raw := range rawInclude {
include[i] = vaults.ResourceExtraInfoIncludeVolumes{
ID: raw.(string),
}
}
if len(exclude) != 0 || len(include) != 0 {
resExtra = &vaults.ResourceExtraInfo{
ExcludeVolumes: exclude,
IncludeVolumes: include,
}
}
return extra, nil
return resExtra, nil
}

func cbrVaultResourcesCreate(d *schema.ResourceData) (res []vaults.ResourceCreate, err error) {
resources := d.Get("resource").(*schema.Set)
res = make([]vaults.ResourceCreate, resources.Len())
for i, v := range resources.List() {
resource := v.(map[string]interface{})
rawExtra := resource["extra_info"].(map[string]interface{})
resourceID := resource["id"].(string)
extra, err := resourceExtraMapToExtra(rawExtra)
resExtra, err := resourceExtraMapToExtra(resource)
if err != nil {
return nil, fmt.Errorf("error converting \"%s\" resource extra: %v", resourceID, rawExtra)
return nil, err
}
res[i] = vaults.ResourceCreate{
ID: resourceID,
Type: resource["type"].(string),
Name: resource["name"].(string),
ExtraInfo: extra,
ExtraInfo: resExtra,
}
}
return
Expand Down Expand Up @@ -480,7 +499,6 @@ func cbrVaultTags(d *schema.ResourceData) []vaults.Tag {
func vaultAddedResources(d *schema.ResourceData) ([]vaults.ResourceCreate, error) {
oldR, newR := d.GetChange("resource")
addedSet := newR.(*schema.Set).Difference(oldR.(*schema.Set))

res := make([]vaults.ResourceCreate, addedSet.Len())
for i, v := range addedSet.List() {
newMap := v.(map[string]interface{})
Expand All @@ -489,14 +507,13 @@ func vaultAddedResources(d *schema.ResourceData) ([]vaults.ResourceCreate, error
Type: newMap["type"].(string),
Name: newMap["name"].(string),
}
extraMap, ok := newMap["extra"].(map[string]interface{})
if ok {
extra, err := resourceExtraMapToExtra(extraMap)
if err != nil {
return nil, err
}
newResource.ExtraInfo = extra

extra, err := resourceExtraMapToExtra(newMap)
if err != nil {
return nil, err
}

newResource.ExtraInfo = extra
res[i] = newResource
}
return res, nil
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/cbr-extra-bea81a63bd50d47a.yaml
@@ -0,0 +1,4 @@
---
fixes:
- |
**[CBR]** Add support of ``exclude_volumes`` and ``include_volumes`` for ``resource`` in ``resource/opentelekomcloud_cbr_vault_v3`` (`#1802 <https://github.com/opentelekomcloud/terraform-provider-opentelekomcloud/pull/1802>`_)

0 comments on commit 4160c6b

Please sign in to comment.