Skip to content

Commit

Permalink
azurerm_site_recovery_replication_recovery_plan: keep the order of …
Browse files Browse the repository at this point in the history
…`recovery_group` (#22348)

* `azurerm_site_recovery_replication_recovery_plan`: keep the order of `recovery_group`

Signed-off-by: ziyeqf <[email protected]>

* update testcase

Signed-off-by: ziyeqf <[email protected]>

* update per comments

Signed-off-by: ziyeqf <[email protected]>

* update code

Signed-off-by: ziyeqf <[email protected]>

* golint

Signed-off-by: ziyeqf <[email protected]>

* update testcase

Signed-off-by: ziyeqf <[email protected]>

* limit `shutdown_recovery_group` and `failover_recovery_group` to 1

Signed-off-by: ziyeqf <[email protected]>

* update code

Signed-off-by: ziyeqf <[email protected]>

* golint

Signed-off-by: ziyeqf <[email protected]>

* lint

Signed-off-by: ziyeqf <[email protected]>

* Document wording tweaks

---------

Signed-off-by: ziyeqf <[email protected]>
Co-authored-by: Tom Bamford <[email protected]>
  • Loading branch information
ziyeqf and manicminer authored Jul 20, 2023
1 parent 842e13b commit 44d26c6
Show file tree
Hide file tree
Showing 5 changed files with 526 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationrecoveryplans"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -18,6 +19,40 @@ import (

type SiteRecoveryReplicationRecoveryPlanDataSource struct{}

type SiteRecoveryReplicationRecoveryPlanDataSourceModel struct {
Name string `tfschema:"name"`
RecoveryGroup []RecoveryGroupDataSourceModel `tfschema:"recovery_group"`
RecoveryVaultId string `tfschema:"recovery_vault_id"`
SourceRecoveryFabricId string `tfschema:"source_recovery_fabric_id"`
TargetRecoveryFabricId string `tfschema:"target_recovery_fabric_id"`
A2ASettings []ReplicationRecoveryPlanA2ASpecificInputDataSourceModel `tfschema:"azure_to_azure_settings"`
}

type RecoveryGroupDataSourceModel struct {
GroupType string `tfschema:"type"`
PostAction []ActionDataSourceModel `tfschema:"post_action"`
PreAction []ActionDataSourceModel `tfschema:"pre_action"`
ReplicatedProtectedItems []string `tfschema:"replicated_protected_items"`
}

type ActionDataSourceModel struct {
ActionDetailType string `tfschema:"type"`
FabricLocation string `tfschema:"fabric_location"`
FailOverDirections []string `tfschema:"fail_over_directions"`
FailOverTypes []string `tfschema:"fail_over_types"`
ManualActionInstruction string `tfschema:"manual_action_instruction"`
Name string `tfschema:"name"`
RunbookId string `tfschema:"runbook_id"`
ScriptPath string `tfschema:"script_path"`
}

type ReplicationRecoveryPlanA2ASpecificInputDataSourceModel struct {
PrimaryZone string `tfschema:"primary_zone"`
RecoveryZone string `tfschema:"recovery_zone"`
PrimaryEdgeZone string `tfschema:"primary_edge_zone"`
RecoveryEdgeZone string `tfschema:"recovery_edge_zone"`
}

var _ sdk.DataSource = SiteRecoveryReplicationRecoveryPlanDataSource{}

func (r SiteRecoveryReplicationRecoveryPlanDataSource) ResourceType() string {
Expand Down Expand Up @@ -63,7 +98,7 @@ func (r SiteRecoveryReplicationRecoveryPlanDataSource) Read() sdk.ResourceFunc {
return fmt.Errorf("making Read request on site recovery replication plan %s : model is nil", id.String())
}

state := SiteRecoveryReplicationRecoveryPlanModel{
state := SiteRecoveryReplicationRecoveryPlanDataSourceModel{
Name: id.ReplicationRecoveryPlanName,
RecoveryVaultId: vaultId.ID(),
}
Expand All @@ -77,19 +112,77 @@ func (r SiteRecoveryReplicationRecoveryPlanDataSource) Read() sdk.ResourceFunc {
}

if group := prop.Groups; group != nil {
state.RecoveryGroup = flattenRecoveryGroups(*group)
state.RecoveryGroup = flattenDataSourceRecoveryGroups(*group)
}

if details := prop.ProviderSpecificDetails; details != nil && len(*details) > 0 {
state.A2ASettings = flattenRecoveryPlanProviderSpecficInput(details)
state.A2ASettings = flattenDataSourceRecoveryPlanProviderSpecficInput(details)
}
}

metadata.SetID(id)
return metadata.Encode(&state)
},
}
}

func flattenDataSourceRecoveryGroups(input []replicationrecoveryplans.RecoveryPlanGroup) []RecoveryGroupDataSourceModel {
output := make([]RecoveryGroupDataSourceModel, 0)
for _, groupItem := range input {
recoveryGroupOutput := RecoveryGroupDataSourceModel{}
recoveryGroupOutput.GroupType = string(groupItem.GroupType)
if groupItem.ReplicationProtectedItems != nil {
recoveryGroupOutput.ReplicatedProtectedItems = flattenRecoveryPlanProtectedItems(groupItem.ReplicationProtectedItems)
}
if groupItem.StartGroupActions != nil {
recoveryGroupOutput.PreAction = flattenDataSourceRecoveryPlanActions(groupItem.StartGroupActions)
}
if groupItem.EndGroupActions != nil {
recoveryGroupOutput.PostAction = flattenDataSourceRecoveryPlanActions(groupItem.EndGroupActions)
}
output = append(output, recoveryGroupOutput)
}
return output
}

func flattenDataSourceRecoveryPlanActions(input *[]replicationrecoveryplans.RecoveryPlanAction) []ActionDataSourceModel {
actionOutputs := make([]ActionDataSourceModel, 0)
for _, action := range *input {
actionOutput := ActionDataSourceModel{
Name: action.ActionName,
}
switch detail := action.CustomDetails.(type) {
case replicationrecoveryplans.RecoveryPlanAutomationRunbookActionDetails:
actionOutput.ActionDetailType = "AutomationRunbookActionDetails"
actionOutput.FabricLocation = string(detail.FabricLocation)
if detail.RunbookId != nil {
actionOutput.RunbookId = *detail.RunbookId
}
case replicationrecoveryplans.RecoveryPlanManualActionDetails:
actionOutput.ActionDetailType = "ManualActionDetails"
if detail.Description != nil {
actionOutput.ManualActionInstruction = *detail.Description
}
case replicationrecoveryplans.RecoveryPlanScriptActionDetails:
actionOutput.ActionDetailType = "ScriptActionDetails"
actionOutput.ScriptPath = detail.Path
actionOutput.FabricLocation = string(detail.FabricLocation)
}

failoverDirections := make([]string, 0)
for _, failoverDirection := range action.FailoverDirections {
failoverDirections = append(failoverDirections, string(failoverDirection))
}

failoverTypes := make([]string, 0)
for _, failoverType := range action.FailoverTypes {
failoverTypes = append(failoverTypes, string(failoverType))
}
actionOutput.FailOverDirections = failoverDirections
actionOutput.FailOverTypes = failoverTypes
actionOutputs = append(actionOutputs, actionOutput)
}
return actionOutputs
}

func (r SiteRecoveryReplicationRecoveryPlanDataSource) Arguments() map[string]*pluginsdk.Schema {
Expand All @@ -108,6 +201,22 @@ func (r SiteRecoveryReplicationRecoveryPlanDataSource) Arguments() map[string]*p
}
}

func flattenDataSourceRecoveryPlanProviderSpecficInput(input *[]replicationrecoveryplans.RecoveryPlanProviderSpecificDetails) []ReplicationRecoveryPlanA2ASpecificInputDataSourceModel {
output := make([]ReplicationRecoveryPlanA2ASpecificInputDataSourceModel, 0)
for _, providerSpecificInput := range *input {
if a2aInput, ok := providerSpecificInput.(replicationrecoveryplans.RecoveryPlanA2ADetails); ok {
o := ReplicationRecoveryPlanA2ASpecificInputDataSourceModel{
PrimaryZone: pointer.From(a2aInput.PrimaryZone),
RecoveryZone: pointer.From(a2aInput.RecoveryZone),
PrimaryEdgeZone: flattenEdgeZone(a2aInput.PrimaryExtendedLocation),
RecoveryEdgeZone: flattenEdgeZone(a2aInput.RecoveryExtendedLocation),
}
output = append(output, o)
}
}
return output
}

func (r SiteRecoveryReplicationRecoveryPlanDataSource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"source_recovery_fabric_id": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ func TestAccDataSourceSiteRecoveryReplicationRecoveryPlan_basic(t *testing.T) {
check.That(data.ResourceName).Key("recovery_vault_id").Exists(),
check.That(data.ResourceName).Key("source_recovery_fabric_id").Exists(),
check.That(data.ResourceName).Key("target_recovery_fabric_id").Exists(),
check.That(data.ResourceName).Key("recovery_group.0.type").HasValue("Boot"),
check.That(data.ResourceName).Key("recovery_group.1.type").HasValue("Failover"),
check.That(data.ResourceName).Key("recovery_group.2.type").HasValue("Shutdown"),
),
},
})
Expand All @@ -45,9 +42,6 @@ func TestAccDataSourceSiteRecoveryReplicationRecoveryPlan_withZones(t *testing.T
check.That(data.ResourceName).Key("recovery_vault_id").Exists(),
check.That(data.ResourceName).Key("source_recovery_fabric_id").Exists(),
check.That(data.ResourceName).Key("target_recovery_fabric_id").Exists(),
check.That(data.ResourceName).Key("recovery_group.0.type").HasValue("Boot"),
check.That(data.ResourceName).Key("recovery_group.1.type").HasValue("Failover"),
check.That(data.ResourceName).Key("recovery_group.2.type").HasValue("Shutdown"),
check.That(data.ResourceName).Key("azure_to_azure_settings.0.primary_zone").HasValue("1"),
check.That(data.ResourceName).Key("azure_to_azure_settings.0.recovery_zone").HasValue("2"),
),
Expand Down
Loading

0 comments on commit 44d26c6

Please sign in to comment.