Skip to content

Commit 7af7a6f

Browse files
committed
Support for Moving DRG Resources Across Compartments
1 parent 35f8104 commit 7af7a6f

23 files changed

+1065
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### Added
44
- Support DBaaS VM DB Fast Provisioning
55
- Support for required default tags
6+
- Support for moving `oci_core_drg` resources across compartments
67

78
### Fixed
89
- Fix compositeId parsing for pre-authenticated requests in object storage [Issue #867](https://github.com/terraform-providers/terraform-provider-oci/issues/867)

oci/core_drg_resource.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/hashicorp/terraform/helper/schema"
99

1010
oci_core "github.com/oracle/oci-go-sdk/core"
11+
oci_work_requests "github.com/oracle/oci-go-sdk/workrequests"
1112
)
1213

1314
func CoreDrgResource() *schema.Resource {
@@ -25,7 +26,6 @@ func CoreDrgResource() *schema.Resource {
2526
"compartment_id": {
2627
Type: schema.TypeString,
2728
Required: true,
28-
ForceNew: true,
2929
},
3030

3131
// Optional
@@ -81,7 +81,7 @@ func updateCoreDrg(d *schema.ResourceData, m interface{}) error {
8181
sync := &CoreDrgResourceCrud{}
8282
sync.D = d
8383
sync.Client = m.(*OracleClients).virtualNetworkClient
84-
84+
sync.workRequestClient = m.(*OracleClients).workRequestClient
8585
return UpdateResource(d, sync)
8686
}
8787

@@ -97,6 +97,7 @@ func deleteCoreDrg(d *schema.ResourceData, m interface{}) error {
9797
type CoreDrgResourceCrud struct {
9898
BaseCrud
9999
Client *oci_core.VirtualNetworkClient
100+
workRequestClient *oci_work_requests.WorkRequestClient
100101
Res *oci_core.Drg
101102
DisableNotFoundRetries bool
102103
}
@@ -183,6 +184,15 @@ func (s *CoreDrgResourceCrud) Get() error {
183184
}
184185

185186
func (s *CoreDrgResourceCrud) Update() error {
187+
if compartment, ok := s.D.GetOkExists("compartment_id"); ok && s.D.HasChange("compartment_id") {
188+
oldRaw, newRaw := s.D.GetChange("compartment_id")
189+
if newRaw != "" && oldRaw != "" {
190+
err := s.updateCompartment(compartment)
191+
if err != nil {
192+
return err
193+
}
194+
}
195+
}
186196
request := oci_core.UpdateDrgRequest{}
187197

188198
if definedTags, ok := s.D.GetOkExists("defined_tags"); ok {
@@ -251,3 +261,26 @@ func (s *CoreDrgResourceCrud) SetData() error {
251261

252262
return nil
253263
}
264+
265+
func (s *CoreDrgResourceCrud) updateCompartment(compartment interface{}) error {
266+
changeCompartmentRequest := oci_core.ChangeDrgCompartmentRequest{}
267+
268+
compartmentTmp := compartment.(string)
269+
changeCompartmentRequest.CompartmentId = &compartmentTmp
270+
271+
idTmp := s.D.Id()
272+
changeCompartmentRequest.DrgId = &idTmp
273+
274+
changeCompartmentRequest.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "core")
275+
276+
response, err := s.Client.ChangeDrgCompartment(context.Background(), changeCompartmentRequest)
277+
if err != nil {
278+
return err
279+
}
280+
workId := response.OpcWorkRequestId
281+
_, err = WaitForWorkRequest(s.workRequestClient, workId, "core", oci_work_requests.WorkRequestResourceActionTypeUpdated, s.D.Timeout(schema.TimeoutUpdate), s.DisableNotFoundRetries)
282+
if err != nil {
283+
return err
284+
}
285+
return nil
286+
}

oci/core_drg_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ func TestCoreDrgResource_basic(t *testing.T) {
4848
compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
4949
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
5050

51+
compartmentIdU := getEnvSettingWithDefault("compartment_id_for_update", compartmentId)
52+
compartmentIdUVariableStr := fmt.Sprintf("variable \"compartment_id_for_update\" { default = \"%s\" }\n", compartmentIdU)
53+
5154
resourceName := "oci_core_drg.test_drg"
5255
datasourceName := "data.oci_core_drgs.test_drgs"
5356

@@ -97,6 +100,31 @@ func TestCoreDrgResource_basic(t *testing.T) {
97100
),
98101
},
99102

103+
// verify update to the compartment (the compartment will be switched back in the next step)
104+
{
105+
Config: config + compartmentIdVariableStr + compartmentIdUVariableStr + DrgResourceDependencies +
106+
generateResourceFromRepresentationMap("oci_core_drg", "test_drg", Optional, Create,
107+
representationCopyWithNewProperties(drgRepresentation, map[string]interface{}{
108+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id_for_update}`},
109+
})),
110+
Check: resource.ComposeAggregateTestCheckFunc(
111+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentIdU),
112+
resource.TestCheckResourceAttr(resourceName, "defined_tags.%", "1"),
113+
resource.TestCheckResourceAttr(resourceName, "display_name", "MyDrg"),
114+
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
115+
resource.TestCheckResourceAttrSet(resourceName, "id"),
116+
resource.TestCheckResourceAttrSet(resourceName, "state"),
117+
118+
func(s *terraform.State) (err error) {
119+
resId2, err = fromInstanceState(s, resourceName, "id")
120+
if resId != resId2 {
121+
return fmt.Errorf("resource recreated when it was supposed to be updated")
122+
}
123+
return err
124+
},
125+
),
126+
},
127+
100128
// verify updates to updatable parameters
101129
{
102130
Config: config + compartmentIdVariableStr + DrgResourceDependencies +

oci/crud_helpers.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
oci_common "github.com/oracle/oci-go-sdk/common"
1919
oci_identity "github.com/oracle/oci-go-sdk/identity"
2020
oci_load_balancer "github.com/oracle/oci-go-sdk/loadbalancer"
21+
oci_work_requests "github.com/oracle/oci-go-sdk/workrequests"
2122

2223
"github.com/terraform-providers/terraform-provider-oci/httpreplay"
2324
"github.com/terraform-providers/terraform-provider-oci/metrics"
@@ -795,3 +796,75 @@ func getRetryPolicyWithAdditionalRetryCondition(timeout time.Duration, retryCond
795796
func elaspedInMillisecond(start time.Time) int64 {
796797
return time.Since(start).Nanoseconds() / int64(time.Millisecond)
797798
}
799+
800+
func WaitForWorkRequest(workRequestClient *oci_work_requests.WorkRequestClient, workRequestId *string, entityType string, action oci_work_requests.WorkRequestResourceActionTypeEnum,
801+
timeout time.Duration, disableFoundRetries bool) (*string, error) {
802+
retryPolicy := getRetryPolicy(disableFoundRetries, "work_request")
803+
retryPolicy.ShouldRetryOperation = workRequestShouldRetryFunc(timeout)
804+
805+
response := oci_work_requests.GetWorkRequestResponse{}
806+
stateConf := &resource.StateChangeConf{
807+
Pending: []string{
808+
string(oci_work_requests.WorkRequestStatusInProgress),
809+
string(oci_work_requests.WorkRequestStatusAccepted),
810+
string(oci_work_requests.WorkRequestStatusCanceling),
811+
},
812+
Target: []string{
813+
string(oci_work_requests.WorkRequestStatusSucceeded),
814+
string(oci_work_requests.WorkRequestStatusFailed),
815+
string(oci_work_requests.WorkRequestStatusCanceled),
816+
},
817+
Refresh: func() (interface{}, string, error) {
818+
var err error
819+
response, err = workRequestClient.GetWorkRequest(context.Background(),
820+
oci_work_requests.GetWorkRequestRequest{
821+
WorkRequestId: workRequestId,
822+
RequestMetadata: oci_common.RequestMetadata{
823+
RetryPolicy: retryPolicy,
824+
},
825+
})
826+
wr := &response.WorkRequest
827+
return wr, string(wr.Status), err
828+
},
829+
Timeout: timeout,
830+
}
831+
if _, e := stateConf.WaitForState(); e != nil {
832+
return nil, e
833+
}
834+
835+
var identifier *string
836+
// The work request response contains an array of objects that finished the operation
837+
for _, res := range response.Resources {
838+
if strings.Contains(strings.ToLower(*res.EntityType), entityType) {
839+
if res.ActionType == action {
840+
identifier = res.Identifier
841+
break
842+
}
843+
}
844+
}
845+
846+
return identifier, nil
847+
}
848+
849+
func workRequestShouldRetryFunc(timeout time.Duration) func(response oci_common.OCIOperationResponse) bool {
850+
startTime := time.Now()
851+
stopTime := startTime.Add(timeout)
852+
return func(response oci_common.OCIOperationResponse) bool {
853+
854+
// Stop after timeout has elapsed
855+
if time.Now().After(stopTime) {
856+
return false
857+
}
858+
859+
// Make sure we stop on default rules
860+
if shouldRetry(response, false, "work_request", startTime) {
861+
return true
862+
}
863+
864+
// Only stop if the time Finished is set
865+
if workRequestResponse, ok := response.Response.(oci_work_requests.GetWorkRequestResponse); ok {
866+
return workRequestResponse.TimeFinished == nil
867+
}
868+
return false
869+
}
870+
}

oci/provider_clients.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
oci_ons "github.com/oracle/oci-go-sdk/ons"
2525
oci_streaming "github.com/oracle/oci-go-sdk/streaming"
2626
oci_waas "github.com/oracle/oci-go-sdk/waas"
27+
oci_work_requests "github.com/oracle/oci-go-sdk/workrequests"
2728

2829
oci_common "github.com/oracle/oci-go-sdk/common"
2930
)
@@ -59,6 +60,7 @@ type OracleClients struct {
5960
streamAdminClient *oci_streaming.StreamAdminClient
6061
virtualNetworkClient *oci_core.VirtualNetworkClient
6162
waasClient *oci_waas.WaasClient
63+
workRequestClient *oci_work_requests.WorkRequestClient
6264
}
6365

6466
func (m *OracleClients) FunctionsInvokeClient(endpoint string) (*oci_functions.FunctionsInvokeClient, error) {
@@ -386,5 +388,15 @@ func createSDKClients(clients *OracleClients, configProvider oci_common.Configur
386388
}
387389
clients.waasClient = &waasClient
388390

391+
workRequestClient, err := oci_work_requests.NewWorkRequestClientWithConfigurationProvider(configProvider)
392+
if err != nil {
393+
return
394+
}
395+
err = configureClient(&workRequestClient.BaseClient)
396+
if err != nil {
397+
return
398+
}
399+
clients.workRequestClient = &workRequestClient
400+
389401
return
390402
}

vendor/github.com/oracle/oci-go-sdk/workrequests/get_work_request_request_response.go

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)