Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CSGI-2782] Fix import for incident workflow #820

Merged
merged 1 commit into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pagerduty/data_source_pagerduty_incident_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func dataSourcePagerDutyIncidentWorkflowRead(ctx context.Context, d *schema.Reso
)
}

err = flattenIncidentWorkflow(d, found, false, nil)
err = flattenIncidentWorkflow(d, found, false, nil, false)
if err != nil {
return retry.NonRetryableError(err)
}
Expand Down
65 changes: 45 additions & 20 deletions pagerduty/resource_pagerduty_incident_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func resourcePagerDutyIncidentWorkflow() *schema.Resource {
DeleteContext: resourcePagerDutyIncidentWorkflowDelete,
CreateContext: resourcePagerDutyIncidentWorkflowCreate,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: resourcePagerDutyIncidentWorkflowImport,
},
CustomizeDiff: customizeIncidentWorkflowDiff(),
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -287,9 +287,7 @@ func customizeIncidentWorkflowDiff() schema.CustomizeDiffFunc {
// 6. Any remaining new inputs that were not already matched to old inputs should now be added to the result.
// This lets new inputs that do not have default values (which are already cached as generated=true) maintain
// their state in the diff, while not disrupting ordering of unchanged inputs.
for _, newInput := range newInputs {
result = append(result, newInput)
}
result = append(result, newInputs...)

return result
}
Expand Down Expand Up @@ -370,7 +368,7 @@ func resourcePagerDutyIncidentWorkflowCreate(ctx context.Context, d *schema.Reso
return diag.FromErr(err)
}

err = flattenIncidentWorkflow(d, createdWorkflow, true, specifiedSteps)
err = flattenIncidentWorkflow(d, createdWorkflow, true, specifiedSteps, false)
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -379,7 +377,7 @@ func resourcePagerDutyIncidentWorkflowCreate(ctx context.Context, d *schema.Reso

func resourcePagerDutyIncidentWorkflowRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
log.Printf("[INFO] Reading PagerDuty incident workflow %s", d.Id())
err := fetchIncidentWorkflow(ctx, d, meta, handleNotFoundError)
err := fetchIncidentWorkflow(ctx, d, meta, handleNotFoundError, false)
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -404,7 +402,7 @@ func resourcePagerDutyIncidentWorkflowUpdate(ctx context.Context, d *schema.Reso
return diag.FromErr(err)
}

err = flattenIncidentWorkflow(d, updatedWorkflow, true, specifiedSteps)
err = flattenIncidentWorkflow(d, updatedWorkflow, true, specifiedSteps, false)
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -424,7 +422,12 @@ func resourcePagerDutyIncidentWorkflowDelete(ctx context.Context, d *schema.Reso
return nil
}

func fetchIncidentWorkflow(ctx context.Context, d *schema.ResourceData, meta interface{}, errorCallback func(error, *schema.ResourceData) error) error {
func resourcePagerDutyIncidentWorkflowImport(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
err := fetchIncidentWorkflow(ctx, d, m, handleNotFoundError, true)
return []*schema.ResourceData{d}, err
}

func fetchIncidentWorkflow(ctx context.Context, d *schema.ResourceData, meta interface{}, errorCallback func(error, *schema.ResourceData) error, isImport bool) error {
client, err := meta.(*Config).Client()
if err != nil {
return err
Expand Down Expand Up @@ -452,7 +455,7 @@ func fetchIncidentWorkflow(ctx context.Context, d *schema.ResourceData, meta int
return nil
}

if err := flattenIncidentWorkflow(d, iw, true, specifiedSteps); err != nil {
if err := flattenIncidentWorkflow(d, iw, true, specifiedSteps, isImport); err != nil {
return retry.NonRetryableError(err)
}
return nil
Expand All @@ -464,6 +467,7 @@ func flattenIncidentWorkflow(
iw *pagerduty.IncidentWorkflow,
includeSteps bool,
specifiedSteps []*SpecifiedStep,
isImport bool,
) error {
d.SetId(iw.ID)
d.Set("name", iw.Name)
Expand All @@ -475,41 +479,51 @@ func flattenIncidentWorkflow(
}

if includeSteps {
steps := flattenIncidentWorkflowSteps(iw, specifiedSteps)
steps := flattenIncidentWorkflowSteps(iw, specifiedSteps, isImport)
d.Set("step", steps)
}

return nil
}

func flattenIncidentWorkflowSteps(iw *pagerduty.IncidentWorkflow, specifiedSteps []*SpecifiedStep) []map[string]interface{} {
func flattenIncidentWorkflowSteps(iw *pagerduty.IncidentWorkflow, specifiedSteps []*SpecifiedStep, isImport bool) []map[string]interface{} {
newSteps := make([]map[string]interface{}, len(iw.Steps))
for i, s := range iw.Steps {
m := make(map[string]interface{})
specifiedStep := *specifiedSteps[i]
m["id"] = s.ID
m["name"] = s.Name
m["action"] = s.Configuration.ActionID
m["input"] = flattenIncidentWorkflowStepInput(s.Configuration.Inputs, specifiedStep.SpecifiedInputNames)

var inputNames []string
inlineInputs := make(map[string][]*SpecifiedStep)
if !isImport {
specifiedStep := *specifiedSteps[i]
inputNames = specifiedStep.SpecifiedInputNames
inlineInputs = specifiedStep.SpecifiedInlineInputs
}

m["input"] = flattenIncidentWorkflowStepInput(s.Configuration.Inputs, inputNames, isImport)
m["inline_steps_input"] = flattenIncidentWorkflowStepInlineStepsInput(
s.Configuration.InlineStepsInputs,
specifiedStep.SpecifiedInlineInputs,
inlineInputs,
isImport,
)

newSteps[i] = m
}

return newSteps
}

func flattenIncidentWorkflowStepInput(inputs []*pagerduty.IncidentWorkflowActionInput, specifiedInputNames []string) *[]interface{} {
func flattenIncidentWorkflowStepInput(inputs []*pagerduty.IncidentWorkflowActionInput, specifiedInputNames []string, isImport bool) *[]interface{} {
newInputs := make([]interface{}, len(inputs))

for i, v := range inputs {
m := make(map[string]interface{})
m["name"] = v.Name
m["value"] = v.Value

if !isInputInNonGeneratedInputNames(v, specifiedInputNames) {
if !isImport && !isInputInNonGeneratedInputNames(v, specifiedInputNames) {
m["generated"] = true
}

Expand All @@ -521,13 +535,14 @@ func flattenIncidentWorkflowStepInput(inputs []*pagerduty.IncidentWorkflowAction
func flattenIncidentWorkflowStepInlineStepsInput(
inlineStepsInputs []*pagerduty.IncidentWorkflowActionInlineStepsInput,
specifiedInlineInputs map[string][]*SpecifiedStep,
isImport bool,
) *[]interface{} {
newInlineStepsInputs := make([]interface{}, len(inlineStepsInputs))

for i, v := range inlineStepsInputs {
m := make(map[string]interface{})
m["name"] = v.Name
m["step"] = flattenIncidentWorkflowStepInlineStepsInputSteps(v.Value.Steps, specifiedInlineInputs[v.Name])
m["step"] = flattenIncidentWorkflowStepInlineStepsInputSteps(v.Value.Steps, specifiedInlineInputs[v.Name], isImport)

newInlineStepsInputs[i] = m
}
Expand All @@ -537,22 +552,32 @@ func flattenIncidentWorkflowStepInlineStepsInput(
func flattenIncidentWorkflowStepInlineStepsInputSteps(
inlineSteps []*pagerduty.IncidentWorkflowActionInlineStep,
specifiedSteps []*SpecifiedStep,
isImport bool,
) *[]interface{} {
newInlineSteps := make([]interface{}, len(inlineSteps))

for i, v := range inlineSteps {
m := make(map[string]interface{})
specifiedStep := *specifiedSteps[i]
m["name"] = v.Name
m["action"] = v.Configuration.ActionID
m["input"] = flattenIncidentWorkflowStepInput(v.Configuration.Inputs, specifiedStep.SpecifiedInputNames)

var inputNames []string
inlineInputs := make(map[string][]*SpecifiedStep)
if !isImport {
specifiedStep := *specifiedSteps[i]
inputNames = specifiedStep.SpecifiedInputNames
inlineInputs = specifiedStep.SpecifiedInlineInputs
}

m["input"] = flattenIncidentWorkflowStepInput(v.Configuration.Inputs, inputNames, isImport)
if v.Configuration.InlineStepsInputs != nil && len(v.Configuration.InlineStepsInputs) > 0 {
// We should prefer to not set inline_steps_input if the array is empty. This doubles as a schema edge guard
// and prevents an invalid set if we try to set inline_steps_input to an empty array where the schema
// disallows setting any value whatsoever.
m["inline_steps_input"] = flattenIncidentWorkflowStepInlineStepsInput(
v.Configuration.InlineStepsInputs,
specifiedStep.SpecifiedInlineInputs,
inlineInputs,
isImport,
)
}

Expand Down
68 changes: 66 additions & 2 deletions pagerduty/resource_pagerduty_incident_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,6 @@ func testAccCheckPagerDutyIncidentWorkflowExists(n string) resource.TestCheckFun
}

func TestFlattenIncidentWorkflowStepsOneGenerated(t *testing.T) {

iw := &pagerduty.IncidentWorkflow{
Steps: []*pagerduty.IncidentWorkflowStep{
{
Expand Down Expand Up @@ -536,7 +535,7 @@ func TestFlattenIncidentWorkflowStepsOneGenerated(t *testing.T) {
},
},
}
flattenedSteps := flattenIncidentWorkflowSteps(iw, specifiedSteps)
flattenedSteps := flattenIncidentWorkflowSteps(iw, specifiedSteps, false)
step1Inputs := flattenedSteps[0]["input"].(*[]interface{})
if len(*step1Inputs) != 3 {
t.Errorf("flattened step1 had wrong number of inputs. want 3 got %v", len(*step1Inputs))
Expand Down Expand Up @@ -592,6 +591,71 @@ func TestFlattenIncidentWorkflowStepsOneGenerated(t *testing.T) {
}
}

func TestFlattenIncidentWorkflowStepsWithoutSpecifiedSteps(t *testing.T) {
iw := &pagerduty.IncidentWorkflow{
Steps: []*pagerduty.IncidentWorkflowStep{
{
ID: "abc-123",
Name: "step1",
Configuration: &pagerduty.IncidentWorkflowActionConfiguration{
ActionID: "step1-action-id",
Inputs: []*pagerduty.IncidentWorkflowActionInput{
{
Name: "step1-input1",
Value: "test1-value",
},
},
InlineStepsInputs: []*pagerduty.IncidentWorkflowActionInlineStepsInput{
{
Name: "step1-inlineinput1",
Value: &pagerduty.IncidentWorkflowActionInlineStepsInputValue{
Steps: []*pagerduty.IncidentWorkflowActionInlineStep{
{
Name: "step1a",
Configuration: &pagerduty.IncidentWorkflowActionConfiguration{
ActionID: "step1a-action-id",
Inputs: []*pagerduty.IncidentWorkflowActionInput{
{
Name: "step1a-input1",
Value: "inlineval1",
},
},
},
},
},
},
},
},
},
},
},
}

flattenedSteps := flattenIncidentWorkflowSteps(iw, nil, true)
step1Inputs := flattenedSteps[0]["input"].(*[]interface{})
if len(*step1Inputs) != 1 {
t.Errorf("flattened step1 had wrong number of inputs. want 1 got %v", len(*step1Inputs))
}
for i, v := range *step1Inputs {
if _, hadGen := v.(map[string]interface{})["generated"]; hadGen {
t.Errorf("was not expecting step1a input %v to have generated key set", i)
}
}

step1aInlineStepInputs := flattenedSteps[0]["inline_steps_input"].(*[]interface{})
step1aInlineStepInputs1 := (*step1aInlineStepInputs)[0].(map[string]interface{})
step1aInlineStepInputs1Steps := step1aInlineStepInputs1["step"].(*[]interface{})
step1aInputs := (*step1aInlineStepInputs1Steps)[0].(map[string]interface{})["input"].(*[]interface{})
if len(*step1aInputs) != 1 {
t.Errorf("flattened step1a had wrong number of inputs. want 1 got %v", len(*step1aInputs))
}
for i, v := range *step1aInputs {
if _, hadGen := v.(map[string]interface{})["generated"]; hadGen {
t.Errorf("was not expecting step1a input %v to have generated key set", i)
}
}
}

func testAccPreCheckIncidentWorkflows(t *testing.T) {
if v := os.Getenv("PAGERDUTY_ACC_INCIDENT_WORKFLOWS"); v == "" {
t.Skip("PAGERDUTY_ACC_INCIDENT_WORKFLOWS not set. Skipping Incident Workflows-related test")
Expand Down
Loading