Merge pull request #1790 from fluxcd/rfc-0010-oci
[RFC-0010] Introduce object-level workload identity for OCIRepository
This commit is contained in:
commit
e2538552af
|
@ -19,6 +19,12 @@ rules:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
- watch
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- serviceaccounts/token
|
||||||
|
verbs:
|
||||||
|
- create
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- source.toolkit.fluxcd.io
|
- source.toolkit.fluxcd.io
|
||||||
resources:
|
resources:
|
||||||
|
|
8
go.mod
8
go.mod
|
@ -24,15 +24,15 @@ require (
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13
|
github.com/fluxcd/cli-utils v0.36.0-flux.13
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0
|
github.com/fluxcd/pkg/apis/event v0.17.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.11.0
|
github.com/fluxcd/pkg/apis/meta v1.11.0
|
||||||
github.com/fluxcd/pkg/auth v0.11.0
|
github.com/fluxcd/pkg/auth v0.12.0
|
||||||
github.com/fluxcd/pkg/cache v0.9.0
|
github.com/fluxcd/pkg/cache v0.9.0
|
||||||
github.com/fluxcd/pkg/git v0.28.0
|
github.com/fluxcd/pkg/git v0.29.0
|
||||||
github.com/fluxcd/pkg/git/gogit v0.30.0
|
github.com/fluxcd/pkg/git/gogit v0.31.0
|
||||||
github.com/fluxcd/pkg/gittestserver v0.17.0
|
github.com/fluxcd/pkg/gittestserver v0.17.0
|
||||||
github.com/fluxcd/pkg/helmtestserver v0.24.0
|
github.com/fluxcd/pkg/helmtestserver v0.24.0
|
||||||
github.com/fluxcd/pkg/lockedfile v0.6.0
|
github.com/fluxcd/pkg/lockedfile v0.6.0
|
||||||
github.com/fluxcd/pkg/masktoken v0.7.0
|
github.com/fluxcd/pkg/masktoken v0.7.0
|
||||||
github.com/fluxcd/pkg/oci v0.47.0
|
github.com/fluxcd/pkg/oci v0.48.0
|
||||||
github.com/fluxcd/pkg/runtime v0.59.0
|
github.com/fluxcd/pkg/runtime v0.59.0
|
||||||
github.com/fluxcd/pkg/sourceignore v0.12.0
|
github.com/fluxcd/pkg/sourceignore v0.12.0
|
||||||
github.com/fluxcd/pkg/ssh v0.18.0
|
github.com/fluxcd/pkg/ssh v0.18.0
|
||||||
|
|
16
go.sum
16
go.sum
|
@ -374,14 +374,14 @@ 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/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 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.11.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
|
||||||
github.com/fluxcd/pkg/auth v0.11.0 h1:1BC6fQ71lCLFKz7juGlvWq9ysR2HVl5JPOWoxy4RMWE=
|
github.com/fluxcd/pkg/auth v0.12.0 h1:35o0ziYMLZVgJwNvJBGsv/wd903B2fMagcrnm1ptUjc=
|
||||||
github.com/fluxcd/pkg/auth v0.11.0/go.mod h1:BJVrbanLH0AoUBzOH7u016D21Zl3dvEd0AnAWVOo5Vs=
|
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 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk=
|
||||||
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU=
|
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU=
|
||||||
github.com/fluxcd/pkg/git v0.28.0 h1:by7XTOvj4ZUPH1alYMJtDCVryhHue+UfjhrnPuJt5vA=
|
github.com/fluxcd/pkg/git v0.29.0 h1:MHQ4F53e6Xt8a/POkd/fiChgysnd/XqiuK7vOWXAXLk=
|
||||||
github.com/fluxcd/pkg/git v0.28.0/go.mod h1:VPv6O3mYnYvn79LOdWAFCl4fE8o651cxW/p/yxBoq2g=
|
github.com/fluxcd/pkg/git v0.29.0/go.mod h1:Ygn+LfrK6Ok+85uiq6s3NWG5LcHS4KY7mzES2JDJsGY=
|
||||||
github.com/fluxcd/pkg/git/gogit v0.30.0 h1:tdKRT4EDV8Cc2tBX+bg4H4gdcND7M4OEl6DQy1jSJmo=
|
github.com/fluxcd/pkg/git/gogit v0.31.0 h1:A56cmtgJBkWAj+gXSOdhPMQVTx0VF91S0PUaqpMXN4g=
|
||||||
github.com/fluxcd/pkg/git/gogit v0.30.0/go.mod h1:UCm/fOBuvX43BNz7Rc61Sukp2gBG/qxlOASaBkwMFvc=
|
github.com/fluxcd/pkg/git/gogit v0.31.0/go.mod h1:ya8z22xTvAAdW12HycxKYv4S+G+lqu5Kx/LyO/jWz8Y=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.17.0 h1:JlBvWZQTDOI+np5Z+084m3DkeAH1hMusEybyRUDF63k=
|
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/gittestserver v0.17.0/go.mod h1:E/40EmLoXcMqd6gLuLDC9F6KJxqHVGbBBeMNKk5XdxU=
|
||||||
github.com/fluxcd/pkg/helmtestserver v0.24.0 h1:9sSfRG17GnDIup4sI8V+fdvKROtunU4JyIo34uvXq3Q=
|
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/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 h1:pitmyOg2pUVdW+nn2Lk/xqm2TaA08uxvOC0ns3sz6bM=
|
||||||
github.com/fluxcd/pkg/masktoken v0.7.0/go.mod h1:Lc1uoDjO1GY6+YdkK+ZqqBIBWquyV58nlSJ5S1N1IYU=
|
github.com/fluxcd/pkg/masktoken v0.7.0/go.mod h1:Lc1uoDjO1GY6+YdkK+ZqqBIBWquyV58nlSJ5S1N1IYU=
|
||||||
github.com/fluxcd/pkg/oci v0.47.0 h1:eQ7syqy91Xcfd7Sgf64v5n+dfRAju/OBiXuOhZsgQAg=
|
github.com/fluxcd/pkg/oci v0.48.0 h1:iSK4JDM0nx9plSlOGx2aI4td6aQdV/awrfXK/bzI35I=
|
||||||
github.com/fluxcd/pkg/oci v0.47.0/go.mod h1:XBnI8+T6YFnIW4uEFojg7iIgHjKH7LXMpZARXJ9qmZk=
|
github.com/fluxcd/pkg/oci v0.48.0/go.mod h1:rnUC8EOpzQp4rugpmopYFMnG3+CR1wqEV3356gHUtSY=
|
||||||
github.com/fluxcd/pkg/runtime v0.59.0 h1:3OrFkMJB39NcQ2vhhoxqls59sQVSn8U+thhyLbsQoA4=
|
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/runtime v0.59.0/go.mod h1:MFbfyNyyoYRgPxpdwC9/dCOkzo7Yxhu/cQ9NKyhvqc0=
|
||||||
github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw=
|
github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw=
|
||||||
|
|
|
@ -132,19 +132,17 @@ type GitRepositoryReconciler struct {
|
||||||
|
|
||||||
Storage *Storage
|
Storage *Storage
|
||||||
ControllerName string
|
ControllerName string
|
||||||
|
TokenCache *cache.TokenCache
|
||||||
|
|
||||||
requeueDependency time.Duration
|
requeueDependency time.Duration
|
||||||
features map[string]bool
|
features map[string]bool
|
||||||
|
|
||||||
patchOptions []patch.Option
|
patchOptions []patch.Option
|
||||||
|
|
||||||
tokenCache *cache.TokenCache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GitRepositoryReconcilerOptions struct {
|
type GitRepositoryReconcilerOptions struct {
|
||||||
DependencyRequeueInterval time.Duration
|
DependencyRequeueInterval time.Duration
|
||||||
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
|
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
|
||||||
TokenCache *cache.TokenCache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// gitRepositoryReconcileFunc is the function type for all the
|
// gitRepositoryReconcileFunc is the function type for all the
|
||||||
|
@ -164,8 +162,6 @@ func (r *GitRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, o
|
||||||
r.features = features.FeatureGates()
|
r.features = features.FeatureGates()
|
||||||
}
|
}
|
||||||
|
|
||||||
r.tokenCache = opts.TokenCache
|
|
||||||
|
|
||||||
return ctrl.NewControllerManagedBy(mgr).
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
For(&sourcev1.GitRepository{}, builder.WithPredicates(
|
For(&sourcev1.GitRepository{}, builder.WithPredicates(
|
||||||
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
|
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
|
||||||
|
@ -689,14 +685,14 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1
|
||||||
|
|
||||||
var authOpts []auth.Option
|
var authOpts []auth.Option
|
||||||
|
|
||||||
if r.tokenCache != nil {
|
if r.TokenCache != nil {
|
||||||
involvedObject := cache.InvolvedObject{
|
involvedObject := cache.InvolvedObject{
|
||||||
Kind: sourcev1.GitRepositoryKind,
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
Name: obj.GetName(),
|
Name: obj.GetName(),
|
||||||
Namespace: obj.GetNamespace(),
|
Namespace: obj.GetNamespace(),
|
||||||
Operation: cache.OperationReconcile,
|
Operation: cache.OperationReconcile,
|
||||||
}
|
}
|
||||||
authOpts = append(authOpts, auth.WithCache(*r.tokenCache, involvedObject))
|
authOpts = append(authOpts, auth.WithCache(*r.TokenCache, involvedObject))
|
||||||
}
|
}
|
||||||
|
|
||||||
if proxyURL != nil {
|
if proxyURL != nil {
|
||||||
|
@ -726,7 +722,7 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1
|
||||||
GitHubOpts: []github.OptFunc{
|
GitHubOpts: []github.OptFunc{
|
||||||
github.WithAppData(authData),
|
github.WithAppData(authData),
|
||||||
github.WithProxyURL(proxyURL),
|
github.WithProxyURL(proxyURL),
|
||||||
github.WithCache(r.tokenCache, sourcev1.GitRepositoryKind,
|
github.WithCache(r.TokenCache, sourcev1.GitRepositoryKind,
|
||||||
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile),
|
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1146,7 @@ func (r *GitRepositoryReconciler) reconcileDelete(ctx context.Context, obj *sour
|
||||||
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
|
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
|
||||||
|
|
||||||
// Cleanup caches.
|
// Cleanup caches.
|
||||||
r.tokenCache.DeleteEventsForObject(sourcev1.GitRepositoryKind,
|
r.TokenCache.DeleteEventsForObject(sourcev1.GitRepositoryKind,
|
||||||
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)
|
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)
|
||||||
|
|
||||||
// Stop reconciliation as the object is being deleted
|
// Stop reconciliation as the object is being deleted
|
||||||
|
|
|
@ -70,7 +70,6 @@ import (
|
||||||
"github.com/fluxcd/source-controller/internal/helm/chart"
|
"github.com/fluxcd/source-controller/internal/helm/chart"
|
||||||
"github.com/fluxcd/source-controller/internal/helm/getter"
|
"github.com/fluxcd/source-controller/internal/helm/getter"
|
||||||
"github.com/fluxcd/source-controller/internal/helm/repository"
|
"github.com/fluxcd/source-controller/internal/helm/repository"
|
||||||
"github.com/fluxcd/source-controller/internal/oci"
|
|
||||||
soci "github.com/fluxcd/source-controller/internal/oci"
|
soci "github.com/fluxcd/source-controller/internal/oci"
|
||||||
scosign "github.com/fluxcd/source-controller/internal/oci/cosign"
|
scosign "github.com/fluxcd/source-controller/internal/oci/cosign"
|
||||||
"github.com/fluxcd/source-controller/internal/oci/notation"
|
"github.com/fluxcd/source-controller/internal/oci/notation"
|
||||||
|
@ -1255,7 +1254,7 @@ func observeChartBuild(ctx context.Context, sp *patch.SerialPatcher, pOpts []pat
|
||||||
if build.Complete() {
|
if build.Complete() {
|
||||||
conditions.Delete(obj, sourcev1.FetchFailedCondition)
|
conditions.Delete(obj, sourcev1.FetchFailedCondition)
|
||||||
conditions.Delete(obj, sourcev1.BuildFailedCondition)
|
conditions.Delete(obj, sourcev1.BuildFailedCondition)
|
||||||
if build.VerifiedResult == oci.VerificationResultSuccess {
|
if build.VerifiedResult == soci.VerificationResultSuccess {
|
||||||
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of version %s", build.Version)
|
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of version %s", build.Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ import (
|
||||||
|
|
||||||
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
|
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/auth"
|
||||||
|
"github.com/fluxcd/pkg/cache"
|
||||||
"github.com/fluxcd/pkg/oci"
|
"github.com/fluxcd/pkg/oci"
|
||||||
"github.com/fluxcd/pkg/runtime/conditions"
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
helper "github.com/fluxcd/pkg/runtime/controller"
|
helper "github.com/fluxcd/pkg/runtime/controller"
|
||||||
|
@ -141,6 +143,7 @@ type OCIRepositoryReconciler struct {
|
||||||
|
|
||||||
Storage *Storage
|
Storage *Storage
|
||||||
ControllerName string
|
ControllerName string
|
||||||
|
TokenCache *cache.TokenCache
|
||||||
requeueDependency time.Duration
|
requeueDependency time.Duration
|
||||||
|
|
||||||
patchOptions []patch.Option
|
patchOptions []patch.Option
|
||||||
|
@ -175,6 +178,7 @@ func (r *OCIRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, o
|
||||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=ocirepositories/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=ocirepositories/status,verbs=get;update;patch
|
||||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=ocirepositories/finalizers,verbs=get;create;update;patch;delete
|
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=ocirepositories/finalizers,verbs=get;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
|
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
|
||||||
|
// +kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create
|
||||||
|
|
||||||
func (r *OCIRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
|
func (r *OCIRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
@ -328,7 +332,7 @@ func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seria
|
||||||
// If this fails, it records v1beta2.FetchFailedCondition=True on the object and returns early.
|
// If this fails, it records v1beta2.FetchFailedCondition=True on the object and returns early.
|
||||||
func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher,
|
func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher,
|
||||||
obj *ociv1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
|
obj *ociv1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
|
||||||
var auth authn.Authenticator
|
var authenticator authn.Authenticator
|
||||||
|
|
||||||
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
|
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -363,9 +367,29 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != ociv1.GenericOCIProvider && ok {
|
if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != ociv1.GenericOCIProvider && ok {
|
||||||
|
var opts []auth.Option
|
||||||
|
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: ociv1.OCIRepositoryKind,
|
||||||
|
Name: obj.GetName(),
|
||||||
|
Namespace: obj.GetNamespace(),
|
||||||
|
Operation: cache.OperationReconcile,
|
||||||
|
}
|
||||||
|
opts = append(opts, auth.WithCache(*r.TokenCache, involvedObject))
|
||||||
|
}
|
||||||
|
if proxyURL != nil {
|
||||||
|
opts = append(opts, auth.WithProxyURL(*proxyURL))
|
||||||
|
}
|
||||||
var authErr error
|
var authErr error
|
||||||
auth, authErr = soci.OIDCAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider, proxyURL)
|
authenticator, authErr = soci.OIDCAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider, opts...)
|
||||||
if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
|
if authErr != nil {
|
||||||
e := serror.NewGeneric(
|
e := serror.NewGeneric(
|
||||||
fmt.Errorf("failed to get credential from %s: %w", obj.Spec.Provider, authErr),
|
fmt.Errorf("failed to get credential from %s: %w", obj.Spec.Provider, authErr),
|
||||||
sourcev1.AuthenticationFailedReason,
|
sourcev1.AuthenticationFailedReason,
|
||||||
|
@ -386,7 +410,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
return sreconcile.ResultEmpty, e
|
return sreconcile.ResultEmpty, e
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := makeRemoteOptions(ctx, transport, keychain, auth)
|
opts := makeRemoteOptions(ctx, transport, keychain, authenticator)
|
||||||
|
|
||||||
// Determine which artifact revision to pull
|
// Determine which artifact revision to pull
|
||||||
ref, err := r.getArtifactRef(obj, opts)
|
ref, err := r.getArtifactRef(obj, opts)
|
||||||
|
@ -446,7 +470,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
conditions.GetObservedGeneration(obj, sourcev1.SourceVerifiedCondition) != obj.Generation ||
|
conditions.GetObservedGeneration(obj, sourcev1.SourceVerifiedCondition) != obj.Generation ||
|
||||||
conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) {
|
conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) {
|
||||||
|
|
||||||
result, err := r.verifySignature(ctx, obj, ref, keychain, auth, transport, opts...)
|
result, err := r.verifySignature(ctx, obj, ref, keychain, authenticator, transport, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
provider := obj.Spec.Verify.Provider
|
provider := obj.Spec.Verify.Provider
|
||||||
if obj.Spec.Verify.SecretRef == nil && obj.Spec.Verify.Provider == "cosign" {
|
if obj.Spec.Verify.SecretRef == nil && obj.Spec.Verify.Provider == "cosign" {
|
||||||
|
@ -1225,6 +1249,10 @@ func (r *OCIRepositoryReconciler) reconcileDelete(ctx context.Context, obj *ociv
|
||||||
// Remove our finalizer from the list
|
// Remove our finalizer from the list
|
||||||
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
|
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
|
||||||
|
|
||||||
|
// Cleanup caches.
|
||||||
|
r.TokenCache.DeleteEventsForObject(ociv1.OCIRepositoryKind,
|
||||||
|
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)
|
||||||
|
|
||||||
// Stop reconciliation as the object is being deleted
|
// Stop reconciliation as the object is being deleted
|
||||||
return sreconcile.ResultEmpty, nil
|
return sreconcile.ResultEmpty, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -872,9 +872,9 @@ func TestOCIRepository_CertSecret(t *testing.T) {
|
||||||
|
|
||||||
tlsSecretClientCert := corev1.Secret{
|
tlsSecretClientCert := corev1.Secret{
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
oci.CACert: tlsCA,
|
"caFile": tlsCA,
|
||||||
oci.ClientCert: clientPublicKey,
|
"certFile": clientPublicKey,
|
||||||
oci.ClientKey: clientPrivateKey,
|
"keyFile": clientPrivateKey,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,9 +907,9 @@ func TestOCIRepository_CertSecret(t *testing.T) {
|
||||||
digest: pi.digest,
|
digest: pi.digest,
|
||||||
certSecret: &corev1.Secret{
|
certSecret: &corev1.Secret{
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
oci.CACert: tlsCA,
|
"caFile": tlsCA,
|
||||||
oci.ClientCert: clientPublicKey,
|
"certFile": clientPublicKey,
|
||||||
oci.ClientKey: []byte("invalid-key"),
|
"keyFile": []byte("invalid-key"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectreadyconition: false,
|
expectreadyconition: false,
|
||||||
|
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/oci"
|
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
"github.com/google/go-containerregistry/pkg/authn"
|
||||||
helmgetter "helm.sh/helm/v3/pkg/getter"
|
helmgetter "helm.sh/helm/v3/pkg/getter"
|
||||||
helmreg "helm.sh/helm/v3/pkg/registry"
|
helmreg "helm.sh/helm/v3/pkg/registry"
|
||||||
|
@ -137,8 +136,8 @@ func GetClientOpts(ctx context.Context, c client.Client, obj *sourcev1.HelmRepos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if obj.Spec.Provider != sourcev1beta2.GenericOCIProvider && obj.Spec.Type == sourcev1.HelmRepositoryTypeOCI && ociRepo {
|
} else if obj.Spec.Provider != sourcev1beta2.GenericOCIProvider && obj.Spec.Type == sourcev1.HelmRepositoryTypeOCI && ociRepo {
|
||||||
authenticator, authErr := soci.OIDCAuth(ctx, obj.Spec.URL, obj.Spec.Provider, nil)
|
authenticator, authErr := soci.OIDCAuth(ctx, obj.Spec.URL, obj.Spec.Provider)
|
||||||
if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
|
if authErr != nil {
|
||||||
return nil, "", fmt.Errorf("failed to get credential from '%s': %w", obj.Spec.Provider, authErr)
|
return nil, "", fmt.Errorf("failed to get credential from '%s': %w", obj.Spec.Provider, authErr)
|
||||||
}
|
}
|
||||||
if authenticator != nil {
|
if authenticator != nil {
|
||||||
|
|
|
@ -18,13 +18,12 @@ package oci
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/oci/auth/login"
|
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
"github.com/google/go-containerregistry/pkg/authn"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
|
||||||
|
"github.com/fluxcd/pkg/auth"
|
||||||
|
authutils "github.com/fluxcd/pkg/auth/utils"
|
||||||
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
|
||||||
)
|
)
|
||||||
|
@ -41,22 +40,7 @@ func (a Anonymous) Resolve(_ authn.Resource) (authn.Authenticator, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OIDCAuth generates the OIDC credential authenticator based on the specified cloud provider.
|
// OIDCAuth generates the OIDC credential authenticator based on the specified cloud provider.
|
||||||
func OIDCAuth(ctx context.Context, url, provider string, proxyURL *url.URL) (authn.Authenticator, error) {
|
func OIDCAuth(ctx context.Context, url, provider string, opts ...auth.Option) (authn.Authenticator, error) {
|
||||||
u := strings.TrimPrefix(url, sourcev1.OCIRepositoryPrefix)
|
u := strings.TrimPrefix(url, sourcev1.OCIRepositoryPrefix)
|
||||||
ref, err := name.ParseReference(u)
|
return authutils.GetArtifactRegistryCredentials(ctx, provider, u, opts...)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to parse URL '%s': %w", u, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := login.ProviderOptions{}
|
|
||||||
switch provider {
|
|
||||||
case sourcev1.AmazonOCIProvider:
|
|
||||||
opts.AwsAutoLogin = true
|
|
||||||
case sourcev1.AzureOCIProvider:
|
|
||||||
opts.AzureAutoLogin = true
|
|
||||||
case sourcev1.GoogleOCIProvider:
|
|
||||||
opts.GcpAutoLogin = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return login.NewManager(login.WithProxyURL(proxyURL)).Login(ctx, u, ref, opts)
|
|
||||||
}
|
}
|
||||||
|
|
3
main.go
3
main.go
|
@ -216,10 +216,10 @@ func main() {
|
||||||
Metrics: metrics,
|
Metrics: metrics,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
ControllerName: controllerName,
|
ControllerName: controllerName,
|
||||||
|
TokenCache: tokenCache,
|
||||||
}).SetupWithManagerAndOptions(mgr, controller.GitRepositoryReconcilerOptions{
|
}).SetupWithManagerAndOptions(mgr, controller.GitRepositoryReconcilerOptions{
|
||||||
DependencyRequeueInterval: requeueDependency,
|
DependencyRequeueInterval: requeueDependency,
|
||||||
RateLimiter: helper.GetRateLimiter(rateLimiterOptions),
|
RateLimiter: helper.GetRateLimiter(rateLimiterOptions),
|
||||||
TokenCache: tokenCache,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", v1.GitRepositoryKind)
|
setupLog.Error(err, "unable to create controller", "controller", v1.GitRepositoryKind)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -278,6 +278,7 @@ func main() {
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
EventRecorder: eventRecorder,
|
EventRecorder: eventRecorder,
|
||||||
ControllerName: controllerName,
|
ControllerName: controllerName,
|
||||||
|
TokenCache: tokenCache,
|
||||||
Metrics: metrics,
|
Metrics: metrics,
|
||||||
}).SetupWithManagerAndOptions(mgr, controller.OCIRepositoryReconcilerOptions{
|
}).SetupWithManagerAndOptions(mgr, controller.OCIRepositoryReconcilerOptions{
|
||||||
RateLimiter: helper.GetRateLimiter(rateLimiterOptions),
|
RateLimiter: helper.GetRateLimiter(rateLimiterOptions),
|
||||||
|
|
Loading…
Reference in New Issue