diff --git a/codefresh/cfclient/pipeline.go b/codefresh/cfclient/pipeline.go index b5afde5a..0b7c9a9b 100644 --- a/codefresh/cfclient/pipeline.go +++ b/codefresh/cfclient/pipeline.go @@ -96,9 +96,9 @@ func (t *Trigger) SetVariables(variables map[string]interface{}, encrypted bool) } } -func (t *CronTrigger) SetVariables(variables map[string]interface{}) { +func (t *CronTrigger) SetVariables(variables map[string]interface{}, encrypted bool) { for key, value := range variables { - t.Variables = append(t.Variables, Variable{Key: key, Value: value.(string)}) + t.Variables = append(t.Variables, Variable{Key: key, Value: value.(string), Encrypted: encrypted}) } } diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go index 7afe99f9..0b04aab2 100644 --- a/codefresh/resource_pipeline.go +++ b/codefresh/resource_pipeline.go @@ -485,6 +485,15 @@ Or: original_yaml_string = file("/path/to/my/codefresh.yml") Type: schema.TypeString, }, }, + "encrypted_variables": { + Description: "Trigger level encrypted variables. Please note that drift will not be detected for encrypted variables", + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + Sensitive: true, + }, + }, }, }, }, @@ -737,11 +746,13 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e flattenedSpec := flattenSpec(pipeline.Spec) - // Set trigger encrypted variables from resource data as they cannot be read from API since they cause constant diff (returned as *****) - encryptedVariables, getEncryptedVariablesOk := d.GetOk("spec.0.encrypted_variables") - - if getEncryptedVariablesOk { - flattenedSpec[0]["encrypted_variables"] = encryptedVariables.(map[string]interface{}) + // Set encrypted variables from resource data, as otherwise they cause constant diff as the value is always returned as ***** + encryptedVariables, ok := flattenedSpec[0]["encrypted_variables"].(map[string]string) + + if ok { + if len(encryptedVariables) > 0 { + setEncryptedVariablesValuesFromResource(d, encryptedVariables, "spec.0.encrypted_variables") + } } // Set trigger encrypted variables from resource data @@ -750,11 +761,27 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e if (getTriggersOK) { for triggerIndex, triggerSpec := range triggers.([]map[string]interface{}) { - encryptedVariables, ok := triggerSpec["encrypted_variables"].(map[string]string) + triggerEncryptedVariables, ok := triggerSpec["encrypted_variables"].(map[string]string) if ok { - if len(encryptedVariables) > 0 { - setEncryptedVariablesValuesFromResource(d, encryptedVariables, fmt.Sprintf("spec.0.trigger.%d.encrypted_variables",triggerIndex)) + if len(triggerEncryptedVariables) > 0 { + setEncryptedVariablesValuesFromResource(d, triggerEncryptedVariables, fmt.Sprintf("spec.0.trigger.%d.encrypted_variables",triggerIndex)) + } + } + } + } + + // Set cron trigger encrypted variables from resource data + cronTriggers, getCronTriggersOK := flattenedSpec[0]["cron_trigger"] + + if (getCronTriggersOK) { + for triggerIndex, triggerSpec := range cronTriggers.([]map[string]interface{}) { + + triggerEncryptedVariables, ok := triggerSpec["encrypted_variables"].(map[string]string) + + if ok { + if len(triggerEncryptedVariables) > 0 { + setEncryptedVariablesValuesFromResource(d, triggerEncryptedVariables, fmt.Sprintf("spec.0.cron_trigger.%d.encrypted_variables",triggerIndex)) } } } @@ -798,7 +825,7 @@ func flattenSpec(spec cfclient.Spec) []map[string]interface{} { if len(spec.Variables) != 0 { // Do not set encrypted variables because they cause constant diff - m["variables"], _ = datautil.ConvertVariables(spec.Variables) + m["variables"], m["encrypted_variables"] = datautil.ConvertVariables(spec.Variables) } if spec.RuntimeEnvironment != (cfclient.RuntimeEnvironment{}) { @@ -949,7 +976,7 @@ func flattenCronTriggers(cronTriggers []cfclient.CronTrigger) []map[string]inter m["disabled"] = trigger.Disabled m["git_trigger_id"] = trigger.GitTriggerId m["branch"] = trigger.Branch - m["variables"], _ = datautil.ConvertVariables(trigger.Variables) + m["variables"], m["encrypted_variables"] = datautil.ConvertVariables(trigger.Variables) if trigger.Options != nil { m["options"] = flattenTriggerOptions(*trigger.Options) } @@ -1092,7 +1119,10 @@ func mapResourceToPipeline(d *schema.ResourceData) (*cfclient.Pipeline, error) { Branch: d.Get(fmt.Sprintf("spec.0.cron_trigger.%v.branch", idx)).(string), } variables := d.Get(fmt.Sprintf("spec.0.cron_trigger.%v.variables", idx)).(map[string]interface{}) - codefreshCronTrigger.SetVariables(variables) + codefreshCronTrigger.SetVariables(variables, false) + encryptedVariables := d.Get(fmt.Sprintf("spec.0.cron_trigger.%v.encrypted_variables", idx)).(map[string]interface{}) + codefreshCronTrigger.SetVariables(encryptedVariables, true) + if _, ok := d.GetOk(fmt.Sprintf("spec.0.cron_trigger.%v.options", idx)); ok { options := cfclient.TriggerOptions{ NoCache: d.Get(fmt.Sprintf("spec.0.cron_trigger.%v.options.0.no_cache", idx)).(bool), diff --git a/codefresh/resource_pipeline_test.go b/codefresh/resource_pipeline_test.go index b5e3971e..dd290001 100644 --- a/codefresh/resource_pipeline_test.go +++ b/codefresh/resource_pipeline_test.go @@ -374,6 +374,8 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { "codefresh-contrib/react-sample-app", "triggerTestVar", "triggerTestValue", + "triggerTestEncryptedVar", + "triggerTestEncryptedValue", "commitstatustitle", ), Check: resource.ComposeTestCheckFunc( @@ -396,6 +398,7 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"spec.0.trigger.1.encrypted_variables"}, }, { Config: testAccCodefreshPipelineBasicConfigTriggers( @@ -424,6 +427,8 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { "codefresh-contrib/react-sample-app", "triggerTestVar", "triggerTestValue", + "triggerTestEncryptedVar", + "triggerTestEncryptedValue", "commitstatustitle", ), Check: resource.ComposeTestCheckFunc( @@ -433,6 +438,7 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.0.pull_request_target_branch_regex", "/release/gi"), resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.0.comment_regex", "/PR comment2/gi"), resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.variables.triggerTestVar", "triggerTestValue"), + resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.encrypted_variables.triggerTestEncryptedVar", "triggerTestEncryptedValue"), resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.contexts.0", "shared_context2_update"), resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.options.0.no_cache", "true"), resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.options.0.no_cf_cache", "true"), @@ -1052,6 +1058,8 @@ func testAccCodefreshPipelineBasicConfigTriggers( trigger2Repo, trigger2VarName, trigger2VarValue, + trigger2EncryptedVarName, + trigger2EncryptedVarValue, trigger2CommitStatusTitle string, ) string { return fmt.Sprintf(` @@ -1123,6 +1131,10 @@ resource "codefresh_pipeline" "test" { %q = %q } + encrypted_variables = { + %q = %q + } + commit_status_title = "%s" } } @@ -1153,6 +1165,8 @@ resource "codefresh_pipeline" "test" { trigger2Repo, trigger2VarName, trigger2VarValue, + trigger2EncryptedVarName, + trigger2EncryptedVarValue, trigger2CommitStatusTitle) }