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

Adding Bicep private registry support using basic auth, Azure workload identity and AWS IRSA #7850

Conversation

vishwahiremat
Copy link
Contributor

@vishwahiremat vishwahiremat commented Aug 27, 2024

Description

  • Adding Bicep Recipe Config changes in typespec, conversions and unit tests.
  • Implementing Bicep FindSecretIDs
  • Adding basic auth support to authenticate private registries and unit tests.
  • Adding workload identity support for ACR registries
  • Adding AWS IRSA support for ECR registries.
  • Updating Recipe Metadata and Recipe Execute functions in the driver to get the oras auth client

Type of change

  • This pull request fixes a bug in Radius and has an approved issue (issue link required).
  • This pull request adds or changes features of Radius and has an approved issue (issue link required).
  • This pull request is a minor refactor, code cleanup, test improvement, or other maintenance task and doesn't change the functionality of Radius (issue link optional).

#6917

Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Copy link

codecov bot commented Aug 27, 2024

Codecov Report

Attention: Patch coverage is 27.54491% with 121 lines in your changes missing coverage. Please review.

Project coverage is 60.99%. Comparing base (cce1fe6) to head (6ee1404).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/rp/util/authclient/awsirsa.go 9.80% 46 Missing ⚠️
pkg/rp/util/authclient/azureworkloadidentity.go 6.45% 29 Missing ⚠️
pkg/recipes/driver/bicep.go 9.67% 26 Missing and 2 partials ⚠️
pkg/rp/util/authclient/basicauthentication.go 15.38% 11 Missing ⚠️
pkg/rp/util/authclient/types.go 62.50% 5 Missing and 1 partial ⚠️
pkg/ucp/aws/ucpcredentialprovider.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7850      +/-   ##
==========================================
- Coverage   61.18%   60.99%   -0.19%     
==========================================
  Files         523      527       +4     
  Lines       27683    27844     +161     
==========================================
+ Hits        16938    16984      +46     
- Misses       9252     9366     +114     
- Partials     1493     1494       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
@vishwahiremat vishwahiremat marked this pull request as ready for review September 3, 2024 20:55
@vishwahiremat vishwahiremat requested review from a team as code owners September 3, 2024 20:55
Signed-off-by: Vishwanath Hiremath <[email protected]>
@@ -21,6 +21,9 @@ type RecipeConfigProperties struct {
// Configuration for Terraform Recipes. Controls how Terraform plans and applies templates as part of Recipe deployment.
Terraform TerraformConfigProperties `json:"terraform,omitempty"`

//Configuration for Bicep Recipes. Controls how Bicep plans and applies templates as part of Recipe deployment.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
//Configuration for Bicep Recipes. Controls how Bicep plans and applies templates as part of Recipe deployment.
// Configuration for Bicep Recipes. Controls how Bicep plans and applies templates as part of Recipe deployment.

// RegistrySecretConfig - Registry Secret Configuration used to authenticate to private bicep registries.
type RegistrySecretConfig struct {
// The ID of an Applications.Core/SecretStore resource containing credential information used to authenticate private container
// registry.The keys in the secretstore depends on the type.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// registry.The keys in the secretstore depends on the type.
// registry. The keys in the secretstore depends on the type.


func (d *bicepDriver) FindSecretIDs(ctx context.Context, envConfig recipes.Configuration, definition recipes.EnvironmentDefinition) (secretStoreIDResourceKeys map[string][]string, err error) {
secretStoreIDResourceKeys = make(map[string][]string)
if envConfig.RecipeConfig.Bicep.Authentication != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

might want to consider nil-checking this in case Authentication, Bicep, or RecipeConfig are nil

@@ -403,3 +434,28 @@ func (d *bicepDriver) getGCOutputResources(current []string, previous []string)

return diff, nil
}

func (d *bicepDriver) FindSecretIDs(ctx context.Context, envConfig recipes.Configuration, definition recipes.EnvironmentDefinition) (secretStoreIDResourceKeys map[string][]string, err error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

does this function get called?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, it is called from recipe Engine, we dont have to make any changes in Engine as we are just implementing a DriverWithSecret interface here , it automatically does the part of calling this function

}

func (b *awsIRSA) GetAuthClient(ctx context.Context, templatePath string) (remote.Client, error) {
// To Do
Copy link
Contributor

Choose a reason for hiding this comment

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

let's put an issue number here to track the work


func (b *azureWorkloadIdentity) GetAuthClient(ctx context.Context, templatePath string) (remote.Client, error) {
c := azcontainerregistry.AuthenticationClientOptions{
azcore.ClientOptions{
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a reason we need to change the defaults? what's the max retry default?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, keeping the defaults for client options

return nil, err
}

rt, err := ac.ExchangeAADAccessTokenForACRRefreshToken(ctx, "access_token", registryHost, &azcontainerregistry.AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions{
Copy link
Contributor

Choose a reason for hiding this comment

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

did you reference this from a docs page somewhere? if so, maybe we should link it here so that future work here will take less ramp-up time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

azure container registry team have not released it yet, its part of their main repo. I will add the referent once the next release of azcontainerregistry is out

tenantID string
}

func NewAzureWorkloadIdentity(clientID string, tenantID string) AuthClient {
Copy link
Contributor

Choose a reason for hiding this comment

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

is this difficult to add a functional test for or does it seem feasible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah it is not straight forward, i am creating a different github issue for that.

Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
@vishwahiremat vishwahiremat changed the title Adding Bicep Recipe Config changes and support for authenticating private bicep registries using basic auth Adding Bicep private registry support using basic auth, Azure workload identity and AWS IRSA Sep 6, 2024
Signed-off-by: Vishwanath Hiremath <[email protected]>
@@ -238,6 +250,17 @@ func fromRecipeConfigDatamodel(config datamodel.RecipeConfigProperties) *RecipeC

recipeConfig.Terraform.Providers = fromRecipeConfigTerraformProvidersDatamodel(config)
}
if !reflect.DeepEqual(config.Bicep, datamodel.BicepConfigProperties{}) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: new line before this

Comment on lines +213 to +218
for k, v := range config.Bicep.Authentication {
authConfig[k] = datamodel.RegistrySecretConfig{
Secret: to.String(v.Secret),
}
}
recipeConfig.Bicep.Authentication = authConfig
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason why we are not doing it this way like you did below?

Suggested change
for k, v := range config.Bicep.Authentication {
authConfig[k] = datamodel.RegistrySecretConfig{
Secret: to.String(v.Secret),
}
}
recipeConfig.Bicep.Authentication = authConfig
for k, v := range config.Bicep.Authentication {
recipeConfig.Bicep.Authentication[k] = datamodel.RegistrySecretConfig{
Secret: to.String(v.Secret),
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because recipeConfig.Bicep.Authentication value would be nil and it will throw nil pointer.

Copy link
Contributor

Choose a reason for hiding this comment

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

We can do recipeConfig.Bicep.Authentication := map[string]datamodel.RegistrySecretConfig{} before the loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can do that, but we will be using the recipeConfig.Bicep.Authentication multiple times , i thought its better to use authConfig variable.

pkg/corerp/datamodel/recipe_types.go Outdated Show resolved Hide resolved
pkg/rp/util/authClient/azureWorkloadIdentity.go Outdated Show resolved Hide resolved
pkg/rp/util/authClient/basicAuthentication.go Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

folder and file names shouldn't have capital letters

pkg/rp/util/registry.go Show resolved Hide resolved
pkg/ucp/aws/ucpcredentialprovider.go Show resolved Hide resolved
Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Signed-off-by: Vishwanath Hiremath <[email protected]>
Comment on lines +213 to +218
for k, v := range config.Bicep.Authentication {
authConfig[k] = datamodel.RegistrySecretConfig{
Secret: to.String(v.Secret),
}
}
recipeConfig.Bicep.Authentication = authConfig
Copy link
Contributor

Choose a reason for hiding this comment

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

We can do recipeConfig.Bicep.Authentication := map[string]datamodel.RegistrySecretConfig{} before the loop.

@@ -21,6 +21,9 @@ type RecipeConfigProperties struct {
// Configuration for Terraform Recipes. Controls how Terraform plans and applies templates as part of Recipe deployment.
Terraform TerraformConfigProperties `json:"terraform,omitempty"`

// BicepConfigProperties represent configuration for Bicep Recipes. Controls how Bicep plans and applies templates as part of Recipe deployment.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// BicepConfigProperties represent configuration for Bicep Recipes. Controls how Bicep plans and applies templates as part of Recipe deployment.
// BicepConfigProperties represents configuration for Bicep Recipes. Controls how Bicep plans and applies templates as part of Recipe deployment.

Copy link
Contributor

Choose a reason for hiding this comment

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

name should be changed

@radius-functional-tests
Copy link

radius-functional-tests bot commented Sep 6, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository vishwahiremat/radius
Commit ref 70ee597
Unique ID funcb60c74cc3f
Image tag pr-funcb60c74cc3f
Click here to see the list of tools in the current test run
  • gotestsum 1.12.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.3.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-funcb60c74cc3f
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-funcb60c74cc3f
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-funcb60c74cc3f
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-funcb60c74cc3f
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting ucp-cloud functional tests...
⌛ Starting datastoresrp-cloud functional tests...
⌛ Starting corerp-cloud functional tests...
✅ ucp-cloud functional tests succeeded
✅ datastoresrp-cloud functional tests succeeded
✅ corerp-cloud functional tests succeeded

ytimocin
ytimocin previously approved these changes Sep 6, 2024
return &awsIRSA{roleARN: roleARN}
}

func (b *awsIRSA) GetAuthClient(ctx context.Context, templatePath string) (remote.Client, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Pls add comment for IRSA implementation. it was added for Azure WI, BasicAuth

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated it

exp: recipes.SecretData{},
},
}
for _, tc := range testset {
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to add test verify returning error when say templatePath passed is not a valid path

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added a test

@@ -133,3 +135,12 @@ func parsePath(path string) (repository string, tag string, err error) {
tag = reference.Tag()
return
}

func GetRegistrySecrets(definition recipes.Configuration, templatePath string, secrets map[string]recipes.SecretData) (recipes.SecretData, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Pls add comment for public function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated it

@@ -72,10 +72,10 @@ enum SecretStoreDataType {
@doc("basicAuthentication type is used to represent username and password based authentication and the secretstore resource is expected to have the keys 'username' and 'password'.")
basicAuthentication,

@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'.")
@doc("azureWorkloadIdentity type is used to represent authentication using azure federated identity and the secretstore resource is expected to have the keys 'clientId' and 'tenantId'.")
Copy link
Contributor

@lakshmimsft lakshmimsft Sep 9, 2024

Choose a reason for hiding this comment

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

👍 thank u!

Signed-off-by: Vishwanath Hiremath <[email protected]>
@radius-functional-tests
Copy link

radius-functional-tests bot commented Sep 9, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository vishwahiremat/radius
Commit ref 6ee1404
Unique ID func20ed078b04
Image tag pr-func20ed078b04
Click here to see the list of tools in the current test run
  • gotestsum 1.12.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.3.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func20ed078b04
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func20ed078b04
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func20ed078b04
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func20ed078b04
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting datastoresrp-cloud functional tests...
⌛ Starting corerp-cloud functional tests...
⌛ Starting ucp-cloud functional tests...
✅ datastoresrp-cloud functional tests succeeded
✅ corerp-cloud functional tests succeeded
✅ ucp-cloud functional tests succeeded

@lakshmimsft lakshmimsft merged commit f89f424 into radius-project:main Sep 9, 2024
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants