From 57925856ce5edf8824567af2e9fe166b366f2200 Mon Sep 17 00:00:00 2001 From: Gerd Oberlechner Date: Mon, 3 Feb 2025 09:47:46 +0100 Subject: [PATCH] chain Signed-off-by: Gerd Oberlechner --- .github/workflows/services-pr-check.yml | 60 +++++++++--------- tooling/templatize/cmd/pipeline/run/cmd.go | 4 +- tooling/templatize/internal/end2end/e2e.go | 4 +- .../templatize/internal/end2end/e2e_test.go | 8 +-- tooling/templatize/pkg/aks/admin.go | 6 +- tooling/templatize/pkg/aks/kubeconfig.go | 4 +- tooling/templatize/pkg/auth/auth.go | 12 ---- tooling/templatize/pkg/azauth/auth.go | 33 ++++++++++ .../templatize/pkg/{auth => azauth}/github.go | 61 ++++++++++--------- tooling/templatize/pkg/pipeline/arm.go | 4 +- .../pkg/pipeline/executiontarget.go | 4 +- 11 files changed, 112 insertions(+), 88 deletions(-) delete mode 100644 tooling/templatize/pkg/auth/auth.go create mode 100644 tooling/templatize/pkg/azauth/auth.go rename tooling/templatize/pkg/{auth => azauth}/github.go (52%) diff --git a/.github/workflows/services-pr-check.yml b/.github/workflows/services-pr-check.yml index d70daec634..23a8fb8906 100644 --- a/.github/workflows/services-pr-check.yml +++ b/.github/workflows/services-pr-check.yml @@ -50,12 +50,12 @@ - name: "install azure-cli" uses: "Azure/ARO-HCP@main" - #- name: 'Az CLI login' - # uses: azure/login@a65d910e8af852a8061c627c456678983e180302 # v2.2.0 - # with: - # client-id: ${{ secrets.AZURE_CLIENT_ID }} - # tenant-id: ${{ secrets.AZURE_TENANT_ID }} - # subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + # - name: 'Az CLI login' + # uses: azure/login@a65d910e8af852a8061c627c456678983e180302 # v2.2.0 + # with: + # client-id: ${{ secrets.AZURE_CLIENT_ID }} + # tenant-id: ${{ secrets.AZURE_TENANT_ID }} + # subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/setup-kubectl@3e0aec4d80787158d308d7b364cb1b702e7feb7f # v4.0.0 @@ -83,29 +83,29 @@ run: | make cluster-service.dry_run - # - name: 'Dry Run Backend' - # run: | - # make backend.dry_run + - name: 'Dry Run Backend' + run: | + make backend.dry_run - # - name: 'Dry Run Frontend' - # run: | - # make frontend.dry_run + - name: 'Dry Run Frontend' + run: | + make frontend.dry_run - # - name: 'Dry Run Maestro Server' - # run: | - # make maestro.server.dry_run + - name: 'Dry Run Maestro Server' + run: | + make maestro.server.dry_run - # - name: 'Dry Run Istio' - # run: | - # make istio.dry_run + - name: 'Dry Run Istio' + run: | + make istio.dry_run - # - name: 'Dry Run ACR Pull' - # run: | - # make acrpull.dry_run + - name: 'Dry Run ACR Pull' + run: | + make acrpull.dry_run - # - name: 'Dry Run Metrics' - # run: | - # make metrics.dry_run + - name: 'Dry Run Metrics' + run: | + make metrics.dry_run mgmt_cluster_pr_check: env: @@ -122,12 +122,12 @@ - name: "install azure-cli" uses: "Azure/ARO-HCP@main" - - name: 'Az CLI login' - uses: azure/login@a65d910e8af852a8061c627c456678983e180302 # v2.2.0 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + # - name: 'Az CLI login' + # uses: azure/login@a65d910e8af852a8061c627c456678983e180302 # v2.2.0 + # with: + # client-id: ${{ secrets.AZURE_CLIENT_ID }} + # tenant-id: ${{ secrets.AZURE_TENANT_ID }} + # subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/setup-kubectl@3e0aec4d80787158d308d7b364cb1b702e7feb7f # v4.0.0 diff --git a/tooling/templatize/cmd/pipeline/run/cmd.go b/tooling/templatize/cmd/pipeline/run/cmd.go index 48c1ce02df..9bc782b4da 100644 --- a/tooling/templatize/cmd/pipeline/run/cmd.go +++ b/tooling/templatize/cmd/pipeline/run/cmd.go @@ -3,7 +3,7 @@ package run import ( "context" - "github.com/Azure/ARO-HCP/tooling/templatize/pkg/auth" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" "github.com/spf13/cobra" ) @@ -32,7 +32,7 @@ func runPipeline(ctx context.Context, opts *RawRunOptions) error { if err != nil { return err } - err = auth.SetupAzureAuth(ctx) + err = azauth.SetupAzureAuth(ctx) if err != nil { return err } diff --git a/tooling/templatize/internal/end2end/e2e.go b/tooling/templatize/internal/end2end/e2e.go index c9a76cfe48..4b66d8ef14 100644 --- a/tooling/templatize/internal/end2end/e2e.go +++ b/tooling/templatize/internal/end2end/e2e.go @@ -9,9 +9,9 @@ import ( "gopkg.in/yaml.v2" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/config" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/pipeline" ) @@ -112,7 +112,7 @@ func (e *e2eImpl) UseRandomRG() func() error { if err != nil { return err } - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() if err != nil { return err } diff --git a/tooling/templatize/internal/end2end/e2e_test.go b/tooling/templatize/internal/end2end/e2e_test.go index 94366e5da4..6b40ee5a14 100644 --- a/tooling/templatize/internal/end2end/e2e_test.go +++ b/tooling/templatize/internal/end2end/e2e_test.go @@ -10,10 +10,10 @@ import ( "gotest.tools/v3/assert" "github.com/Azure/ARO-HCP/tooling/templatize/cmd/pipeline/run" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/config" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/pipeline" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" ) @@ -107,7 +107,7 @@ param zoneName = 'e2etestarmdeploy.foo.bar.example.com' subsriptionID, err := pipeline.LookupSubscriptionID(context.Background(), "ARO Hosted Control Planes (EA Subscription 1)") assert.NilError(t, err) - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() assert.NilError(t, err) zonesClient, err := armdns.NewZonesClient(subsriptionID, cred, nil) @@ -314,7 +314,7 @@ resource newRG 'Microsoft.Resources/resourceGroups@2024-03-01' = { subsriptionID, err := pipeline.LookupSubscriptionID(context.Background(), "ARO Hosted Control Planes (EA Subscription 1)") assert.NilError(t, err) - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() assert.NilError(t, err) rgClient, err := armresources.NewResourceGroupsClient(subsriptionID, cred, nil) @@ -354,7 +354,7 @@ param zoneName = 'e2etestarmdeploy.foo.bar.example.com' subsriptionID, err := pipeline.LookupSubscriptionID(context.Background(), "ARO Hosted Control Planes (EA Subscription 1)") assert.NilError(t, err) - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() assert.NilError(t, err) zonesClient, err := armdns.NewZonesClient(subsriptionID, cred, nil) diff --git a/tooling/templatize/pkg/aks/admin.go b/tooling/templatize/pkg/aks/admin.go index 3e8700f003..e0a4c7ea9b 100644 --- a/tooling/templatize/pkg/aks/admin.go +++ b/tooling/templatize/pkg/aks/admin.go @@ -7,9 +7,9 @@ import ( "os" "time" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" armauthorization "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3" "github.com/google/uuid" auth "github.com/microsoft/kiota-authentication-azure-go" @@ -99,7 +99,7 @@ func getCurrentUserObjectID(ctx context.Context) (string, error) { } // Create a Graph client using Azure Credentials - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() if err != nil { return "", fmt.Errorf("failed to obtain a credential: %w", err) } @@ -130,7 +130,7 @@ func getCurrentUserObjectID(ctx context.Context) (string, error) { func assignClusterAdminRBACRole(ctx context.Context, subscriptionID, resourceGroupName, aksClusterName, userObjectID, roleID string) error { // Create a new Azure identity client - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() if err != nil { return fmt.Errorf("failed to obtain a credential: %w", err) } diff --git a/tooling/templatize/pkg/aks/kubeconfig.go b/tooling/templatize/pkg/aks/kubeconfig.go index 3baf53503a..0b31f9bb0f 100644 --- a/tooling/templatize/pkg/aks/kubeconfig.go +++ b/tooling/templatize/pkg/aks/kubeconfig.go @@ -6,7 +6,7 @@ import ( "os" "os/exec" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice" ) @@ -16,7 +16,7 @@ func GetKubeConfig(ctx context.Context, subscriptionID, resourceGroupName, aksCl } // Create a new Azure identity client - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() if err != nil { return "", fmt.Errorf("failed to obtain a credential: %v", err) } diff --git a/tooling/templatize/pkg/auth/auth.go b/tooling/templatize/pkg/auth/auth.go deleted file mode 100644 index 142ed95e29..0000000000 --- a/tooling/templatize/pkg/auth/auth.go +++ /dev/null @@ -1,12 +0,0 @@ -package auth - -import ( - "context" -) - -func SetupAzureAuth(ctx context.Context) error { - if githubAuthSupported() { - setupGithubAzureFederationAuth(ctx) - } - return nil -} diff --git a/tooling/templatize/pkg/azauth/auth.go b/tooling/templatize/pkg/azauth/auth.go new file mode 100644 index 0000000000..3f0b3d0667 --- /dev/null +++ b/tooling/templatize/pkg/azauth/auth.go @@ -0,0 +1,33 @@ +package azauth + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" +) + +func SetupAzureAuth(ctx context.Context) error { + if githubAuthSupported() { + setupGithubAzureFederationAuthRefresher(ctx) + } + return nil +} + +func GetAzureTokenCredentials() (azcore.TokenCredential, error) { + azCLI, err := azidentity.NewAzureCLICredential(nil) + if err != nil { + return nil, err + } + + def, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return nil, err + } + + chain, err := azidentity.NewChainedTokenCredential([]azcore.TokenCredential{azCLI, def}, nil) + if err != nil { + return nil, err + } + return chain, nil +} diff --git a/tooling/templatize/pkg/auth/github.go b/tooling/templatize/pkg/azauth/github.go similarity index 52% rename from tooling/templatize/pkg/auth/github.go rename to tooling/templatize/pkg/azauth/github.go index ac9975a495..0ebd5fb769 100644 --- a/tooling/templatize/pkg/auth/github.go +++ b/tooling/templatize/pkg/azauth/github.go @@ -1,4 +1,4 @@ -package auth +package azauth import ( "context" @@ -9,41 +9,54 @@ import ( "os" "os/exec" "time" + + "github.com/go-logr/logr" ) const ( - AZURE_FEDERATED_TOKEN_FILE_ENV = "AZURE_FEDERATED_TOKEN_FILE" - ACTIONS_ID_TOKEN_REQUEST_URL_ENV = "ACTIONS_ID_TOKEN_REQUEST_URL" - ACTIONS_ID_TOKEN_REQUEST_TOKEN_ENV = "ACTIONS_ID_TOKEN_REQUEST_TOKEN" + AZURE_CLIENT_ID = "AZURE_CLIENT_ID" + AZURE_TENANT_ID = "AZURE_TENANT_ID" + AZURE_FEDERATED_TOKEN_FILE = "AZURE_FEDERATED_TOKEN_FILE" + ACTIONS_ID_TOKEN_REQUEST_URL = "ACTIONS_ID_TOKEN_REQUEST_URL" + ACTIONS_ID_TOKEN_REQUEST_TOKEN = "ACTIONS_ID_TOKEN_REQUEST_TOKEN" ) func githubAuthSupported() bool { - if _, ok := os.LookupEnv("AZURE_CLIENT_ID"); !ok { + if _, ok := os.LookupEnv(AZURE_CLIENT_ID); !ok { return false } - if _, ok := os.LookupEnv("AZURE_TENANT_ID"); !ok { + if _, ok := os.LookupEnv(AZURE_TENANT_ID); !ok { return false } - if _, ok := os.LookupEnv(ACTIONS_ID_TOKEN_REQUEST_URL_ENV); !ok { + if _, ok := os.LookupEnv(ACTIONS_ID_TOKEN_REQUEST_URL); !ok { return false } - if _, ok := os.LookupEnv(ACTIONS_ID_TOKEN_REQUEST_TOKEN_ENV); !ok { + if _, ok := os.LookupEnv(ACTIONS_ID_TOKEN_REQUEST_TOKEN); !ok { return false } return true } -func setupGithubAzureFederationAuth(ctx context.Context) error { - clientId := getAzureClientId() - tenantId := getAzureTenantId() - refreshGithubAzureFederatedSession(ctx, clientId, tenantId) +func setupGithubAzureFederationAuthRefresher(ctx context.Context) error { + logger := logr.FromContextOrDiscard(ctx) + clientId := os.Getenv(AZURE_CLIENT_ID) + tenantId := os.Getenv(AZURE_TENANT_ID) + requestToken := os.Getenv(ACTIONS_ID_TOKEN_REQUEST_TOKEN) + requestURL := os.Getenv(ACTIONS_ID_TOKEN_REQUEST_URL) + err := refreshGithubAzureFederatedSession(ctx, clientId, tenantId, requestURL, requestToken) + if err != nil { + return fmt.Errorf("failed to refresh Azure session with federated GitHub ID token: %w", err) + } go func() { ticker := time.NewTicker(5 * time.Minute) defer ticker.Stop() for { select { case <-ticker.C: - refreshGithubAzureFederatedSession(ctx, clientId, tenantId) + err := refreshGithubAzureFederatedSession(ctx, clientId, tenantId, requestURL, requestToken) + if err != nil { + logger.Error(err, "failed to refresh Azure session with federated GitHub ID token") + } case <-ctx.Done(): return } @@ -52,17 +65,10 @@ func setupGithubAzureFederationAuth(ctx context.Context) error { return nil } -func getAzureClientId() string { - return os.Getenv("AZURE_CLIENT_ID") -} - -func getAzureTenantId() string { - return os.Getenv("AZURE_TENANT_ID") -} - -func refreshGithubAzureFederatedSession(ctx context.Context, clientId string, tenantId string) error { - fmt.Println("Refreshing Azure session with federated GitHub ID token") - token, err := getGithubIDToken() +func refreshGithubAzureFederatedSession(ctx context.Context, clientId, tenantId, requestUrl, requestToken string) error { + logger := logr.FromContextOrDiscard(ctx) + logger.V(7).Info("Refreshing Azure session with federated GitHub ID token") + token, err := getGithubIDToken(requestUrl, requestToken) if err != nil { return fmt.Errorf("failed to get GitHub ID token: %w", err) } @@ -71,14 +77,11 @@ func refreshGithubAzureFederatedSession(ctx context.Context, clientId string, te if err != nil { return fmt.Errorf("failed to run az login: %s %v", string(output), err) } - fmt.Printf("Azure session refreshed with federated GitHub ID token: %s\n", output) + logger.V(7).Info("Azure session refreshed with federated GitHub ID token", "az cli output", output) return nil } -func getGithubIDToken() (string, error) { - requestToken := os.Getenv(ACTIONS_ID_TOKEN_REQUEST_TOKEN_ENV) - requestURL := os.Getenv(ACTIONS_ID_TOKEN_REQUEST_URL_ENV) - +func getGithubIDToken(requestURL, requestToken string) (string, error) { req, err := http.NewRequest("GET", requestURL, nil) if err != nil { return "", fmt.Errorf("failed to create request: %w", err) diff --git a/tooling/templatize/pkg/pipeline/arm.go b/tooling/templatize/pkg/pipeline/arm.go index b0637a0747..4cf84da903 100644 --- a/tooling/templatize/pkg/pipeline/arm.go +++ b/tooling/templatize/pkg/pipeline/arm.go @@ -6,11 +6,11 @@ import ( "strings" "time" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/config" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" "github.com/go-logr/logr" ) @@ -25,7 +25,7 @@ type armClient struct { } func newArmClient(subscriptionID, region string) *armClient { - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() if err != nil { return nil } diff --git a/tooling/templatize/pkg/pipeline/executiontarget.go b/tooling/templatize/pkg/pipeline/executiontarget.go index 7964e0bced..76c46ed8c7 100644 --- a/tooling/templatize/pkg/pipeline/executiontarget.go +++ b/tooling/templatize/pkg/pipeline/executiontarget.go @@ -4,15 +4,15 @@ import ( "context" "fmt" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" "github.com/Azure/ARO-HCP/tooling/templatize/pkg/aks" + "github.com/Azure/ARO-HCP/tooling/templatize/pkg/azauth" ) func LookupSubscriptionID(ctx context.Context, subscriptionName string) (string, error) { // Create a new Azure identity client - cred, err := azidentity.NewDefaultAzureCredential(nil) + cred, err := azauth.GetAzureTokenCredentials() if err != nil { return "", fmt.Errorf("failed to obtain a credential: %v", err) }