2022-02-15 11:52:52 +00:00
/ *
Copyright © 2022 ESO Maintainer Team
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
2022-09-06 17:46:36 +00:00
http : //www.apache.org/licenses/LICENSE-2.0
2022-02-15 11:52:52 +00:00
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2024-02-12 15:44:45 +00:00
2022-02-15 11:52:52 +00:00
package cmd
import (
"os"
"time"
"github.com/spf13/cobra"
"go.uber.org/zap/zapcore"
2022-02-17 12:35:20 +00:00
v1 "k8s.io/api/core/v1"
2022-02-17 22:14:39 +00:00
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2022-02-15 11:52:52 +00:00
"k8s.io/apimachinery/pkg/runtime"
2024-11-28 08:28:21 +00:00
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2022-02-15 11:52:52 +00:00
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
2023-08-28 09:50:46 +00:00
"sigs.k8s.io/controller-runtime/pkg/cache"
2022-02-17 12:35:20 +00:00
"sigs.k8s.io/controller-runtime/pkg/client"
2022-02-15 11:52:52 +00:00
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
2023-08-28 09:50:46 +00:00
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"
2022-02-15 11:52:52 +00:00
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
2022-10-29 18:15:50 +00:00
genv1alpha1 "github.com/external-secrets/external-secrets/apis/generators/v1alpha1"
2022-03-20 08:32:27 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/clusterexternalsecret"
2023-05-22 20:43:23 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/clusterexternalsecret/cesmetrics"
2022-02-15 11:52:52 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/externalsecret"
2023-04-05 17:58:17 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/externalsecret/esmetrics"
2023-05-22 20:43:23 +00:00
ctrlmetrics "github.com/external-secrets/external-secrets/pkg/controllers/metrics"
2022-11-29 19:04:46 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/pushsecret"
2023-06-05 19:26:25 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/pushsecret/psmetrics"
2022-02-15 11:52:52 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore"
2023-06-05 19:26:25 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore/cssmetrics"
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore/ssmetrics"
2023-01-19 16:25:47 +00:00
"github.com/external-secrets/external-secrets/pkg/feature"
2024-04-25 09:36:11 +00:00
// To allow using gcp auth.
_ "k8s.io/client-go/plugin/pkg/client/auth"
2022-02-15 11:52:52 +00:00
)
var (
2022-03-24 13:29:03 +00:00
scheme = runtime . NewScheme ( )
setupLog = ctrl . Log . WithName ( "setup" )
dnsName string
certDir string
metricsAddr string
healthzAddr string
controllerClass string
enableLeaderElection bool
2022-07-23 22:56:02 +00:00
enableSecretsCache bool
enableConfigMapsCache bool
2024-11-24 21:53:53 +00:00
enableManagedSecretsCache bool
2024-06-16 10:52:10 +00:00
enablePartialCache bool
2022-03-24 13:29:03 +00:00
concurrent int
2022-04-07 11:54:01 +00:00
port int
2022-07-23 22:56:02 +00:00
clientQPS float32
clientBurst int
2022-03-24 13:29:03 +00:00
loglevel string
2022-12-13 20:01:07 +00:00
zapTimeEncoding string
2022-03-24 13:29:03 +00:00
namespace string
enableClusterStoreReconciler bool
enableClusterExternalSecretReconciler bool
2022-11-29 19:04:46 +00:00
enablePushSecretReconciler bool
2022-04-06 04:02:19 +00:00
enableFloodGate bool
2023-04-05 17:58:17 +00:00
enableExtendedMetricLabels bool
2022-03-24 13:29:03 +00:00
storeRequeueInterval time . Duration
serviceName , serviceNamespace string
secretName , secretNamespace string
2022-12-13 19:56:30 +00:00
crdNames [ ] string
2022-03-24 13:29:03 +00:00
crdRequeueInterval time . Duration
certCheckInterval time . Duration
2022-07-12 09:25:16 +00:00
certLookaheadInterval time . Duration
2022-08-31 16:18:45 +00:00
tlsCiphers string
tlsMinVersion string
2022-02-15 11:52:52 +00:00
)
const (
errCreateController = "unable to create controller"
)
func init ( ) {
2024-11-28 08:28:21 +00:00
// kubernetes schemes
utilruntime . Must ( clientgoscheme . AddToScheme ( scheme ) )
utilruntime . Must ( apiextensionsv1 . AddToScheme ( scheme ) )
// external-secrets schemes
utilruntime . Must ( esv1beta1 . AddToScheme ( scheme ) )
utilruntime . Must ( esv1alpha1 . AddToScheme ( scheme ) )
utilruntime . Must ( genv1alpha1 . AddToScheme ( scheme ) )
2022-02-15 11:52:52 +00:00
}
var rootCmd = & cobra . Command {
Use : "external-secrets" ,
Short : "operator that reconciles ExternalSecrets and SecretStores" ,
Long : ` For more information visit https://external-secrets.io ` ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
var lvl zapcore . Level
2022-12-13 20:01:07 +00:00
var enc zapcore . TimeEncoder
lvlErr := lvl . UnmarshalText ( [ ] byte ( loglevel ) )
if lvlErr != nil {
setupLog . Error ( lvlErr , "error unmarshalling loglevel" )
os . Exit ( 1 )
}
encErr := enc . UnmarshalText ( [ ] byte ( zapTimeEncoding ) )
if encErr != nil {
setupLog . Error ( encErr , "error unmarshalling timeEncoding" )
2022-02-15 11:52:52 +00:00
os . Exit ( 1 )
}
2022-12-13 20:01:07 +00:00
opts := zap . Options {
Level : lvl ,
TimeEncoder : enc ,
}
logger := zap . New ( zap . UseFlagOptions ( & opts ) )
2022-02-15 11:52:52 +00:00
ctrl . SetLogger ( logger )
2023-05-22 20:43:23 +00:00
ctrlmetrics . SetUpLabelNames ( enableExtendedMetricLabels )
esmetrics . SetUpMetrics ( )
2022-07-23 22:56:02 +00:00
config := ctrl . GetConfigOrDie ( )
config . QPS = clientQPS
config . Burst = clientBurst
2024-11-24 21:53:53 +00:00
// the client creates a ListWatch for resources that are requested with .Get() or .List()
// some users might want to completely disable caching of Secrets and ConfigMaps
// to decrease memory usage at the expense of high Kubernetes API usage
// see: https://github.com/external-secrets/external-secrets/issues/721
clientCacheDisableFor := make ( [ ] client . Object , 0 )
if ! enableSecretsCache {
// dont cache any secrets
clientCacheDisableFor = append ( clientCacheDisableFor , & v1 . Secret { } )
}
if ! enableConfigMapsCache {
// dont cache any configmaps
clientCacheDisableFor = append ( clientCacheDisableFor , & v1 . ConfigMap { } )
}
2023-08-28 09:50:46 +00:00
ctrlOpts := ctrl . Options {
Scheme : scheme ,
Metrics : server . Options {
BindAddress : metricsAddr ,
} ,
WebhookServer : webhook . NewServer ( webhook . Options {
Port : 9443 ,
} ) ,
Client : client . Options {
Cache : & client . CacheOptions {
2024-11-24 21:53:53 +00:00
DisableFor : clientCacheDisableFor ,
2023-08-28 09:50:46 +00:00
} ,
} ,
LeaderElection : enableLeaderElection ,
LeaderElectionID : "external-secrets-controller" ,
}
if namespace != "" {
ctrlOpts . Cache . DefaultNamespaces = map [ string ] cache . Config {
namespace : { } ,
}
}
mgr , err := ctrl . NewManager ( config , ctrlOpts )
2022-02-15 11:52:52 +00:00
if err != nil {
setupLog . Error ( err , "unable to start manager" )
os . Exit ( 1 )
}
2023-06-05 19:26:25 +00:00
2024-11-24 21:53:53 +00:00
// we create a special client for accessing secrets in the ExternalSecret reconcile loop.
// by default, it is the same as the normal client, but if `--enable-managed-secrets-caching`
// is set, we use a special client that only caches secrets managed by an ExternalSecret.
// if we are already caching all secrets, we don't need to use the special client.
secretClient := mgr . GetClient ( )
if enableManagedSecretsCache && ! enableSecretsCache {
secretClient , err = externalsecret . BuildManagedSecretClient ( mgr )
if err != nil {
setupLog . Error ( err , "unable to create managed secret client" )
os . Exit ( 1 )
}
}
2023-06-05 19:26:25 +00:00
ssmetrics . SetUpMetrics ( )
2022-02-15 11:52:52 +00:00
if err = ( & secretstore . StoreReconciler {
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "SecretStore" ) ,
Scheme : mgr . GetScheme ( ) ,
ControllerClass : controllerClass ,
RequeueInterval : storeRequeueInterval ,
2023-06-12 10:58:29 +00:00
} ) . SetupWithManager ( mgr , controller . Options {
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
2022-02-15 11:52:52 +00:00
setupLog . Error ( err , errCreateController , "controller" , "SecretStore" )
os . Exit ( 1 )
}
2022-03-07 16:19:26 +00:00
if enableClusterStoreReconciler {
2023-06-05 19:26:25 +00:00
cssmetrics . SetUpMetrics ( )
2022-03-07 16:19:26 +00:00
if err = ( & secretstore . ClusterStoreReconciler {
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "ClusterSecretStore" ) ,
Scheme : mgr . GetScheme ( ) ,
ControllerClass : controllerClass ,
RequeueInterval : storeRequeueInterval ,
2024-11-19 11:20:05 +00:00
} ) . SetupWithManager ( mgr , controller . Options {
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
2022-03-07 16:19:26 +00:00
setupLog . Error ( err , errCreateController , "controller" , "ClusterSecretStore" )
os . Exit ( 1 )
}
2022-02-15 11:52:52 +00:00
}
if err = ( & externalsecret . Reconciler {
2022-03-10 22:58:49 +00:00
Client : mgr . GetClient ( ) ,
2024-11-24 21:53:53 +00:00
SecretClient : secretClient ,
2022-03-10 22:58:49 +00:00
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "ExternalSecret" ) ,
Scheme : mgr . GetScheme ( ) ,
2022-10-29 18:15:50 +00:00
RestConfig : mgr . GetConfig ( ) ,
2022-03-10 22:58:49 +00:00
ControllerClass : controllerClass ,
RequeueInterval : time . Hour ,
ClusterSecretStoreEnabled : enableClusterStoreReconciler ,
2022-04-06 04:02:19 +00:00
EnableFloodGate : enableFloodGate ,
2022-02-15 11:52:52 +00:00
} ) . SetupWithManager ( mgr , controller . Options {
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
setupLog . Error ( err , errCreateController , "controller" , "ExternalSecret" )
os . Exit ( 1 )
}
2022-11-29 19:04:46 +00:00
if enablePushSecretReconciler {
2023-06-05 19:26:25 +00:00
psmetrics . SetUpMetrics ( )
2022-11-29 19:04:46 +00:00
if err = ( & pushsecret . Reconciler {
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "PushSecret" ) ,
Scheme : mgr . GetScheme ( ) ,
ControllerClass : controllerClass ,
2024-10-02 06:43:00 +00:00
RestConfig : mgr . GetConfig ( ) ,
2022-11-29 19:04:46 +00:00
RequeueInterval : time . Hour ,
2024-11-19 11:20:05 +00:00
} ) . SetupWithManager ( mgr , controller . Options {
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
2022-11-29 19:04:46 +00:00
setupLog . Error ( err , errCreateController , "controller" , "PushSecret" )
os . Exit ( 1 )
}
}
2022-03-24 13:29:03 +00:00
if enableClusterExternalSecretReconciler {
2023-05-22 20:43:23 +00:00
cesmetrics . SetUpMetrics ( )
2022-03-24 13:29:03 +00:00
if err = ( & clusterexternalsecret . Reconciler {
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "ClusterExternalSecret" ) ,
Scheme : mgr . GetScheme ( ) ,
RequeueInterval : time . Hour ,
} ) . SetupWithManager ( mgr , controller . Options {
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
setupLog . Error ( err , errCreateController , "controller" , "ClusterExternalSecret" )
os . Exit ( 1 )
}
2022-03-20 08:32:27 +00:00
}
2023-01-19 16:25:47 +00:00
fs := feature . Features ( )
for _ , f := range fs {
if f . Initialize == nil {
continue
}
f . Initialize ( )
2022-09-30 18:41:36 +00:00
}
2022-02-15 11:52:52 +00:00
setupLog . Info ( "starting manager" )
if err := mgr . Start ( ctrl . SetupSignalHandler ( ) ) ; err != nil {
setupLog . Error ( err , "problem running manager" )
os . Exit ( 1 )
}
} ,
}
func Execute ( ) {
cobra . CheckErr ( rootCmd . Execute ( ) )
}
func init ( ) {
rootCmd . Flags ( ) . StringVar ( & metricsAddr , "metrics-addr" , ":8080" , "The address the metric endpoint binds to." )
2022-10-29 18:15:50 +00:00
rootCmd . Flags ( ) . StringVar ( & controllerClass , "controller-class" , "default" , "The controller is instantiated with a specific controller name and filters ES based on this property" )
2022-02-15 11:52:52 +00:00
rootCmd . Flags ( ) . BoolVar ( & enableLeaderElection , "enable-leader-election" , false ,
"Enable leader election for controller manager. " +
"Enabling this will ensure there is only one active controller manager." )
2023-06-12 10:58:29 +00:00
rootCmd . Flags ( ) . IntVar ( & concurrent , "concurrent" , 1 , "The number of concurrent reconciles." )
2022-07-23 22:56:02 +00:00
rootCmd . Flags ( ) . Float32Var ( & clientQPS , "client-qps" , 0 , "QPS configuration to be passed to rest.Client" )
rootCmd . Flags ( ) . IntVar ( & clientBurst , "client-burst" , 0 , "Maximum Burst allowed to be passed to rest.Client" )
2022-02-15 11:52:52 +00:00
rootCmd . Flags ( ) . StringVar ( & loglevel , "loglevel" , "info" , "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal" )
2022-12-13 20:01:07 +00:00
rootCmd . Flags ( ) . StringVar ( & zapTimeEncoding , "zap-time-encoding" , "epoch" , "Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano')" )
2022-02-15 11:52:52 +00:00
rootCmd . Flags ( ) . StringVar ( & namespace , "namespace" , "" , "watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces" )
2022-11-29 19:04:46 +00:00
rootCmd . Flags ( ) . BoolVar ( & enableClusterStoreReconciler , "enable-cluster-store-reconciler" , true , "Enable cluster store reconciler." )
rootCmd . Flags ( ) . BoolVar ( & enableClusterExternalSecretReconciler , "enable-cluster-external-secret-reconciler" , true , "Enable cluster external secret reconciler." )
rootCmd . Flags ( ) . BoolVar ( & enablePushSecretReconciler , "enable-push-secret-reconciler" , true , "Enable push secret reconciler." )
2024-11-24 21:53:53 +00:00
rootCmd . Flags ( ) . BoolVar ( & enableSecretsCache , "enable-secrets-caching" , false , "Enable secrets caching for ALL secrets in the cluster (WARNING: can increase memory usage)." )
rootCmd . Flags ( ) . BoolVar ( & enableConfigMapsCache , "enable-configmaps-caching" , false , "Enable configmaps caching for ALL configmaps in the cluster (WARNING: can increase memory usage)." )
rootCmd . Flags ( ) . BoolVar ( & enableManagedSecretsCache , "enable-managed-secrets-caching" , true , "Enable secrets caching for secrets managed by an ExternalSecret" )
2022-04-06 04:02:19 +00:00
rootCmd . Flags ( ) . DurationVar ( & storeRequeueInterval , "store-requeue-interval" , time . Minute * 5 , "Default Time duration between reconciling (Cluster)SecretStores" )
rootCmd . Flags ( ) . BoolVar ( & enableFloodGate , "enable-flood-gate" , true , "Enable flood gate. External secret will be reconciled only if the ClusterStore or Store have an healthy or unknown state." )
2023-04-05 17:58:17 +00:00
rootCmd . Flags ( ) . BoolVar ( & enableExtendedMetricLabels , "enable-extended-metric-labels" , false , "Enable recommended kubernetes annotations as labels in metrics." )
2023-01-19 16:25:47 +00:00
fs := feature . Features ( )
for _ , f := range fs {
rootCmd . Flags ( ) . AddFlagSet ( f . Flags )
}
2022-02-15 11:52:52 +00:00
}