From 843163f2544d5d996b8e8a351187aaff39e799d9 Mon Sep 17 00:00:00 2001 From: ilia-medvedev-codefresh Date: Tue, 12 Mar 2024 18:37:32 +0200 Subject: [PATCH] Feat: Support encrypted variables in project and pipeline (including triggers) (#142) ## What Support for encrypted variables - closes #97 ## Why ## Notes ## Checklist * [x] _I have read [CONTRIBUTING.md](https://github.com/codefresh-io/terraform-provider-codefresh/blob/master/CONTRIBUTING.md)._ * [x] _I have [allowed changes to my fork to be made](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)._ * [x] _I have added tests, assuming new tests are warranted_. * [x] _I understand that the `/test` comment will be ignored by the CI trigger [unless it is made by a repo admin or collaborator](https://codefresh.io/docs/docs/pipelines/triggers/git-triggers/#support-for-building-pull-requests-from-forks)._ --- codefresh/cfclient/pipeline.go | 12 +-- codefresh/cfclient/project.go | 4 +- codefresh/cfclient/utils.go | 5 +- codefresh/internal/datautil/strings.go | 26 ++++-- codefresh/resource_pipeline.go | 117 ++++++++++++++++++++++--- codefresh/resource_pipeline_test.go | 44 +++++++--- codefresh/resource_project.go | 33 ++++++- codefresh/resource_project_test.go | 15 +++- docs/resources/pipeline.md | 3 + docs/resources/project.md | 1 + 10 files changed, 218 insertions(+), 42 deletions(-) diff --git a/codefresh/cfclient/pipeline.go b/codefresh/cfclient/pipeline.go index d25de84d..0b7c9a9b 100644 --- a/codefresh/cfclient/pipeline.go +++ b/codefresh/cfclient/pipeline.go @@ -90,15 +90,15 @@ type RuntimeEnvironment struct { RequiredAvailableStorage string `json:"requiredAvailableStorage,omitempty"` } -func (t *Trigger) SetVariables(variables map[string]interface{}) { +func (t *Trigger) 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}) } } -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}) } } @@ -169,9 +169,9 @@ type Pipeline struct { Version string `json:"version,omitempty"` } -func (p *Pipeline) SetVariables(variables map[string]interface{}) { +func (p *Pipeline) SetVariables(variables map[string]interface{}, encrypted bool) { for key, value := range variables { - p.Spec.Variables = append(p.Spec.Variables, Variable{Key: key, Value: value.(string)}) + p.Spec.Variables = append(p.Spec.Variables, Variable{Key: key, Value: value.(string), Encrypted: encrypted}) } } diff --git a/codefresh/cfclient/project.go b/codefresh/cfclient/project.go index daf524dd..04a053de 100644 --- a/codefresh/cfclient/project.go +++ b/codefresh/cfclient/project.go @@ -19,9 +19,9 @@ func (project *Project) GetID() string { } // SetVariables project variables -func (project *Project) SetVariables(variables map[string]interface{}) { +func (project *Project) SetVariables(variables map[string]interface{}, encrypted bool) { for key, value := range variables { - project.Variables = append(project.Variables, Variable{Key: key, Value: value.(string)}) + project.Variables = append(project.Variables, Variable{Key: key, Value: value.(string), Encrypted: encrypted}) } } diff --git a/codefresh/cfclient/utils.go b/codefresh/cfclient/utils.go index 93c24585..45b7589d 100644 --- a/codefresh/cfclient/utils.go +++ b/codefresh/cfclient/utils.go @@ -7,8 +7,9 @@ import ( // Variable spec type Variable struct { - Key string `json:"key"` - Value string `json:"value"` + Key string `json:"key"` + Value string `json:"value"` + Encrypted bool `json:"encrypted",omitempty` } // CodefreshObject codefresh interface diff --git a/codefresh/internal/datautil/strings.go b/codefresh/internal/datautil/strings.go index 004b544a..227b5773 100644 --- a/codefresh/internal/datautil/strings.go +++ b/codefresh/internal/datautil/strings.go @@ -22,13 +22,29 @@ func ConvertAndMapStringArr(ifaceArr []interface{}, f func(string) string) []str return arr } -// ConvertVariables converts an array of cfclient.Variables to a map of key/value pairs. -func ConvertVariables(vars []cfclient.Variable) map[string]string { - res := make(map[string]string, len(vars)) +// ConvertVariables converts an array of cfclient. Variables to 2 maps of key/value pairs - first one for un-encrypted variables second one for encrypted variables. +func ConvertVariables(vars []cfclient.Variable) (map[string]string, map[string]string) { + + numberOfEncryptedVars := 0 + for _, v := range vars { - res[v.Key] = v.Value + if v.Encrypted { + numberOfEncryptedVars++ + } } - return res + + resUnencrptedVars := make(map[string]string, len(vars)-numberOfEncryptedVars) + resEncryptedVars := make(map[string]string, numberOfEncryptedVars) + + for _, v := range vars { + if v.Encrypted { + resEncryptedVars[v.Key] = v.Value + } else { + resUnencrptedVars[v.Key] = v.Value + } + } + + return resUnencrptedVars, resEncryptedVars } // FlattenStringArr flattens an array of strings. diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go index 698ab3fb..0da0da6a 100644 --- a/codefresh/resource_pipeline.go +++ b/codefresh/resource_pipeline.go @@ -151,6 +151,15 @@ Or: original_yaml_string = file("/path/to/my/codefresh.yml") Type: schema.TypeString, }, }, + "encrypted_variables": { + Description: "Pipeline 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, + }, + }, "trigger": { Description: "The pipeline's triggers (currently the only nested trigger supported is git; for other trigger types, use the `codefresh_pipeline_*_trigger` resources).", Type: schema.TypeList, @@ -336,6 +345,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, + }, + }, }, }, }, @@ -467,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, + }, + }, }, }, }, @@ -608,8 +635,8 @@ Pipeline concurrency policy: Builds on 'Pending Approval' state should be: }, "enable_notifications": { Type: schema.TypeBool, - Optional: true, - Default: false, + Optional: true, + Default: false, }, }, }, @@ -717,7 +744,51 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e return err } - err = d.Set("spec", flattenSpec(pipeline.Spec)) + flattenedSpec := flattenSpec(pipeline.Spec) + + // 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 + triggers, getTriggersOK := flattenedSpec[0]["trigger"] + + if getTriggersOK { + for triggerIndex, triggerSpec := range triggers.([]map[string]interface{}) { + + triggerEncryptedVariables, ok := triggerSpec["encrypted_variables"].(map[string]string) + + if ok { + 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)) + } + } + } + } + + err = d.Set("spec", flattenedSpec) + if err != nil { return err } @@ -735,9 +806,9 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e return nil } -func flattenSpec(spec cfclient.Spec) []interface{} { +func flattenSpec(spec cfclient.Spec) []map[string]interface{} { - var res = make([]interface{}, 0) + var res = make([]map[string]interface{}, 0) m := make(map[string]interface{}) if len(spec.Triggers) > 0 { @@ -753,7 +824,8 @@ func flattenSpec(spec cfclient.Spec) []interface{} { } if len(spec.Variables) != 0 { - m["variables"] = datautil.ConvertVariables(spec.Variables) + // Do not set encrypted variables because they cause constant diff + m["variables"], m["encrypted_variables"] = datautil.ConvertVariables(spec.Variables) } if spec.RuntimeEnvironment != (cfclient.RuntimeEnvironment{}) { @@ -884,7 +956,7 @@ func flattenTriggers(triggers []cfclient.Trigger) []map[string]interface{} { m["provider"] = trigger.Provider m["type"] = trigger.Type m["events"] = trigger.Events - m["variables"] = datautil.ConvertVariables(trigger.Variables) + m["variables"], m["encrypted_variables"] = datautil.ConvertVariables(trigger.Variables) if trigger.RuntimeEnvironment != nil { m["runtime_environment"] = flattenSpecRuntimeEnvironment(*trigger.RuntimeEnvironment) } @@ -904,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) } @@ -977,7 +1049,11 @@ func mapResourceToPipeline(d *schema.ResourceData) (*cfclient.Pipeline, error) { } if variables, ok := d.GetOk("spec.0.variables"); ok { - pipeline.SetVariables(variables.(map[string]interface{})) + pipeline.SetVariables(variables.(map[string]interface{}), false) + } + + if encryptedVariables, ok := d.GetOk("spec.0.encrypted_variables"); ok { + pipeline.SetVariables(encryptedVariables.(map[string]interface{}), true) } if triggers, ok := d.GetOk("spec.0.trigger"); ok { @@ -1003,7 +1079,11 @@ func mapResourceToPipeline(d *schema.ResourceData) (*cfclient.Pipeline, error) { Events: datautil.ConvertStringArr(events), } variables := d.Get(fmt.Sprintf("spec.0.trigger.%v.variables", idx)).(map[string]interface{}) - codefreshTrigger.SetVariables(variables) + codefreshTrigger.SetVariables(variables, false) + + encryptedVariables := d.Get(fmt.Sprintf("spec.0.trigger.%v.encrypted_variables", idx)).(map[string]interface{}) + codefreshTrigger.SetVariables(encryptedVariables, true) + if _, ok := d.GetOk(fmt.Sprintf("spec.0.trigger.%v.options", idx)); ok { options := cfclient.TriggerOptions{ NoCache: d.Get(fmt.Sprintf("spec.0.trigger.%v.options.0.no_cache", idx)).(bool), @@ -1039,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), @@ -1181,3 +1264,15 @@ func convertOnCreateBranchAttributeToPipelineFormat(src string) string { return "_" + strings.ToLower(w) }) } + +func setEncryptedVariablesValuesFromResource(d *schema.ResourceData, flattenedVariables map[string]string, schemaPath string) error { + + if len(flattenedVariables) > 0 { + // Iterate over variables and set the value from resource data + for k := range flattenedVariables { + flattenedVariables[k] = d.Get(fmt.Sprintf("%s.%s", schemaPath, k)).(string) + } + } + + return nil +} diff --git a/codefresh/resource_pipeline_test.go b/codefresh/resource_pipeline_test.go index 9bd580ca..9c82d82a 100644 --- a/codefresh/resource_pipeline_test.go +++ b/codefresh/resource_pipeline_test.go @@ -150,24 +150,29 @@ func TestAccCodefreshPipeline_Variables(t *testing.T) { CheckDestroy: testAccCheckCodefreshPipelineDestroy, Steps: []resource.TestStep{ { - Config: testAccCodefreshPipelineBasicConfigVariables(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "var1", "val1", "var2", "val2"), + Config: testAccCodefreshPipelineBasicConfigVariables(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "var1", "val1", "var2", "val2", "var1", "val1", "var2", "val2"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshPipelineExists(resourceName, &pipeline), resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var1", "val1"), resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var2", "val2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.encrypted_variables.var1", "val1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.encrypted_variables.var2", "val2"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"spec.0.encrypted_variables"}, }, { - Config: testAccCodefreshPipelineBasicConfigVariables(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "var1", "val1_updated", "var2", "val2_updated"), + Config: testAccCodefreshPipelineBasicConfigVariables(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "var1", "val1_updated", "var2", "val2_updated", "var1", "val1_updated", "var2", "val2_updated"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshPipelineExists(resourceName, &pipeline), resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var1", "val1_updated"), resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var2", "val2_updated"), + resource.TestCheckResourceAttr(resourceName, "spec.0.encrypted_variables.var1", "val1_updated"), + resource.TestCheckResourceAttr(resourceName, "spec.0.encrypted_variables.var2", "val2_updated"), ), }, }, @@ -369,6 +374,8 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { "codefresh-contrib/react-sample-app", "triggerTestVar", "triggerTestValue", + "triggerTestEncryptedVar", + "triggerTestEncryptedValue", "commitstatustitle", ), Check: resource.ComposeTestCheckFunc( @@ -388,9 +395,10 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"spec.0.trigger.1.encrypted_variables"}, }, { Config: testAccCodefreshPipelineBasicConfigTriggers( @@ -419,6 +427,8 @@ func TestAccCodefreshPipeline_Triggers(t *testing.T) { "codefresh-contrib/react-sample-app", "triggerTestVar", "triggerTestValue", + "triggerTestEncryptedVar", + "triggerTestEncryptedValue", "commitstatustitle", ), Check: resource.ComposeTestCheckFunc( @@ -428,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"), @@ -901,7 +912,7 @@ resource "codefresh_pipeline" "test" { `, rName, repo, path, revision, context, tag1, tag2) } -func testAccCodefreshPipelineBasicConfigVariables(rName, repo, path, revision, context, var1Name, var1Value, var2Name, var2Value string) string { +func testAccCodefreshPipelineBasicConfigVariables(rName, repo, path, revision, context, var1Name, var1Value, var2Name, var2Value, encVar1Name, encVar1Value, encVar2Name, encVar2Value string) string { return fmt.Sprintf(` resource "codefresh_pipeline" "test" { @@ -925,9 +936,14 @@ resource "codefresh_pipeline" "test" { %q = %q %q = %q } + + encrypted_variables = { + %q = %q + %q = %q + } } } -`, rName, repo, path, revision, context, var1Name, var1Value, var2Name, var2Value) +`, rName, repo, path, revision, context, var1Name, var1Value, var2Name, var2Value, encVar1Name, encVar1Value, encVar2Name, encVar2Value) } func testAccCodefreshPipelineBasicConfigContexts(rName, repo, path, revision, context, sharedContext1, sharedContext2 string) string { @@ -1042,6 +1058,8 @@ func testAccCodefreshPipelineBasicConfigTriggers( trigger2Repo, trigger2VarName, trigger2VarValue, + trigger2EncryptedVarName, + trigger2EncryptedVarValue, trigger2CommitStatusTitle string, ) string { return fmt.Sprintf(` @@ -1113,6 +1131,10 @@ resource "codefresh_pipeline" "test" { %q = %q } + encrypted_variables = { + %q = %q + } + commit_status_title = "%s" } } @@ -1143,6 +1165,8 @@ resource "codefresh_pipeline" "test" { trigger2Repo, trigger2VarName, trigger2VarValue, + trigger2EncryptedVarName, + trigger2EncryptedVarValue, trigger2CommitStatusTitle) } diff --git a/codefresh/resource_project.go b/codefresh/resource_project.go index b4506347..4eb49cf4 100644 --- a/codefresh/resource_project.go +++ b/codefresh/resource_project.go @@ -1,6 +1,7 @@ package codefresh import ( + "fmt" "log" "time" @@ -46,6 +47,15 @@ You are free to use projects as you see fit. For example, you could create a pro Type: schema.TypeString, }, }, + "encrypted_variables": { + Description: "Project 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, + }, + }, }, } } @@ -133,10 +143,27 @@ func mapProjectToResource(project *cfclient.Project, d *schema.ResourceData) err return err } - err = d.Set("variables", datautil.ConvertVariables(project.Variables)) + vars, encryptedVars := datautil.ConvertVariables(project.Variables) + + err = d.Set("variables", vars) + if err != nil { + return err + } + + // Set encrypted vars from resource data to avoid constant diff + if len(encryptedVars) > 0 { + // Iterate over variables and set the value from resource data + for k := range encryptedVars { + encryptedVars[k] = d.Get(fmt.Sprintf("encrypted_variables.%s", k)).(string) + } + } + + err = d.Set("encrypted_variables", encryptedVars) + if err != nil { return err } + return nil } @@ -148,6 +175,8 @@ func mapResourceToProject(d *schema.ResourceData) *cfclient.Project { Tags: datautil.ConvertStringArr(tags), } variables := d.Get("variables").(map[string]interface{}) - project.SetVariables(variables) + project.SetVariables(variables, false) + encryptedVariables := d.Get("encrypted_variables").(map[string]interface{}) + project.SetVariables(encryptedVariables, true) return project } diff --git a/codefresh/resource_project_test.go b/codefresh/resource_project_test.go index 6123c19c..e94de0a5 100644 --- a/codefresh/resource_project_test.go +++ b/codefresh/resource_project_test.go @@ -74,24 +74,27 @@ func TestAccCodefreshProject_Variables(t *testing.T) { CheckDestroy: testAccCheckCodefreshProjectDestroy, Steps: []resource.TestStep{ { - Config: testAccCodefreshProjectBasicConfigVariables(name, "var1", "val1", "var2", "val2"), + Config: testAccCodefreshProjectBasicConfigVariables(name, "var1", "val1", "var2", "val2", "encvar1", "encval1"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshProjectExists(resourceName), resource.TestCheckResourceAttr(resourceName, "variables.var1", "val1"), resource.TestCheckResourceAttr(resourceName, "variables.var2", "val2"), + resource.TestCheckResourceAttr(resourceName, "encrypted_variables.encvar1", "encval1"), ), }, { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"encrypted_variables"}, }, { - Config: testAccCodefreshProjectBasicConfigVariables(name, "var1", "val1_updated", "var2", "val2_updated"), + Config: testAccCodefreshProjectBasicConfigVariables(name, "var1", "val1_updated", "var2", "val2_updated", "encvar1", "encvar1_updated"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshProjectExists(resourceName), resource.TestCheckResourceAttr(resourceName, "variables.var1", "val1_updated"), resource.TestCheckResourceAttr(resourceName, "variables.var2", "val2_updated"), + resource.TestCheckResourceAttr(resourceName, "encrypted_variables.encvar1", "encvar1_updated"), // resource.TestCheckResourceAttr(resourceName, "variables.", name), ), }, @@ -167,7 +170,7 @@ resource "codefresh_project" "test" { `, rName, tag1, tag2) } -func testAccCodefreshProjectBasicConfigVariables(rName, var1Name, var1Value, var2Name, var2Value string) string { +func testAccCodefreshProjectBasicConfigVariables(rName, var1Name, var1Value, var2Name, var2Value, encrytedVar1Name,encrytedVar1Value string) string { return fmt.Sprintf(` resource "codefresh_project" "test" { name = "%s" @@ -175,6 +178,10 @@ resource "codefresh_project" "test" { %q = %q %q = %q } + + encrypted_variables = { + %q = %q + } } -`, rName, var1Name, var1Value, var2Name, var2Value) +`, rName, var1Name, var1Value, var2Name, var2Value, encrytedVar1Name,encrytedVar1Value) } diff --git a/docs/resources/pipeline.md b/docs/resources/pipeline.md index 589a117e..c1b467c3 100644 --- a/docs/resources/pipeline.md +++ b/docs/resources/pipeline.md @@ -128,6 +128,7 @@ Optional: - `concurrency` (Number) The maximum amount of concurrent builds. Zero is unlimited (default: `0`). - `contexts` (List of String) A list of strings representing the contexts ([shared_configuration](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/shared-configuration/)) to be configured for the pipeline. - `cron_trigger` (Block List) The pipeline's cron triggers. Conflicts with the deprecated [codefresh_pipeline_cron_trigger](https://registry.terraform.io/providers/codefresh-io/codefresh/latest/docs/resources/pipeline_cron_trigger) resource. (see [below for nested schema](#nestedblock--spec--cron_trigger)) +- `encrypted_variables` (Map of String) Pipeline level encrypted variables. Please note that drift will not be detected for encrypted variables - `options` (Block List, Max: 1) The options for the pipeline. (see [below for nested schema](#nestedblock--spec--options)) - `pack_id` (String) SAAS pack (`5cd1746617313f468d669013` for Small; `5cd1746717313f468d669014` for Medium; `5cd1746817313f468d669015` for Large; `5cd1746817313f468d669017` for XL; `5cd1746817313f468d669018` for XXL); `5cd1746817313f468d669020` for 4XL). - `permit_restart_from_failed_steps` (Boolean) Defines whether it is permitted to restart builds in this pipeline from failed step. Defaults to true @@ -153,6 +154,7 @@ Optional: - `branch` (String) Branch that should be passed for build triggered by this cron trigger. - `disabled` (Boolean) Flag to disable the trigger. +- `encrypted_variables` (Map of String) Trigger level encrypted variables. Please note that drift will not be detected for encrypted variables - `git_trigger_id` (String) Related git-trigger id. Will by used to take all possible git information by branch. - `options` (Block List) The trigger's options. (see [below for nested schema](#nestedblock--spec--cron_trigger--options)) - `runtime_environment` (Block List) The runtime environment for the trigger. (see [below for nested schema](#nestedblock--spec--cron_trigger--runtime_environment)) @@ -270,6 +272,7 @@ Optional: - `contexts` (List of String) A list of strings representing the contexts ([shared_configuration](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/shared-configuration/)) to be loaded when the trigger is executed. - `description` (String) The description of the trigger. - `disabled` (Boolean) Flag to disable the trigger. +- `encrypted_variables` (Map of String) Trigger level encrypted variables. Please note that drift will not be detected for encrypted variables - `events` (List of String) A list of GitHub events for which a Pipeline is triggered. - `modified_files_glob` (String) Allows to constrain the build and trigger it only if the modified files from the commit match this glob expression (default: `""`). - `name` (String) The name of the trigger. diff --git a/docs/resources/project.md b/docs/resources/project.md index b2547bdf..b5a6939f 100644 --- a/docs/resources/project.md +++ b/docs/resources/project.md @@ -41,6 +41,7 @@ resource "codefresh_project" "test" { ### Optional +- `encrypted_variables` (Map of String) Project level encrypted variables. Please note that drift will not be detected for encrypted variables - `tags` (Set of String) A list of tags to mark a project for easy management and access control. - `variables` (Map of String) Project variables.