From cbc4fc0aa8ede402f30c8844bf310510b86f2d63 Mon Sep 17 00:00:00 2001 From: David Corrigan <47994662+davidcorrigan714@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:30:21 -0500 Subject: [PATCH] Remove service connections hashing & secret data handling cleanup (#11) * remove hashing shenanigans --- .../resource_serviceendpoint_aws_test.go | 9 +-- ...rce_serviceendpoint_dockerregistry_test.go | 6 +- ...source_serviceendpoint_generic_git_test.go | 4 +- ...esource_serviceendpoint_sonarcloud_test.go | 2 + ...resource_serviceendpoint_sonarqube_test.go | 4 +- .../service/serviceendpoint/commons.go | 14 ++-- .../resource_serviceendpoint_aws.go | 32 +++----- .../resource_serviceendpoint_aws_test.go | 4 +- .../resource_serviceendpoint_azuredevops.go | 2 - .../resource_serviceendpoint_azurerm.go | 21 +++-- .../resource_serviceendpoint_azurerm_test.go | 2 +- .../resource_serviceendpoint_bitbucket.go | 2 - ...resource_serviceendpoint_dockerregistry.go | 16 ++-- ...rce_serviceendpoint_dockerregistry_test.go | 2 +- .../resource_serviceendpoint_generic.go | 15 ++-- .../resource_serviceendpoint_generic_git.go | 16 ++-- .../resource_serviceendpoint_github.go | 5 -- ...ource_serviceendpoint_github_enterprise.go | 5 -- ...esource_serviceendpoint_incomingwebhook.go | 1 - .../resource_serviceendpoint_kubernetes.go | 17 +--- .../resource_serviceendpoint_nuget.go | 3 - .../resource_serviceendpoint_runpipeline.go | 6 -- .../resource_serviceendpoint_sonaqube.go | 18 ++--- ...resource_serviceendpoint_sonarqube_test.go | 2 +- .../resource_serviceendpoint_ssh.go | 26 ++----- .../internal/utils/secretmemo/secretmemo.go | 52 ------------- .../utils/secretmemo/secretmemo_test.go | 69 ----------------- .../internal/utils/tfhelper/tfhelper.go | 77 ------------------- 28 files changed, 73 insertions(+), 359 deletions(-) delete mode 100644 azuredevops/internal/utils/secretmemo/secretmemo.go delete mode 100644 azuredevops/internal/utils/secretmemo/secretmemo_test.go diff --git a/azuredevops/internal/acceptancetests/resource_serviceendpoint_aws_test.go b/azuredevops/internal/acceptancetests/resource_serviceendpoint_aws_test.go index cca25f968..0cbd9dc13 100644 --- a/azuredevops/internal/acceptancetests/resource_serviceendpoint_aws_test.go +++ b/azuredevops/internal/acceptancetests/resource_serviceendpoint_aws_test.go @@ -30,8 +30,7 @@ func TestAccServiceEndpointAws_Basic(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointName), resource.TestCheckResourceAttr(tfSvcEpNode, "access_key_id", "0000"), - resource.TestCheckResourceAttr(tfSvcEpNode, "secret_access_key", ""), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "secret_access_key_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "secret_access_key", "secretkey"), ), }, }, @@ -61,11 +60,9 @@ func TestAccServiceEndpointAws_Complete(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointName), resource.TestCheckResourceAttr(tfSvcEpNode, "access_key_id", "0000"), - resource.TestCheckResourceAttr(tfSvcEpNode, "secret_access_key", ""), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "secret_access_key_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "secret_access_key", "secretkey"), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), - resource.TestCheckResourceAttr(tfSvcEpNode, "session_token", ""), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "session_token_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "session_token", "foobar"), resource.TestCheckResourceAttr(tfSvcEpNode, "role_to_assume", rta), resource.TestCheckResourceAttr(tfSvcEpNode, "role_session_name", rsn), resource.TestCheckResourceAttr(tfSvcEpNode, "external_id", externalId), diff --git a/azuredevops/internal/acceptancetests/resource_serviceendpoint_dockerregistry_test.go b/azuredevops/internal/acceptancetests/resource_serviceendpoint_dockerregistry_test.go index ce9178c40..3dae4e2cb 100644 --- a/azuredevops/internal/acceptancetests/resource_serviceendpoint_dockerregistry_test.go +++ b/azuredevops/internal/acceptancetests/resource_serviceendpoint_dockerregistry_test.go @@ -33,8 +33,7 @@ func TestAccServiceEndpointDockerRegistry_CreateAndUpdate(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "docker_username", "testuser"), resource.TestCheckResourceAttr(tfSvcEpNode, "docker_email", "test@email.com"), - resource.TestCheckResourceAttr(tfSvcEpNode, "docker_password", ""), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "docker_password_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "docker_password", "secret"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointNameFirst), testutils.CheckServiceEndpointExistsWithName(tfSvcEpNode, serviceEndpointNameFirst), ), @@ -44,8 +43,7 @@ func TestAccServiceEndpointDockerRegistry_CreateAndUpdate(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttrSet(tfSvcEpNode, "docker_username"), resource.TestCheckResourceAttrSet(tfSvcEpNode, "docker_email"), - resource.TestCheckResourceAttr(tfSvcEpNode, "docker_password", ""), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "docker_password_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "docker_password", "secret"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointNameSecond), testutils.CheckServiceEndpointExistsWithName(tfSvcEpNode, serviceEndpointNameSecond)), }, diff --git a/azuredevops/internal/acceptancetests/resource_serviceendpoint_generic_git_test.go b/azuredevops/internal/acceptancetests/resource_serviceendpoint_generic_git_test.go index 403c30b0b..2bc1f7a6e 100644 --- a/azuredevops/internal/acceptancetests/resource_serviceendpoint_generic_git_test.go +++ b/azuredevops/internal/acceptancetests/resource_serviceendpoint_generic_git_test.go @@ -56,7 +56,7 @@ func TestAccServiceEndpointGenericGit_complete(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "repository_url", "https://dev.azure.com/org/project/_git/repository"), resource.TestCheckResourceAttr(tfSvcEpNode, "username", "username"), - resource.TestCheckResourceAttr(tfSvcEpNode, "password", ""), + resource.TestCheckResourceAttr(tfSvcEpNode, "password", "password"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointName), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), resource.TestCheckResourceAttr(tfSvcEpNode, "enable_pipelines_access", "true"), @@ -96,7 +96,7 @@ func TestAccServiceEndpointGenericGit_update(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "repository_url", "https://dev.azure.com/org/project/_git/repository"), resource.TestCheckResourceAttr(tfSvcEpNode, "username", "username"), - resource.TestCheckResourceAttr(tfSvcEpNode, "password", ""), + resource.TestCheckResourceAttr(tfSvcEpNode, "password", "password"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointNameSecond), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), resource.TestCheckResourceAttr(tfSvcEpNode, "enable_pipelines_access", "false"), diff --git a/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarcloud_test.go b/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarcloud_test.go index 46bede6f7..5a42c6047 100644 --- a/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarcloud_test.go +++ b/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarcloud_test.go @@ -54,6 +54,7 @@ func TestAccServiceEndpointSonarCloud_complete(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointName), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), + resource.TestCheckResourceAttr(tfSvcEpNode, "token", "redacted"), ), }, }, @@ -88,6 +89,7 @@ func TestAccServiceEndpointSonarCloud_update(t *testing.T) { resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointNameSecond), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), + resource.TestCheckResourceAttr(tfSvcEpNode, "token", "redacted2"), ), }, }, diff --git a/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarqube_test.go b/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarqube_test.go index 785b68f29..a7edf03fe 100644 --- a/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarqube_test.go +++ b/azuredevops/internal/acceptancetests/resource_serviceendpoint_sonarqube_test.go @@ -52,7 +52,7 @@ func TestAccServiceEndpointSonarQube_complete(t *testing.T) { Check: resource.ComposeTestCheckFunc( testutils.CheckServiceEndpointExistsWithName(tfSvcEpNode, serviceEndpointName), resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "token_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "token", "redacted"), resource.TestCheckResourceAttr(tfSvcEpNode, "url", "https://url.com/"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointName), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), @@ -88,7 +88,7 @@ func TestAccServiceEndpointSonarQube_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testutils.CheckServiceEndpointExistsWithName(tfSvcEpNode, serviceEndpointNameSecond), resource.TestCheckResourceAttrSet(tfSvcEpNode, "project_id"), - resource.TestCheckResourceAttrSet(tfSvcEpNode, "token_hash"), + resource.TestCheckResourceAttr(tfSvcEpNode, "token", "redacted2"), resource.TestCheckResourceAttr(tfSvcEpNode, "url", "https://url.com/2"), resource.TestCheckResourceAttr(tfSvcEpNode, "service_endpoint_name", serviceEndpointNameSecond), resource.TestCheckResourceAttr(tfSvcEpNode, "description", description), diff --git a/azuredevops/internal/service/serviceendpoint/commons.go b/azuredevops/internal/service/serviceendpoint/commons.go index b07eb74f3..8c20eadbf 100644 --- a/azuredevops/internal/service/serviceendpoint/commons.go +++ b/azuredevops/internal/service/serviceendpoint/commons.go @@ -128,16 +128,12 @@ func doBaseFlattening(d *schema.ResourceData, serviceEndpoint *serviceendpoint.S // makeProtectedSchema create protected schema func makeProtectedSchema(r *schema.Resource, keyName, envVarName, description string) { r.Schema[keyName] = &schema.Schema{ - Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc(envVarName, nil), - Description: description, - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc(envVarName, nil), + Description: description, + Sensitive: true, } - - secretHashKey, secretHashSchema := tfhelper.GenerateSecreteMemoSchema(keyName) - r.Schema[secretHashKey] = secretHashSchema } // makeUnprotectedSchema create unprotected schema diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws.go index 2902aedd9..3f26a4c85 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointAws schema and implementation for aws service endpoint resource @@ -18,25 +17,19 @@ func ResourceServiceEndpointAws() *schema.Resource { Description: "The AWS access key ID for signing programmatic requests.", } r.Schema["secret_access_key"] = &schema.Schema{ - Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("AZDO_AWS_SERVICE_CONNECTION_SECRET_ACCESS_KEY", nil), - Description: "The AWS secret access key for signing programmatic requests.", - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("AZDO_AWS_SERVICE_CONNECTION_SECRET_ACCESS_KEY", nil), + Description: "The AWS secret access key for signing programmatic requests.", + Sensitive: true, } - saSecretHashKey, saSecretHashSchema := tfhelper.GenerateSecreteMemoSchema("secret_access_key") - r.Schema[saSecretHashKey] = saSecretHashSchema r.Schema["session_token"] = &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("AZDO_AWS_SERVICE_CONNECTION_SESSION_TOKEN", nil), - Description: "The AWS session token for signing programmatic requests.", - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("AZDO_AWS_SERVICE_CONNECTION_SESSION_TOKEN", nil), + Description: "The AWS session token for signing programmatic requests.", + Sensitive: true, } - stSecretHashKey, stSecretHashSchema := tfhelper.GenerateSecreteMemoSchema("session_token") - r.Schema[stSecretHashKey] = stSecretHashSchema r.Schema["role_to_assume"] = &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -81,12 +74,7 @@ func expandServiceEndpointAws(d *schema.ResourceData) (*serviceendpoint.ServiceE func flattenServiceEndpointAws(d *schema.ResourceData, serviceEndpoint *serviceendpoint.ServiceEndpoint, projectID *uuid.UUID) { doBaseFlattening(d, serviceEndpoint, projectID) - tfhelper.HelpFlattenSecret(d, "secret_access_key") - tfhelper.HelpFlattenSecret(d, "session_token") - d.Set("access_key_id", (*serviceEndpoint.Authorization.Parameters)["username"]) - d.Set("secret_access_key", (*serviceEndpoint.Authorization.Parameters)["password"]) - d.Set("session_token", (*serviceEndpoint.Authorization.Parameters)["sessionToken"]) d.Set("role_to_assume", (*serviceEndpoint.Authorization.Parameters)["assumeRoleArn"]) d.Set("role_session_name", (*serviceEndpoint.Authorization.Parameters)["roleSessionName"]) d.Set("external_id", (*serviceEndpoint.Authorization.Parameters)["externalId"]) diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws_test.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws_test.go index cf97e2e2e..1881b9270 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws_test.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_aws_test.go @@ -27,8 +27,8 @@ var awsTestServiceEndpoint = serviceendpoint.ServiceEndpoint{ Authorization: &serviceendpoint.EndpointAuthorization{ Parameters: &map[string]string{ "username": "AWS_TEST_username", - "password": "AWS_TEST_password", - "sessionToken": "AWS_TEST_sessionToken", + "password": "", + "sessionToken": "", "assumeRoleArn": "AWS_TEST_assumeRoleArn", "roleSessionName": "ARS_TEST_roleSessionName", "externalId": "AWS_TEST_externalId", diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azuredevops.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azuredevops.go index 9560ce5cf..d521dd6df 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azuredevops.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azuredevops.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) func ResourceServiceEndpointAzureDevOps() *schema.Resource { @@ -49,6 +48,5 @@ func expandServiceEndpointAzureDevOps(d *schema.ResourceData) (*serviceendpoint. func flattenServiceEndpointAzureDevOps(d *schema.ResourceData, serviceEndpoint *serviceendpoint.ServiceEndpoint, projectID *uuid.UUID) { doBaseFlattening(d, serviceEndpoint, projectID) d.Set("org_url", serviceEndpoint.Url) - tfhelper.HelpFlattenSecret(d, "password") d.Set("release_api_url", (*serviceEndpoint.Data)["releaseUrl"]) } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm.go index 7660f7f75..7ef01a71d 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointAzureRM schema and implementation for AzureRM service endpoint resource @@ -33,7 +32,6 @@ func ResourceServiceEndpointAzureRM() *schema.Resource { makeUnprotectedOptionalSchema(r, "azurerm_management_group_id", "ARM_MGMT_GROUP_ID", "The Azure managementGroup Id which should be used.", []string{"azurerm_subscription_id", "resource_group"}) makeUnprotectedOptionalSchema(r, "azurerm_management_group_name", "ARM_MGMT_GROUP_NAME", "The Azure managementGroup name which should be used.", []string{"azurerm_subscription_id", "resource_group"}) - secretHashKey, secretHashSchema := tfhelper.GenerateSecreteMemoSchema("serviceprincipalkey") r.Schema["credentials"] = &schema.Schema{ Type: schema.TypeList, Optional: true, @@ -47,13 +45,11 @@ func ResourceServiceEndpointAzureRM() *schema.Resource { Description: "The service principal id which should be used.", }, "serviceprincipalkey": { - Type: schema.TypeString, - Required: true, - Description: "The service principal secret which should be used.", - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + Required: true, + Description: "The service principal secret which should be used.", + Sensitive: true, }, - secretHashKey: secretHashSchema, }, }, } @@ -164,9 +160,12 @@ func flattenServiceEndpointAzureRM(d *schema.ResourceData, serviceEndpoint *serv scope := (*serviceEndpoint.Authorization.Parameters)["scope"] if (*serviceEndpoint.Data)["creationMode"] == "Manual" { - newHash, hashKey := tfhelper.HelpFlattenSecretNested(d, "credentials", d.Get("credentials.0").(map[string]interface{}), "serviceprincipalkey") - credentials := flattenCredentials(d, serviceEndpoint, hashKey, newHash) - d.Set("credentials", credentials) + if _, ok := d.GetOk("credentials"); !ok { + credentials := make(map[string]interface{}) + credentials["serviceprincipalid"] = (*serviceEndpoint.Authorization.Parameters)["serviceprincipalid"] + credentials["serviceprincipalkey"] = "" + d.Set("credentials", []interface{}{credentials}) + } } s := strings.SplitN(scope, "/", -1) diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm_test.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm_test.go index 4860915fb..479365f3f 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm_test.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_azurerm_test.go @@ -29,7 +29,7 @@ func getManualAuthServiceEndpoint() serviceendpoint.ServiceEndpoint { Parameters: &map[string]string{ "authenticationType": "spnKey", "serviceprincipalid": "e31eaaac-47da-4156-b433-9b0538c94b7e", //fake value - "serviceprincipalkey": "d96d8515-20b2-4413-8879-27c5d040cbc2", //fake value + "serviceprincipalkey": "", //fake value "tenantid": "aba07645-051c-44b4-b806-c34d33f3dcd1", //fake value }, Scheme: converter.String("ServicePrincipal"), diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_bitbucket.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_bitbucket.go index 4c601574c..a2325967a 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_bitbucket.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_bitbucket.go @@ -6,7 +6,6 @@ import ( "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/model" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointBitBucket schema and implementation for bitbucket service endpoint resource @@ -34,5 +33,4 @@ func expandServiceEndpointBitBucket(d *schema.ResourceData) (*serviceendpoint.Se func flattenServiceEndpointBitBucket(d *schema.ResourceData, serviceEndpoint *serviceendpoint.ServiceEndpoint, projectID *uuid.UUID) { doBaseFlattening(d, serviceEndpoint, projectID) d.Set("username", (*serviceEndpoint.Authorization.Parameters)["username"]) - tfhelper.HelpFlattenSecret(d, "password") } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry.go index cf69f36ff..5f7a1d45e 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointDockerRegistry schema and implementation for docker registry service endpoint resource @@ -25,15 +24,12 @@ func ResourceServiceEndpointDockerRegistry() *schema.Resource { Description: "The DockerRegistry username which should be used.", } r.Schema["docker_password"] = &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("AZDO_DOCKERREGISTRY_SERVICE_CONNECTION_PASSWORD", nil), - Description: "The DockerRegistry password which should be used.", - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("AZDO_DOCKERREGISTRY_SERVICE_CONNECTION_PASSWORD", nil), + Description: "The DockerRegistry password which should be used.", + Sensitive: true, } - secretHashKey, secretHashSchema := tfhelper.GenerateSecreteMemoSchema("docker_password") - r.Schema[secretHashKey] = secretHashSchema r.Schema["docker_email"] = &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -79,7 +75,5 @@ func flattenServiceEndpointDockerRegistry(d *schema.ResourceData, serviceEndpoin d.Set("docker_registry", (*serviceEndpoint.Authorization.Parameters)["registry"]) d.Set("docker_email", (*serviceEndpoint.Authorization.Parameters)["email"]) d.Set("docker_username", (*serviceEndpoint.Authorization.Parameters)["username"]) - tfhelper.HelpFlattenSecret(d, "docker_password") - d.Set("docker_password", (*serviceEndpoint.Authorization.Parameters)["password"]) d.Set("registry_type", (*serviceEndpoint.Data)["registrytype"]) } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry_test.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry_test.go index 482b2949c..150ca611d 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry_test.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_dockerregistry_test.go @@ -27,7 +27,7 @@ var dockerRegistryTestServiceEndpoint = serviceendpoint.ServiceEndpoint{ //todo Authorization: &serviceendpoint.EndpointAuthorization{ Parameters: &map[string]string{ "username": "DH_TEST_username", - "password": "DH_TEST_password", + "password": "", "email": "DH_TEST_email", "registry": "https://index.docker.io/v1/", }, diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic.go index 8f2e89a42..4a79a58ab 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointGeneric schema and implementation for generic service endpoint resource @@ -25,15 +24,12 @@ func ResourceServiceEndpointGeneric() *schema.Resource { Optional: true, } r.Schema["password"] = &schema.Schema{ - Type: schema.TypeString, - DefaultFunc: schema.EnvDefaultFunc("AZDO_GENERIC_SERVICE_CONNECTION_PASSWORD", nil), - Description: "The password or token key to use for the generic service connection.", - Sensitive: true, - Optional: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + DefaultFunc: schema.EnvDefaultFunc("AZDO_GENERIC_SERVICE_CONNECTION_PASSWORD", nil), + Description: "The password or token key to use for the generic service connection.", + Sensitive: true, + Optional: true, } - secretHashKey, secretHashSchema := tfhelper.GenerateSecreteMemoSchema("password") - r.Schema[secretHashKey] = secretHashSchema return r } @@ -55,5 +51,4 @@ func flattenServiceEndpointGeneric(d *schema.ResourceData, serviceEndpoint *serv doBaseFlattening(d, serviceEndpoint, projectID) d.Set("server_url", *serviceEndpoint.Url) d.Set("username", (*serviceEndpoint.Authorization.Parameters)["username"]) - tfhelper.HelpFlattenSecret(d, "password") } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic_git.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic_git.go index 6f9a6dafc..323b08f83 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic_git.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_generic_git.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointGenericGit schema and implementation for generic git service endpoint resource @@ -27,12 +26,11 @@ func ResourceServiceEndpointGenericGit() *schema.Resource { Optional: true, } r.Schema["password"] = &schema.Schema{ - Type: schema.TypeString, - DefaultFunc: schema.EnvDefaultFunc("AZDO_GENERIC_GIT_SERVICE_CONNECTION_PASSWORD", nil), - Description: "The password or token key to use for the generic git service connection.", - Sensitive: true, - Optional: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, + Type: schema.TypeString, + DefaultFunc: schema.EnvDefaultFunc("AZDO_GENERIC_GIT_SERVICE_CONNECTION_PASSWORD", nil), + Description: "The password or token key to use for the generic git service connection.", + Sensitive: true, + Optional: true, } r.Schema["enable_pipelines_access"] = &schema.Schema{ Type: schema.TypeBool, @@ -40,8 +38,6 @@ func ResourceServiceEndpointGenericGit() *schema.Resource { Description: "A value indicating whether or not to attempt accessing this git server from Azure Pipelines.", Optional: true, } - secretHashKey, secretHashSchema := tfhelper.GenerateSecreteMemoSchema("password") - r.Schema[secretHashKey] = secretHashSchema return r } @@ -69,6 +65,4 @@ func flattenServiceEndpointGenericGit(d *schema.ResourceData, serviceEndpoint *s d.Set("enable_pipelines_access", v) } d.Set("username", (*serviceEndpoint.Authorization.Parameters)["username"]) - tfhelper.HelpFlattenSecret(d, "password") - d.Set("password", (*serviceEndpoint.Authorization.Parameters)["password"]) } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github.go index e54932798..246ad57d5 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) const ( @@ -30,8 +29,6 @@ func ResourceServiceEndpointGitHub() *schema.Resource { }, }, } - patHashKey, patHashSchema := tfhelper.GenerateSecreteMemoSchema(personalAccessTokenGithub) - authPersonal.Schema[patHashKey] = patHashSchema r.Schema["auth_personal"] = &schema.Schema{ Type: schema.TypeSet, Optional: true, @@ -124,8 +121,6 @@ func flattenServiceEndpointGitHub(d *schema.ResourceData, serviceEndpoint *servi func flattenAuthPerson(d *schema.ResourceData, authPersonalSet []interface{}) []interface{} { if len(authPersonalSet) == 1 { if authPersonal, ok := authPersonalSet[0].(map[string]interface{}); ok { - newHash, hashKey := tfhelper.HelpFlattenSecretNested(d, "auth_personal", authPersonal, personalAccessTokenGithub) - authPersonal[hashKey] = newHash return []interface{}{authPersonal} } } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github_enterprise.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github_enterprise.go index 228ea365d..0574bb945 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github_enterprise.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_github_enterprise.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) const ( @@ -30,8 +29,6 @@ func ResourceServiceEndpointGitHubEnterprise() *schema.Resource { }, }, } - patHashKey, patHashSchema := tfhelper.GenerateSecreteMemoSchema(personalAccessTokenGithubEnterprise) - authPersonal.Schema[patHashKey] = patHashSchema r.Schema["auth_personal"] = &schema.Schema{ Type: schema.TypeSet, MinItems: 1, @@ -64,8 +61,6 @@ func flattenServiceEndpointGitHubEnterprise(d *schema.ResourceData, serviceEndpo func flattenAuthPersonGithubEnterprise(d *schema.ResourceData, authPersonalSet []interface{}) []interface{} { if len(authPersonalSet) == 1 { if authPersonal, ok := authPersonalSet[0].(map[string]interface{}); ok { - newHash, hashKey := tfhelper.HelpFlattenSecretNested(d, "auth_personal", authPersonal, personalAccessTokenGithub) - authPersonal[hashKey] = newHash return []interface{}{authPersonal} } } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_incomingwebhook.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_incomingwebhook.go index a49e34598..5cfd44f63 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_incomingwebhook.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_incomingwebhook.go @@ -53,5 +53,4 @@ func flattenServiceEndpointIncomingWebhook(d *schema.ResourceData, serviceEndpoi doBaseFlattening(d, serviceEndpoint, projectID) d.Set("webhook_name", (*serviceEndpoint.Authorization.Parameters)["webhookname"]) d.Set("http_header", (*serviceEndpoint.Authorization.Parameters)["header"]) - // secret value won't be returned by service and should not be overwritten } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_kubernetes.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_kubernetes.go index 929d184df..75e51a872 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_kubernetes.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_kubernetes.go @@ -10,7 +10,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" "gopkg.in/yaml.v3" ) @@ -304,23 +303,15 @@ func flattenServiceEndpointKubernetes(d *schema.ResourceData, serviceEndpoint *s serviceAccountSet := d.Get("service_account").([]interface{}) if len(serviceAccountSet) == 0 { - newHashToken, hashKeyToken := tfhelper.HelpFlattenSecretNested(d, resourceBlockServiceAccount, nil, "token") - newHashCert, hashKeyCert := tfhelper.HelpFlattenSecretNested(d, resourceBlockServiceAccount, nil, "ca_cert") serviceAccount = map[string]interface{}{ - "token": "", - "ca_cert": "", - hashKeyToken: newHashToken, - hashKeyCert: newHashCert, + "token": "", + "ca_cert": "", } } else { configuration := serviceAccountSet[0].(map[string]interface{}) - newHashToken, hashKeyToken := tfhelper.HelpFlattenSecretNested(d, resourceBlockServiceAccount, configuration, "token") - newHashCert, hashKeyCert := tfhelper.HelpFlattenSecretNested(d, resourceBlockServiceAccount, configuration, "ca_cert") serviceAccount = map[string]interface{}{ - "token": configuration["token"].(string), - "ca_cert": configuration["ca_cert"].(string), - hashKeyToken: newHashToken, - hashKeyCert: newHashCert, + "token": configuration["token"].(string), + "ca_cert": configuration["ca_cert"].(string), } } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_nuget.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_nuget.go index cf6db6f83..cf2070e0a 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_nuget.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_nuget.go @@ -10,7 +10,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointNuget schema and implementation for Nuget service endpoint resource @@ -35,7 +34,6 @@ func ResourceServiceEndpointNuget() *schema.Resource { Description: "Url for the Nuget Feed", } - patHashKey, patHashSchema := tfhelper.GenerateSecreteMemoSchema("token") at := &schema.Resource{ Schema: map[string]*schema.Schema{ "token": { @@ -44,7 +42,6 @@ func ResourceServiceEndpointNuget() *schema.Resource { Required: true, Sensitive: true, }, - patHashKey: patHashSchema, }, } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_runpipeline.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_runpipeline.go index 09dbfdfcb..74d16d8b3 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_runpipeline.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_runpipeline.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointRunPipeline schema and implementation for Azure DevOps service endpoint resource @@ -78,9 +77,6 @@ func rpPersonalAccessTokenField() *schema.Resource { }, }, } - patHashKey, patHashSchema := tfhelper.GenerateSecreteMemoSchema(fieldName) - personalAccessToken.Schema[patHashKey] = patHashSchema - return personalAccessToken } @@ -97,8 +93,6 @@ func flattenServiceEndpointRunPipeline(d *schema.ResourceData, serviceEndpoint * func rpFlattenAuthPersonal(d *schema.ResourceData, authPersonalSet []interface{}) []interface{} { if len(authPersonalSet) == 1 { if authPersonal, ok := authPersonalSet[0].(map[string]interface{}); ok { - newHash, hashKey := tfhelper.HelpFlattenSecretNested(d, "auth_personal", authPersonal, "personal_access_token") - authPersonal[hashKey] = newHash return []interface{}{authPersonal} } } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonaqube.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonaqube.go index b2aef0208..537f18796 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonaqube.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonaqube.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) // ResourceServiceEndpointSonarQube schema and implementation for SonarQube service endpoint resource @@ -21,16 +20,12 @@ func ResourceServiceEndpointSonarQube() *schema.Resource { } r.Schema["token"] = &schema.Schema{ - Type: schema.TypeString, - Required: true, - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, - ValidateFunc: validation.StringIsNotWhiteSpace, - Description: "Authentication Token generated through SonarQube (go to My Account > Security > Generate Tokens)", + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validation.StringIsNotWhiteSpace, + Description: "Authentication Token generated through SonarQube (go to My Account > Security > Generate Tokens)", } - // Add a spot in the schema to store the token secretly - stSecretHashKey, stSecretHashSchema := tfhelper.GenerateSecreteMemoSchema("token") - r.Schema[stSecretHashKey] = stSecretHashSchema return r } @@ -53,8 +48,5 @@ func expandServiceEndpointSonarQube(d *schema.ResourceData) (*serviceendpoint.Se func flattenServiceEndpointSonarQube(d *schema.ResourceData, serviceEndpoint *serviceendpoint.ServiceEndpoint, projectID *uuid.UUID) { doBaseFlattening(d, serviceEndpoint, projectID) - tfhelper.HelpFlattenSecret(d, "token") - d.Set("url", *serviceEndpoint.Url) - d.Set("token", (*serviceEndpoint.Authorization.Parameters)["username"]) } diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonarqube_test.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonarqube_test.go index b43036ae3..4e921c1c9 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonarqube_test.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_sonarqube_test.go @@ -26,7 +26,7 @@ var sonarQubeTestServiceEndpointProjectID = &sonarQubeRandomServiceEndpointProje var sonarQubeTestServiceEndpoint = serviceendpoint.ServiceEndpoint{ Authorization: &serviceendpoint.EndpointAuthorization{ Parameters: &map[string]string{ - "username": "SQ_TEST_token", + "username": "", }, Scheme: converter.String("UsernamePassword"), }, diff --git a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_ssh.go b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_ssh.go index 20409c108..61ccd8063 100644 --- a/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_ssh.go +++ b/azuredevops/internal/service/serviceendpoint/resource_serviceendpoint_ssh.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/serviceendpoint" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/tfhelper" ) func ResourceServiceEndpointSSH() *schema.Resource { @@ -34,25 +33,18 @@ func ResourceServiceEndpointSSH() *schema.Resource { } r.Schema["password"] = &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, - ValidateFunc: validation.StringIsNotEmpty, + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringIsNotEmpty, } r.Schema["private_key"] = &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Sensitive: true, - DiffSuppressFunc: tfhelper.DiffFuncSuppressSecretChanged, - ValidateFunc: validation.StringIsNotEmpty, + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringIsNotEmpty, } - - privateKeyHashKey, privateKeyHashSchema := tfhelper.GenerateSecreteMemoSchema("private_key") - r.Schema[privateKeyHashKey] = privateKeyHashSchema - pwdHashKey, pwdHashSchema := tfhelper.GenerateSecreteMemoSchema("password") - r.Schema[pwdHashKey] = pwdHashSchema return r } @@ -90,6 +82,4 @@ func flattenServiceEndpointSSH(d *schema.ResourceData, serviceEndpoint *servicee d.Set("port", port) } d.Set("username", (*serviceEndpoint.Authorization.Parameters)["username"]) - tfhelper.HelpFlattenSecret(d, "private_key") - tfhelper.HelpFlattenSecret(d, "password") } diff --git a/azuredevops/internal/utils/secretmemo/secretmemo.go b/azuredevops/internal/utils/secretmemo/secretmemo.go deleted file mode 100644 index def2f5cb6..000000000 --- a/azuredevops/internal/utils/secretmemo/secretmemo.go +++ /dev/null @@ -1,52 +0,0 @@ -package secretmemo - -import ( - "strings" - - "golang.org/x/crypto/bcrypt" -) - -const isUpdating = true -const isNotUpdating = false -const isErr = false - -func isBlank(s string) bool { - return len(strings.TrimSpace(s)) == 0 -} - -func calcMementoForSecret(secret, memento string) (string, error) { - secretAsBytes := []byte(secret) - hash, err := bcrypt.GenerateFromPassword(secretAsBytes, bcrypt.MinCost) - if err != nil { - return "", err - } - return string(hash), nil -} - -func doesMemoMatchSecret(secret, memento string) bool { - if isBlank(memento) { - return false - } - secretAsBytes := []byte(secret) - mementoAsBytes := []byte(memento) - err := bcrypt.CompareHashAndPassword(mementoAsBytes, secretAsBytes) - return err == nil -} - -// IsUpdating is used to determine if the secret getting updated? -func IsUpdating(secret, oldMemo string) (bool, string, error) { - if isBlank(secret) { - return isNotUpdating, oldMemo, nil - } - - if doesMemoMatchSecret(secret, oldMemo) { - return isNotUpdating, oldMemo, nil - } - - newMemo, err := calcMementoForSecret(secret, oldMemo) - if err != nil { - return isErr, "", err - } - - return isUpdating, newMemo, nil -} diff --git a/azuredevops/internal/utils/secretmemo/secretmemo_test.go b/azuredevops/internal/utils/secretmemo/secretmemo_test.go deleted file mode 100644 index 4099e579d..000000000 --- a/azuredevops/internal/utils/secretmemo/secretmemo_test.go +++ /dev/null @@ -1,69 +0,0 @@ -//go:build all || utils || secretmemo -// +build all utils secretmemo - -package secretmemo - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestIsNewHappyPath(t *testing.T) { - result, memo, err := IsUpdating("mysecret", "") - require.True(t, result) - require.NotEmpty(t, memo) - require.Nil(t, err) -} - -func TestIsUpdatingHappyPath(t *testing.T) { - firstResult, firstMemo, err1 := IsUpdating("mysecret", "") - secondResult, secondMemo, err2 := IsUpdating("mychange", firstMemo) - require.True(t, firstResult) - require.True(t, secondResult) - require.NotEqual(t, firstMemo, secondMemo) - require.Nil(t, err1) - require.Nil(t, err2) -} - -func TestIsSameValueAsBeforeHappyPath(t *testing.T) { - firstResult, firstMemo, err1 := IsUpdating("mysecret", "") - secondResult, secondMemo, err2 := IsUpdating("mysecret", firstMemo) - require.True(t, firstResult) - require.False(t, secondResult) - require.EqualValues(t, firstMemo, secondMemo) - require.Nil(t, err1) - require.Nil(t, err2) -} - -func TestIsRottenMemo(t *testing.T) { - result, memo, err := IsUpdating("mysecret", "!@#$") - require.True(t, result) - require.NotEmpty(t, memo) - require.Nil(t, err) -} - -func TestIsMissingSecret(t *testing.T) { - result, memo, err := IsUpdating("", "anything") - require.False(t, result) - require.Equal(t, "anything", memo) - require.Nil(t, err) -} - -func TestIsValidMemo(t *testing.T) { - require.False(t, isValidMemo("foo")) - require.True(t, isValidMemo("$2a$")) - require.True(t, isValidMemo("$2b$")) - require.True(t, isValidMemo("$2y$")) -} - -func isValidMemo(memo string) bool { - validBcryptHashPrefixes := [3]string{"$2a$", "$2b$", "$2y$"} - for _, s := range validBcryptHashPrefixes { - if strings.HasPrefix(memo, s) { - return true - } - } - return false -} diff --git a/azuredevops/internal/utils/tfhelper/tfhelper.go b/azuredevops/internal/utils/tfhelper/tfhelper.go index f28a0ac50..ba7d7ff28 100644 --- a/azuredevops/internal/utils/tfhelper/tfhelper.go +++ b/azuredevops/internal/utils/tfhelper/tfhelper.go @@ -3,7 +3,6 @@ package tfhelper import ( "fmt" "hash/crc32" - "log" "strconv" "strings" @@ -12,7 +11,6 @@ import ( "github.com/microsoft/azure-devops-go-api/azuredevops/v6/core" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/client" "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter" - "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/secretmemo" ) func HashString(s string) int { @@ -27,81 +25,6 @@ func HashString(s string) int { return 0 } -func calcSecretHashKey(secretKey string) string { - return secretKey + "_hash" -} - -// DiffFuncSuppressSecretChanged is used to suppress unneeded `apply` updates to a resource. -// -// It returns `true` when `new` appears to be the same value -// as a previously stored and bcrypt'd value stored in state during a previous `apply`. -// Relies on flatten/expand logic to help store that hash. See FlattenSecret, below.*/ -func DiffFuncSuppressSecretChanged(k, old, new string, d *schema.ResourceData) bool { - memoKey := calcSecretHashKey(k) - memoValue := d.Get(memoKey).(string) - - isUpdating, _, err := secretmemo.IsUpdating(new, memoValue) - isUnchanged := !isUpdating - - if nil != err { - log.Printf("Change forced. Swallowing err while using secret hashing: %s", err) - return false - } - - log.Printf("\nk: %s, old: %s, new: %s, memoKey: %s, memoValue: %s, isUnchanged: %t\n", - k, old, new, memoKey, memoValue, isUnchanged) - return isUnchanged -} - -// HelpFlattenSecretNested is used to store a hashed secret value into `tfstate` -func HelpFlattenSecretNested(d *schema.ResourceData, parentKey string, d2 map[string]interface{}, secretKey string) (string, string) { - hashKey := calcSecretHashKey(secretKey) - if len(d2) == 0 { - return hashKey, "" - } - oldHash := d2[hashKey].(string) - if !d.HasChange(parentKey) { - log.Printf("key %s didn't get updated.", parentKey) - return oldHash, hashKey - } - newSecret := d2[secretKey].(string) - _, newHash, err := secretmemo.IsUpdating(newSecret, oldHash) - if nil != err { - log.Printf("Swallowing err while using secret hashing: %s", err) - } - log.Printf("Secret has changed. It's new hash value is %s.", newHash) - return newHash, hashKey -} - -// HelpFlattenSecret is used to store a hashed secret value into `tfstate` -func HelpFlattenSecret(d *schema.ResourceData, secretKey string) { - if !d.HasChange(secretKey) { - log.Printf("Secret key %s didn't get updated.", secretKey) - return - } - hashKey := calcSecretHashKey(secretKey) - newSecret := d.Get(secretKey).(string) - oldHash := d.Get(hashKey).(string) - _, newHash, err := secretmemo.IsUpdating(newSecret, oldHash) - if nil != err { - log.Printf("Swallowing err while using secret hashing: %s", err) - } - log.Printf("Secret key %s is updated. It's new hash key and value is %s and %s.", secretKey, hashKey, newHash) - d.Set(hashKey, newHash) -} - -// GenerateSecreteMemoSchema is used to create Schema defs to house the hashed secret in `tfstate` -func GenerateSecreteMemoSchema(secretKey string) (string, *schema.Schema) { - out := schema.Schema{ - Type: schema.TypeString, - Computed: true, - Default: nil, - Description: fmt.Sprintf("A bcrypted hash of the attribute '%s'", secretKey), - Sensitive: true, - } - return calcSecretHashKey(secretKey), &out -} - // ParseProjectIDAndResourceID parses from the schema's resource data. func ParseProjectIDAndResourceID(d *schema.ResourceData) (string, int, error) { projectID := d.Get("project_id").(string)