From 7232cc61549e8034e5097390d118691987266ed8 Mon Sep 17 00:00:00 2001 From: Lakshmi Javadekar <103459615+lakshmimsft@users.noreply.github.com> Date: Fri, 30 Aug 2024 16:07:58 -0700 Subject: [PATCH] Updates to adding secret types PR (#7867) # Description Updates per comments in https://github.com/radius-project/radius/pull/7816 ## Type of change - This pull request adds or changes features of Radius and has an approved issue (#6917 ). Fixes: Part of #6917 --- .../secretstore_conversion_test.go | 46 +++++++++++++++++++ .../zz_generated_constants.go | 4 +- .../v20231001preview/zz_generated_models.go | 3 +- .../controller/secretstores/kubernetes.go | 14 +++--- .../frontend/controller/secretstores/types.go | 20 +++++--- .../preview/2023-10-01-preview/openapi.json | 4 +- typespec/Applications.Core/environments.tsp | 2 +- typespec/Applications.Core/secretstores.tsp | 2 +- 8 files changed, 75 insertions(+), 20 deletions(-) diff --git a/pkg/corerp/api/v20231001preview/secretstore_conversion_test.go b/pkg/corerp/api/v20231001preview/secretstore_conversion_test.go index e1024ac086..60357c5948 100644 --- a/pkg/corerp/api/v20231001preview/secretstore_conversion_test.go +++ b/pkg/corerp/api/v20231001preview/secretstore_conversion_test.go @@ -159,3 +159,49 @@ func TestSecretStoreConvertFromValidation(t *testing.T) { require.ErrorAs(t, tc.err, &err) } } + +func TestSecretStorefromSecretStoreDataTypeDataModel(t *testing.T) { + tests := []struct { + name string + input datamodel.SecretType + expected *SecretStoreDataType + }{ + { + name: "Generic Secret Type", + input: datamodel.SecretTypeGeneric, + expected: to.Ptr(SecretStoreDataTypeGeneric), + }, + { + name: "Certificate Secret Type", + input: datamodel.SecretTypeCert, + expected: to.Ptr(SecretStoreDataTypeCertificate), + }, + { + name: "Basic Authentication Secret Type", + input: datamodel.SecretTypeBasicAuthentication, + expected: to.Ptr(SecretStoreDataTypeBasicAuthentication), + }, + { + name: "Azure Workload Identity Secret Type", + input: datamodel.SecretTypeAzureWorkloadIdentity, + expected: to.Ptr(SecretStoreDataTypeAzureWorkloadIdentity), + }, + { + name: "AWS IRSA Secret Type", + input: datamodel.SecretTypeAWSIRSA, + expected: to.Ptr(SecretStoreDataTypeAwsIRSA), + }, + { + name: "None Secret Type", + input: datamodel.SecretTypeNone, + expected: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := fromSecretStoreDataTypeDataModel(tt.input) + require.Equal(t, tt.expected, result) + }) + } +} diff --git a/pkg/corerp/api/v20231001preview/zz_generated_constants.go b/pkg/corerp/api/v20231001preview/zz_generated_constants.go index 5513e441df..8e38920b85 100644 --- a/pkg/corerp/api/v20231001preview/zz_generated_constants.go +++ b/pkg/corerp/api/v20231001preview/zz_generated_constants.go @@ -329,8 +329,8 @@ func PossibleRestartPolicyValues() []RestartPolicy { type SecretStoreDataType string const ( - // SecretStoreDataTypeAwsIRSA - awsIRSA type is used to represent registry authentication using AWS IRSA(IAM Roles for Service -// accounts) and the secretstore resource is expected to have the keys 'roleARN'. + // SecretStoreDataTypeAwsIRSA - awsIRSA type is used to represent registry authentication using AWS IRSA (IAM Roles for Service +// accounts) and the secretstore resource is expected to have the key 'roleARN'. SecretStoreDataTypeAwsIRSA SecretStoreDataType = "awsIRSA" // SecretStoreDataTypeAzureWorkloadIdentity - azureWorkloadIdentity type is used to represent registry authentication using // azure federated identity and the secretstore resource is expected to have the keys 'clientId' and 'tenantId'. diff --git a/pkg/corerp/api/v20231001preview/zz_generated_models.go b/pkg/corerp/api/v20231001preview/zz_generated_models.go index b96432971e..2c4257e39e 100644 --- a/pkg/corerp/api/v20231001preview/zz_generated_models.go +++ b/pkg/corerp/api/v20231001preview/zz_generated_models.go @@ -1312,7 +1312,8 @@ type Recipe struct { // RecipeConfigProperties - Configuration for Recipes. Defines how each type of Recipe should be configured and run. type RecipeConfigProperties struct { - // Environment variables injected during recipe execution for the recipes in the environment. + // Environment variables injected during recipe execution for the recipes in the environment, currently supported for Terraform +// recipes. Env map[string]*string // Environment variables containing sensitive information can be stored as secrets. The secrets are stored in Applications.Core/SecretStores diff --git a/pkg/corerp/frontend/controller/secretstores/kubernetes.go b/pkg/corerp/frontend/controller/secretstores/kubernetes.go index fff7c01bbe..62296b5ec6 100644 --- a/pkg/corerp/frontend/controller/secretstores/kubernetes.go +++ b/pkg/corerp/frontend/controller/secretstores/kubernetes.go @@ -78,17 +78,17 @@ func getOrDefaultEncoding(t datamodel.SecretType, e datamodel.SecretValueEncodin return e, err } -// Define a map of required keys for each SecretType -var requiredKeys = map[datamodel.SecretType][]string{ - datamodel.SecretTypeBasicAuthentication: {RequiredUsername, RequiredPassword}, - datamodel.SecretTypeAzureWorkloadIdentity: {RequiredClientId, RequiredTenantId}, - datamodel.SecretTypeAWSIRSA: {RequiredRoleARN}, -} - // ValidateAndMutateRequest checks the type and encoding of the secret store, and ensures that the secret store data is // valid and required keys are present for the secret type. If any of these checks fail, a BadRequestResponse is returned. func ValidateAndMutateRequest(ctx context.Context, newResource *datamodel.SecretStore, oldResource *datamodel.SecretStore, options *controller.Options) (rest.Response, error) { + // Define a map of required keys for each SecretType + var requiredKeys = map[datamodel.SecretType][]string{ + datamodel.SecretTypeBasicAuthentication: {UsernameKey, PasswordKey}, + datamodel.SecretTypeAzureWorkloadIdentity: {ClientIdKey, TenantIdKey}, + datamodel.SecretTypeAWSIRSA: {RoleARNKey}, + } var err error + newResource.Properties.Type, err = getOrDefaultType(newResource.Properties.Type) if err != nil { return rest.NewBadRequestResponse(err.Error()), nil diff --git a/pkg/corerp/frontend/controller/secretstores/types.go b/pkg/corerp/frontend/controller/secretstores/types.go index a4375f8420..34e61ffad8 100644 --- a/pkg/corerp/frontend/controller/secretstores/types.go +++ b/pkg/corerp/frontend/controller/secretstores/types.go @@ -20,10 +20,18 @@ const ( // ResourceTypeName is the resource type name for secret stores. ResourceTypeName = "Applications.Core/secretStores" - // The following are possible required keys in a SecretStore depending on it's SecretType - RequiredUsername = "username" - RequiredPassword = "password" - RequiredClientId = "clientId" - RequiredTenantId = "tenantId" - RequiredRoleARN = "roleARN" + // UsernameKey is a required key in a secret store when SecretType is Basic Authentication. + UsernameKey = "username" + + // PasswordKey is a required key in a secret store when SecretType is Basic Authentication. + PasswordKey = "password" + + // ClientIdKey is a required key in a secret store when SecretType is Azure Workload Identity. + ClientIdKey = "clientId" + + // TenantIdKey is a required key in a secret store when SecretType is Azure workload Identity. + TenantIdKey = "tenantId" + + // RoleARNKey is a required key in a secret store when SecretType is AWS IRSA. + RoleARNKey = "roleARN" ) diff --git a/swagger/specification/applications/resource-manager/Applications.Core/preview/2023-10-01-preview/openapi.json b/swagger/specification/applications/resource-manager/Applications.Core/preview/2023-10-01-preview/openapi.json index dfbe7a8301..67e43e73b0 100644 --- a/swagger/specification/applications/resource-manager/Applications.Core/preview/2023-10-01-preview/openapi.json +++ b/swagger/specification/applications/resource-manager/Applications.Core/preview/2023-10-01-preview/openapi.json @@ -4356,7 +4356,7 @@ }, "env": { "$ref": "#/definitions/EnvironmentVariables", - "description": "Environment variables injected during recipe execution for the recipes in the environment." + "description": "Environment variables injected during recipe execution for the recipes in the environment, currently supported for Terraform recipes." }, "envSecrets": { "type": "object", @@ -4692,7 +4692,7 @@ { "name": "awsIRSA", "value": "awsIRSA", - "description": "awsIRSA type is used to represent registry authentication using AWS IRSA(IAM Roles for Service accounts) and the secretstore resource is expected to have the keys 'roleARN'." + "description": "awsIRSA type is used to represent registry authentication using AWS IRSA (IAM Roles for Service accounts) and the secretstore resource is expected to have the key 'roleARN'." } ] } diff --git a/typespec/Applications.Core/environments.tsp b/typespec/Applications.Core/environments.tsp index aac6eb9a91..476042b5da 100644 --- a/typespec/Applications.Core/environments.tsp +++ b/typespec/Applications.Core/environments.tsp @@ -79,7 +79,7 @@ model RecipeConfigProperties { @doc("Configuration for Terraform Recipes. Controls how Terraform plans and applies templates as part of Recipe deployment.") terraform?: TerraformConfigProperties; - @doc("Environment variables injected during recipe execution for the recipes in the environment.") + @doc("Environment variables injected during recipe execution for the recipes in the environment, currently supported for Terraform recipes.") env?: EnvironmentVariables; @doc("Environment variables containing sensitive information can be stored as secrets. The secrets are stored in Applications.Core/SecretStores resource.") diff --git a/typespec/Applications.Core/secretstores.tsp b/typespec/Applications.Core/secretstores.tsp index f1e4e173dc..d3837bc9ce 100644 --- a/typespec/Applications.Core/secretstores.tsp +++ b/typespec/Applications.Core/secretstores.tsp @@ -75,7 +75,7 @@ enum SecretStoreDataType { @doc("azureWorkloadIdentity type is used to represent registry authentication using azure federated identity and the secretstore resource is expected to have the keys 'clientId' and 'tenantId'.") azureWorkloadIdentity, - @doc("awsIRSA type is used to represent registry authentication using AWS IRSA(IAM Roles for Service accounts) and the secretstore resource is expected to have the keys 'roleARN'.") + @doc("awsIRSA type is used to represent registry authentication using AWS IRSA (IAM Roles for Service accounts) and the secretstore resource is expected to have the key 'roleARN'.") awsIRSA, }