Skip to content

Commit 8de04c2

Browse files
dyajamanNagaRajuPasunuri
authored andcommitted
Added - Support for refresh DR Plans
1 parent a1d7a87 commit 8de04c2

File tree

8 files changed

+388
-21
lines changed

8 files changed

+388
-21
lines changed

examples/disaster_recovery/dr_plan/dr_plan.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ resource "oci_disaster_recovery_dr_plan" "test_dr_plan" {
4949
display_name = var.dr_plan_display_name
5050
dr_protection_group_id = data.oci_disaster_recovery_dr_protection_groups.test_dr_protection_groups.dr_protection_group_collection.0.items.0.id
5151
type = var.dr_plan_type
52+
refresh_trigger = 0
53+
verify_trigger = 0
5254

5355
lifecycle {
5456
ignore_changes = [defined_tags]

internal/integrationtest/disaster_recovery_dr_plan_test.go

Lines changed: 164 additions & 20 deletions
Large diffs are not rendered by default.

internal/service/disaster_recovery/disaster_recovery_dr_plan_data_source.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ func (s *DisasterRecoveryDrPlanDataSourceCrud) SetData() error {
8888
s.D.Set("life_cycle_details", *s.Res.LifeCycleDetails)
8989
}
9090

91+
s.D.Set("lifecycle_sub_state", s.Res.LifecycleSubState)
92+
9193
if s.Res.PeerDrProtectionGroupId != nil {
9294
s.D.Set("peer_dr_protection_group_id", *s.Res.PeerDrProtectionGroupId)
9395
}
@@ -102,6 +104,10 @@ func (s *DisasterRecoveryDrPlanDataSourceCrud) SetData() error {
102104
}
103105
s.D.Set("plan_groups", planGroups)
104106

107+
if s.Res.SourcePlanId != nil {
108+
s.D.Set("source_plan_id", *s.Res.SourcePlanId)
109+
}
110+
105111
s.D.Set("state", s.Res.LifecycleState)
106112

107113
if s.Res.SystemTags != nil {

internal/service/disaster_recovery/disaster_recovery_dr_plan_resource.go

Lines changed: 190 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ func DisasterRecoveryDrPlanResource() *schema.Resource {
6161
Computed: true,
6262
Elem: schema.TypeString,
6363
},
64+
"source_plan_id": {
65+
Type: schema.TypeString,
66+
Optional: true,
67+
Computed: true,
68+
ForceNew: true,
69+
},
70+
"refresh_trigger": {
71+
Type: schema.TypeInt,
72+
Optional: true,
73+
},
74+
"verify_trigger": {
75+
Type: schema.TypeInt,
76+
Optional: true,
77+
},
6478

6579
// Computed
6680
"compartment_id": {
@@ -71,6 +85,10 @@ func DisasterRecoveryDrPlanResource() *schema.Resource {
7185
Type: schema.TypeString,
7286
Computed: true,
7387
},
88+
"lifecycle_sub_state": {
89+
Type: schema.TypeString,
90+
Computed: true,
91+
},
7492
"peer_dr_protection_group_id": {
7593
Type: schema.TypeString,
7694
Computed: true,
@@ -101,6 +119,10 @@ func DisasterRecoveryDrPlanResource() *schema.Resource {
101119
Type: schema.TypeBool,
102120
Computed: true,
103121
},
122+
"refresh_status": {
123+
Type: schema.TypeString,
124+
Computed: true,
125+
},
104126
"steps": {
105127
Type: schema.TypeList,
106128
Computed: true,
@@ -135,6 +157,10 @@ func DisasterRecoveryDrPlanResource() *schema.Resource {
135157
Type: schema.TypeString,
136158
Computed: true,
137159
},
160+
"refresh_status": {
161+
Type: schema.TypeString,
162+
Computed: true,
163+
},
138164
"timeout": {
139165
Type: schema.TypeInt,
140166
Computed: true,
@@ -265,7 +291,30 @@ func updateDisasterRecoveryDrPlan(d *schema.ResourceData, m interface{}) error {
265291
sync.D = d
266292
sync.Client = m.(*client.OracleClients).DisasterRecoveryClient()
267293

268-
return tfresource.UpdateResource(d, sync)
294+
if _, ok := sync.D.GetOkExists("refresh_trigger"); ok && sync.D.HasChange("refresh_trigger") {
295+
oldRaw, newRaw := sync.D.GetChange("refresh_trigger")
296+
oldValue := oldRaw.(int)
297+
newValue := newRaw.(int)
298+
if oldValue < newValue {
299+
return sync.RefreshDrPlan()
300+
} else {
301+
sync.D.Set("refresh_trigger", oldRaw)
302+
return fmt.Errorf("new value of trigger should be greater than the old value")
303+
}
304+
305+
} else if _, ok := sync.D.GetOkExists("verify_trigger"); ok && sync.D.HasChange("verify_trigger") {
306+
oldRaw, newRaw := sync.D.GetChange("verify_trigger")
307+
oldValue := oldRaw.(int)
308+
newValue := newRaw.(int)
309+
if oldValue < newValue {
310+
return sync.VerifyDrPlan()
311+
} else {
312+
sync.D.Set("verify_trigger", oldRaw)
313+
return fmt.Errorf("new value of trigger should be greater than the old value")
314+
}
315+
} else {
316+
return tfresource.UpdateResource(d, sync)
317+
}
269318
}
270319

271320
func deleteDisasterRecoveryDrPlan(d *schema.ResourceData, m interface{}) error {
@@ -338,6 +387,11 @@ func (s *DisasterRecoveryDrPlanResourceCrud) Create() error {
338387
request.FreeformTags = tfresource.ObjectMapToStringMap(freeformTags.(map[string]interface{}))
339388
}
340389

390+
if sourcePlanId, ok := s.D.GetOkExists("source_plan_id"); ok {
391+
tmp := sourcePlanId.(string)
392+
request.SourcePlanId = &tmp
393+
}
394+
341395
if type_, ok := s.D.GetOkExists("type"); ok {
342396
request.Type = oci_disaster_recovery.DrPlanTypeEnum(type_.(string))
343397
}
@@ -588,6 +642,8 @@ func (s *DisasterRecoveryDrPlanResourceCrud) SetData() error {
588642
s.D.Set("life_cycle_details", *s.Res.LifeCycleDetails)
589643
}
590644

645+
s.D.Set("lifecycle_sub_state", s.Res.LifecycleSubState)
646+
591647
if s.Res.PeerDrProtectionGroupId != nil {
592648
s.D.Set("peer_dr_protection_group_id", *s.Res.PeerDrProtectionGroupId)
593649
}
@@ -602,6 +658,10 @@ func (s *DisasterRecoveryDrPlanResourceCrud) SetData() error {
602658
}
603659
s.D.Set("plan_groups", planGroups)
604660

661+
if s.Res.SourcePlanId != nil {
662+
s.D.Set("source_plan_id", *s.Res.SourcePlanId)
663+
}
664+
605665
s.D.Set("state", s.Res.LifecycleState)
606666

607667
if s.Res.SystemTags != nil {
@@ -621,6 +681,67 @@ func (s *DisasterRecoveryDrPlanResourceCrud) SetData() error {
621681
return nil
622682
}
623683

684+
func (s *DisasterRecoveryDrPlanResourceCrud) RefreshDrPlan() error {
685+
request := oci_disaster_recovery.RefreshDrPlanRequest{}
686+
err := s.populateTopLevelPolymorphicRefreshDrPlanRequest(&request)
687+
if err != nil {
688+
return err
689+
}
690+
691+
request.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "disaster_recovery")
692+
693+
response, err := s.Client.RefreshDrPlan(context.Background(), request)
694+
if err != nil {
695+
return err
696+
}
697+
698+
if waitErr := tfresource.WaitForUpdatedState(s.D, s); waitErr != nil {
699+
return waitErr
700+
}
701+
702+
val := s.D.Get("refresh_trigger")
703+
if val != nil {
704+
err := s.D.Set("refresh_trigger", val)
705+
if err != nil {
706+
return err
707+
}
708+
}
709+
710+
workId := response.OpcWorkRequestId
711+
return s.getDrPlanFromWorkRequest(workId, tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "disaster_recovery"), oci_disaster_recovery.ActionTypeUpdated, s.D.Timeout(schema.TimeoutUpdate))
712+
}
713+
714+
func (s *DisasterRecoveryDrPlanResourceCrud) VerifyDrPlan() error {
715+
request := oci_disaster_recovery.VerifyDrPlanRequest{}
716+
717+
err := s.populateTopLevelPolymorphicVerifyDrPlanRequest(&request)
718+
if err != nil {
719+
return err
720+
}
721+
722+
request.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "disaster_recovery")
723+
724+
response, err := s.Client.VerifyDrPlan(context.Background(), request)
725+
if err != nil {
726+
return err
727+
}
728+
729+
if waitErr := tfresource.WaitForUpdatedState(s.D, s); waitErr != nil {
730+
return waitErr
731+
}
732+
733+
val := s.D.Get("verify_trigger")
734+
if val != nil {
735+
err := s.D.Set("verify_trigger", val)
736+
if err != nil {
737+
return err
738+
}
739+
}
740+
741+
workId := response.OpcWorkRequestId
742+
return s.getDrPlanFromWorkRequest(workId, tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "disaster_recovery"), oci_disaster_recovery.ActionTypeUpdated, s.D.Timeout(schema.TimeoutUpdate))
743+
}
744+
624745
func (s *DisasterRecoveryDrPlanResourceCrud) mapToDrPlanGroup(fieldKeyFormat string) (oci_disaster_recovery.DrPlanGroup, error) {
625746
result := oci_disaster_recovery.DrPlanGroup{}
626747

@@ -757,6 +878,8 @@ func DrPlanGroupToMap(obj oci_disaster_recovery.DrPlanGroup) map[string]interfac
757878
result["is_pause_enabled"] = bool(*obj.IsPauseEnabled)
758879
}
759880

881+
result["refresh_status"] = string(obj.RefreshStatus)
882+
760883
steps := []interface{}{}
761884
for _, item := range obj.Steps {
762885
steps = append(steps, DrPlanStepToMap(item))
@@ -834,6 +957,8 @@ func DrPlanStepToMap(obj oci_disaster_recovery.DrPlanStep) map[string]interface{
834957
result["member_id"] = string(*obj.MemberId)
835958
}
836959

960+
result["refresh_status"] = string(obj.RefreshStatus)
961+
837962
if obj.Timeout != nil {
838963
result["timeout"] = int(*obj.Timeout)
839964
}
@@ -880,6 +1005,8 @@ func DrPlanSummaryToMap(obj oci_disaster_recovery.DrPlanSummary) map[string]inte
8801005
result["life_cycle_details"] = string(*obj.LifeCycleDetails)
8811006
}
8821007

1008+
result["lifecycle_sub_state"] = string(obj.LifecycleSubState)
1009+
8831010
if obj.PeerDrProtectionGroupId != nil {
8841011
result["peer_dr_protection_group_id"] = string(*obj.PeerDrProtectionGroupId)
8851012
}
@@ -1173,3 +1300,65 @@ func UpdateObjectStorageScriptLocationDetailsToMap(obj *oci_disaster_recovery.Up
11731300

11741301
return result
11751302
}
1303+
1304+
func (s *DisasterRecoveryDrPlanResourceCrud) populateTopLevelPolymorphicRefreshDrPlanRequest(request *oci_disaster_recovery.RefreshDrPlanRequest) error {
1305+
//typeRaw, ok := s.D.GetOkExists("type")
1306+
//var type_ string
1307+
//if ok {
1308+
// type_ = typeRaw.(string)
1309+
//} else {
1310+
// type_ = "" // default value
1311+
//}
1312+
1313+
details := oci_disaster_recovery.RefreshDrPlanDefaultDetails{}
1314+
tmp := s.D.Id()
1315+
request.DrPlanId = &tmp
1316+
request.RefreshDrPlanDetails = details
1317+
1318+
//switch strings.ToLower(type_) {
1319+
//case strings.ToLower("DEFAULT"):
1320+
// details := oci_disaster_recovery.RefreshDrPlanDefaultDetails{}
1321+
//
1322+
// tmp := s.D.Id()
1323+
// request.DrPlanId = &tmp
1324+
//
1325+
// request.RefreshDrPlanDetails = details
1326+
1327+
//default:
1328+
// return fmt.Errorf("unknown type '%v' was specified", type_)
1329+
//}
1330+
1331+
return nil
1332+
}
1333+
1334+
func (s *DisasterRecoveryDrPlanResourceCrud) populateTopLevelPolymorphicVerifyDrPlanRequest(request *oci_disaster_recovery.VerifyDrPlanRequest) error {
1335+
//typeRaw, ok := s.D.GetOkExists("type")
1336+
//var type_ string
1337+
//if ok {
1338+
// type_ = typeRaw.(string)
1339+
//} else {
1340+
// type_ = "" // default value
1341+
//}
1342+
1343+
details := oci_disaster_recovery.VerifyDrPlanDefaultDetails{}
1344+
1345+
tmp := s.D.Id()
1346+
request.DrPlanId = &tmp
1347+
1348+
request.VerifyDrPlanDetails = details
1349+
1350+
//switch strings.ToLower(type_) {
1351+
//case strings.ToLower("DEFAULT"):
1352+
// details := oci_disaster_recovery.VerifyDrPlanDefaultDetails{}
1353+
//
1354+
// tmp := s.D.Id()
1355+
// request.DrPlanId = &tmp
1356+
//
1357+
// request.VerifyDrPlanDetails = details
1358+
//
1359+
//default:
1360+
// return fmt.Errorf("unknown type '%v' was specified", type_)
1361+
//}
1362+
1363+
return nil
1364+
}

internal/service/disaster_recovery/disaster_recovery_dr_plans_data_source.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ func DisasterRecoveryDrPlansDataSource() *schema.Resource {
3434
Type: schema.TypeString,
3535
Required: true,
3636
},
37+
"lifecycle_sub_state": {
38+
Type: schema.TypeString,
39+
Optional: true,
40+
},
3741
"state": {
3842
Type: schema.TypeString,
3943
Optional: true,
@@ -96,6 +100,10 @@ func (s *DisasterRecoveryDrPlansDataSourceCrud) Get() error {
96100
request.DrProtectionGroupId = &tmp
97101
}
98102

103+
if lifecycleSubState, ok := s.D.GetOkExists("lifecycle_sub_state"); ok {
104+
request.LifecycleSubState = oci_disaster_recovery.ListDrPlansLifecycleSubStateEnum(lifecycleSubState.(string))
105+
}
106+
99107
if state, ok := s.D.GetOkExists("state"); ok {
100108
request.LifecycleState = oci_disaster_recovery.ListDrPlansLifecycleStateEnum(state.(string))
101109
}

website/docs/d/disaster_recovery_dr_plan.html.markdown

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,22 @@ The following attributes are exported:
3939
* `freeform_tags` - Simple key-value pair that is applied without any predefined name, type or scope. Exists for cross-compatibility only. Example: `{"Department": "Finance"}`
4040
* `id` - The OCID of the DR plan. Example: `ocid1.drplan.oc1..uniqueID`
4141
* `life_cycle_details` - A message describing the DR plan's current state in more detail.
42+
* `lifecycle_sub_state` - The current state of the DR plan.
4243
* `peer_dr_protection_group_id` - The OCID of the peer DR protection group associated with this plan's DR protection group. Example: `ocid1.drprotectiongroup.oc1..uniqueID`
4344
* `peer_region` - The region of the peer DR protection group associated with this plan's DR protection group. Example: `us-ashburn-1`
4445
* `plan_groups` - The list of groups in this DR plan.
4546
* `display_name` - The display name of the group. Example: `DATABASE_SWITCHOVER`
4647
* `id` - The unique id of the group. Must not be modified by user. Example: `sgid1.group..uniqueID`
4748
* `is_pause_enabled` - A flag indicating whether this group should be enabled for execution. This flag is only applicable to the `USER_DEFINED_PAUSE` group. The flag should be null for the remaining group types. Example: `true`
49+
* `refresh_status` - The DR plan group refresh status. Example: `GROUP_MODIFIED`
4850
* `steps` - The list of steps in the group.
4951
* `display_name` - The display name of the group. Example: `DATABASE_SWITCHOVER`
5052
* `error_mode` - The error mode for this step.
5153
* `group_id` - The unique id of the group to which this step belongs. Must not be modified by user. Example: `sgid1.group..uniqueID`
5254
* `id` - The unique id of the step. Must not be modified by the user. Example: `sgid1.step..uniqueID`
5355
* `is_enabled` - A flag indicating whether this step should be enabled for execution. Example: `true`
5456
* `member_id` - The OCID of the member associated with this step. Example: `ocid1.database.oc1..uniqueID`
57+
* `refresh_status` - The DR plan step refresh status. Example: `STEP_ADDED`
5558
* `timeout` - The timeout in seconds for executing this step. Example: `600`
5659
* `type` - The plan step type.
5760
* `user_defined_step` - The details for a user-defined step in a DR plan.
@@ -86,6 +89,7 @@ The following attributes are exported:
8689

8790
**INVOKE_FUNCTION** - A step which invokes an Oracle Cloud Infrastructure function. See https://docs.oracle.com/en-us/iaas/Content/Functions/home.htm.
8891
* `type` - The group type. Example: `BUILT_IN`
92+
* `source_plan_id` - If this is a cloned DR plan, the OCID of the source DR plan that was used to clone this DR plan. If this DR plan was not cloned, then the value for this will be `null`. Example: `ocid1.drplan.oc1..uniqueID`
8993
* `state` - The current state of the DR plan.
9094
* `system_tags` - Usage of system tag keys. These predefined keys are scoped to namespaces. Example: `{"orcl-cloud.free-tier-retained": "true"}`
9195
* `time_created` - The date and time the DR plan was created. An RFC3339 formatted datetime string. Example: `2019-03-29T09:36:42Z`

0 commit comments

Comments
 (0)