Skip to content

Commit

Permalink
rebase cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
lakshmimsft committed Feb 26, 2024
1 parent 96370be commit 1773b5b
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 87 deletions.
32 changes: 21 additions & 11 deletions pkg/recipes/terraform/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ func (cfg *TerraformConfig) Save(ctx context.Context, workingDir string) error {
// by Radius to generate custom provider configurations. Save() must be called to save
// the generated providers config. requiredProviders contains a list of provider names
// that are required for the module.
func (cfg *TerraformConfig) AddProviders(ctx context.Context, requiredProviders []string, ucpSupportedProviders map[string]providers.Provider, envConfig *recipes.Configuration) error {
providerConfigs, err := getProviderConfigs(ctx, requiredProviders, ucpSupportedProviders, envConfig)
func (cfg *TerraformConfig) AddProviders(ctx context.Context, requiredProviders []string, ucpConfiguredProviders map[string]providers.Provider, envConfig *recipes.Configuration) error {
providerConfigs, err := getProviderConfigs(ctx, requiredProviders, ucpConfiguredProviders, envConfig)
if err != nil {
return err
}
Expand Down Expand Up @@ -165,21 +165,21 @@ func newModuleConfig(moduleSource string, moduleVersion string, params ...Recipe
return moduleConfig
}

// getProviderConfigs generates the Terraform provider configurations for the required providers.
func getProviderConfigs(ctx context.Context, requiredProviders []string, ucpSupportedProviders map[string]providers.Provider, envConfig *recipes.Configuration) (map[string]any, error) {
providerConfigs := make(map[string]any)

// getProviderConfigs generates the Terraform provider configurations. This is built from a combination of environment level recipe configuration for
// providers and the provider configurations registered with UCP. The environment level recipe configuration for providers takes precedence over UCP provider configurations.
func getProviderConfigs(ctx context.Context, requiredProviders []string, ucpConfiguredProviders map[string]providers.Provider, envConfig *recipes.Configuration) (map[string]any, error) {
// Get recipe provider configurations from the environment configuration
providerConfigs = getRecipeProviderConfigs(ctx, envConfig)
providerConfigs := getRecipeProviderConfigs(ctx, envConfig)

// Build provider configurations for required providers excluding the ones already present in providerConfigs
for _, provider := range requiredProviders {
if _, ok := providerConfigs[provider]; ok {
// If provider is in providerConfigs, skip this iteration
// Environment level recipe configuration for providers will take precedence over
// UCP provider configuration (currently these include azurerm, aws, kubernetes providers)
continue
}

builder, ok := ucpSupportedProviders[provider]
builder, ok := ucpConfiguredProviders[provider]
if !ok {
// No-op: For any other provider under required_providers, Radius doesn't generate any custom configuration.
continue
Expand All @@ -198,15 +198,25 @@ func getProviderConfigs(ctx context.Context, requiredProviders []string, ucpSupp
return providerConfigs, nil
}

// getRecipeProviderConfigs returns the Terraform provider configurations for Terraform providers.
// getRecipeProviderConfigs returns the Terraform provider configurations for Terraform providers
// specified under the RecipeConfig/Terraform/Providers section under environment configuration.
func getRecipeProviderConfigs(ctx context.Context, envConfig *recipes.Configuration) map[string]any {
providerConfigs := make(map[string]any)

// If the provider is not configured, or has empty configuration, skip this iteration
if envConfig.RecipeConfig.Terraform.Providers != nil {
for provider, config := range envConfig.RecipeConfig.Terraform.Providers {
if len(config) > 0 {
providerConfigs[provider] = config
configList := make([]any, 0)

for _, configDetails := range config {
//for _, additionalProperty := range configDetails.AdditionalProperties {
// configList = append(configList, additionalProperty)
//}
configList = append(configList, configDetails.AdditionalProperties)
}

providerConfigs[provider] = configList
}
}
}
Expand Down
96 changes: 53 additions & 43 deletions pkg/recipes/terraform/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package config

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -341,17 +342,17 @@ func Test_AddProviders(t *testing.T) {
}

configTests := []struct {
desc string
envConfig recipes.Configuration
requiredProviders []string
expectedUCPSupportedProviders []map[string]any
expectedConfigFile string
Err error
times int
desc string
envConfig recipes.Configuration
requiredProviders []string
expectedUCPConfiguredProviders []map[string]any
expectedConfigFile string
Err error
numFuncCall int
}{
{
desc: "valid all supported providers",
expectedUCPSupportedProviders: []map[string]any{
expectedUCPConfiguredProviders: []map[string]any{
{
"region": "test-region",
},
Expand Down Expand Up @@ -380,13 +381,13 @@ func Test_AddProviders(t *testing.T) {
providers.KubernetesProviderName,
"sql",
},
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-valid.tf.json",
},
/*{
desc: "invalid aws scope",
expectedUCPSupportedProviders: nil,
Err: errors.New("Invalid AWS provider scope"),
{
desc: "invalid aws scope",
expectedUCPConfiguredProviders: nil,
Err: errors.New("Invalid AWS provider scope"),
envConfig: recipes.Configuration{
Providers: datamodel.Providers{
AWS: datamodel.ProvidersAWS{
Expand All @@ -397,24 +398,24 @@ func Test_AddProviders(t *testing.T) {
requiredProviders: []string{
providers.AWSProviderName,
},
times: 1,
numFuncCall: 1,
},
{
desc: "empty aws provider config",
expectedUCPSupportedProviders: []map[string]any{
expectedUCPConfiguredProviders: []map[string]any{
{},
},
Err: nil,
envConfig: recipes.Configuration{},
requiredProviders: []string{
providers.AWSProviderName,
},
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-empty.tf.json",
},
{
desc: "empty aws scope",
expectedUCPSupportedProviders: []map[string]any{
expectedUCPConfiguredProviders: []map[string]any{
nil,
},
Err: nil,
Expand All @@ -431,12 +432,12 @@ func Test_AddProviders(t *testing.T) {
requiredProviders: []string{
providers.AWSProviderName,
},
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-empty.tf.json",
},
{
desc: "empty azure provider config",
expectedUCPSupportedProviders: []map[string]any{
expectedUCPConfiguredProviders: []map[string]any{
{
"features": map[string]any{},
},
Expand All @@ -446,13 +447,13 @@ func Test_AddProviders(t *testing.T) {
requiredProviders: []string{
providers.AzureProviderName,
},
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-emptyazureconfig.tf.json",
},
{
desc: "valid recipe providers",
expectedUCPSupportedProviders: nil,
Err: nil,
desc: "valid recipe providers in env config",
expectedUCPConfiguredProviders: nil,
Err: nil,
envConfig: recipes.Configuration{
RecipeConfig: datamodel.RecipeConfigProperties{
Terraform: datamodel.TerraformConfigProperties{
Expand All @@ -477,12 +478,12 @@ func Test_AddProviders(t *testing.T) {
},
},
requiredProviders: nil,
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-envrecipeproviders.tf.json",
},
{
desc: "overridding required provider configs",
expectedUCPSupportedProviders: []map[string]any{
desc: "recipe provider config overridding required provider configs",
expectedUCPConfiguredProviders: []map[string]any{
{
"region": "test-region",
},
Expand Down Expand Up @@ -515,52 +516,61 @@ func Test_AddProviders(t *testing.T) {
providers.AWSProviderName,
providers.KubernetesProviderName,
},
times: -1,
numFuncCall: -1,
expectedConfigFile: "testdata/providers-overridereqproviders.tf.json",
},
{
desc: "recipe providers not populated",
expectedUCPSupportedProviders: nil,
Err: nil,
desc: "recipe providers not populated",
expectedUCPConfiguredProviders: nil,
Err: nil,
envConfig: recipes.Configuration{
RecipeConfig: datamodel.RecipeConfigProperties{
Terraform: datamodel.TerraformConfigProperties{},
},
},
requiredProviders: nil,
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-empty.tf.json",
},
{
desc: "recipe providers not populated",
expectedUCPSupportedProviders: nil,
Err: nil,
desc: "recipe providers and tfconfigproperties not populated",
expectedUCPConfiguredProviders: nil,
Err: nil,
envConfig: recipes.Configuration{
RecipeConfig: datamodel.RecipeConfigProperties{},
},
requiredProviders: nil,
times: 1,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-empty.tf.json",
},*/
},
{
desc: "envConfig not populated",
expectedUCPConfiguredProviders: nil,
Err: nil,
envConfig: recipes.Configuration{},
requiredProviders: nil,
numFuncCall: 1,
expectedConfigFile: "testdata/providers-empty.tf.json",
},
}

for _, tc := range configTests {
t.Run(tc.desc, func(t *testing.T) {
ctx := testcontext.New(t)
workingDir := t.TempDir()

tfconfig, err := New(ctx, testRecipeName, &envRecipe, nil, &tc.envConfig)
tfconfig, err := New(ctx, testRecipeName, &envRecipe, &resourceRecipe, &tc.envConfig)
require.NoError(t, err)
for _, p := range tc.expectedUCPSupportedProviders {
if tc.times > 0 {
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Times(tc.times).Return(p, nil)
for _, p := range tc.expectedUCPConfiguredProviders {
if tc.numFuncCall > 0 {
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Times(tc.numFuncCall).Return(p, nil)
} else {
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Return(p, tc.Err).AnyTimes()
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Return(p, nil).AnyTimes()
}
}
if tc.Err != nil {
if tc.times > 0 {
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Times(1).Return(nil, tc.Err)
if tc.numFuncCall > 0 {
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Times(tc.numFuncCall).Return(nil, tc.Err)
} else {
mProvider.EXPECT().BuildConfig(ctx, &tc.envConfig).Return(nil, tc.Err).AnyTimes()
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/recipes/terraform/config/providers/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ type Provider interface {
BuildConfig(ctx context.Context, envConfig *recipes.Configuration) (map[string]any, error)
}

// GetUCPSupportedTerraformProviders returns a map of Terraform provider names with configuration details stored in UCP, to provider config builder.
// These providers represent Terraform providers for which Radius generates custom provider configurations based on credentials stored with UCP.
// For example, the Azure subscription id is added to Azure provider config using Radius Environment's Azure provider scope.
func GetUCPSupportedTerraformProviders(ucpConn sdk.Connection, secretProvider *ucp_provider.SecretProvider) map[string]Provider {
// GetUCPConfiguredTerraformProviders returns a map of Terraform provider names with configuration details stored in UCP, to provider config builder.
// These providers represent Terraform providers for which Radius generates custom provider configurations based on credentials stored with UCP
// and providers configured on the Radius environment. For example, the Azure subscription id is added to Azure provider config using Radius Environment's Azure provider scope.
func GetUCPConfiguredTerraformProviders(ucpConn sdk.Connection, secretProvider *ucp_provider.SecretProvider) map[string]Provider {
return map[string]Provider{
AWSProviderName: NewAWSProvider(ucpConn, secretProvider),
AzureProviderName: NewAzureProvider(ucpConn, secretProvider),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
}
},
"provider": {
"azurerm": [
{
"features": {}
}
]
"azurerm": {
"features": {}
}
},
"module": {
"redis-azure": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@
}
},
"provider": {
"aws": [
{
"region": "test-region"
}
],
"aws": {
"region": "test-region"
},
"kubernetes": [
{
"config_path": "/home/radius/.kube/configPath1"
"ConfigPath": "/home/radius/.kube/configPath1"
},
{
"config_path": "/home/radius/.kube/configPath2"
"ConfigPath": "/home/radius/.kube/configPath2"
}
]
},
Expand Down
26 changes: 10 additions & 16 deletions pkg/recipes/terraform/config/testdata/providers-valid.tf.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,16 @@
}
},
"provider": {
"aws": [
{
"region": "test-region"
}
],
"azurerm": [
{
"features": {},
"subscription_id": "test-sub"
}
],
"kubernetes": [
{
"config_path": "/home/radius/.kube/config"
}
]
"aws": {
"region": "test-region"
},
"azurerm": {
"features": {},
"subscription_id": "test-sub"
},
"kubernetes": {
"config_path": "/home/radius/.kube/config"
}
},
"module": {
"redis-azure": {
Expand Down
2 changes: 1 addition & 1 deletion pkg/recipes/terraform/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (e *executor) generateConfig(ctx context.Context, tf *tfexec.Terraform, opt

// Generate Terraform providers configuration for required providers and add it to the Terraform configuration.
logger.Info(fmt.Sprintf("Adding provider config for required providers %+v", loadedModule.RequiredProviders))
if err := tfConfig.AddProviders(ctx, loadedModule.RequiredProviders, providers.GetUCPSupportedTerraformProviders(e.ucpConn, e.secretProvider),
if err := tfConfig.AddProviders(ctx, loadedModule.RequiredProviders, providers.GetUCPConfiguredTerraformProviders(e.ucpConn, e.secretProvider),
options.EnvConfig); err != nil {
return "", err
}
Expand Down

0 comments on commit 1773b5b

Please sign in to comment.