diff --git a/.golangci.yml b/.golangci.yml index 5151399..44bc5dc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,17 +1,33 @@ linters-settings: cyclop: max-complexity: 27 + depguard: + rules: + main: + list-mode: lax + allow: + - $gostd + - k8s.io/api + - k8s.io/apimachinery + - k8s.io/client-go + - github.com/projectcapsule + - github.com/go-logr/logr + - github.com/pkg/errors + - github.com/spf13/cobra + - sigs.k8s.io/controller-runtime + funlen: + lines: 110 gci: sections: - standard # Captures all standard packages if they do not match another section. - default # Contains all imports that could not be matched to another section type. - - prefix(github.com/projectcapsule/capsule-addon-fluxcd) # Groups all imports with the specified Prefix. + - prefix(github.com/projectcapsule/capsule-addon-flux) # Groups all imports with the specified Prefix. goconst: min-len: 2 min-occurrences: 3 goheader: template: |- - Copyright 2020-2023 Project Capsule Authors. + Copyright 2020-2024 Project Capsule Authors. SPDX-License-Identifier: Apache-2.0 govet: check-shadowing: true diff --git a/cmd/constants.go b/cmd/constants.go index 77e0064..f4c92e8 100644 --- a/cmd/constants.go +++ b/cmd/constants.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package cmd const ( diff --git a/cmd/manager/constants.go b/cmd/manager/constants.go index a25e436..e7d38d8 100644 --- a/cmd/manager/constants.go +++ b/cmd/manager/constants.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package manager const ( diff --git a/cmd/manager/manager.go b/cmd/manager/manager.go index b8f0a34..5d9b29f 100644 --- a/cmd/manager/manager.go +++ b/cmd/manager/manager.go @@ -1,8 +1,13 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package manager import ( "flag" "fmt" + "os" + "github.com/go-logr/logr" "github.com/pkg/errors" capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2" @@ -11,7 +16,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - "os" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" @@ -56,6 +60,7 @@ func New() *cobra.Command { // Add Zap options. var fs flag.FlagSet + opts.Zo.BindFlags(&fs) cmd.Flags().AddGoFlagSet(&fs) @@ -67,6 +72,7 @@ func (o *Options) Run(_ *cobra.Command, _ []string) error { if err := clientgoscheme.AddToScheme(scheme); err != nil { return errors.Wrap(err, "unable to add client-go types to the manager's scheme") } + if err := capsulev1beta2.AddToScheme(scheme); err != nil { return errors.Wrap(err, "unable to add Capsule types to the manager's scheme") } @@ -87,6 +93,7 @@ func (o *Options) Run(_ *cobra.Command, _ []string) error { }) if err != nil { o.SetupLog.Error(err, "unable to create manager") + return errors.Wrap(err, "unable to create manager") } @@ -102,6 +109,7 @@ func (o *Options) Run(_ *cobra.Command, _ []string) error { if err = indexer.AddToManager(ctx, o.SetupLog, mgr); err != nil { o.SetupLog.Error(err, "unable to setup indexers") + return errors.Wrap(err, "unable to setup indexers") } @@ -112,11 +120,13 @@ func (o *Options) Run(_ *cobra.Command, _ []string) error { serviceaccount.WithProxyURL(o.ProxyURL), ).SetupWithManager(ctx, mgr); err != nil { o.SetupLog.Error(err, "unable to create manager", "controller", "ServiceAccount") + return errors.Wrap(err, "unable to setup the service account controller") } if err = mgr.Start(ctx); err != nil { o.SetupLog.Error(err, "problem running manager") + return errors.Wrap(err, "unable to start the manager") } diff --git a/cmd/root.go b/cmd/root.go index 5e02045..30579b1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,8 +1,12 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package cmd import ( - "github.com/projectcapsule/capsule-addon-flux/cmd/manager" "github.com/spf13/cobra" + + "github.com/projectcapsule/capsule-addon-flux/cmd/manager" ) func New() *cobra.Command { @@ -17,5 +21,6 @@ func New() *cobra.Command { func Execute() error { cmd := New() + return cmd.Execute() } diff --git a/e2e/charts/serviceaccount_test.go b/e2e/charts/serviceaccount_test.go index ca520a9..c6acb37 100644 --- a/e2e/charts/serviceaccount_test.go +++ b/e2e/charts/serviceaccount_test.go @@ -1,5 +1,8 @@ //go:build e2e +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package charts import ( diff --git a/e2e/charts/suite_test.go b/e2e/charts/suite_test.go index dd9cbaa..868edf3 100644 --- a/e2e/charts/suite_test.go +++ b/e2e/charts/suite_test.go @@ -1,5 +1,8 @@ //go:build e2e +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package charts import ( diff --git a/e2e/serviceaccount_test.go b/e2e/serviceaccount_test.go index 803744f..3811040 100644 --- a/e2e/serviceaccount_test.go +++ b/e2e/serviceaccount_test.go @@ -1,5 +1,8 @@ //go:build e2e +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package e2e import ( diff --git a/e2e/suite_test.go b/e2e/suite_test.go index 47242a8..6900e72 100644 --- a/e2e/suite_test.go +++ b/e2e/suite_test.go @@ -1,5 +1,8 @@ //go:build e2e +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package e2e import ( diff --git a/e2e/utils/utils.go b/e2e/utils/utils.go index 2fed325..a89fcc3 100644 --- a/e2e/utils/utils.go +++ b/e2e/utils/utils.go @@ -1,5 +1,8 @@ //go:build e2e +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package utils import ( diff --git a/main.go b/main.go index 1bb0f09..347101f 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package main import ( @@ -9,6 +12,7 @@ import ( func main() { if err := cmd.Execute(); err != nil { + //nolint:forbidigo fmt.Println(err) os.Exit(1) } diff --git a/pkg/controller/serviceaccount/constants.go b/pkg/controller/serviceaccount/constants.go index 28bb188..fef117e 100644 --- a/pkg/controller/serviceaccount/constants.go +++ b/pkg/controller/serviceaccount/constants.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package serviceaccount const ( diff --git a/pkg/controller/serviceaccount/errors.go b/pkg/controller/serviceaccount/errors.go index f596a16..7a887f8 100644 --- a/pkg/controller/serviceaccount/errors.go +++ b/pkg/controller/serviceaccount/errors.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package serviceaccount import "github.com/pkg/errors" diff --git a/pkg/controller/serviceaccount/globaltenantresources.go b/pkg/controller/serviceaccount/globaltenantresources.go index cba4c91..5ce10bf 100644 --- a/pkg/controller/serviceaccount/globaltenantresources.go +++ b/pkg/controller/serviceaccount/globaltenantresources.go @@ -1,7 +1,11 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package serviceaccount import ( "context" + capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/controller/serviceaccount/rolebindings.go b/pkg/controller/serviceaccount/rolebindings.go index 3aee5c6..1050423 100644 --- a/pkg/controller/serviceaccount/rolebindings.go +++ b/pkg/controller/serviceaccount/rolebindings.go @@ -1,8 +1,12 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package serviceaccount import ( "context" "fmt" + rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" diff --git a/pkg/controller/serviceaccount/serviceaccount.go b/pkg/controller/serviceaccount/serviceaccount.go index 7212f7e..ea3e416 100644 --- a/pkg/controller/serviceaccount/serviceaccount.go +++ b/pkg/controller/serviceaccount/serviceaccount.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package serviceaccount import ( @@ -21,6 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) +//nolint:revive type ServiceAccountReconciler struct { proxyURL string proxyCA string @@ -83,6 +87,7 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, request ctrl.R return reconcile.Result{}, nil } + r.Log.Error(err, "Error reading the object") return ctrl.Result{}, err @@ -102,16 +107,15 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, request ctrl.R if err != nil { return reconcile.Result{}, errors.Wrap(err, "error getting token of the service account") } + if tokenSecret.Data == nil { r.Log.Info("ServiceAccount token data is missing. Requeueing.") + return reconcile.Result{Requeue: true}, nil } // Build the kubeConfig for the ServiceAccount Tenant Owner. - config, err := r.buildKubeconfig(r.proxyURL, string(tokenSecret.Data[corev1.ServiceAccountTokenKey])) - if err != nil { - return reconcile.Result{}, errors.Wrap(err, "error building the tenant owner config") - } + config := r.buildKubeconfig(r.proxyURL, string(tokenSecret.Data[corev1.ServiceAccountTokenKey])) configRaw, err := clientcmd.Write(*config) if err != nil { @@ -142,10 +146,12 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, request ctrl.R if sa.GetAnnotations()[ServiceAccountGlobalAnnotationKey] == ServiceAccountGlobalAnnotationValue { // Get the Tenant owned by the ServiceAccount. ownerName := fmt.Sprintf("system:serviceaccount:%s:%s", sa.GetNamespace(), sa.GetName()) + tenantList, err := r.listTenantsOwned(ctx, string(capsulev1beta2.ServiceAccountOwner), ownerName) if err != nil { return reconcile.Result{}, errors.Wrap(err, "error listing Tenants for owner") } + if tenantList.Items == nil { return reconcile.Result{}, errors.New("Tenant list for owner is empty") } @@ -176,6 +182,7 @@ func (r *ServiceAccountReconciler) forOption(ctx context.Context) builder.ForOpt predicate.NewPredicateFuncs(func(object client.Object) bool { ownerName := fmt.Sprintf("system:serviceaccount:%s:%s", object.GetNamespace(), object.GetName()) tntList, err := r.listTenantsOwned(ctx, string(capsulev1beta2.ServiceAccountOwner), ownerName) + return err == nil && tntList.Items != nil && len(tntList.Items) != 0 }), ), @@ -196,7 +203,7 @@ func (r *ServiceAccountReconciler) listTenantsOwned(ctx context.Context, ownerKi // buildKubeconfig returns a client-go/clientcmd/api.Config with a token and server URL specified as arguments. // The server set is be the proxy configured at ServiceAccountReconciler-level. -func (r *ServiceAccountReconciler) buildKubeconfig(server, token string) (*clientcmdapi.Config, error) { +func (r *ServiceAccountReconciler) buildKubeconfig(server, token string) *clientcmdapi.Config { // Build the client API Config. config := clientcmdapi.NewConfig() config.APIVersion = clientcmdlatest.Version @@ -228,5 +235,5 @@ func (r *ServiceAccountReconciler) buildKubeconfig(server, token string) (*clien config.Contexts = contexts config.CurrentContext = KubeconfigContextName - return config, nil + return config } diff --git a/pkg/controller/serviceaccount/tokens.go b/pkg/controller/serviceaccount/tokens.go index 4702d0d..c3d2099 100644 --- a/pkg/controller/serviceaccount/tokens.go +++ b/pkg/controller/serviceaccount/tokens.go @@ -1,10 +1,13 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package serviceaccount import ( "context" "fmt" - "github.com/pkg/errors" + "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -34,6 +37,7 @@ func (r *ServiceAccountReconciler) ensureSATokenSecret(ctx context.Context, name return nil } + return err } @@ -44,7 +48,6 @@ func (r *ServiceAccountReconciler) ensureSATokenSecret(ctx context.Context, name // are specified as arguments. func (r *ServiceAccountReconciler) getSATokenSecret(ctx context.Context, saName, saNamespace string) (*corev1.Secret, error) { saTokenList := new(corev1.SecretList) - // TODO: filter by Service Account-type and Namespace. Need index by Secret type. if err := r.Client.List(ctx, saTokenList); err != nil { return nil, ErrServiceAccountTokenNotFound } @@ -54,15 +57,16 @@ func (r *ServiceAccountReconciler) getSATokenSecret(ctx context.Context, saName, } var tokenSecret *corev1.Secret + for _, v := range saTokenList.Items { v := v - switch v.Type { - case corev1.SecretTypeServiceAccountToken: + if v.Type == corev1.SecretTypeServiceAccountToken { if v.Namespace == saNamespace && v.Annotations[corev1.ServiceAccountNameKey] == saName { return &v, nil } } } + if tokenSecret == nil { return nil, ErrServiceAccountTokenNotFound } diff --git a/pkg/indexer/indexer.go b/pkg/indexer/indexer.go index 133dc7c..3cd8184 100644 --- a/pkg/indexer/indexer.go +++ b/pkg/indexer/indexer.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 Project Capsule Authors. +// SPDX-License-Identifier: Apache-2.0 + package indexer import (