diff --git a/codefresh/cfclient/project.go b/codefresh/cfclient/project.go
index daf524d..04a053d 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 011fb72..45b7589 100644
--- a/codefresh/cfclient/utils.go
+++ b/codefresh/cfclient/utils.go
@@ -9,7 +9,7 @@ import (
type Variable struct {
Key string `json:"key"`
Value string `json:"value"`
- Encrypted bool `json:"encrypted",omitempty`
+ Encrypted bool `json:"encrypted",omitempty`
}
// CodefreshObject codefresh interface
diff --git a/codefresh/internal/datautil/strings.go b/codefresh/internal/datautil/strings.go
index 5a1f6f5..227b577 100644
--- a/codefresh/internal/datautil/strings.go
+++ b/codefresh/internal/datautil/strings.go
@@ -23,17 +23,17 @@ func ConvertAndMapStringArr(ifaceArr []interface{}, f func(string) string) []str
}
// 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) {
-
+func ConvertVariables(vars []cfclient.Variable) (map[string]string, map[string]string) {
+
numberOfEncryptedVars := 0
-
+
for _, v := range vars {
if v.Encrypted {
numberOfEncryptedVars++
}
}
- resUnencrptedVars := make(map[string]string, len(vars) - numberOfEncryptedVars)
+ resUnencrptedVars := make(map[string]string, len(vars)-numberOfEncryptedVars)
resEncryptedVars := make(map[string]string, numberOfEncryptedVars)
for _, v := range vars {
@@ -44,7 +44,7 @@ func ConvertVariables(vars []cfclient.Variable) (map[string]string,map[string]st
}
}
- return resUnencrptedVars,resEncryptedVars
+ return resUnencrptedVars, resEncryptedVars
}
// FlattenStringArr flattens an array of strings.
diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go
index 0b04aab..0da0da6 100644
--- a/codefresh/resource_pipeline.go
+++ b/codefresh/resource_pipeline.go
@@ -156,7 +156,7 @@ Or: original_yaml_string = file("/path/to/my/codefresh.yml")
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{
- Type: schema.TypeString,
+ Type: schema.TypeString,
Sensitive: true,
},
},
@@ -350,7 +350,7 @@ Or: original_yaml_string = file("/path/to/my/codefresh.yml")
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{
- Type: schema.TypeString,
+ Type: schema.TypeString,
Sensitive: true,
},
},
@@ -490,7 +490,7 @@ Or: original_yaml_string = file("/path/to/my/codefresh.yml")
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{
- Type: schema.TypeString,
+ Type: schema.TypeString,
Sensitive: true,
},
},
@@ -635,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,
},
},
},
@@ -748,7 +748,7 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e
// 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")
@@ -758,14 +758,14 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e
// Set trigger encrypted variables from resource data
triggers, getTriggersOK := flattenedSpec[0]["trigger"]
- if (getTriggersOK) {
+ 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))
+ setEncryptedVariablesValuesFromResource(d, triggerEncryptedVariables, fmt.Sprintf("spec.0.trigger.%d.encrypted_variables", triggerIndex))
}
}
}
@@ -774,14 +774,14 @@ func mapPipelineToResource(pipeline cfclient.Pipeline, d *schema.ResourceData) e
// Set cron trigger encrypted variables from resource data
cronTriggers, getCronTriggersOK := flattenedSpec[0]["cron_trigger"]
- if (getCronTriggersOK) {
+ 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))
+ setEncryptedVariablesValuesFromResource(d, triggerEncryptedVariables, fmt.Sprintf("spec.0.cron_trigger.%d.encrypted_variables", triggerIndex))
}
}
}
@@ -1080,7 +1080,7 @@ func mapResourceToPipeline(d *schema.ResourceData) (*cfclient.Pipeline, error) {
}
variables := d.Get(fmt.Sprintf("spec.0.trigger.%v.variables", idx)).(map[string]interface{})
codefreshTrigger.SetVariables(variables, false)
-
+
encryptedVariables := d.Get(fmt.Sprintf("spec.0.trigger.%v.encrypted_variables", idx)).(map[string]interface{})
codefreshTrigger.SetVariables(encryptedVariables, true)
diff --git a/codefresh/resource_pipeline_test.go b/codefresh/resource_pipeline_test.go
index dd29000..9c82d82 100644
--- a/codefresh/resource_pipeline_test.go
+++ b/codefresh/resource_pipeline_test.go
@@ -160,13 +160,13 @@ func TestAccCodefreshPipeline_Variables(t *testing.T) {
),
},
{
- 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","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"),
@@ -395,9 +395,9 @@ 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"},
},
{
diff --git a/codefresh/resource_project.go b/codefresh/resource_project.go
index 465fe1a..4eb49cf 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,12 +143,27 @@ func mapProjectToResource(project *cfclient.Project, d *schema.ResourceData) err
return err
}
- vars, _ := 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
}
@@ -150,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 6123c19..e94de0a 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)
}