Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dev-deploy: manifests

# Generate manifests e.g. CRD, RBAC etc.
manifests: controller-gen
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role paths="./..." output:crd:artifacts:config="config/crd/bases"
cd api; $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role paths="./..." output:crd:artifacts:config="../config/crd/bases"

# Generate API reference documentation
Expand Down
32 changes: 9 additions & 23 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: manager-role
rules:
- apiGroups:
- ""
resources:
- namespaces
- secrets
- serviceaccounts
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand All @@ -24,28 +12,25 @@ rules:
- create
- patch
- apiGroups:
- image.toolkit.fluxcd.io
- ""
resources:
- imagepolicies
- namespaces
- secrets
- serviceaccounts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- image.toolkit.fluxcd.io
- ""
resources:
- imagepolicies/status
- serviceaccounts/token
verbs:
- get
- patch
- update
- create
- apiGroups:
- image.toolkit.fluxcd.io
resources:
- imagepolicies
- imagerepositories
verbs:
- create
Expand All @@ -58,6 +43,7 @@ rules:
- apiGroups:
- image.toolkit.fluxcd.io
resources:
- imagepolicies/status
- imagerepositories/status
verbs:
- get
Expand Down
4 changes: 2 additions & 2 deletions docs/spec/v1beta2/imagerepositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ metadata:
namespace: default
spec:
interval: 5m0s
url: example.com
image: example.com
certSecretRef:
name: example-tls
---
Expand Down Expand Up @@ -252,7 +252,7 @@ metadata:
namespace: default
spec:
interval: 5m0s
url: example.com
image: example.com
proxySecretRef:
name: http-proxy
---
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ require (
github.com/fluxcd/pkg/apis/acl v0.7.0
github.com/fluxcd/pkg/apis/event v0.17.0
github.com/fluxcd/pkg/apis/meta v1.11.0
github.com/fluxcd/pkg/oci v0.47.0
github.com/fluxcd/pkg/auth v0.12.0
github.com/fluxcd/pkg/cache v0.9.0
github.com/fluxcd/pkg/runtime v0.59.0
github.com/fluxcd/pkg/version v0.7.0
github.com/google/go-containerregistry v0.20.3
Expand Down Expand Up @@ -132,7 +133,9 @@ require (
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.63.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
Expand Down
19 changes: 13 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRcc
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
Expand Down Expand Up @@ -161,8 +163,10 @@ github.com/fluxcd/pkg/apis/event v0.17.0 h1:foEINE++pCJlWVhWjYDXfkVmGKu8mQ4BDBlb
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/oci v0.47.0 h1:eQ7syqy91Xcfd7Sgf64v5n+dfRAju/OBiXuOhZsgQAg=
github.com/fluxcd/pkg/oci v0.47.0/go.mod h1:XBnI8+T6YFnIW4uEFojg7iIgHjKH7LXMpZARXJ9qmZk=
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/cache v0.9.0 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk=
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU=
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/version v0.7.0 h1:jZT5I6WFy1KlM40nHCSqlHmjC1VT1/DfmbAdOkIVVJc=
Expand All @@ -176,6 +180,8 @@ github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vt
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
Expand Down Expand Up @@ -357,13 +363,13 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
Expand Down Expand Up @@ -569,6 +575,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
1 change: 1 addition & 0 deletions internal/controller/imagepolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const imageRepoKey = ".spec.imageRepository"
// +kubebuilder:rbac:groups=image.toolkit.fluxcd.io,resources=imagerepositories,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
// +kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create

// ImagePolicyReconciler reconciles a ImagePolicy object
type ImagePolicyReconciler struct {
Expand Down
76 changes: 47 additions & 29 deletions internal/controller/imagerepository_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ import (

eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/oci"
"github.com/fluxcd/pkg/oci/auth/login"
"github.com/fluxcd/pkg/auth"
authutils "github.com/fluxcd/pkg/auth/utils"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/runtime/conditions"
helper "github.com/fluxcd/pkg/runtime/controller"
"github.com/fluxcd/pkg/runtime/patch"
Expand Down Expand Up @@ -111,11 +112,12 @@ type ImageRepositoryReconciler struct {
helper.Metrics

ControllerName string
TokenCache *cache.TokenCache
Database interface {
DatabaseWriter
DatabaseReader
}
DeprecatedLoginOpts login.ProviderOptions
DeprecatedLoginOpts []auth.Provider

patchOptions []patch.Option
}
Expand Down Expand Up @@ -350,7 +352,7 @@ func (r *ImageRepositoryReconciler) setAuthOptions(ctx context.Context, obj *ima
// Configure authentication strategy to access the registry.
var options []remote.Option
var authSecret corev1.Secret
var auth authn.Authenticator
var authenticator authn.Authenticator
var authErr error

if obj.Spec.SecretRef != nil {
Expand All @@ -360,37 +362,49 @@ func (r *ImageRepositoryReconciler) setAuthOptions(ctx context.Context, obj *ima
}, &authSecret); err != nil {
return nil, err
}
auth, authErr = secret.AuthFromSecret(authSecret, ref)
authenticator, authErr = secret.AuthFromSecret(authSecret, ref)
} else {
// Build login provider options and use it to attempt registry login.
opts := login.ProviderOptions{}
switch obj.GetProvider() {
case "aws":
opts.AwsAutoLogin = true
case "azure":
opts.AzureAutoLogin = true
case "gcp":
opts.GcpAutoLogin = true
default:
opts = r.DeprecatedLoginOpts
}
var managerOpts []login.Option
var opts []auth.Option
if proxyURL != nil {
managerOpts = append(managerOpts, login.WithProxyURL(proxyURL))
opts = append(opts, auth.WithProxyURL(*proxyURL))
}
switch provider := obj.GetProvider(); provider {
case "aws", "azure", "gcp":
// Support new features (service account and cache) only for non-deprecated code paths.
if obj.Spec.ServiceAccountName != "" {
serviceAccount := client.ObjectKey{
Name: obj.Spec.ServiceAccountName,
Namespace: obj.GetNamespace(),
}
opts = append(opts, auth.WithServiceAccount(serviceAccount, r.Client))
}
if r.TokenCache != nil {
involvedObject := cache.InvolvedObject{
Kind: imagev1.ImageRepositoryKind,
Name: obj.GetName(),
Namespace: obj.GetNamespace(),
Operation: cache.OperationReconcile,
}
opts = append(opts, auth.WithCache(*r.TokenCache, involvedObject))
}
authenticator, authErr = authutils.GetArtifactRegistryCredentials(ctx, provider, obj.Spec.Image, opts...)
default:
// Handle deprecated auto-login controller flags.
for _, provider := range r.DeprecatedLoginOpts {
if _, err := provider.ParseArtifactRepository(obj.Spec.Image); err == nil {
authenticator, authErr = authutils.GetArtifactRegistryCredentials(ctx,
provider.GetName(), obj.Spec.Image, opts...)
break
}
}
}
manager := login.NewManager(managerOpts...)
auth, authErr = manager.Login(ctx, obj.Spec.Image, ref, opts)
}
if authErr != nil {
// If it's not unconfigured provider error, abort reconciliation.
// Continue reconciliation if it's unconfigured providers for scanning
// public repositories.
if !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
return nil, authErr
}
return nil, authErr
}
if auth != nil {
options = append(options, remote.WithAuth(auth))
if authenticator != nil {
options = append(options, remote.WithAuth(authenticator))
}

// Load any provided certificate.
Expand Down Expand Up @@ -437,7 +451,7 @@ func (r *ImageRepositoryReconciler) setAuthOptions(ctx context.Context, obj *ima
options = append(options, remote.WithTransport(tr))
}

if obj.Spec.ServiceAccountName != "" {
if authenticator == nil && obj.Spec.ServiceAccountName != "" {
serviceAccount := corev1.ServiceAccount{}
// Lookup service account
if err := r.Get(ctx, types.NamespacedName{
Expand Down Expand Up @@ -619,6 +633,10 @@ func (r *ImageRepositoryReconciler) reconcileDelete(ctx context.Context, obj *im
// Remove our finalizer from the list.
controllerutil.RemoveFinalizer(obj, imagev1.ImageFinalizer)

// Cleanup caches.
r.TokenCache.DeleteEventsForObject(imagev1.ImageRepositoryKind,
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)

// Stop reconciliation as the object is being deleted.
return ctrl.Result{}, nil
}
Expand Down
54 changes: 43 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ import (
ctrlcache "sigs.k8s.io/controller-runtime/pkg/cache"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/config"
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

"github.com/fluxcd/pkg/oci/auth/login"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/auth/aws"
"github.com/fluxcd/pkg/auth/azure"
"github.com/fluxcd/pkg/auth/gcp"
pkgcache "github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/runtime/acl"
"github.com/fluxcd/pkg/runtime/client"
helper "github.com/fluxcd/pkg/runtime/controller"
Expand Down Expand Up @@ -70,6 +75,10 @@ func init() {
}

func main() {
const (
tokenCacheDefaultMaxSize = 100
)

var (
metricsAddr string
eventsAddr string
Expand All @@ -87,6 +96,7 @@ func main() {
aclOptions acl.Options
rateLimiterOptions helper.RateLimiterOptions
featureGates feathelper.FeatureGates
tokenCacheOptions pkgcache.TokenFlags
)

flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
Expand All @@ -108,6 +118,7 @@ func main() {
rateLimiterOptions.BindFlags(flag.CommandLine)
featureGates.BindFlags(flag.CommandLine)
watchOptions.BindFlags(flag.CommandLine)
tokenCacheOptions.BindFlags(flag.CommandLine, tokenCacheDefaultMaxSize)

flag.Parse()

Expand Down Expand Up @@ -215,17 +226,38 @@ func main() {

metricsH := helper.NewMetrics(mgr, metrics.MustMakeRecorder(), imagev1.ImageFinalizer)

var tokenCache *pkgcache.TokenCache
if tokenCacheOptions.MaxSize > 0 {
var err error
tokenCache, err = pkgcache.NewTokenCache(tokenCacheOptions.MaxSize,
pkgcache.WithMaxDuration(tokenCacheOptions.MaxDuration),
pkgcache.WithMetricsRegisterer(ctrlmetrics.Registry),
pkgcache.WithMetricsPrefix("gotk_token_"))
if err != nil {
setupLog.Error(err, "unable to create token cache")
os.Exit(1)
}
}

var deprecatedLoginOpts []auth.Provider
if awsAutoLogin {
deprecatedLoginOpts = append(deprecatedLoginOpts, aws.Provider{})
}
if azureAutoLogin {
deprecatedLoginOpts = append(deprecatedLoginOpts, azure.Provider{})
}
if gcpAutoLogin {
deprecatedLoginOpts = append(deprecatedLoginOpts, gcp.Provider{})
}

if err := (&controller.ImageRepositoryReconciler{
Client: mgr.GetClient(),
EventRecorder: eventRecorder,
Metrics: metricsH,
Database: db,
ControllerName: controllerName,
DeprecatedLoginOpts: login.ProviderOptions{
AwsAutoLogin: awsAutoLogin,
AzureAutoLogin: azureAutoLogin,
GcpAutoLogin: gcpAutoLogin,
},
Client: mgr.GetClient(),
EventRecorder: eventRecorder,
Metrics: metricsH,
Database: db,
ControllerName: controllerName,
TokenCache: tokenCache,
DeprecatedLoginOpts: deprecatedLoginOpts,
}).SetupWithManager(mgr, controller.ImageRepositoryReconcilerOptions{
RateLimiter: helper.GetRateLimiter(rateLimiterOptions),
}); err != nil {
Expand Down
Loading