Skip to content

Commit 84030fc

Browse files
authored
Merge pull request #932 from fluxcd/gcp-wif-int-test
[RFC-0010] Add integration test for GCP workload identity federation
2 parents 3d6f759 + df77507 commit 84030fc

File tree

10 files changed

+295
-40
lines changed

10 files changed

+295
-40
lines changed

auth/gcp/options.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ func getWorkloadIdentityProviderAudience(serviceAccount corev1.ServiceAccount) (
5454
return "", fmt.Errorf("invalid %s annotation: '%s'. must match %s",
5555
key, wip, workloadIdentityProviderPattern)
5656
}
57-
return fmt.Sprintf("https://iam.googleapis.com/%s", wip), nil
57+
return fmt.Sprintf("//iam.googleapis.com/%s", wip), nil
5858
}

auth/gcp/provider_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func TestProvider_NewTokenForServiceAccount(t *testing.T) {
9797
{
9898
name: "direct access - federation",
9999
conf: externalaccount.Config{
100-
Audience: "https://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
100+
Audience: "//iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
101101
SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
102102
TokenURL: "https://sts.googleapis.com/v1/token",
103103
TokenInfoURL: "https://sts.googleapis.com/v1/introspect",
@@ -115,7 +115,7 @@ func TestProvider_NewTokenForServiceAccount(t *testing.T) {
115115
{
116116
name: "impersonation - federation",
117117
conf: externalaccount.Config{
118-
Audience: "https://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
118+
Audience: "//iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
119119
SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
120120
TokenURL: "https://sts.googleapis.com/v1/token",
121121
ServiceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/test-sa@project-id.iam.gserviceaccount.com:generateAccessToken",
@@ -197,7 +197,7 @@ func TestProvider_GetAudience(t *testing.T) {
197197
annotations: map[string]string{
198198
"gcp.auth.fluxcd.io/workload-identity-provider": "projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
199199
},
200-
expected: "https://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
200+
expected: "//iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/test-pool/providers/test-provider",
201201
},
202202
{
203203
name: "gke",

oci/tests/integration/gcp_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ const (
3232
// gcpIAMAnnotation is the key for the annotation on the kubernetes serviceaccount
3333
// with the email address of the IAM service account on GCP.
3434
gcpIAMAnnotation = "iam.gke.io/gcp-service-account"
35+
36+
// gcpWorkloadIdentityProviderAnnotation is the key for the annotation on the kubernetes serviceaccount
37+
// with the name of the workload identity provider on GCP.
38+
gcpWorkloadIdentityProviderAnnotation = "gcp.auth.fluxcd.io/workload-identity-provider"
3539
)
3640

3741
// createKubeconfigGKE constructs kubeconfig from the terraform state output at
@@ -85,6 +89,18 @@ func getWISAAnnotationsGCP(output map[string]*tfjson.StateOutput) (map[string]st
8589
}, nil
8690
}
8791

92+
// getWIFederationSAAnnotationsGCP returns workload identity federation annotations for a kubernetes ServiceAccount
93+
func getWIFederationSAAnnotationsGCP(output map[string]*tfjson.StateOutput) (map[string]string, error) {
94+
workloadIdentityProvider := output["workload_identity_provider"].Value.(string)
95+
if workloadIdentityProvider == "" {
96+
return nil, fmt.Errorf("no GCP workload identity provider in terraform output")
97+
}
98+
99+
return map[string]string{
100+
gcpWorkloadIdentityProviderAnnotation: workloadIdentityProvider,
101+
}, nil
102+
}
103+
88104
// When implemented, getGitTestConfigGCP would return the git-specific test config for GCP
89105
func getGitTestConfigGCP(outputs map[string]*tfjson.StateOutput) (*gitTestConfig, error) {
90106
return nil, fmt.Errorf("NotImplemented for GCP")

oci/tests/integration/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ replace (
1010
)
1111

1212
require (
13-
github.com/fluxcd/pkg/auth v0.14.0
13+
github.com/fluxcd/pkg/auth v0.16.0
1414
github.com/fluxcd/pkg/git v0.31.0
1515
github.com/fluxcd/pkg/git/gogit v0.33.0
1616
github.com/fluxcd/test-infra/tftestenv v0.0.0-20240903092121-c783b14801d1

oci/tests/integration/job_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const (
3434
objectLevelWIModeDisabled objectLevelWIMode = iota
3535
objectLevelWIModeDirectAccess
3636
objectLevelWIModeImpersonation
37+
objectLevelWIModeDirectAccessFederation
38+
objectLevelWIModeImpersonationFederation
3739
)
3840

3941
type objectLevelWIMode int
@@ -78,6 +80,10 @@ func testjobExecutionWithArgs(t *testing.T, args []string, opts ...jobOption) {
7880
args = append(args, "-wisa-name="+wiServiceAccount)
7981
case objectLevelWIModeDirectAccess:
8082
args = append(args, "-wisa-name="+wiServiceAccountDirectAccess)
83+
case objectLevelWIModeImpersonationFederation:
84+
args = append(args, "-wisa-name="+wiServiceAccountFederation)
85+
case objectLevelWIModeDirectAccessFederation:
86+
args = append(args, "-wisa-name="+wiServiceAccountFederationDirectAccess)
8187
}
8288
}
8389
job.Spec.Template.Spec.ServiceAccountName = saName

oci/tests/integration/oci_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,46 @@ func TestOciImageRepositoryListTagsUsingObjectLevelWorkloadIdentityWithDirectAcc
8181
}
8282
}
8383

84+
func TestOciImageRepositoryListTagsUsingObjectLevelWorkloadIdentityFederation(t *testing.T) {
85+
if !testWIFederation {
86+
t.Skip("Skipping workload identity federation test, not supported for provider")
87+
}
88+
89+
if len(testRepos) == 0 {
90+
t.Fatalf("expected testRepos to be set")
91+
}
92+
93+
for name, repo := range testRepos {
94+
t.Run(name, func(t *testing.T) {
95+
args := []string{
96+
"-category=oci",
97+
fmt.Sprintf("-repo=%s", repo),
98+
}
99+
testjobExecutionWithArgs(t, args, withObjectLevelWI(objectLevelWIModeImpersonationFederation))
100+
})
101+
}
102+
}
103+
104+
func TestOciImageRepositoryListTagsUsingObjectLevelWorkloadIdentityFederationWithDirectAccess(t *testing.T) {
105+
if !testWIFederation || !testWIDirectAccess {
106+
t.Skip("Skipping workload identity federation direct access test, not supported for provider")
107+
}
108+
109+
if len(testRepos) == 0 {
110+
t.Fatalf("expected testRepos to be set")
111+
}
112+
113+
for name, repo := range testRepos {
114+
t.Run(name, func(t *testing.T) {
115+
args := []string{
116+
"-category=oci",
117+
fmt.Sprintf("-repo=%s", repo),
118+
}
119+
testjobExecutionWithArgs(t, args, withObjectLevelWI(objectLevelWIModeDirectAccessFederation))
120+
})
121+
}
122+
}
123+
84124
func TestOciRepositoryRootLoginListTags(t *testing.T) {
85125
if len(testRepos) == 0 {
86126
t.Fatalf("expected testRepos to be set")

0 commit comments

Comments
 (0)