Skip to content

Commit ca5bf86

Browse files
committed
Add support for moving Compartment tree across compartments
1 parent 40ac113 commit ca5bf86

File tree

5 files changed

+71
-13
lines changed

5 files changed

+71
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Support for moving `oci_kms_key` and `oci_kms_vault` Across Compartments
1313
- Support for moving `core_instance` resources across compartments
1414
- Support for LBaaS Cookie Insertion (Sticky Cookie)
15+
- Support for moving `identity_compartment` resource tree across compartments
1516

1617
## 3.33.0 (July 10, 2019)
1718

oci/identity_compartment_resource.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ func IdentityCompartmentResource() *schema.Resource {
3636
Type: schema.TypeString,
3737
Computed: true,
3838
Optional: true,
39-
ForceNew: true,
4039
},
4140
"enable_delete": {
4241
Type: schema.TypeBool,
@@ -277,6 +276,15 @@ func (s *IdentityCompartmentResourceCrud) Get() error {
277276
}
278277

279278
func (s *IdentityCompartmentResourceCrud) Update() error {
279+
if compartment, ok := s.D.GetOkExists("compartment_id"); ok && s.D.HasChange("compartment_id") {
280+
oldRaw, newRaw := s.D.GetChange("compartment_id")
281+
if newRaw != "" && oldRaw != "" {
282+
err := s.updateCompartment(compartment)
283+
if err != nil {
284+
return err
285+
}
286+
}
287+
}
280288
request := oci_identity.UpdateCompartmentRequest{}
281289

282290
tmp := s.D.Id()
@@ -362,3 +370,23 @@ func (s *IdentityCompartmentResourceCrud) SetData() error {
362370

363371
return nil
364372
}
373+
374+
func (s *IdentityCompartmentResourceCrud) updateCompartment(compartment interface{}) error {
375+
changeCompartmentRequest := oci_identity.MoveCompartmentRequest{}
376+
377+
idTmp := s.D.Id()
378+
changeCompartmentRequest.CompartmentId = &idTmp
379+
380+
if targetCompartmentId, ok := s.D.GetOkExists("compartment_id"); ok {
381+
tmp := targetCompartmentId.(string)
382+
changeCompartmentRequest.TargetCompartmentId = &tmp
383+
}
384+
385+
changeCompartmentRequest.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "identity")
386+
387+
_, err := s.Client.MoveCompartment(context.Background(), changeCompartmentRequest)
388+
if err != nil {
389+
return err
390+
}
391+
return nil
392+
}

oci/identity_compartment_test.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var (
2828
}
2929

3030
compartmentDataSourceRepresentation = map[string]interface{}{
31-
"compartment_id": Representation{repType: Required, create: `${var.tenancy_ocid}`},
31+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
3232
"access_level": Representation{repType: Optional, create: `ANY`},
3333
"compartment_id_in_subtree": Representation{repType: Optional, create: `false`},
3434
"filter": RepresentationGroup{Required, compartmentDataSourceFilterRepresentation}}
@@ -38,7 +38,7 @@ var (
3838
}
3939

4040
compartmentRepresentation = map[string]interface{}{
41-
"compartment_id": Representation{repType: Required, create: `${var.tenancy_ocid}`},
41+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
4242
"description": Representation{repType: Required, create: `For network components`, update: `description2`},
4343
"name": Representation{repType: Required, create: `Network`, update: `name2`},
4444
"defined_tags": Representation{repType: Optional, create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
@@ -57,7 +57,9 @@ func TestIdentityCompartmentResource_basic(t *testing.T) {
5757

5858
compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
5959
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
60-
tenancyId := getEnvSettingWithBlankDefault("tenancy_ocid")
60+
61+
compartmentIdU := getEnvSettingWithDefault("compartment_id_for_update", compartmentId)
62+
compartmentIdUVariableStr := fmt.Sprintf("variable \"compartment_id_for_update\" { default = \"%s\" }\n", compartmentIdU)
6163

6264
resourceName := "oci_identity_compartment.test_compartment"
6365
datasourceName := "data.oci_identity_compartments.test_compartments"
@@ -77,7 +79,7 @@ func TestIdentityCompartmentResource_basic(t *testing.T) {
7779
Config: config + compartmentIdVariableStr + CompartmentResourceDependencies +
7880
generateResourceFromRepresentationMap("oci_identity_compartment", "test_compartment", Required, Create, compartmentRepresentation),
7981
Check: resource.ComposeAggregateTestCheckFunc(
80-
resource.TestCheckResourceAttr(resourceName, "compartment_id", tenancyId),
82+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
8183
resource.TestCheckResourceAttr(resourceName, "description", "For network components"),
8284
resource.TestCheckResourceAttr(resourceName, "name", "Network"),
8385

@@ -92,7 +94,7 @@ func TestIdentityCompartmentResource_basic(t *testing.T) {
9294
Config: config + compartmentIdVariableStr + CompartmentResourceDependencies +
9395
generateResourceFromRepresentationMap("oci_identity_compartment", "test_compartment", Optional, Create, compartmentRepresentation),
9496
Check: resource.ComposeAggregateTestCheckFunc(
95-
resource.TestCheckResourceAttr(resourceName, "compartment_id", tenancyId),
97+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
9698
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
9799
resource.TestCheckResourceAttr(resourceName, "description", "For network components"),
98100
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
@@ -108,12 +110,39 @@ func TestIdentityCompartmentResource_basic(t *testing.T) {
108110
),
109111
},
110112

113+
// verify update to the compartment (the compartment will be switched back in the next step)
114+
{
115+
Config: config + compartmentIdVariableStr + compartmentIdUVariableStr + CompartmentResourceDependencies +
116+
generateResourceFromRepresentationMap("oci_identity_compartment", "test_compartment", Optional, Create,
117+
representationCopyWithNewProperties(compartmentRepresentation, map[string]interface{}{
118+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id_for_update}`},
119+
})),
120+
Check: resource.ComposeAggregateTestCheckFunc(
121+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentIdU),
122+
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
123+
resource.TestCheckResourceAttr(resourceName, "description", "For network components"),
124+
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
125+
resource.TestCheckResourceAttrSet(resourceName, "id"),
126+
resource.TestCheckResourceAttr(resourceName, "name", "Network"),
127+
resource.TestCheckResourceAttrSet(resourceName, "state"),
128+
resource.TestCheckResourceAttrSet(resourceName, "time_created"),
129+
130+
func(s *terraform.State) (err error) {
131+
resId2, err = fromInstanceState(s, resourceName, "id")
132+
if resId != resId2 {
133+
return fmt.Errorf("resource recreated when it was supposed to be updated")
134+
}
135+
return err
136+
},
137+
),
138+
},
139+
111140
// verify updates to updatable parameters
112141
{
113142
Config: config + compartmentIdVariableStr + CompartmentResourceDependencies +
114143
generateResourceFromRepresentationMap("oci_identity_compartment", "test_compartment", Optional, Update, compartmentRepresentation),
115144
Check: resource.ComposeAggregateTestCheckFunc(
116-
resource.TestCheckResourceAttr(resourceName, "compartment_id", tenancyId),
145+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
117146
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
118147
resource.TestCheckResourceAttr(resourceName, "description", "description2"),
119148
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
@@ -139,11 +168,11 @@ func TestIdentityCompartmentResource_basic(t *testing.T) {
139168
generateResourceFromRepresentationMap("oci_identity_compartment", "test_compartment", Optional, Update, compartmentRepresentation),
140169
Check: resource.ComposeAggregateTestCheckFunc(
141170
resource.TestCheckResourceAttr(datasourceName, "access_level", "ANY"),
142-
resource.TestCheckResourceAttr(datasourceName, "compartment_id", tenancyId),
171+
resource.TestCheckResourceAttr(datasourceName, "compartment_id", compartmentId),
143172
resource.TestCheckResourceAttr(datasourceName, "compartment_id_in_subtree", "false"),
144173

145174
resource.TestCheckResourceAttr(datasourceName, "compartments.#", "1"),
146-
resource.TestCheckResourceAttr(datasourceName, "compartments.0.compartment_id", tenancyId),
175+
resource.TestCheckResourceAttr(datasourceName, "compartments.0.compartment_id", compartmentId),
147176
resource.TestCheckResourceAttr(datasourceName, "compartments.0.defined_tags.%", "1"),
148177
resource.TestCheckResourceAttr(datasourceName, "compartments.0.description", "description2"),
149178
resource.TestCheckResourceAttr(datasourceName, "compartments.0.freeform_tags.%", "1"),
@@ -159,7 +188,7 @@ func TestIdentityCompartmentResource_basic(t *testing.T) {
159188
generateDataSourceFromRepresentationMap("oci_identity_compartment", "test_compartment", Required, Create, compartmentSingularDataSourceRepresentation) +
160189
compartmentIdVariableStr + CompartmentResourceConfig,
161190
Check: resource.ComposeAggregateTestCheckFunc(
162-
resource.TestCheckResourceAttrSet(singularDatasourceName, "compartment_id"),
191+
resource.TestCheckResourceAttr(singularDatasourceName, "compartment_id", compartmentId),
163192
resource.TestCheckResourceAttr(singularDatasourceName, "defined_tags.%", "1"),
164193
resource.TestCheckResourceAttr(singularDatasourceName, "description", "description2"),
165194
resource.TestCheckResourceAttr(singularDatasourceName, "freeform_tags.%", "1"),

website/docs/d/identity_compartments.html.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ See [Where to Get the Tenancy's OCID and User's OCID](https://docs.cloud.oracle.
3434
```hcl
3535
data "oci_identity_compartments" "test_compartments" {
3636
#Required
37-
compartment_id = "${var.tenancy_ocid}"
37+
compartment_id = "${var.compartment_id}"
3838
3939
#Optional
4040
access_level = "${var.compartment_access_level}"

website/docs/r/identity_compartment.html.markdown

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ not have to be unique, and you can change it anytime with
3434
```hcl
3535
resource "oci_identity_compartment" "test_compartment" {
3636
#Required
37-
compartment_id = "${var.tenancy_ocid}"
37+
compartment_id = "${var.compartment_id}"
3838
description = "${var.compartment_description}"
3939
name = "${var.compartment_name}"
4040
@@ -48,7 +48,7 @@ resource "oci_identity_compartment" "test_compartment" {
4848

4949
The following arguments are supported:
5050

51-
* `compartment_id` - (Required) The OCID of the parent compartment containing the compartment.
51+
* `compartment_id` - (Required) (Updatable) The OCID of the parent compartment containing the compartment.
5252
* `defined_tags` - (Optional) (Updatable) Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcetags.htm). Example: `{"Operations.CostCenter": "42"}`
5353
* `description` - (Required) (Updatable) The description you assign to the compartment during creation. Does not have to be unique, and it's changeable.
5454
* `freeform_tags` - (Optional) (Updatable) Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcetags.htm). Example: `{"Department": "Finance"}`

0 commit comments

Comments
 (0)