Merge pull request #1802 from fluxcd/rfc-0010-feature-gate
[RFC-0010] Introduce feature gate
This commit is contained in:
commit
0d9ed5936f
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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=
|
||||
|
|
10
go.mod
10
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
|
||||
|
|
20
go.sum
20
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=
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
9
main.go
9
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)
|
||||
|
|
Loading…
Reference in New Issue