Skip to content

Commit

Permalink
Feat. CBR policy replication, policy and vault importers
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-sidelnikov committed Sep 18, 2024
1 parent b1c341f commit a25d563
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 72 deletions.
64 changes: 52 additions & 12 deletions docs/resources/cbr_policy_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
```
10 changes: 8 additions & 2 deletions docs/resources/cbr_vault_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -16,21 +17,30 @@ 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() {
common.TestAccPreCheck(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"),
Expand All @@ -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"),
),
Expand All @@ -50,19 +60,20 @@ 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() {
common.TestAccPreCheck(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"),
Expand All @@ -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)
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
},
},
})
}
Expand Down
6 changes: 6 additions & 0 deletions opentelekomcloud/acceptance/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 == "" {
Expand Down
2 changes: 2 additions & 0 deletions opentelekomcloud/acceptance/env/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit a25d563

Please sign in to comment.