diff --git a/api/go.mod b/api/go.mod index 8429d555..140cea2e 100644 --- a/api/go.mod +++ b/api/go.mod @@ -4,7 +4,7 @@ go 1.24.0 require ( github.com/fluxcd/pkg/apis/acl v0.7.0 - github.com/fluxcd/pkg/apis/meta v1.11.0 + github.com/fluxcd/pkg/apis/meta v1.12.0 k8s.io/apimachinery v0.33.0 sigs.k8s.io/controller-runtime v0.20.4 ) diff --git a/api/go.sum b/api/go.sum index 76f50729..a2b46abc 100644 --- a/api/go.sum +++ b/api/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0= github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ= -github.com/fluxcd/pkg/apis/meta v1.11.0 h1:h8q95k6ZEK1HCfsLkt8Np3i6ktb6ZzcWJ6hg++oc9w0= -github.com/fluxcd/pkg/apis/meta v1.11.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= +github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg= +github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= diff --git a/go.mod b/go.mod index 6134ad00..4c2721c6 100644 --- a/go.mod +++ b/go.mod @@ -23,16 +23,16 @@ require ( github.com/elazarl/goproxy v1.7.2 github.com/fluxcd/cli-utils v0.36.0-flux.13 github.com/fluxcd/pkg/apis/event v0.17.0 - github.com/fluxcd/pkg/apis/meta v1.11.0 - github.com/fluxcd/pkg/auth v0.12.0 + github.com/fluxcd/pkg/apis/meta v1.12.0 + github.com/fluxcd/pkg/auth v0.14.0 github.com/fluxcd/pkg/cache v0.9.0 - github.com/fluxcd/pkg/git v0.29.0 - github.com/fluxcd/pkg/git/gogit v0.31.0 + github.com/fluxcd/pkg/git v0.31.0 + github.com/fluxcd/pkg/git/gogit v0.33.0 github.com/fluxcd/pkg/gittestserver v0.17.0 github.com/fluxcd/pkg/helmtestserver v0.24.0 github.com/fluxcd/pkg/lockedfile v0.6.0 github.com/fluxcd/pkg/masktoken v0.7.0 - github.com/fluxcd/pkg/oci v0.48.0 + github.com/fluxcd/pkg/oci v0.49.0 github.com/fluxcd/pkg/runtime v0.59.0 github.com/fluxcd/pkg/sourceignore v0.12.0 github.com/fluxcd/pkg/ssh v0.18.0 diff --git a/go.sum b/go.sum index 4a832fbd..da448e6b 100644 --- a/go.sum +++ b/go.sum @@ -372,16 +372,16 @@ github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5o github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ= github.com/fluxcd/pkg/apis/event v0.17.0 h1:foEINE++pCJlWVhWjYDXfkVmGKu8mQ4BDBlbYi5NU7M= github.com/fluxcd/pkg/apis/event v0.17.0/go.mod h1:0fLhLFiHlRTDKPDXdRnv+tS7mCMIQ0fJxnEfmvGM/5A= -github.com/fluxcd/pkg/apis/meta v1.11.0 h1:h8q95k6ZEK1HCfsLkt8Np3i6ktb6ZzcWJ6hg++oc9w0= -github.com/fluxcd/pkg/apis/meta v1.11.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= -github.com/fluxcd/pkg/auth v0.12.0 h1:35o0ziYMLZVgJwNvJBGsv/wd903B2fMagcrnm1ptUjc= -github.com/fluxcd/pkg/auth v0.12.0/go.mod h1:gQD2VT5OhIR1E8ZTEsTaho3bDQZidr9P10smH/awcew= +github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg= +github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= +github.com/fluxcd/pkg/auth v0.14.0 h1:AA9nmbFzTN5jcGROJK51LvQoDetMrXJLAo4Sd6WHpFI= +github.com/fluxcd/pkg/auth v0.14.0/go.mod h1:o91WIZZshLooBALXY/MVn0mmdUw3eATrqGXrG1M7nTE= github.com/fluxcd/pkg/cache v0.9.0 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk= github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU= -github.com/fluxcd/pkg/git v0.29.0 h1:MHQ4F53e6Xt8a/POkd/fiChgysnd/XqiuK7vOWXAXLk= -github.com/fluxcd/pkg/git v0.29.0/go.mod h1:Ygn+LfrK6Ok+85uiq6s3NWG5LcHS4KY7mzES2JDJsGY= -github.com/fluxcd/pkg/git/gogit v0.31.0 h1:A56cmtgJBkWAj+gXSOdhPMQVTx0VF91S0PUaqpMXN4g= -github.com/fluxcd/pkg/git/gogit v0.31.0/go.mod h1:ya8z22xTvAAdW12HycxKYv4S+G+lqu5Kx/LyO/jWz8Y= +github.com/fluxcd/pkg/git v0.31.0 h1:hVUJcRujNa+GA5zrjrMpuVcgHbCBjfq0CZIZJqJl22I= +github.com/fluxcd/pkg/git v0.31.0/go.mod h1:rUgLXVQGBkBggHOLVMhHMHaweQ8Oc6HwZiN2Zm08Zxs= +github.com/fluxcd/pkg/git/gogit v0.33.0 h1:JYKa3XqA91AX7/sKEgARO9VzkwouXWjUgpwudEZEWq0= +github.com/fluxcd/pkg/git/gogit v0.33.0/go.mod h1:EvsVYcB3KjfhpdoyU1sO9HuMH5Xt0cVhW49kFlZcFLY= github.com/fluxcd/pkg/gittestserver v0.17.0 h1:JlBvWZQTDOI+np5Z+084m3DkeAH1hMusEybyRUDF63k= github.com/fluxcd/pkg/gittestserver v0.17.0/go.mod h1:E/40EmLoXcMqd6gLuLDC9F6KJxqHVGbBBeMNKk5XdxU= github.com/fluxcd/pkg/helmtestserver v0.24.0 h1:9sSfRG17GnDIup4sI8V+fdvKROtunU4JyIo34uvXq3Q= @@ -390,8 +390,8 @@ github.com/fluxcd/pkg/lockedfile v0.6.0 h1:64RRMiPv3ZK9Y4sjI8c78kZAdfEo+Sjr2iP8a github.com/fluxcd/pkg/lockedfile v0.6.0/go.mod h1:gpdUVm7+05NIT1ZvzuNnHfnT81OhZtIySlxxkZ68pXk= github.com/fluxcd/pkg/masktoken v0.7.0 h1:pitmyOg2pUVdW+nn2Lk/xqm2TaA08uxvOC0ns3sz6bM= github.com/fluxcd/pkg/masktoken v0.7.0/go.mod h1:Lc1uoDjO1GY6+YdkK+ZqqBIBWquyV58nlSJ5S1N1IYU= -github.com/fluxcd/pkg/oci v0.48.0 h1:iSK4JDM0nx9plSlOGx2aI4td6aQdV/awrfXK/bzI35I= -github.com/fluxcd/pkg/oci v0.48.0/go.mod h1:rnUC8EOpzQp4rugpmopYFMnG3+CR1wqEV3356gHUtSY= +github.com/fluxcd/pkg/oci v0.49.0 h1:L8/dmNSIzqu6X8vzIkPLrW8NAF7Et/SnOuI8WJkXeq8= +github.com/fluxcd/pkg/oci v0.49.0/go.mod h1:iZkF4bQTpc6YOU5IJWMBp0Q8voGm7bkMYiAarJ9407U= github.com/fluxcd/pkg/runtime v0.59.0 h1:3OrFkMJB39NcQ2vhhoxqls59sQVSn8U+thhyLbsQoA4= github.com/fluxcd/pkg/runtime v0.59.0/go.mod h1:MFbfyNyyoYRgPxpdwC9/dCOkzo7Yxhu/cQ9NKyhvqc0= github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw= diff --git a/internal/controller/gitrepository_controller.go b/internal/controller/gitrepository_controller.go index 045bb244..3ebfea22 100644 --- a/internal/controller/gitrepository_controller.go +++ b/internal/controller/gitrepository_controller.go @@ -28,6 +28,7 @@ import ( securejoin "github.com/cyphar/filepath-securejoin" "github.com/fluxcd/pkg/auth" + authutils "github.com/fluxcd/pkg/auth/utils" "github.com/fluxcd/pkg/git/github" "github.com/fluxcd/pkg/runtime/logger" "github.com/go-git/go-git/v5/plumbing/transport" @@ -683,28 +684,28 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1 return nil, e } - var authOpts []auth.Option + // Configure provider authentication if specified. + var getCreds func() (*authutils.GitCredentials, error) + switch provider := obj.GetProvider(); provider { + case sourcev1.GitProviderAzure: // If AWS or GCP are added in the future they can be added here separated by a comma. + getCreds = func() (*authutils.GitCredentials, error) { + var opts []auth.Option - if r.TokenCache != nil { - involvedObject := cache.InvolvedObject{ - Kind: sourcev1.GitRepositoryKind, - Name: obj.GetName(), - Namespace: obj.GetNamespace(), - Operation: cache.OperationReconcile, - } - authOpts = append(authOpts, auth.WithCache(*r.TokenCache, involvedObject)) - } + if r.TokenCache != nil { + involvedObject := cache.InvolvedObject{ + Kind: sourcev1.GitRepositoryKind, + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + Operation: cache.OperationReconcile, + } + opts = append(opts, auth.WithCache(*r.TokenCache, involvedObject)) + } - if proxyURL != nil { - authOpts = append(authOpts, auth.WithProxyURL(*proxyURL)) - } + if proxyURL != nil { + opts = append(opts, auth.WithProxyURL(*proxyURL)) + } - // Configure provider authentication if specified in spec - switch obj.GetProvider() { - case sourcev1.GitProviderAzure: - opts.ProviderOpts = &git.ProviderOptions{ - Name: sourcev1.GitProviderAzure, - AuthOpts: authOpts, + return authutils.GetGitCredentials(ctx, provider, opts...) } case sourcev1.GitProviderGitHub: // if provider is github, but secret ref is not specified @@ -717,14 +718,30 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1 return nil, e } - opts.ProviderOpts = &git.ProviderOptions{ - Name: sourcev1.GitProviderGitHub, - GitHubOpts: []github.OptFunc{ - github.WithAppData(authData), - github.WithProxyURL(proxyURL), - github.WithCache(r.TokenCache, sourcev1.GitRepositoryKind, - obj.GetName(), obj.GetNamespace(), cache.OperationReconcile), - }, + getCreds = func() (*authutils.GitCredentials, error) { + var opts []github.OptFunc + + if len(authData) > 0 { + opts = append(opts, github.WithAppData(authData)) + } + + if proxyURL != nil { + opts = append(opts, github.WithProxyURL(proxyURL)) + } + + if r.TokenCache != nil { + opts = append(opts, github.WithCache(r.TokenCache, sourcev1.GitRepositoryKind, + obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)) + } + + username, password, err := github.GetCredentials(ctx, opts...) + if err != nil { + return nil, err + } + return &authutils.GitCredentials{ + Username: username, + Password: password, + }, nil } default: // analyze secret, if it has github app data, perhaps provider should have been github. @@ -737,6 +754,20 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1 return nil, e } } + if getCreds != nil { + creds, err := getCreds() + if err != nil { + e := serror.NewGeneric( + fmt.Errorf("failed to configure authentication options: %w", err), + sourcev1.AuthenticationFailedReason, + ) + conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e) + return nil, e + } + opts.BearerToken = creds.BearerToken + opts.Username = creds.Username + opts.Password = creds.Password + } return opts, nil } diff --git a/internal/controller/gitrepository_controller_test.go b/internal/controller/gitrepository_controller_test.go index 596f0148..fdb1353f 100644 --- a/internal/controller/gitrepository_controller_test.go +++ b/internal/controller/gitrepository_controller_test.go @@ -787,12 +787,11 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) { func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { tests := []struct { - name string - url string - secret *corev1.Secret - beforeFunc func(obj *sourcev1.GitRepository) - wantProviderOptsName string - wantErr error + name string + url string + secret *corev1.Secret + beforeFunc func(obj *sourcev1.GitRepository) + wantErr string }{ { name: "azure provider", @@ -800,7 +799,7 @@ func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { beforeFunc: func(obj *sourcev1.GitRepository) { obj.Spec.Provider = sourcev1.GitProviderAzure }, - wantProviderOptsName: sourcev1.GitProviderAzure, + wantErr: "ManagedIdentityCredential", }, { name: "github provider with no secret ref", @@ -808,8 +807,7 @@ func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { beforeFunc: func(obj *sourcev1.GitRepository) { obj.Spec.Provider = sourcev1.GitProviderGitHub }, - wantProviderOptsName: sourcev1.GitProviderGitHub, - wantErr: errors.New("secretRef with github app data must be specified when provider is set to github"), + wantErr: "secretRef with github app data must be specified when provider is set to github", }, { name: "github provider with github app data in secret", @@ -830,7 +828,7 @@ func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { Name: "githubAppSecret", } }, - wantProviderOptsName: sourcev1.GitProviderGitHub, + wantErr: "Key must be a PEM encoded PKCS1 or PKCS8 key", }, { name: "generic provider with github app data in secret", @@ -849,7 +847,7 @@ func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { Name: "githubAppSecret", } }, - wantErr: errors.New("secretRef '/githubAppSecret' has github app data but provider is not set to github"), + wantErr: "secretRef '/githubAppSecret' has github app data but provider is not set to github", }, { name: "generic provider", @@ -866,7 +864,7 @@ func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { Name: "authSecret", } }, - wantErr: errors.New("failed to get secret '/authSecret': secrets \"authSecret\" not found"), + wantErr: "failed to get secret '/authSecret': secrets \"authSecret\" not found", }, { url: "https://example.com/org/repo", @@ -899,20 +897,19 @@ func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) { if tt.beforeFunc != nil { tt.beforeFunc(obj) } - opts, err := r.getAuthOpts(context.TODO(), obj, *url, nil) + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + opts, err := r.getAuthOpts(ctx, obj, *url, nil) - if tt.wantErr != nil { + if tt.wantErr != "" { g.Expect(err).To(HaveOccurred()) - g.Expect(err.Error()).To(ContainSubstring(tt.wantErr.Error())) + g.Expect(err.Error()).To(ContainSubstring(tt.wantErr)) } else { g.Expect(err).ToNot(HaveOccurred()) g.Expect(opts).ToNot(BeNil()) - if tt.wantProviderOptsName != "" { - g.Expect(opts.ProviderOpts).ToNot(BeNil()) - g.Expect(opts.ProviderOpts.Name).To(Equal(tt.wantProviderOptsName)) - } else { - g.Expect(opts.ProviderOpts).To(BeNil()) - } + g.Expect(opts.BearerToken).To(BeEmpty()) + g.Expect(opts.Username).To(BeEmpty()) + g.Expect(opts.Password).To(BeEmpty()) } }) } diff --git a/internal/controller/ocirepository_controller.go b/internal/controller/ocirepository_controller.go index 577cf863..9bdbbfdf 100644 --- a/internal/controller/ocirepository_controller.go +++ b/internal/controller/ocirepository_controller.go @@ -369,6 +369,13 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != ociv1.GenericOCIProvider && ok { var opts []auth.Option if obj.Spec.ServiceAccountName != "" { + // Check object-level workload identity feature gate. + if !auth.IsObjectLevelWorkloadIdentityEnabled() { + const gate = auth.FeatureGateObjectLevelWorkloadIdentity + const msgFmt = "to use spec.serviceAccountName for provider authentication please enable the %s feature gate in the controller" + err := fmt.Errorf(msgFmt, gate) + return sreconcile.ResultEmpty, serror.NewStalling(err, meta.FeatureGateDisabledReason) + } serviceAccount := client.ObjectKey{ Name: obj.Spec.ServiceAccountName, Namespace: obj.GetNamespace(), diff --git a/internal/controller/ocirepository_controller_test.go b/internal/controller/ocirepository_controller_test.go index 93e34384..4fb6fca6 100644 --- a/internal/controller/ocirepository_controller_test.go +++ b/internal/controller/ocirepository_controller_test.go @@ -60,6 +60,7 @@ import ( kstatus "github.com/fluxcd/cli-utils/pkg/kstatus/status" "github.com/fluxcd/pkg/apis/meta" + "github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/oci" "github.com/fluxcd/pkg/runtime/conditions" @@ -2971,10 +2972,10 @@ func TestOCIRepository_getArtifactRef(t *testing.T) { } } -func TestOCIRepository_stalled(t *testing.T) { +func TestOCIRepository_invalidURL(t *testing.T) { g := NewWithT(t) - ns, err := testEnv.CreateNamespace(ctx, "ocirepository-stalled-test") + ns, err := testEnv.CreateNamespace(ctx, "ocirepository-invalid-url-test") g.Expect(err).ToNot(HaveOccurred()) defer func() { g.Expect(testEnv.Delete(ctx, ns)).To(Succeed()) }() @@ -3013,6 +3014,74 @@ func TestOCIRepository_stalled(t *testing.T) { g.Expect(stalledCondition.Reason).Should(Equal(sourcev1.URLInvalidReason)) } +func TestOCIRepository_objectLevelWorkloadIdentityFeatureGate(t *testing.T) { + g := NewWithT(t) + + ns, err := testEnv.CreateNamespace(ctx, "ocirepository-olwifg-test") + g.Expect(err).ToNot(HaveOccurred()) + defer func() { g.Expect(testEnv.Delete(ctx, ns)).To(Succeed()) }() + + err = testEnv.Create(ctx, &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns.Name, + Name: "test", + }, + }) + g.Expect(err).NotTo(HaveOccurred()) + + obj := &ociv1.OCIRepository{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "ocirepository-reconcile", + Namespace: ns.Name, + }, + Spec: ociv1.OCIRepositorySpec{ + URL: "oci://ghcr.io/stefanprodan/manifests/podinfo", + Interval: metav1.Duration{Duration: 60 * time.Minute}, + Provider: "aws", + ServiceAccountName: "test", + }, + } + + g.Expect(testEnv.Create(ctx, obj)).To(Succeed()) + + key := client.ObjectKey{Name: obj.Name, Namespace: obj.Namespace} + resultobj := &ociv1.OCIRepository{} + + g.Eventually(func() bool { + if err := testEnv.Get(ctx, key, resultobj); err != nil { + return false + } + return conditions.IsStalled(resultobj) + }).Should(BeTrue()) + + stalledCondition := conditions.Get(resultobj, meta.StalledCondition) + g.Expect(stalledCondition).ToNot(BeNil()) + g.Expect(stalledCondition.Reason).Should(Equal(meta.FeatureGateDisabledReason)) + g.Expect(stalledCondition.Message).Should(Equal("to use spec.serviceAccountName for provider authentication please enable the ObjectLevelWorkloadIdentity feature gate in the controller")) + + t.Setenv(auth.EnvVarEnableObjectLevelWorkloadIdentity, "true") + + g.Eventually(func() bool { + if err := testEnv.Get(ctx, key, resultobj); err != nil { + return false + } + resultobj.Annotations = map[string]string{ + meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339), + } + return testEnv.Update(ctx, resultobj) == nil + }).Should(BeTrue()) + + g.Expect(testEnv.Update(ctx, resultobj)).To(Succeed()) + g.Eventually(func() bool { + if err := testEnv.Get(ctx, key, resultobj); err != nil { + return false + } + logOCIRepoStatus(t, resultobj) + return !conditions.IsReady(resultobj) && + conditions.GetReason(resultobj, meta.ReadyCondition) == sourcev1.AuthenticationFailedReason + }).Should(BeTrue()) +} + func TestOCIRepository_reconcileStorage(t *testing.T) { tests := []struct { name string diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 89a51bea..e1f29f8f 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -43,6 +43,7 @@ import ( "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/yaml" "github.com/distribution/distribution/v3/configuration" dockerRegistry "github.com/distribution/distribution/v3/registry" @@ -452,3 +453,8 @@ func randStringRunes(n int) string { func int64p(i int64) *int64 { return &i } + +func logOCIRepoStatus(t *testing.T, obj *sourcev1beta2.OCIRepository) { + sts, _ := yaml.Marshal(obj.Status) + t.Log(string(sts)) +} diff --git a/internal/features/features.go b/internal/features/features.go index c2622ce3..edb9beb1 100644 --- a/internal/features/features.go +++ b/internal/features/features.go @@ -19,7 +19,10 @@ limitations under the License. // states. package features -import feathelper "github.com/fluxcd/pkg/runtime/features" +import ( + "github.com/fluxcd/pkg/auth" + feathelper "github.com/fluxcd/pkg/runtime/features" +) const ( // CacheSecretsAndConfigMaps controls whether secrets and configmaps should be cached. @@ -35,6 +38,10 @@ var features = map[string]bool{ CacheSecretsAndConfigMaps: false, } +func init() { + auth.SetFeatureGates(features) +} + // FeatureGates contains a list of all supported feature gates and // their default values. func FeatureGates() map[string]bool { diff --git a/main.go b/main.go index a8c0f518..e3feaf6c 100644 --- a/main.go +++ b/main.go @@ -39,6 +39,7 @@ import ( ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "github.com/fluxcd/pkg/auth" pkgcache "github.com/fluxcd/pkg/cache" "github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/runtime/client" @@ -178,6 +179,14 @@ func main() { os.Exit(1) } + switch enabled, err := features.Enabled(auth.FeatureGateObjectLevelWorkloadIdentity); { + case err != nil: + setupLog.Error(err, "unable to check feature gate "+auth.FeatureGateObjectLevelWorkloadIdentity) + os.Exit(1) + case enabled: + auth.EnableObjectLevelWorkloadIdentity() + } + if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil { setupLog.Error(err, "unable to set global jitter") os.Exit(1)