From 698e20c8165fd823addd7292c19366c7a1ca3a74 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Thu, 5 Dec 2024 20:57:57 +0200 Subject: [PATCH 1/8] initial version of fix --- codefresh/cfclient/context.go | 9 +++-- codefresh/data_context.go | 2 +- codefresh/resource_context.go | 56 ++++++++++++++++++++++++++---- codefresh/resource_context_test.go | 8 ++--- 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/codefresh/cfclient/context.go b/codefresh/cfclient/context.go index 934e718e..d66f2d7d 100644 --- a/codefresh/cfclient/context.go +++ b/codefresh/cfclient/context.go @@ -31,8 +31,13 @@ func (context *Context) GetID() string { return context.Metadata.Name } -func (client *Client) GetContext(name string) (*Context, error) { - fullPath := fmt.Sprintf("/contexts/%s?decrypt=true", url.PathEscape(name)) +func (client *Client) GetContext(name string, decrypt bool) (*Context, error) { + fullPath := fmt.Sprintf("/contexts/%s", url.PathEscape(name)) + + if decrypt { + fullPath += "?decrypt=true" + } + opts := RequestOptions{ Path: fullPath, Method: "GET", diff --git a/codefresh/data_context.go b/codefresh/data_context.go index 032b51bb..0fc6579f 100644 --- a/codefresh/data_context.go +++ b/codefresh/data_context.go @@ -36,7 +36,7 @@ func dataSourceContextRead(d *schema.ResourceData, meta interface{}) error { var err error if name, nameOk := d.GetOk("name"); nameOk { - context, err = client.GetContext(name.(string)) + context, err = client.GetContext(name.(string), true) } else { return fmt.Errorf("data.codefresh_context - must specify name") } diff --git a/codefresh/resource_context.go b/codefresh/resource_context.go index 7e9556cb..4f1e4e7a 100644 --- a/codefresh/resource_context.go +++ b/codefresh/resource_context.go @@ -28,6 +28,11 @@ var supportedContextType = []string{ contextSecretYaml, } +var encryptedContextTypes = []string{ + contextSecret, + contextSecretYaml, +} + func getConflictingContexts(context string) []string { var conflictingTypes []string normalizedContext := schemautil.MustNormalizeFieldName(context) @@ -57,6 +62,12 @@ func resourceContext() *schema.Resource { Required: true, ForceNew: true, }, + "decrypt_spec": { + Type: schema.TypeBool, + Default: true, + Optional: true, + Description: "Whether to allow decryption of context spec for encrypted contexts on read. If set to false context content diff will not be calculated against the API. Must be set to false if `forbidDecrypt` feature flag on Codefresh platfrom is enabled", + }, "spec": { Description: "The context's specs.", Type: schema.TypeList, @@ -174,12 +185,18 @@ func resourceContextRead(d *schema.ResourceData, meta interface{}) error { contextName := d.Id() + currentContextType := getContextTypeFromResource(d) + + // Explicitly set decypt flag to true only if context type is encrypted and decrypt_spec is set to true + setExplicitDecrypt := contains(encryptedContextTypes, currentContextType) && d.Get("decrypt_spec").(bool) + if contextName == "" { d.SetId("") return nil } - context, err := client.GetContext(contextName) + context, err := client.GetContext(contextName, setExplicitDecrypt) + if err != nil { log.Printf("[DEBUG] Error while getting context. Error = %v", contextName) return err @@ -225,14 +242,22 @@ func resourceContextDelete(d *schema.ResourceData, meta interface{}) error { func mapContextToResource(context cfclient.Context, d *schema.ResourceData) error { err := d.Set("name", context.Metadata.Name) + if err != nil { return err } - err = d.Set("spec", flattenContextSpec(context.Spec)) - if err != nil { - log.Printf("[DEBUG] Failed to flatten Context spec = %v", context.Spec) - return err + currentContextType := getContextTypeFromResource(d) + + // Read spec from API if context is not encrypted or decrypt_spec is set to true explicitly + if d.Get("decrypt_spec").(bool) || !contains(encryptedContextTypes, currentContextType) { + + err = d.Set("spec", flattenContextSpec(context.Spec)) + + if err != nil { + log.Printf("[DEBUG] Failed to flatten Context spec = %v", context.Spec) + return err + } } return nil @@ -253,7 +278,6 @@ func flattenContextSpec(spec cfclient.ContextSpec) []interface{} { case contextAzureStorage: m[schemautil.MustNormalizeFieldName(currentContextType)] = storageContext.FlattenAzureStorageContextConfig(spec) default: - log.Printf("[DEBUG] Invalid context type = %v", currentContextType) return nil } @@ -319,3 +343,23 @@ func mapResourceToContext(d *schema.ResourceData) *cfclient.Context { }, } } + +func getContextTypeFromResource(d *schema.ResourceData) string { + if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextConfig) + ".0.data"); ok { + return contextConfig + } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextSecret) + ".0.data"); ok { + return contextSecret + } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextYaml) + ".0.data"); ok { + return contextYaml + } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextSecretYaml) + ".0.data"); ok { + return contextSecretYaml + } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextGoogleStorage) + ".0.data"); ok { + return contextGoogleStorage + } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextS3Storage) + ".0.data"); ok { + return contextS3Storage + } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextAzureStorage) + ".0.data"); ok { + return contextAzureStorage + } + + return "" +} diff --git a/codefresh/resource_context_test.go b/codefresh/resource_context_test.go index 4e634c16..cacc354a 100644 --- a/codefresh/resource_context_test.go +++ b/codefresh/resource_context_test.go @@ -159,7 +159,7 @@ func testAccCheckCodefreshContextExists(resource string) resource.TestCheckFunc contextID := rs.Primary.ID apiClient := testAccProvider.Meta().(*cfclient.Client) - _, err := apiClient.GetContext(contextID) + _, err := apiClient.GetContext(contextID, true) if err != nil { return fmt.Errorf("error fetching context with ID %s. %s", contextID, err) @@ -177,7 +177,7 @@ func testAccCheckCodefreshContextDestroy(s *terraform.State) error { continue } - _, err := apiClient.GetContext(rs.Primary.ID) + _, err := apiClient.GetContext(rs.Primary.ID, true) if err == nil { return fmt.Errorf("Alert still exists") @@ -204,7 +204,7 @@ resource "codefresh_context" "test" { spec { config { - data = { + data = { %q = %q %q = %q } @@ -223,7 +223,7 @@ resource "codefresh_context" "test" { spec { secret { - data = { + data = { %q = %q %q = %q } From 2ab8e22ba68aa4e702635a40936b8cce2dbbfc16 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Mon, 9 Dec 2024 20:04:32 +0200 Subject: [PATCH 2/8] wip --- codefresh/context/storage.go | 2 +- codefresh/resource_context.go | 2 ++ codefresh/resource_context_test.go | 12 +++++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/codefresh/context/storage.go b/codefresh/context/storage.go index 99f88404..9d250840 100644 --- a/codefresh/context/storage.go +++ b/codefresh/context/storage.go @@ -54,7 +54,7 @@ func flattenStorageContextConfig(spec cfclient.ContextSpec, auth map[string]inte func FlattenJsonConfigStorageContextConfig(spec cfclient.ContextSpec) []interface{} { auth := make(map[string]interface{}) auth["json_config"] = spec.Data["auth"].(map[string]interface{})["jsonConfig"] - auth["type"] = spec.Data["type"] + auth["type"] = spec.Data["auth"].(map[string]interface{})["type"] return flattenStorageContextConfig(spec, auth) } diff --git a/codefresh/resource_context.go b/codefresh/resource_context.go index 4f1e4e7a..3ee445f9 100644 --- a/codefresh/resource_context.go +++ b/codefresh/resource_context.go @@ -31,6 +31,8 @@ var supportedContextType = []string{ var encryptedContextTypes = []string{ contextSecret, contextSecretYaml, + contextS3Storage, + contextAzureStorage, } func getConflictingContexts(context string) []string { diff --git a/codefresh/resource_context_test.go b/codefresh/resource_context_test.go index cacc354a..f8efeaf1 100644 --- a/codefresh/resource_context_test.go +++ b/codefresh/resource_context_test.go @@ -129,7 +129,7 @@ func TestAccCodefreshContextSecretYaml(t *testing.T) { CheckDestroy: testAccCheckCodefreshContextDestroy, Steps: []resource.TestStep{ { - Config: testAccCodefreshContextSecretYaml(name, "rootKey", "plainKey", "plainValue", "listKey", "listValue1", "listValue2"), + Config: testAccCodefreshContextSecretYaml(name, "rootKey", "plainKey", "plainValue", "listKey", "listValue1", "listValue2", true), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshContextExists(resourceName), resource.TestCheckResourceAttr(resourceName, "name", name), @@ -159,7 +159,7 @@ func testAccCheckCodefreshContextExists(resource string) resource.TestCheckFunc contextID := rs.Primary.ID apiClient := testAccProvider.Meta().(*cfclient.Client) - _, err := apiClient.GetContext(contextID, true) + _, err := apiClient.GetContext(contextID, false) if err != nil { return fmt.Errorf("error fetching context with ID %s. %s", contextID, err) @@ -177,7 +177,7 @@ func testAccCheckCodefreshContextDestroy(s *terraform.State) error { continue } - _, err := apiClient.GetContext(rs.Primary.ID, true) + _, err := apiClient.GetContext(rs.Primary.ID, false) if err == nil { return fmt.Errorf("Alert still exists") @@ -249,18 +249,20 @@ resource "codefresh_context" "test" { `, rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2) } -func testAccCodefreshContextSecretYaml(rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2 string) string { +func testAccCodefreshContextSecretYaml(rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2 string, decryptSpec bool) string { return fmt.Sprintf(` resource "codefresh_context" "test" { name = "%s" + decrypt_spec = %v + spec { secretyaml { data = "%s: \n %s: %s\n %s: \n - %s\n - %s" } } } -`, rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2) +`, rName, decryptSpec, rootKey, plainKey, plainValue, listKey, listValue1, listValue2) } From ced2787eba883651965e77e20d541465215b7553 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Mon, 9 Dec 2024 20:04:39 +0200 Subject: [PATCH 3/8] wip --- templates/resources/context.md.tmpl | 77 +++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/templates/resources/context.md.tmpl b/templates/resources/context.md.tmpl index baee2942..a1dcaab4 100644 --- a/templates/resources/context.md.tmpl +++ b/templates/resources/context.md.tmpl @@ -88,6 +88,7 @@ YAML ```hcl resource "codefresh_context" "test-secret-yaml" { name = "my-shared-secret-yaml" + decrypt_spec = false spec { # NOTE: The `-` from secret-yaml is stripped because the character is not allowed in Field name # File passed MUST be a valid YAML @@ -96,4 +97,80 @@ resource "codefresh_context" "test-secret-yaml" { } ``` +#### AWS S3 storage context + +```hcl +resource "codefresh_context" "test-s3" { + name = "my-s3-context" + + decrypt_spec = false + + spec { + storages3 { + data { + auth { + type = "basic" + json_config = {accessKeyId = "key", secretAccessKey = "secret"} + } + } + } + } +} +``` + +#### Azure file storage context + +```hcl +resource "codefresh_context" "test-azure" { + name = "my-azure-file-context" + + decrypt_spec = false + + spec { + storageazuref { + data { + auth { + type = "basic" + account_name = "account" + account_key = "key" + } + } + } + } +} +``` + +#### Google cloud storage context + +```hcl +resource "codefresh_context" "test-google-cloud-storage" { + name = "my-gcs-context" + + spec { + storagegc { + data { + auth { + type = "basic" + json_config = jsondecode(< Date: Tue, 10 Dec 2024 13:56:05 +0200 Subject: [PATCH 4/8] change implementation --- codefresh/cfclient/client.go | 41 ++++++++++++++++++++------- codefresh/cfclient/context.go | 29 +++++++++++++++---- codefresh/cfclient/current_account.go | 21 +++++++++----- codefresh/data_context.go | 2 +- codefresh/provider.go | 2 +- codefresh/resource_context.go | 40 +++----------------------- codefresh/resource_context_test.go | 12 ++++---- 7 files changed, 79 insertions(+), 68 deletions(-) diff --git a/codefresh/cfclient/client.go b/codefresh/cfclient/client.go index b8f4442f..9b3afc50 100644 --- a/codefresh/cfclient/client.go +++ b/codefresh/cfclient/client.go @@ -11,11 +11,12 @@ import ( // Client token, host, htpp.Client type Client struct { - Token string - TokenHeader string - Host string - HostV2 string - Client *http.Client + Token string + TokenHeader string + Host string + HostV2 string + featureFlags map[string]bool + Client *http.Client } // RequestOptions path, method, etc @@ -35,11 +36,12 @@ func NewClient(hostname string, hostnameV2 string, token string, tokenHeader str tokenHeader = "Authorization" } return &Client{ - Host: hostname, - HostV2: hostnameV2, - Token: token, - TokenHeader: tokenHeader, - Client: &http.Client{}, + Host: hostname, + HostV2: hostnameV2, + Token: token, + TokenHeader: tokenHeader, + Client: &http.Client{}, + featureFlags: map[string]bool{}, } } @@ -112,6 +114,25 @@ func (client *Client) RequestApiXAccessToken(opt *RequestOptions) ([]byte, error return body, nil } +func (client *Client) isFeatureFlagEnabled(flagName string) (bool, error) { + + if len(client.featureFlags) == 0 { + currAcc, err := client.GetCurrentAccount() + + if err != nil { + return false, err + } + + client.featureFlags = currAcc.FeatureFlags + } + + if val, ok := client.featureFlags[flagName]; ok { + return val, nil + } + + return false, nil +} + // ToQS add extra parameters to path func ToQS(qs map[string]string) string { var arr = []string{} diff --git a/codefresh/cfclient/context.go b/codefresh/cfclient/context.go index d66f2d7d..009fada2 100644 --- a/codefresh/cfclient/context.go +++ b/codefresh/cfclient/context.go @@ -4,8 +4,16 @@ import ( "fmt" "log" "net/url" + "slices" ) +var encryptedContextTypes = []string{ + "secret", + "secret-yaml", + "storage.s3", + "storage.azuref", +} + type ContextErrorResponse struct { Status int `json:"status,omitempty"` Message string `json:"message,omitempty"` @@ -17,9 +25,10 @@ type ContextMetadata struct { } type Context struct { - Metadata ContextMetadata `json:"metadata,omitempty"` - Spec ContextSpec `json:"spec,omitempty"` - Version string `json:"version,omitempty"` + Metadata ContextMetadata `json:"metadata,omitempty"` + Spec ContextSpec `json:"spec,omitempty"` + Version string `json:"version,omitempty"` + IsEncrypred bool `json:"isEncrypted,omitempty"` } type ContextSpec struct { @@ -31,10 +40,16 @@ func (context *Context) GetID() string { return context.Metadata.Name } -func (client *Client) GetContext(name string, decrypt bool) (*Context, error) { +func (client *Client) GetContext(name string) (*Context, error) { fullPath := fmt.Sprintf("/contexts/%s", url.PathEscape(name)) - if decrypt { + forbidDecrypt, err := client.isFeatureFlagEnabled("forbidDecrypt") + + if err != nil { + forbidDecrypt = false + } + + if !forbidDecrypt { fullPath += "?decrypt=true" } @@ -54,8 +69,10 @@ func (client *Client) GetContext(name string, decrypt bool) (*Context, error) { return nil, err } - return &respContext, nil + isEncryptedType := slices.Contains(encryptedContextTypes, respContext.Spec.Type) + respContext.IsEncrypred = isEncryptedType && !forbidDecrypt + return &respContext, nil } func (client *Client) CreateContext(context *Context) (*Context, error) { diff --git a/codefresh/cfclient/current_account.go b/codefresh/cfclient/current_account.go index 6e5f00a0..73da855e 100644 --- a/codefresh/cfclient/current_account.go +++ b/codefresh/cfclient/current_account.go @@ -18,10 +18,11 @@ type CurrentAccountUser struct { // CurrentAccount spec type CurrentAccount struct { - ID string - Name string - Users []CurrentAccountUser - Admins []CurrentAccountUser + ID string + Name string + Users []CurrentAccountUser + Admins []CurrentAccountUser + FeatureFlags map[string]bool } // GetCurrentAccount - @@ -46,9 +47,10 @@ func (client *Client) GetCurrentAccount() (*CurrentAccount, error) { return nil, fmt.Errorf("GetCurrentAccount - cannot get activeAccountName") } currentAccount := &CurrentAccount{ - Name: activeAccountName, - Users: make([]CurrentAccountUser, 0), - Admins: make([]CurrentAccountUser, 0), + Name: activeAccountName, + Users: make([]CurrentAccountUser, 0), + Admins: make([]CurrentAccountUser, 0), + FeatureFlags: make(map[string]bool), } accountAdminsIDs := make([]string, 0) @@ -62,6 +64,11 @@ func (client *Client) GetCurrentAccount() (*CurrentAccount, error) { for _, adminI := range admins { accountAdminsIDs = append(accountAdminsIDs, adminI.(string)) } + featureFlags := accX.Get("features").ObjxMap() + + for k, v := range featureFlags { + currentAccount.FeatureFlags[k] = v.(bool) + } break } } diff --git a/codefresh/data_context.go b/codefresh/data_context.go index 0fc6579f..032b51bb 100644 --- a/codefresh/data_context.go +++ b/codefresh/data_context.go @@ -36,7 +36,7 @@ func dataSourceContextRead(d *schema.ResourceData, meta interface{}) error { var err error if name, nameOk := d.GetOk("name"); nameOk { - context, err = client.GetContext(name.(string), true) + context, err = client.GetContext(name.(string)) } else { return fmt.Errorf("data.codefresh_context - must specify name") } diff --git a/codefresh/provider.go b/codefresh/provider.go index ad08cfca..fb30cad3 100644 --- a/codefresh/provider.go +++ b/codefresh/provider.go @@ -5,7 +5,6 @@ import ( "github.com/codefresh-io/terraform-provider-codefresh/codefresh/cfclient" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "os" ) @@ -87,5 +86,6 @@ func configureProvider(d *schema.ResourceData) (interface{}, error) { if token == "" { token = os.Getenv(ENV_CODEFRESH_API_KEY) } + return cfclient.NewClient(apiURL, apiURLV2, token, ""), nil } diff --git a/codefresh/resource_context.go b/codefresh/resource_context.go index 3ee445f9..18a931d2 100644 --- a/codefresh/resource_context.go +++ b/codefresh/resource_context.go @@ -64,12 +64,6 @@ func resourceContext() *schema.Resource { Required: true, ForceNew: true, }, - "decrypt_spec": { - Type: schema.TypeBool, - Default: true, - Optional: true, - Description: "Whether to allow decryption of context spec for encrypted contexts on read. If set to false context content diff will not be calculated against the API. Must be set to false if `forbidDecrypt` feature flag on Codefresh platfrom is enabled", - }, "spec": { Description: "The context's specs.", Type: schema.TypeList, @@ -187,17 +181,12 @@ func resourceContextRead(d *schema.ResourceData, meta interface{}) error { contextName := d.Id() - currentContextType := getContextTypeFromResource(d) - - // Explicitly set decypt flag to true only if context type is encrypted and decrypt_spec is set to true - setExplicitDecrypt := contains(encryptedContextTypes, currentContextType) && d.Get("decrypt_spec").(bool) - if contextName == "" { d.SetId("") return nil } - context, err := client.GetContext(contextName, setExplicitDecrypt) + context, err := client.GetContext(contextName) if err != nil { log.Printf("[DEBUG] Error while getting context. Error = %v", contextName) @@ -205,6 +194,7 @@ func resourceContextRead(d *schema.ResourceData, meta interface{}) error { } err = mapContextToResource(*context, d) + if err != nil { log.Printf("[DEBUG] Error while mapping context to resource. Error = %v", err) return err @@ -249,10 +239,8 @@ func mapContextToResource(context cfclient.Context, d *schema.ResourceData) erro return err } - currentContextType := getContextTypeFromResource(d) - - // Read spec from API if context is not encrypted or decrypt_spec is set to true explicitly - if d.Get("decrypt_spec").(bool) || !contains(encryptedContextTypes, currentContextType) { + // Read spec from API if context is not encrypted or forbitDecrypt is not set + if !context.IsEncrypred { err = d.Set("spec", flattenContextSpec(context.Spec)) @@ -345,23 +333,3 @@ func mapResourceToContext(d *schema.ResourceData) *cfclient.Context { }, } } - -func getContextTypeFromResource(d *schema.ResourceData) string { - if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextConfig) + ".0.data"); ok { - return contextConfig - } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextSecret) + ".0.data"); ok { - return contextSecret - } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextYaml) + ".0.data"); ok { - return contextYaml - } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextSecretYaml) + ".0.data"); ok { - return contextSecretYaml - } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextGoogleStorage) + ".0.data"); ok { - return contextGoogleStorage - } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextS3Storage) + ".0.data"); ok { - return contextS3Storage - } else if _, ok := d.GetOk("spec.0." + schemautil.MustNormalizeFieldName(contextAzureStorage) + ".0.data"); ok { - return contextAzureStorage - } - - return "" -} diff --git a/codefresh/resource_context_test.go b/codefresh/resource_context_test.go index f8efeaf1..8b1e6309 100644 --- a/codefresh/resource_context_test.go +++ b/codefresh/resource_context_test.go @@ -129,7 +129,7 @@ func TestAccCodefreshContextSecretYaml(t *testing.T) { CheckDestroy: testAccCheckCodefreshContextDestroy, Steps: []resource.TestStep{ { - Config: testAccCodefreshContextSecretYaml(name, "rootKey", "plainKey", "plainValue", "listKey", "listValue1", "listValue2", true), + Config: testAccCodefreshContextSecretYaml(name, "rootKey", "plainKey", "plainValue", "listKey", "listValue1", "listValue2"), Check: resource.ComposeTestCheckFunc( testAccCheckCodefreshContextExists(resourceName), resource.TestCheckResourceAttr(resourceName, "name", name), @@ -159,7 +159,7 @@ func testAccCheckCodefreshContextExists(resource string) resource.TestCheckFunc contextID := rs.Primary.ID apiClient := testAccProvider.Meta().(*cfclient.Client) - _, err := apiClient.GetContext(contextID, false) + _, err := apiClient.GetContext(contextID) if err != nil { return fmt.Errorf("error fetching context with ID %s. %s", contextID, err) @@ -177,7 +177,7 @@ func testAccCheckCodefreshContextDestroy(s *terraform.State) error { continue } - _, err := apiClient.GetContext(rs.Primary.ID, false) + _, err := apiClient.GetContext(rs.Primary.ID) if err == nil { return fmt.Errorf("Alert still exists") @@ -249,20 +249,18 @@ resource "codefresh_context" "test" { `, rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2) } -func testAccCodefreshContextSecretYaml(rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2 string, decryptSpec bool) string { +func testAccCodefreshContextSecretYaml(rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2 string) string { return fmt.Sprintf(` resource "codefresh_context" "test" { name = "%s" - decrypt_spec = %v - spec { secretyaml { data = "%s: \n %s: %s\n %s: \n - %s\n - %s" } } } -`, rName, decryptSpec, rootKey, plainKey, plainValue, listKey, listValue1, listValue2) +`, rName, rootKey, plainKey, plainValue, listKey, listValue1, listValue2) } From d8474f8d525a8bb240b756b1bb8ca1909091358b Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Tue, 10 Dec 2024 13:58:38 +0200 Subject: [PATCH 5/8] change implementation --- codefresh/resource_context.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/codefresh/resource_context.go b/codefresh/resource_context.go index 18a931d2..7c123253 100644 --- a/codefresh/resource_context.go +++ b/codefresh/resource_context.go @@ -28,13 +28,6 @@ var supportedContextType = []string{ contextSecretYaml, } -var encryptedContextTypes = []string{ - contextSecret, - contextSecretYaml, - contextS3Storage, - contextAzureStorage, -} - func getConflictingContexts(context string) []string { var conflictingTypes []string normalizedContext := schemautil.MustNormalizeFieldName(context) From 05ae26bfbd0e502ddff5532d08f47b6dd6e2c42d Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Tue, 10 Dec 2024 14:00:41 +0200 Subject: [PATCH 6/8] docs --- docs/resources/context.md | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/docs/resources/context.md b/docs/resources/context.md index 3a5a6cc1..e51660e0 100644 --- a/docs/resources/context.md +++ b/docs/resources/context.md @@ -88,6 +88,7 @@ YAML ```hcl resource "codefresh_context" "test-secret-yaml" { name = "my-shared-secret-yaml" + decrypt_spec = false spec { # NOTE: The `-` from secret-yaml is stripped because the character is not allowed in Field name # File passed MUST be a valid YAML @@ -96,6 +97,82 @@ resource "codefresh_context" "test-secret-yaml" { } ``` +#### AWS S3 storage context + +```hcl +resource "codefresh_context" "test-s3" { + name = "my-s3-context" + + decrypt_spec = false + + spec { + storages3 { + data { + auth { + type = "basic" + json_config = {accessKeyId = "key", secretAccessKey = "secret"} + } + } + } + } +} +``` + +#### Azure file storage context + +```hcl +resource "codefresh_context" "test-azure" { + name = "my-azure-file-context" + + decrypt_spec = false + + spec { + storageazuref { + data { + auth { + type = "basic" + account_name = "account" + account_key = "key" + } + } + } + } +} +``` + +#### Google cloud storage context + +```hcl +resource "codefresh_context" "test-google-cloud-storage" { + name = "my-gcs-context" + + spec { + storagegc { + data { + auth { + type = "basic" + json_config = jsondecode(< ## Schema From 309c89c421a6a87b2b6808f875db07b3fe69e649 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Tue, 10 Dec 2024 15:17:09 +0200 Subject: [PATCH 7/8] fix contains --- codefresh/cfclient/context.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codefresh/cfclient/context.go b/codefresh/cfclient/context.go index 009fada2..9b1f0e8f 100644 --- a/codefresh/cfclient/context.go +++ b/codefresh/cfclient/context.go @@ -4,7 +4,8 @@ import ( "fmt" "log" "net/url" - "slices" + + "golang.org/x/exp/slices" ) var encryptedContextTypes = []string{ From 54cfa22720bbfce9d0b2a122cc49ea60f0721ef8 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Tue, 10 Dec 2024 15:49:11 +0200 Subject: [PATCH 8/8] fix --- codefresh/cfclient/context.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/codefresh/cfclient/context.go b/codefresh/cfclient/context.go index 9b1f0e8f..4a29decc 100644 --- a/codefresh/cfclient/context.go +++ b/codefresh/cfclient/context.go @@ -70,8 +70,15 @@ func (client *Client) GetContext(name string) (*Context, error) { return nil, err } + // This is so not to break existing behavior while adding support for forbidDecrypt feature flag + // The provider used to always decrypt the contexts, hence we treat all contexts as decrypted unless forbidDecrypt is set isEncryptedType := slices.Contains(encryptedContextTypes, respContext.Spec.Type) - respContext.IsEncrypred = isEncryptedType && !forbidDecrypt + + respContext.IsEncrypred = false + + if forbidDecrypt && isEncryptedType { + respContext.IsEncrypred = true + } return &respContext, nil }