Merge pull request #1872 from cappyzawa/feat/default-service-account-flag
[RFC-0010] Add default-service-account for lockdown
This commit is contained in:
commit
e5189f6791
2
go.mod
2
go.mod
|
@ -28,7 +28,7 @@ require (
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.14
|
github.com/fluxcd/cli-utils v0.36.0-flux.14
|
||||||
github.com/fluxcd/pkg/apis/event v0.18.0
|
github.com/fluxcd/pkg/apis/event v0.18.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.18.0
|
github.com/fluxcd/pkg/apis/meta v1.18.0
|
||||||
github.com/fluxcd/pkg/auth v0.21.0
|
github.com/fluxcd/pkg/auth v0.27.0
|
||||||
github.com/fluxcd/pkg/cache v0.10.0
|
github.com/fluxcd/pkg/cache v0.10.0
|
||||||
github.com/fluxcd/pkg/git v0.35.0
|
github.com/fluxcd/pkg/git v0.35.0
|
||||||
github.com/fluxcd/pkg/git/gogit v0.38.0
|
github.com/fluxcd/pkg/git/gogit v0.38.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -378,8 +378,8 @@ github.com/fluxcd/pkg/apis/event v0.18.0 h1:PNbWk9gvX8gMIi6VsJapnuDO+giLEeY+6olL
|
||||||
github.com/fluxcd/pkg/apis/event v0.18.0/go.mod h1:7S/DGboLolfbZ6stO6dcDhG1SfkPWQ9foCULvbiYpiA=
|
github.com/fluxcd/pkg/apis/event v0.18.0/go.mod h1:7S/DGboLolfbZ6stO6dcDhG1SfkPWQ9foCULvbiYpiA=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.18.0 h1:ACHrMIjlcioE9GKS7NGk62KX4NshqNewr8sBwMcXABs=
|
github.com/fluxcd/pkg/apis/meta v1.18.0 h1:ACHrMIjlcioE9GKS7NGk62KX4NshqNewr8sBwMcXABs=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.18.0/go.mod h1:97l3hTwBpJbXBY+wetNbqrUsvES8B1jGioKcBUxmqd8=
|
github.com/fluxcd/pkg/apis/meta v1.18.0/go.mod h1:97l3hTwBpJbXBY+wetNbqrUsvES8B1jGioKcBUxmqd8=
|
||||||
github.com/fluxcd/pkg/auth v0.21.0 h1:ckAQqP12wuptXEkMY18SQKWEY09m9e6yI0mEMsDV15M=
|
github.com/fluxcd/pkg/auth v0.27.0 h1:DFsizUxt9ZDAc+z7+o7jcbtfaxRH55MRD/wdU4CXNCQ=
|
||||||
github.com/fluxcd/pkg/auth v0.21.0/go.mod h1:MXmpsXT97c874HCw5hnfqFUP7TsG8/Ss1vFrk8JccfM=
|
github.com/fluxcd/pkg/auth v0.27.0/go.mod h1:YEAHpBFuW5oLlH9ekuJaQdnJ2Q3A7Ny8kha3WY7QMnY=
|
||||||
github.com/fluxcd/pkg/cache v0.10.0 h1:M+OGDM4da1cnz7q+sZSBtkBJHpiJsLnKVmR9OdMWxEY=
|
github.com/fluxcd/pkg/cache v0.10.0 h1:M+OGDM4da1cnz7q+sZSBtkBJHpiJsLnKVmR9OdMWxEY=
|
||||||
github.com/fluxcd/pkg/cache v0.10.0/go.mod h1:pPXRzQUDQagsCniuOolqVhnAkbNgYOg8d2cTliPs7ME=
|
github.com/fluxcd/pkg/cache v0.10.0/go.mod h1:pPXRzQUDQagsCniuOolqVhnAkbNgYOg8d2cTliPs7ME=
|
||||||
github.com/fluxcd/pkg/git v0.35.0 h1:mAauhsdfxNW4yQdXviVlvcN/uCGGG0+6p5D1+HFZI9w=
|
github.com/fluxcd/pkg/git v0.35.0 h1:mAauhsdfxNW4yQdXviVlvcN/uCGGG0+6p5D1+HFZI9w=
|
||||||
|
|
|
@ -860,14 +860,13 @@ func (r *BucketReconciler) setupCredentials(ctx context.Context, obj *sourcev1.B
|
||||||
// createBucketProvider creates a provider-specific bucket client using the given credentials and configuration.
|
// createBucketProvider creates a provider-specific bucket client using the given credentials and configuration.
|
||||||
// It handles different bucket providers (AWS, GCP, Azure, generic) and returns the appropriate client.
|
// It handles different bucket providers (AWS, GCP, Azure, generic) and returns the appropriate client.
|
||||||
func (r *BucketReconciler) createBucketProvider(ctx context.Context, obj *sourcev1.Bucket, creds *bucketCredentials) (BucketProvider, error) {
|
func (r *BucketReconciler) createBucketProvider(ctx context.Context, obj *sourcev1.Bucket, creds *bucketCredentials) (BucketProvider, error) {
|
||||||
var authOpts []auth.Option
|
authOpts := []auth.Option{
|
||||||
|
auth.WithClient(r.Client),
|
||||||
|
auth.WithServiceAccountNamespace(obj.GetNamespace()),
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Spec.ServiceAccountName != "" {
|
if obj.Spec.ServiceAccountName != "" {
|
||||||
serviceAccount := client.ObjectKey{
|
authOpts = append(authOpts, auth.WithServiceAccountName(obj.Spec.ServiceAccountName))
|
||||||
Name: obj.Spec.ServiceAccountName,
|
|
||||||
Namespace: obj.GetNamespace(),
|
|
||||||
}
|
|
||||||
authOpts = append(authOpts, auth.WithServiceAccount(serviceAccount, r.Client))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.TokenCache != nil {
|
if r.TokenCache != nil {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import (
|
||||||
|
|
||||||
kstatus "github.com/fluxcd/cli-utils/pkg/kstatus/status"
|
kstatus "github.com/fluxcd/cli-utils/pkg/kstatus/status"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/auth"
|
||||||
"github.com/fluxcd/pkg/runtime/conditions"
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
conditionscheck "github.com/fluxcd/pkg/runtime/conditions/check"
|
conditionscheck "github.com/fluxcd/pkg/runtime/conditions/check"
|
||||||
"github.com/fluxcd/pkg/runtime/jitter"
|
"github.com/fluxcd/pkg/runtime/jitter"
|
||||||
|
@ -1390,11 +1391,10 @@ func TestBucketReconciler_reconcileSource_gcs(t *testing.T) {
|
||||||
patchOptions: getPatchOptions(bucketReadyCondition.Owned, "sc"),
|
patchOptions: getPatchOptions(bucketReadyCondition.Owned, "sc"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle ObjectLevelWorkloadIdentity feature gate environment variable
|
// Handle ObjectLevelWorkloadIdentity feature gate
|
||||||
if tt.disableObjectLevelWorkloadIdentity {
|
if !tt.disableObjectLevelWorkloadIdentity {
|
||||||
t.Setenv("ENABLE_OBJECT_LEVEL_WORKLOAD_IDENTITY", "false")
|
auth.EnableObjectLevelWorkloadIdentity()
|
||||||
} else if tt.serviceAccount != nil {
|
t.Cleanup(auth.DisableObjectLevelWorkloadIdentity)
|
||||||
t.Setenv("ENABLE_OBJECT_LEVEL_WORKLOAD_IDENTITY", "true")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
|
|
|
@ -661,7 +661,10 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1
|
||||||
switch provider := obj.GetProvider(); provider {
|
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.
|
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) {
|
getCreds = func() (*authutils.GitCredentials, error) {
|
||||||
var opts []auth.Option
|
opts := []auth.Option{
|
||||||
|
auth.WithClient(r.Client),
|
||||||
|
auth.WithServiceAccountNamespace(obj.GetNamespace()),
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Spec.ServiceAccountName != "" {
|
if obj.Spec.ServiceAccountName != "" {
|
||||||
// Check object-level workload identity feature gate.
|
// Check object-level workload identity feature gate.
|
||||||
|
@ -672,11 +675,8 @@ func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1
|
||||||
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, meta.FeatureGateDisabledReason, "%s", err)
|
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, meta.FeatureGateDisabledReason, "%s", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
serviceAccount := client.ObjectKey{
|
// Set ServiceAccountName only if explicitly specified
|
||||||
Name: obj.Spec.ServiceAccountName,
|
opts = append(opts, auth.WithServiceAccountName(obj.Spec.ServiceAccountName))
|
||||||
Namespace: obj.GetNamespace(),
|
|
||||||
}
|
|
||||||
opts = append(opts, auth.WithServiceAccount(serviceAccount, r.Client))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.TokenCache != nil {
|
if r.TokenCache != nil {
|
||||||
|
|
|
@ -373,7 +373,11 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != "" && obj.Spec.Provider != sourcev1.GenericOCIProvider && ok {
|
if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != "" && obj.Spec.Provider != sourcev1.GenericOCIProvider && ok {
|
||||||
var opts []auth.Option
|
opts := []auth.Option{
|
||||||
|
auth.WithClient(r.Client),
|
||||||
|
auth.WithServiceAccountNamespace(obj.GetNamespace()),
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Spec.ServiceAccountName != "" {
|
if obj.Spec.ServiceAccountName != "" {
|
||||||
// Check object-level workload identity feature gate.
|
// Check object-level workload identity feature gate.
|
||||||
if !auth.IsObjectLevelWorkloadIdentityEnabled() {
|
if !auth.IsObjectLevelWorkloadIdentityEnabled() {
|
||||||
|
@ -382,11 +386,8 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
err := fmt.Errorf(msgFmt, gate)
|
err := fmt.Errorf(msgFmt, gate)
|
||||||
return sreconcile.ResultEmpty, serror.NewStalling(err, meta.FeatureGateDisabledReason)
|
return sreconcile.ResultEmpty, serror.NewStalling(err, meta.FeatureGateDisabledReason)
|
||||||
}
|
}
|
||||||
serviceAccount := client.ObjectKey{
|
// Set ServiceAccountName only if explicitly specified
|
||||||
Name: obj.Spec.ServiceAccountName,
|
opts = append(opts, auth.WithServiceAccountName(obj.Spec.ServiceAccountName))
|
||||||
Namespace: obj.GetNamespace(),
|
|
||||||
}
|
|
||||||
opts = append(opts, auth.WithServiceAccount(serviceAccount, r.Client))
|
|
||||||
}
|
}
|
||||||
if r.TokenCache != nil {
|
if r.TokenCache != nil {
|
||||||
involvedObject := cache.InvolvedObject{
|
involvedObject := cache.InvolvedObject{
|
||||||
|
|
|
@ -3059,7 +3059,8 @@ func TestOCIRepository_objectLevelWorkloadIdentityFeatureGate(t *testing.T) {
|
||||||
g.Expect(stalledCondition.Reason).Should(Equal(meta.FeatureGateDisabledReason))
|
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"))
|
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")
|
auth.EnableObjectLevelWorkloadIdentity()
|
||||||
|
t.Cleanup(auth.DisableObjectLevelWorkloadIdentity)
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
if err := testEnv.Get(ctx, key, resultobj); err != nil {
|
if err := testEnv.Get(ctx, key, resultobj); err != nil {
|
||||||
|
|
12
main.go
12
main.go
|
@ -121,6 +121,7 @@ func main() {
|
||||||
artifactRetentionRecords int
|
artifactRetentionRecords int
|
||||||
artifactDigestAlgo string
|
artifactDigestAlgo string
|
||||||
tokenCacheOptions pkgcache.TokenFlags
|
tokenCacheOptions pkgcache.TokenFlags
|
||||||
|
defaultServiceAccount string
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.StringVar(&metricsAddr, "metrics-addr", envOrDefault("METRICS_ADDR", ":8080"),
|
flag.StringVar(&metricsAddr, "metrics-addr", envOrDefault("METRICS_ADDR", ":8080"),
|
||||||
|
@ -159,6 +160,8 @@ func main() {
|
||||||
"The maximum number of artifacts to be kept in storage after a garbage collection.")
|
"The maximum number of artifacts to be kept in storage after a garbage collection.")
|
||||||
flag.StringVar(&artifactDigestAlgo, "artifact-digest-algo", intdigest.Canonical.String(),
|
flag.StringVar(&artifactDigestAlgo, "artifact-digest-algo", intdigest.Canonical.String(),
|
||||||
"The algorithm to use to calculate the digest of artifacts.")
|
"The algorithm to use to calculate the digest of artifacts.")
|
||||||
|
flag.StringVar(&defaultServiceAccount, auth.ControllerFlagDefaultServiceAccount,
|
||||||
|
"", "Default service account to use for workload identity when not specified in resources.")
|
||||||
|
|
||||||
clientOptions.BindFlags(flag.CommandLine)
|
clientOptions.BindFlags(flag.CommandLine)
|
||||||
logOptions.BindFlags(flag.CommandLine)
|
logOptions.BindFlags(flag.CommandLine)
|
||||||
|
@ -173,6 +176,10 @@ func main() {
|
||||||
|
|
||||||
logger.SetLogger(logger.NewLogger(logOptions))
|
logger.SetLogger(logger.NewLogger(logOptions))
|
||||||
|
|
||||||
|
if defaultServiceAccount != "" {
|
||||||
|
auth.SetDefaultServiceAccount(defaultServiceAccount)
|
||||||
|
}
|
||||||
|
|
||||||
if err := featureGates.WithLogger(setupLog).SupportedFeatures(features.FeatureGates()); err != nil {
|
if err := featureGates.WithLogger(setupLog).SupportedFeatures(features.FeatureGates()); err != nil {
|
||||||
setupLog.Error(err, "unable to load feature gates")
|
setupLog.Error(err, "unable to load feature gates")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -186,6 +193,11 @@ func main() {
|
||||||
auth.EnableObjectLevelWorkloadIdentity()
|
auth.EnableObjectLevelWorkloadIdentity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if auth.InconsistentObjectLevelConfiguration() {
|
||||||
|
setupLog.Error(auth.ErrInconsistentObjectLevelConfiguration, "invalid configuration")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil {
|
if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil {
|
||||||
setupLog.Error(err, "unable to set global jitter")
|
setupLog.Error(err, "unable to set global jitter")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
Loading…
Reference in New Issue