Skip to content

Commit e982683

Browse files
committed
Add support to move Volumes and Backups across compartments
1 parent 6f317a4 commit e982683

25 files changed

+435
-38
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
### Added
55
- Support for scheduling KMS key deletion
6+
- Support for moving Volumes, Volume groups, Boot Volumes and corresponding Backups across compartments
67

78
## 3.29.0 (June 12, 2019)
89

oci/core_boot_volume_backup_resource.go

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package provider
44

55
import (
66
"context"
7+
"log"
78
"strconv"
89

910
"github.com/hashicorp/terraform/helper/schema"
@@ -30,6 +31,11 @@ func CoreBootVolumeBackupResource() *schema.Resource {
3031
},
3132

3233
// Optional
34+
"compartment_id": {
35+
Type: schema.TypeString,
36+
Optional: true,
37+
Computed: true,
38+
},
3339
"defined_tags": {
3440
Type: schema.TypeMap,
3541
Optional: true,
@@ -56,10 +62,6 @@ func CoreBootVolumeBackupResource() *schema.Resource {
5662
},
5763

5864
// Computed
59-
"compartment_id": {
60-
Type: schema.TypeString,
61-
Computed: true,
62-
},
6365
"expiration_time": {
6466
Type: schema.TypeString,
6567
Computed: true,
@@ -101,7 +103,30 @@ func createCoreBootVolumeBackup(d *schema.ResourceData, m interface{}) error {
101103
sync.D = d
102104
sync.Client = m.(*OracleClients).blockstorageClient
103105

104-
return CreateResource(d, sync)
106+
compartment, ok := sync.D.GetOkExists("compartment_id")
107+
108+
err := CreateResource(d, sync)
109+
if err != nil {
110+
return err
111+
}
112+
113+
if ok && compartment != *sync.Res.CompartmentId {
114+
err = sync.updateCompartment(compartment)
115+
if err != nil {
116+
return err
117+
}
118+
tmp := compartment.(string)
119+
sync.Res.CompartmentId = &tmp
120+
err := sync.Get()
121+
if err != nil {
122+
log.Printf("error doing a Get() after compartment update: %v", err)
123+
}
124+
err = sync.SetData()
125+
if err != nil {
126+
log.Printf("error doing a SetData() after compartment update: %v", err)
127+
}
128+
}
129+
return nil
105130
}
106131

107132
func readCoreBootVolumeBackup(d *schema.ResourceData, m interface{}) error {
@@ -223,6 +248,15 @@ func (s *CoreBootVolumeBackupResourceCrud) Get() error {
223248
}
224249

225250
func (s *CoreBootVolumeBackupResourceCrud) Update() error {
251+
if compartment, ok := s.D.GetOkExists("compartment_id"); ok && s.D.HasChange("compartment_id") {
252+
oldRaw, newRaw := s.D.GetChange("compartment_id")
253+
if newRaw != "" && oldRaw != "" {
254+
err := s.updateCompartment(compartment)
255+
if err != nil {
256+
return err
257+
}
258+
}
259+
}
226260
request := oci_core.UpdateBootVolumeBackupRequest{}
227261

228262
tmp := s.D.Id()
@@ -319,3 +353,21 @@ func (s *CoreBootVolumeBackupResourceCrud) SetData() error {
319353

320354
return nil
321355
}
356+
357+
func (s *CoreBootVolumeBackupResourceCrud) updateCompartment(compartment interface{}) error {
358+
changeCompartmentRequest := oci_core.ChangeBootVolumeBackupCompartmentRequest{}
359+
360+
idTmp := s.D.Id()
361+
changeCompartmentRequest.BootVolumeBackupId = &idTmp
362+
363+
compartmentTmp := compartment.(string)
364+
changeCompartmentRequest.CompartmentId = &compartmentTmp
365+
366+
changeCompartmentRequest.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "core")
367+
368+
_, err := s.Client.ChangeBootVolumeBackupCompartment(context.Background(), changeCompartmentRequest)
369+
if err != nil {
370+
return err
371+
}
372+
return nil
373+
}

oci/core_boot_volume_backup_test.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ func TestCoreBootVolumeBackupResource_basic(t *testing.T) {
6464
compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
6565
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
6666

67+
compartmentIdU := getEnvSettingWithDefault("compartment_id_for_update", compartmentId)
68+
compartmentIdUVariableStr := fmt.Sprintf("variable \"compartment_id_for_update\" { default = \"%s\" }\n", compartmentIdU)
69+
6770
resourceName := "oci_core_boot_volume_backup.test_boot_volume_backup"
6871
datasourceName := "data.oci_core_boot_volume_backups.test_boot_volume_backups"
6972
singularDatasourceName := "data.oci_core_boot_volume_backup.test_boot_volume_backup"
@@ -97,11 +100,14 @@ func TestCoreBootVolumeBackupResource_basic(t *testing.T) {
97100
},
98101
// verify create with optionals
99102
{
100-
Config: config + compartmentIdVariableStr + BootVolumeBackupResourceDependencies +
101-
generateResourceFromRepresentationMap("oci_core_boot_volume_backup", "test_boot_volume_backup", Optional, Create, bootVolumeBackupRepresentation),
103+
Config: config + compartmentIdVariableStr + compartmentIdUVariableStr + BootVolumeBackupResourceDependencies +
104+
generateResourceFromRepresentationMap("oci_core_boot_volume_backup", "test_boot_volume_backup", Optional, Create,
105+
representationCopyWithNewProperties(bootVolumeBackupRepresentation, map[string]interface{}{
106+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id_for_update}`},
107+
})),
102108
Check: resource.ComposeAggregateTestCheckFunc(
109+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentIdU),
103110
resource.TestCheckResourceAttrSet(resourceName, "boot_volume_id"),
104-
resource.TestCheckResourceAttrSet(resourceName, "compartment_id"),
105111
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
106112
resource.TestCheckResourceAttr(resourceName, "display_name", "displayName"),
107113
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
@@ -120,10 +126,13 @@ func TestCoreBootVolumeBackupResource_basic(t *testing.T) {
120126
// verify updates to updatable parameters
121127
{
122128
Config: config + compartmentIdVariableStr + BootVolumeBackupResourceDependencies +
123-
generateResourceFromRepresentationMap("oci_core_boot_volume_backup", "test_boot_volume_backup", Optional, Update, bootVolumeBackupRepresentation),
129+
generateResourceFromRepresentationMap("oci_core_boot_volume_backup", "test_boot_volume_backup", Optional, Update,
130+
representationCopyWithNewProperties(bootVolumeBackupRepresentation, map[string]interface{}{
131+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
132+
})),
124133
Check: resource.ComposeAggregateTestCheckFunc(
134+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
125135
resource.TestCheckResourceAttrSet(resourceName, "boot_volume_id"),
126-
resource.TestCheckResourceAttrSet(resourceName, "compartment_id"),
127136
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
128137
resource.TestCheckResourceAttr(resourceName, "display_name", "displayName2"),
129138
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
@@ -155,7 +164,7 @@ func TestCoreBootVolumeBackupResource_basic(t *testing.T) {
155164

156165
resource.TestCheckResourceAttr(datasourceName, "boot_volume_backups.#", "1"),
157166
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_backups.0.boot_volume_id"),
158-
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_backups.0.compartment_id"),
167+
resource.TestCheckResourceAttr(datasourceName, "boot_volume_backups.0.compartment_id", compartmentId),
159168
resource.TestCheckResourceAttr(datasourceName, "boot_volume_backups.0.defined_tags.%", "1"),
160169
resource.TestCheckResourceAttr(datasourceName, "boot_volume_backups.0.display_name", "displayName2"),
161170
resource.TestCheckResourceAttr(datasourceName, "boot_volume_backups.0.freeform_tags.%", "1"),
@@ -178,7 +187,7 @@ func TestCoreBootVolumeBackupResource_basic(t *testing.T) {
178187
Check: resource.ComposeAggregateTestCheckFunc(
179188
resource.TestCheckResourceAttrSet(singularDatasourceName, "boot_volume_backup_id"),
180189

181-
resource.TestCheckResourceAttrSet(singularDatasourceName, "compartment_id"),
190+
resource.TestCheckResourceAttr(singularDatasourceName, "compartment_id", compartmentId),
182191
resource.TestCheckResourceAttr(singularDatasourceName, "defined_tags.%", "1"),
183192
resource.TestCheckResourceAttr(singularDatasourceName, "display_name", "displayName2"),
184193
resource.TestCheckResourceAttr(singularDatasourceName, "freeform_tags.%", "1"),

oci/core_boot_volume_resource.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ func CoreBootVolumeResource() *schema.Resource {
3636
"compartment_id": {
3737
Type: schema.TypeString,
3838
Required: true,
39-
ForceNew: true,
4039
},
4140
"source_details": {
4241
Type: schema.TypeList,
@@ -308,6 +307,15 @@ func (s *CoreBootVolumeResourceCrud) Get() error {
308307
}
309308

310309
func (s *CoreBootVolumeResourceCrud) Update() error {
310+
if compartment, ok := s.D.GetOkExists("compartment_id"); ok && s.D.HasChange("compartment_id") {
311+
oldRaw, newRaw := s.D.GetChange("compartment_id")
312+
if newRaw != "" && oldRaw != "" {
313+
err := s.updateCompartment(compartment)
314+
if err != nil {
315+
return err
316+
}
317+
}
318+
}
311319
request := oci_core.UpdateBootVolumeRequest{}
312320

313321
tmp := s.D.Id()
@@ -501,3 +509,21 @@ func BootVolumeSourceDetailsToMap(obj *oci_core.BootVolumeSourceDetails) map[str
501509

502510
return result
503511
}
512+
513+
func (s *CoreBootVolumeResourceCrud) updateCompartment(compartment interface{}) error {
514+
changeCompartmentRequest := oci_core.ChangeBootVolumeCompartmentRequest{}
515+
516+
idTmp := s.D.Id()
517+
changeCompartmentRequest.BootVolumeId = &idTmp
518+
519+
compartmentTmp := compartment.(string)
520+
changeCompartmentRequest.CompartmentId = &compartmentTmp
521+
522+
changeCompartmentRequest.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "core")
523+
524+
_, err := s.Client.ChangeBootVolumeCompartment(context.Background(), changeCompartmentRequest)
525+
if err != nil {
526+
return err
527+
}
528+
return nil
529+
}

oci/core_boot_volume_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ func TestCoreBootVolumeResource_basic(t *testing.T) {
7676
compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
7777
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
7878

79+
compartmentIdU := getEnvSettingWithDefault("compartment_id_for_update", compartmentId)
80+
compartmentIdUVariableStr := fmt.Sprintf("variable \"compartment_id_for_update\" { default = \"%s\" }\n", compartmentIdU)
81+
7982
resourceName := "oci_core_boot_volume.test_boot_volume"
8083
datasourceName := "data.oci_core_boot_volumes.test_boot_volumes"
8184
singularDatasourceName := "data.oci_core_boot_volume.test_boot_volume"
@@ -142,6 +145,41 @@ func TestCoreBootVolumeResource_basic(t *testing.T) {
142145
),
143146
},
144147

148+
// verify update to the compartment (the compartment will be switched back in the next step)
149+
{
150+
Config: config + compartmentIdVariableStr + compartmentIdUVariableStr + BootVolumeResourceDependencies +
151+
generateResourceFromRepresentationMap("oci_core_boot_volume", "test_boot_volume", Optional, Create,
152+
representationCopyWithNewProperties(bootVolumeRepresentation, map[string]interface{}{
153+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id_for_update}`},
154+
})),
155+
Check: resource.ComposeAggregateTestCheckFunc(
156+
resource.TestCheckResourceAttrSet(resourceName, "availability_domain"),
157+
resource.TestCheckResourceAttrSet(resourceName, "backup_policy_id"),
158+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentIdU),
159+
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
160+
resource.TestCheckResourceAttr(resourceName, "display_name", "displayName"),
161+
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
162+
resource.TestCheckResourceAttrSet(resourceName, "id"),
163+
resource.TestCheckResourceAttrSet(resourceName, "kms_key_id"),
164+
resource.TestCheckResourceAttr(resourceName, "size_in_gbs", "50"),
165+
resource.TestCheckResourceAttrSet(resourceName, "size_in_mbs"),
166+
resource.TestCheckResourceAttr(resourceName, "source_details.#", "1"),
167+
resource.TestCheckResourceAttrSet(resourceName, "source_details.0.id"),
168+
resource.TestCheckResourceAttr(resourceName, "source_details.0.type", "bootVolume"),
169+
resource.TestCheckResourceAttrSet(resourceName, "state"),
170+
resource.TestCheckResourceAttrSet(resourceName, "time_created"),
171+
resource.TestCheckNoResourceAttr(resourceName, "volume_group_id"),
172+
173+
func(s *terraform.State) (err error) {
174+
resId2, err = fromInstanceState(s, resourceName, "id")
175+
if resId != resId2 {
176+
return fmt.Errorf("resource recreated when it was supposed to be updated")
177+
}
178+
return err
179+
},
180+
),
181+
},
182+
145183
// verify updates to updatable parameters
146184
{
147185
PreConfig: waitTillCondition(testAccProvider, &resId, bootVolumeWaitCondition, BootVolumeWaitConditionDuration,

oci/core_volume_backup_resource.go

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package provider
55
import (
66
"context"
77
"fmt"
8+
"log"
89
"strconv"
910

1011
"github.com/hashicorp/terraform/helper/schema"
@@ -55,6 +56,13 @@ func CoreVolumeBackupResource() *schema.Resource {
5556
},
5657
},
5758
},
59+
60+
// Optional
61+
"compartment_id": {
62+
Type: schema.TypeString,
63+
Optional: true,
64+
Computed: true,
65+
},
5866
"defined_tags": {
5967
Type: schema.TypeMap,
6068
Optional: true,
@@ -84,10 +92,6 @@ func CoreVolumeBackupResource() *schema.Resource {
8492
},
8593

8694
// Computed
87-
"compartment_id": {
88-
Type: schema.TypeString,
89-
Computed: true,
90-
},
9195
"expiration_time": {
9296
Type: schema.TypeString,
9397
Computed: true,
@@ -139,7 +143,30 @@ func createCoreVolumeBackup(d *schema.ResourceData, m interface{}) error {
139143
sync.D = d
140144
sync.Client = m.(*OracleClients).blockstorageClient
141145

142-
return CreateResource(d, sync)
146+
compartment, ok := sync.D.GetOkExists("compartment_id")
147+
148+
err := CreateResource(d, sync)
149+
if err != nil {
150+
return err
151+
}
152+
153+
if ok && compartment != *sync.Res.CompartmentId {
154+
err = sync.updateCompartment(compartment)
155+
if err != nil {
156+
return err
157+
}
158+
tmp := compartment.(string)
159+
sync.Res.CompartmentId = &tmp
160+
err := sync.Get()
161+
if err != nil {
162+
log.Printf("error doing a Get() after compartment update: %v", err)
163+
}
164+
err = sync.SetData()
165+
if err != nil {
166+
log.Printf("error doing a SetData() after compartment update: %v", err)
167+
}
168+
}
169+
return nil
143170
}
144171

145172
func readCoreVolumeBackup(d *schema.ResourceData, m interface{}) error {
@@ -325,6 +352,15 @@ func (s *CoreVolumeBackupResourceCrud) Get() error {
325352
}
326353

327354
func (s *CoreVolumeBackupResourceCrud) Update() error {
355+
if compartment, ok := s.D.GetOkExists("compartment_id"); ok && s.D.HasChange("compartment_id") {
356+
oldRaw, newRaw := s.D.GetChange("compartment_id")
357+
if newRaw != "" && oldRaw != "" {
358+
err := s.updateCompartment(compartment)
359+
if err != nil {
360+
return err
361+
}
362+
}
363+
}
328364
request := oci_core.UpdateVolumeBackupRequest{}
329365

330366
if definedTags, ok := s.D.GetOkExists("defined_tags"); ok {
@@ -429,3 +465,21 @@ func (s *CoreVolumeBackupResourceCrud) SetData() error {
429465

430466
return nil
431467
}
468+
469+
func (s *CoreVolumeBackupResourceCrud) updateCompartment(compartment interface{}) error {
470+
changeCompartmentRequest := oci_core.ChangeVolumeBackupCompartmentRequest{}
471+
472+
compartmentTmp := compartment.(string)
473+
changeCompartmentRequest.CompartmentId = &compartmentTmp
474+
475+
idTmp := s.D.Id()
476+
changeCompartmentRequest.VolumeBackupId = &idTmp
477+
478+
changeCompartmentRequest.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "core")
479+
480+
_, err := s.Client.ChangeVolumeBackupCompartment(context.Background(), changeCompartmentRequest)
481+
if err != nil {
482+
return err
483+
}
484+
return nil
485+
}

0 commit comments

Comments
 (0)