diff --git a/app.go b/app.go index 5425b83..64305e2 100644 --- a/app.go +++ b/app.go @@ -426,6 +426,31 @@ func Run() { Usage: "build target", EnvVar: "PLUGIN_HARNESS_SELF_HOSTED_GCP_JSON_KEY", }, + cli.StringFlag{ + Name: "harness-self-hosted-azure-account-key", + Usage: "Harness self-hosted azure account key for cache", + EnvVar: "PLUGIN_HARNESS_SELF_HOSTED_AZURE_ACCOUNT_KEY", + }, + cli.StringFlag{ + Name: "harness-self-hosted-azure-tenant-id", + Usage: "Harness self-hosted azure tenant id for cache", + EnvVar: "PLUGIN_HARNESS_SELF_HOSTED_AZURE_TENANT_ID", + }, + cli.StringFlag{ + Name: "harness-self-hosted-azure-client-id", + Usage: "Harness self-hosted azure client id for cache", + EnvVar: "PLUGIN_HARNESS_SELF_HOSTED_AZURE_CLIENT_ID", + }, + cli.StringFlag{ + Name: "harness-self-hosted-azure-client-secret", + Usage: "Harness self-hosted azure client secret for cache", + EnvVar: "PLUGIN_HARNESS_SELF_HOSTED_AZURE_CLIENT_SECRET", + }, + cli.StringFlag{ + Name: "harness-self-hosted-azure-oidc-token", + Usage: "Harness self-hosted azure oidc token for cache", + EnvVar: "PLUGIN_HARNESS_SELF_HOSTED_AZURE_OIDC_TOKEN", + }, cli.StringSliceFlag{ Name: "buildx-options", Usage: "additional options to pass directly to the buildx command", @@ -531,9 +556,14 @@ func run(c *cli.Context) error { Platform: c.String("platform"), SSHAgentKey: c.String("ssh-agent-key"), BuildxLoad: c.Bool("buildx-load"), - HarnessSelfHostedS3AccessKey: c.String("harness-self-hosted-s3-access-key"), - HarnessSelfHostedS3SecretKey: c.String("harness-self-hosted-s3-secret-key"), - HarnessSelfHostedGcpJsonKey: c.String("harness-self-hosted-gcp-json-key"), + HarnessSelfHostedS3AccessKey: c.String("harness-self-hosted-s3-access-key"), + HarnessSelfHostedS3SecretKey: c.String("harness-self-hosted-s3-secret-key"), + HarnessSelfHostedGcpJsonKey: c.String("harness-self-hosted-gcp-json-key"), + HarnessSelfHostedAzureAccountKey: c.String("harness-self-hosted-azure-account-key"), + HarnessSelfHostedAzureTenantID: c.String("harness-self-hosted-azure-tenant-id"), + HarnessSelfHostedAzureClientID: c.String("harness-self-hosted-azure-client-id"), + HarnessSelfHostedAzureClientSecret: c.String("harness-self-hosted-azure-client-secret"), + HarnessSelfHostedAzureOidcToken: c.String("harness-self-hosted-azure-oidc-token"), BuildxOptions: c.StringSlice("buildx-options"), BuildxOptionsSemicolon: c.String("buildx-options-semicolon"), BakeFile: c.String("bake-file"), diff --git a/buildkit/version.json b/buildkit/version.json index ae0e2cd..25146c4 100644 --- a/buildkit/version.json +++ b/buildkit/version.json @@ -1,3 +1,3 @@ { - "buildkit_version": "harness/buildkit:1.0.17" + "buildkit_version": "harness/buildkit:1.0.19" } \ No newline at end of file diff --git a/docker.go b/docker.go index a6fead5..1961c77 100644 --- a/docker.go +++ b/docker.go @@ -94,9 +94,14 @@ type ( SSHAgentKey string // Docker build ssh agent key SSHKeyPath string // Docker build ssh key path BuildxLoad bool // Docker buildx --load - HarnessSelfHostedS3AccessKey string // Harness self-hosted s3 access key - HarnessSelfHostedS3SecretKey string // Harness self-hosted s3 secret key - HarnessSelfHostedGcpJsonKey string // Harness self hosted gcp json region + HarnessSelfHostedS3AccessKey string // Harness self-hosted s3 access key + HarnessSelfHostedS3SecretKey string // Harness self-hosted s3 secret key + HarnessSelfHostedGcpJsonKey string // Harness self hosted gcp json key + HarnessSelfHostedAzureAccountKey string // Harness self-hosted azure account key + HarnessSelfHostedAzureTenantID string // Harness self-hosted azure tenant id + HarnessSelfHostedAzureClientID string // Harness self-hosted azure client id + HarnessSelfHostedAzureClientSecret string // Harness self-hosted azure client secret + HarnessSelfHostedAzureOidcToken string // Harness self-hosted azure oidc token BuildxOptions []string // Generic buildx options passed directly to the buildx command BuildxOptionsSemicolon string // Buildx options separated by semicolons instead of commas // Buildx Bake (opt-in) @@ -812,6 +817,19 @@ func commandBuildxBake(build Build, builder Builder, dryrun bool, metadataFile s return exec.Command(dockerExe, args...) } +func replaceOrRemoveAzureCacheAttr(arg, attr, value string) string { + placeholder := attr + "=harness_placeholder_azure_creds" + if !strings.Contains(arg, placeholder) { + return arg + } + if value != "" { + return strings.Replace(arg, placeholder, attr+"="+value, 1) + } + arg = strings.Replace(arg, ","+placeholder, "", 1) + arg = strings.Replace(arg, placeholder+",", "", 1) + return strings.Replace(arg, placeholder, "", 1) +} + func sanitizeCacheCommand(build *Build) { // Helper function to sanitize cache arguments sanitizeCacheArgs := func(args []string) []string { @@ -842,6 +860,13 @@ func sanitizeCacheCommand(build *Build) { } } + // Handle azure cache credential placeholders + arg = replaceOrRemoveAzureCacheAttr(arg, "account_key", build.HarnessSelfHostedAzureAccountKey) + arg = replaceOrRemoveAzureCacheAttr(arg, "tenant_id", build.HarnessSelfHostedAzureTenantID) + arg = replaceOrRemoveAzureCacheAttr(arg, "client_id", build.HarnessSelfHostedAzureClientID) + arg = replaceOrRemoveAzureCacheAttr(arg, "client_secret", build.HarnessSelfHostedAzureClientSecret) + arg = replaceOrRemoveAzureCacheAttr(arg, "oidc_token", build.HarnessSelfHostedAzureOidcToken) + if build.PathStyle && strings.Contains(arg, "type=s3") { if strings.Contains(arg, "use_path_style=false") { fmt.Printf("use_path_style is set to false in cache-from or cache-to but env var PLUGIN_PATH_STYLE is true\n") diff --git a/docker_test.go b/docker_test.go index 218b5ae..889c973 100644 --- a/docker_test.go +++ b/docker_test.go @@ -390,6 +390,38 @@ func TestSanitizeCacheCommand(t *testing.T) { expectedCacheFrom: []string{"type=gcs,gcp_json_key=YWN0dWFsX2djcF9rZXk=,access_key_id=actual_access_key,secret_access_key=actual_secret_key"}, expectedCacheTo: []string{}, }, + { + name: "Replace Azure placeholders in CacheFrom and CacheTo", + build: Build{ + CacheFrom: []string{"type=azure,account_name=myaccount,container_name=cache,account_key=harness_placeholder_azure_creds,tenant_id=harness_placeholder_azure_creds,client_id=harness_placeholder_azure_creds,client_secret=harness_placeholder_azure_creds"}, + CacheTo: []string{"type=azure,account_name=myaccount,container_name=cache,account_key=harness_placeholder_azure_creds,tenant_id=harness_placeholder_azure_creds,client_id=harness_placeholder_azure_creds,client_secret=harness_placeholder_azure_creds,mode=max"}, + HarnessSelfHostedAzureAccountKey: "actual_account_key", + HarnessSelfHostedAzureTenantID: "actual_tenant_id", + HarnessSelfHostedAzureClientID: "actual_client_id", + HarnessSelfHostedAzureClientSecret: "actual_client_secret", + }, + expectedCacheFrom: []string{"type=azure,account_name=myaccount,container_name=cache,account_key=actual_account_key,tenant_id=actual_tenant_id,client_id=actual_client_id,client_secret=actual_client_secret"}, + expectedCacheTo: []string{"type=azure,account_name=myaccount,container_name=cache,account_key=actual_account_key,tenant_id=actual_tenant_id,client_id=actual_client_id,client_secret=actual_client_secret,mode=max"}, + }, + { + name: "Remove Azure placeholders when credentials are empty", + build: Build{ + CacheFrom: []string{"type=azure,account_name=myaccount,container_name=cache,account_key=harness_placeholder_azure_creds,oidc_token=harness_placeholder_azure_creds"}, + CacheTo: []string{"type=azure,account_name=myaccount,container_name=cache,client_secret=harness_placeholder_azure_creds"}, + }, + expectedCacheFrom: []string{"type=azure,account_name=myaccount,container_name=cache"}, + expectedCacheTo: []string{"type=azure,account_name=myaccount,container_name=cache"}, + }, + { + name: "Replace Azure oidc_token placeholder", + build: Build{ + CacheFrom: []string{"type=azure,account_name=myaccount,container_name=cache,tenant_id=tenant,client_id=client,oidc_token=harness_placeholder_azure_creds"}, + CacheTo: []string{}, + HarnessSelfHostedAzureOidcToken: "actual_oidc_token", + }, + expectedCacheFrom: []string{"type=azure,account_name=myaccount,container_name=cache,tenant_id=tenant,client_id=client,oidc_token=actual_oidc_token"}, + expectedCacheTo: []string{}, + }, { name: "No placeholders in CacheFrom and CacheTo", build: Build{