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"
2024-06-16 10:52:10 +00:00
admissionregistration "k8s.io/api/admissionregistration/v1"
2022-02-17 12:35:20 +00:00
v1 "k8s.io/api/core/v1"
2024-06-16 10:52:10 +00:00
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/labels"
2022-02-15 11:52:52 +00:00
ctrl "sigs.k8s.io/controller-runtime"
2024-06-16 10:52:10 +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
2024-06-16 10:52:10 +00:00
"github.com/external-secrets/external-secrets/pkg/constants"
2022-02-15 11:52:52 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/crds"
2022-02-17 22:14:39 +00:00
"github.com/external-secrets/external-secrets/pkg/controllers/webhookconfig"
2022-02-15 11:52:52 +00:00
)
var certcontrollerCmd = & cobra . Command {
Use : "certcontroller" ,
2022-02-17 22:14:39 +00:00
Short : "Controller to manage certificates for external secrets CRDs and ValidatingWebhookConfigs" ,
Long : ` Controller to manage certificates for external secrets CRDs and ValidatingWebhookConfigs .
2022-02-15 11:52:52 +00:00
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 )
2024-11-24 21:53:53 +00:00
// completely disable caching of Secrets and ConfigMaps to save memory
// see: https://github.com/external-secrets/external-secrets/issues/721
clientCacheDisableFor := make ( [ ] client . Object , 0 )
clientCacheDisableFor = append ( clientCacheDisableFor , & v1 . Secret { } , & v1 . ConfigMap { } )
// in large clusters, the CRDs and ValidatingWebhookConfigurations can take up a lot of memory
// see: https://github.com/external-secrets/external-secrets/pull/3588
cacheByObject := make ( map [ client . Object ] cache . ByObject )
2024-06-16 10:52:10 +00:00
if enablePartialCache {
2024-11-24 21:53:53 +00:00
// only cache ValidatingWebhookConfiguration with "external-secrets.io/component=webhook" label
cacheByObject [ & admissionregistration . ValidatingWebhookConfiguration { } ] = cache . ByObject {
Label : labels . SelectorFromSet ( labels . Set {
constants . WellKnownLabelKey : constants . WellKnownLabelValueWebhook ,
} ) ,
}
// only cache CustomResourceDefinition with "external-secrets.io/component=controller" label
cacheByObject [ & apiextensions . CustomResourceDefinition { } ] = cache . ByObject {
Label : labels . SelectorFromSet ( labels . Set {
constants . WellKnownLabelKey : constants . WellKnownLabelValueController ,
} ) ,
2024-06-16 10:52:10 +00:00
}
}
2022-02-15 11:52:52 +00:00
mgr , err := ctrl . NewManager ( ctrl . GetConfigOrDie ( ) , ctrl . Options {
2023-08-28 09:50:46 +00:00
Scheme : scheme ,
Metrics : server . Options {
BindAddress : metricsAddr ,
} ,
WebhookServer : webhook . NewServer ( webhook . Options {
Port : 9443 ,
} ) ,
2022-02-17 22:14:39 +00:00
HealthProbeBindAddress : healthzAddr ,
LeaderElection : enableLeaderElection ,
LeaderElectionID : "crd-certs-controller" ,
2024-11-24 21:53:53 +00:00
Cache : cache . Options {
ByObject : cacheByObject ,
} ,
2023-08-28 09:50:46 +00:00
Client : client . Options {
Cache : & client . CacheOptions {
2024-11-24 21:53:53 +00:00
DisableFor : clientCacheDisableFor ,
2023-08-28 09:50:46 +00:00
} ,
2022-02-17 22:14:39 +00:00
} ,
} )
2022-02-15 11:52:52 +00:00
if err != nil {
setupLog . Error ( err , "unable to start manager" )
os . Exit ( 1 )
}
2023-11-07 08:51:27 +00:00
crdctrl := crds . New ( mgr . GetClient ( ) , mgr . GetScheme ( ) , mgr . Elected ( ) ,
2022-02-17 22:14:39 +00:00
ctrl . Log . WithName ( "controllers" ) . WithName ( "webhook-certs-updater" ) ,
2022-12-13 19:56:30 +00:00
crdRequeueInterval , serviceName , serviceNamespace , secretName , secretNamespace , crdNames )
2022-02-17 22:14:39 +00:00
if err := crdctrl . SetupWithManager ( mgr , controller . Options {
2022-02-15 11:52:52 +00:00
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
setupLog . Error ( err , errCreateController , "controller" , "CustomResourceDefinition" )
os . Exit ( 1 )
}
2022-02-17 22:14:39 +00:00
2023-11-07 08:51:27 +00:00
whc := webhookconfig . New ( mgr . GetClient ( ) , mgr . GetScheme ( ) , mgr . Elected ( ) ,
2022-02-17 22:14:39 +00:00
ctrl . Log . WithName ( "controllers" ) . WithName ( "webhook-certs-updater" ) ,
serviceName , serviceNamespace ,
secretName , secretNamespace , crdRequeueInterval )
if err := whc . SetupWithManager ( mgr , controller . Options {
MaxConcurrentReconciles : concurrent ,
} ) ; err != nil {
setupLog . Error ( err , errCreateController , "controller" , "WebhookConfig" )
os . Exit ( 1 )
}
err = mgr . AddReadyzCheck ( "crd-inject" , crdctrl . ReadyCheck )
if err != nil {
setupLog . Error ( err , "unable to add crd readyz check" )
os . Exit ( 1 )
}
err = mgr . AddReadyzCheck ( "validation-webhook-inject" , whc . ReadyCheck )
if err != nil {
setupLog . Error ( err , "unable to add webhook readyz check" )
os . Exit ( 1 )
}
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 init ( ) {
rootCmd . AddCommand ( certcontrollerCmd )
certcontrollerCmd . Flags ( ) . StringVar ( & metricsAddr , "metrics-addr" , ":8080" , "The address the metric endpoint binds to." )
2022-02-17 22:14:39 +00:00
certcontrollerCmd . Flags ( ) . StringVar ( & healthzAddr , "healthz-addr" , ":8081" , "The address the health endpoint binds to." )
2022-02-15 11:52:52 +00:00
certcontrollerCmd . Flags ( ) . StringVar ( & serviceName , "service-name" , "external-secrets-webhook" , "Webhook service name" )
certcontrollerCmd . Flags ( ) . StringVar ( & serviceNamespace , "service-namespace" , "default" , "Webhook service namespace" )
certcontrollerCmd . Flags ( ) . StringVar ( & secretName , "secret-name" , "external-secrets-webhook" , "Secret to store certs for webhook" )
certcontrollerCmd . Flags ( ) . StringVar ( & secretNamespace , "secret-namespace" , "default" , "namespace of the secret to store certs" )
2022-12-13 19:56:30 +00:00
certcontrollerCmd . Flags ( ) . StringSliceVar ( & crdNames , "crd-names" , [ ] string { "externalsecrets.external-secrets.io" , "clustersecretstores.external-secrets.io" , "secretstores.external-secrets.io" } , "CRD names reconciled by the controller" )
2024-06-16 10:52:10 +00:00
certcontrollerCmd . Flags ( ) . BoolVar ( & enablePartialCache , "enable-partial-cache" , false ,
"Enable caching of only the relevant CRDs and Webhook configurations in the Informer to improve memory efficiency" )
2022-02-15 11:52:52 +00:00
certcontrollerCmd . Flags ( ) . BoolVar ( & enableLeaderElection , "enable-leader-election" , false ,
"Enable leader election for controller manager. " +
"Enabling this will ensure there is only one active controller manager." )
certcontrollerCmd . 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
certcontrollerCmd . 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
certcontrollerCmd . Flags ( ) . DurationVar ( & crdRequeueInterval , "crd-requeue-interval" , time . Minute * 5 , "Time duration between reconciling CRDs for new certs" )
}