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"
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-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 ( ) {
_ = clientgoscheme . AddToScheme ( scheme )
_ = esv1beta1 . AddToScheme ( scheme )
_ = esv1alpha1 . AddToScheme ( scheme )
2022-10-29 18:15:50 +00:00
_ = genv1alpha1 . AddToScheme ( scheme )
2022-02-17 22:14:39 +00:00
_ = apiextensionsv1 . 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
2022-07-23 22:56:02 +00:00
// the client creates a ListWatch for all resource kinds that
// are requested with .Get().
// We want to avoid to cache all secrets or configmaps in memory.
// The ES controller uses v1.PartialObjectMetadata for the secrets
// that he owns.
// see #721
cacheList := make ( [ ] client . Object , 0 )
if ! enableSecretsCache {
cacheList = append ( cacheList , & v1 . Secret { } )
}
if ! enableConfigMapsCache {
cacheList = append ( cacheList , & v1 . ConfigMap { } )
}
2022-12-13 20:01:07 +00:00
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
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 {
DisableFor : cacheList ,
} ,
} ,
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
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 ,
} ) . SetupWithManager ( mgr ) ; err != nil {
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 ( ) ,
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 ,
RequeueInterval : time . Hour ,
} ) . SetupWithManager ( mgr ) ; err != nil {
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." )
rootCmd . Flags ( ) . BoolVar ( & enableSecretsCache , "enable-secrets-caching" , false , "Enable secrets caching for external-secrets pod." )
rootCmd . Flags ( ) . BoolVar ( & enableConfigMapsCache , "enable-configmaps-caching" , false , "Enable secrets caching for external-secrets pod." )
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
}