Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating an optional interface to get secret id references for driver with secrets. #7306

51 changes: 51 additions & 0 deletions pkg/recipes/configloader/mock_secret_loader.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions pkg/recipes/configloader/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@ import (
"github.com/radius-project/radius/pkg/ucp/resources"
)

var _ SecretsLoader = (*secretsLoader)(nil)

// NewSecretStoreLoader creates a new SecretsLoader instance with the given ARM Client Options.
func NewSecretStoreLoader(armOptions *arm.ClientOptions) SecretsLoader {
return SecretsLoader{ArmClientOptions: armOptions}
return &secretsLoader{ArmClientOptions: armOptions}
}

// SecretsLoader struct provides functionality to get secret information from Application.Core/SecretStore resource.
type SecretsLoader struct {
type secretsLoader struct {
ArmClientOptions *arm.ClientOptions
}

func (e *SecretsLoader) LoadSecrets(ctx context.Context, secretStore string) (v20231001preview.SecretStoresClientListSecretsResponse, error) {
func (e *secretsLoader) LoadSecrets(ctx context.Context, secretStore string) (v20231001preview.SecretStoresClientListSecretsResponse, error) {
secretStoreID, err := resources.ParseResource(secretStore)
if err != nil {
return v20231001preview.SecretStoresClientListSecretsResponse{}, err
Expand Down
6 changes: 6 additions & 0 deletions pkg/recipes/configloader/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package configloader
import (
"context"

"github.com/radius-project/radius/pkg/corerp/api/v20231001preview"
"github.com/radius-project/radius/pkg/recipes"
)

Expand All @@ -28,3 +29,8 @@ type ConfigurationLoader interface {
// LoadRecipe fetches the recipe information from the environment.
LoadRecipe(ctx context.Context, recipe *recipes.ResourceMetadata) (*recipes.EnvironmentDefinition, error)
}

//go:generate mockgen -destination=./mock_secret_loader.go -package=configloader -self_package github.com/radius-project/radius/pkg/recipes/configloader github.com/radius-project/radius/pkg/recipes/configloader SecretsLoader
type SecretsLoader interface {
LoadSecrets(ctx context.Context, secretStore string) (v20231001preview.SecretStoresClientListSecretsResponse, error)
}
1 change: 0 additions & 1 deletion pkg/recipes/driver/bicep.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import (
"github.com/radius-project/radius/pkg/ucp/ucplog"
)

//go:generate mockgen -destination=./mock_driver.go -package=driver -self_package github.com/radius-project/radius/pkg/recipes/driver github.com/radius-project/radius/pkg/recipes/driver Driver
const (
deploymentPrefix = "recipe"
pollFrequency = time.Second * 5
Expand Down
95 changes: 95 additions & 0 deletions pkg/recipes/driver/mock_driver_with_secrets.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions pkg/recipes/driver/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,17 @@ func (d *terraformDriver) GetRecipeMetadata(ctx context.Context, opts BaseOption
return recipeData, nil
}

// FindSecretIDs is used to retrieve the secret reference associated with private terraform module source.
// As of today, it only supports retrieving secret references associated with private git repositories.
func (d *terraformDriver) FindSecretIDs(ctx context.Context, envConfig recipes.Configuration, definition recipes.EnvironmentDefinition) (string, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Please add comment.


// We can move the GetSecretStoreID() implementation here when we have containerization.
// Today we use this function in config.go to check for secretstore to add prefix to the template path.
// GetSecretStoreID is added outside of driver package because it created cyclic dependency between driver and config packages.

return recipes.GetSecretStoreID(envConfig, definition.TemplatePath)
}

// getDeployedOutputResources is used to the get the resource IDs by parsing the terraform state for resource information and using it to create UCP qualified IDs.
// Currently only Azure, AWS and Kubernetes providers are supported by output resources.
func (d *terraformDriver) getDeployedOutputResources(ctx context.Context, module *tfjson.StateModule) ([]string, error) {
Expand Down
14 changes: 14 additions & 0 deletions pkg/recipes/driver/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const (
)

// Driver is an interface to implement recipe deployment and recipe resources deletion.
//
//go:generate mockgen -destination=./mock_driver.go -package=driver -self_package github.com/radius-project/radius/pkg/recipes/driver github.com/radius-project/radius/pkg/recipes/driver Driver
type Driver interface {
// Execute fetches the recipe contents and deploys the recipe and returns deployed resources, secrets and values.
Execute(ctx context.Context, opts ExecuteOptions) (*recipes.RecipeOutput, error)
Expand All @@ -42,6 +44,18 @@ type Driver interface {
GetRecipeMetadata(ctx context.Context, opts BaseOptions) (map[string]any, error)
}

// DriverWithSecrets is an optional interface and used when the driver needs to load secrets for recipe deployment.
//
//go:generate mockgen -destination=./mock_driver_with_secrets.go -package=driver -self_package github.com/radius-project/radius/pkg/recipes/driver github.com/radius-project/radius/pkg/recipes/driver DriverWithSecrets
type DriverWithSecrets interface {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Please add comment

// Driver is an interface to implement recipe deployment and recipe resources deletion.
Driver

// FindSecretIDs gets the secret ID references associated with git private terraform repository source.
// In the future it will be extended to get secret references for provider secrets.
FindSecretIDs(ctx context.Context, config recipes.Configuration, definition recipes.EnvironmentDefinition) (string, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return ([]string, error)?

What would happen in the future if a driver needed to read multiple secrets?

Copy link
Contributor Author

@vishwahiremat vishwahiremat Mar 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently we are keeping it to return module secret. But in the future when we have provider secrets etc, return type will be map because we may need to specify secret kind then ex: module secret or provider secret. It will be discussed in detail during the design for provider secrets.

}

// BaseOptions is the base options for the driver operations.
type BaseOptions struct {
// Configuration is the configuration for the recipe.
Expand Down
23 changes: 12 additions & 11 deletions pkg/recipes/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,20 @@ func (e *engine) executeCore(ctx context.Context, recipe recipes.ResourceMetadat
return nil, nil, err
}

// Retrieves the secret store id from the recipes configuration for the terraform module source of type git.
// secretStoreID returned will be an empty string for other types.
secretStore, err := recipes.GetSecretStoreID(*configuration, definition.TemplatePath)
if err != nil {
return nil, nil, err
}

// Retrieves the secret values from the secret store ID provided.
secrets := v20231001preview.SecretStoresClientListSecretsResponse{}
if secretStore != "" {
secrets, err = e.options.SecretsLoader.LoadSecrets(ctx, secretStore)
driverWithSecrets, ok := driver.(recipedriver.DriverWithSecrets)
if ok {
secretStore, err := driverWithSecrets.FindSecretIDs(ctx, *configuration, *definition)
if err != nil {
return nil, nil, fmt.Errorf("failed to fetch secrets from the secret store resource id %s for Terraform recipe %s deployment: %w", secretStore, definition.TemplatePath, err)
return nil, nil, err
}

// Retrieves the secret values from the secret store ID provided.
if secretStore != "" {
secrets, err = e.options.SecretsLoader.LoadSecrets(ctx, secretStore)
if err != nil {
return nil, nil, recipes.NewRecipeError(recipes.LoadSecretsFailed, fmt.Sprintf("failed to fetch secrets from the secret store resource id %s for Terraform recipe %s deployment: %s", secretStore, definition.TemplatePath, err.Error()), util.RecipeSetupError, recipes.GetErrorDetails(err))
}
}
}

Expand Down
Loading
Loading