cmd/main.go (131 lines of code) (raw):

package main import ( "flag" "fmt" "net" "net/http" _ "net/http/pprof" // #nosec "net/url" "os" "os/signal" "runtime" "strconv" "syscall" "time" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/secrets-store-csi-driver-provider-azure/pkg/metrics" "github.com/Azure/secrets-store-csi-driver-provider-azure/pkg/server" "github.com/Azure/secrets-store-csi-driver-provider-azure/pkg/utils" "github.com/Azure/secrets-store-csi-driver-provider-azure/pkg/version" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" logsapi "k8s.io/component-base/logs/api/v1" json "k8s.io/component-base/logs/json" "k8s.io/klog/v2" k8spb "sigs.k8s.io/secrets-store-csi-driver/provider/v1alpha1" ) const ( readHeaderTimeout = 5 * time.Second ) var ( versionInfo = flag.Bool("version", false, "prints the version information") endpoint = flag.String("endpoint", "unix:///tmp/azure.sock", "CSI gRPC endpoint") logFormatJSON = flag.Bool("log-format-json", false, "set log formatter to json") enableProfile = flag.Bool("enable-pprof", false, "enable pprof profiling") profilePort = flag.Int("pprof-port", 6060, "port for pprof profiling") healthzPort = flag.Int("healthz-port", 8989, "port for health check") healthzPath = flag.String("healthz-path", "/healthz", "path for health check") healthzTimeout = flag.Duration("healthz-timeout", 5*time.Second, "RPC timeout for health check") metricsBackend = flag.String("metrics-backend", "Prometheus", "Backend used for metrics") prometheusPort = flag.Int("prometheus-port", 8898, "Prometheus port for metrics backend") constructPEMChain = flag.Bool("construct-pem-chain", true, "explicitly reconstruct the pem chain in the order: SERVER, INTERMEDIATE, ROOT") writeCertAndKeyInSeparateFiles = flag.Bool("write-cert-and-key-in-separate-files", false, "Write cert and key in separate files. The individual files will be named as <secret-name>.crt and <secret-name>.key. These files will be created in addition to the single file.") cloudName = flag.String("cloud-name", "AzurePublicCloud", "default cloud environment to use for Azure SDK if not provided in the SecretProviderClass. "+ "Allowed values: AzurePublicCloud, AzureUSGovernmentCloud, AzureChinaCloud, AzureGermanCloud or AzureStackCloud") ) func main() { klog.InitFlags(nil) defer klog.Flush() flag.Parse() signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT, os.Interrupt) if *logFormatJSON { jsonFactory := json.Factory{} logger, _ := jsonFactory.Create(logsapi.LoggingConfiguration{Format: "json"}) klog.SetLogger(logger) } if *versionInfo { if err := version.PrintVersion(); err != nil { klog.ErrorS(err, "failed to print version") os.Exit(1) } os.Exit(0) } klog.InfoS("Starting Azure Key Vault Provider", "version", version.BuildVersion) cloudEnv, err := azure.EnvironmentFromName(*cloudName) if err != nil { klog.ErrorS(err, "failed validating default cloud environment", "cloudName", *cloudName) os.Exit(1) } if *enableProfile { klog.InfoS("Starting profiling", "port", *profilePort) go func() { server := &http.Server{ Addr: fmt.Sprintf("%s:%d", "localhost", *profilePort), ReadHeaderTimeout: readHeaderTimeout, } klog.ErrorS(server.ListenAndServe(), "unable to start profiling server") }() } // initialize metrics exporter before creating measurements if err = metrics.InitMetricsExporter(*metricsBackend, *prometheusPort); err != nil { klog.ErrorS(err, "failed to initialize metrics exporter") os.Exit(1) } if *constructPEMChain { klog.Infof("construct pem chain feature enabled") } if *writeCertAndKeyInSeparateFiles { klog.Infof("write cert and key in separate files feature enabled") } // Initialize and run the gRPC server proto, addr, err := utils.ParseEndpoint(*endpoint) if err != nil { klog.ErrorS(err, "failed to parse endpoint") os.Exit(1) } if proto == "unix" { if runtime.GOOS != "windows" { addr = "/" + addr } if err := os.Remove(addr); err != nil && !os.IsNotExist(err) { klog.ErrorS(err, "failed to remove socket", "addr", addr) os.Exit(1) } } listener, err := net.Listen(proto, addr) if err != nil { klog.ErrorS(err, "failed to listen", "proto", proto, "addr", addr) os.Exit(1) } opts := []grpc.ServerOption{ grpc.UnaryInterceptor(utils.LogInterceptor()), } s := grpc.NewServer(opts...) csiDriverProviderServer := server.New(*constructPEMChain, *writeCertAndKeyInSeparateFiles, cloudEnv) k8spb.RegisterCSIDriverProviderServer(s, csiDriverProviderServer) // Register the health service. grpc_health_v1.RegisterHealthServer(s, csiDriverProviderServer) klog.InfoS("Listening for connections", "address", listener.Addr()) go s.Serve(listener) healthz := &server.HealthZ{ HealthCheckURL: &url.URL{ Host: net.JoinHostPort("", strconv.Itoa(*healthzPort)), Path: *healthzPath, }, UnixSocketPath: listener.Addr().String(), RPCTimeout: *healthzTimeout, } go healthz.Serve() <-signalChan // gracefully stop the grpc server klog.Infof("terminating the server") s.GracefulStop() }