From 74a8187394ecc98fba19308d327936ff397fa91f Mon Sep 17 00:00:00 2001 From: AlexFenlon Date: Thu, 28 Nov 2024 14:45:42 +0000 Subject: [PATCH] add events to special secrets (#6878) --- cmd/nginx-ingress/main.go | 46 ++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index aa3c1946f6..13917ec05b 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -34,6 +34,7 @@ import ( "github.com/prometheus/client_golang/prometheus" api_v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + pkg_runtime "k8s.io/apimachinery/pkg/runtime" util_version "k8s.io/apimachinery/pkg/util/version" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" @@ -75,6 +76,8 @@ const ( appProtectVersionPath = "/opt/app_protect/RELEASE" appProtectv4BundleFolder = "/etc/nginx/waf/bundles/" appProtectv5BundleFolder = "/etc/app_protect/bundles/" + fatalEventFlushTime = 200 * time.Millisecond + secretErrorReason = "SecretError" ) func main() { @@ -89,9 +92,14 @@ func main() { buildOS := os.Getenv("BUILD_OS") controllerNamespace := os.Getenv("POD_NAMESPACE") + podName := os.Getenv("POD_NAME") config, kubeClient := mustCreateConfigAndKubeClient(ctx) mustValidateKubernetesVersionInfo(ctx, kubeClient) + pod, err := kubeClient.CoreV1().Pods(controllerNamespace).Get(context.TODO(), podName, meta_v1.GetOptions{}) + if err != nil { + nl.Fatalf(l, "Failed to get pod: %v", err) + } eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(func(format string, args ...interface{}) { nl.Infof(l, format, args...) @@ -101,6 +109,7 @@ func main() { }) eventRecorder := eventBroadcaster.NewRecorder(scheme.Scheme, api_v1.EventSource{Component: "nginx-ingress-controller"}) + defer eventBroadcaster.Shutdown() mustValidateIngressClass(ctx, kubeClient) checkNamespaces(ctx, kubeClient) @@ -143,12 +152,17 @@ func main() { templateExecutor, templateExecutorV2 := createTemplateExecutors(ctx) - sslRejectHandshake := processDefaultServerSecret(ctx, kubeClient, nginxManager) - - isWildcardEnabled := processWildcardSecret(ctx, kubeClient, nginxManager) + sslRejectHandshake, err := processDefaultServerSecret(kubeClient, nginxManager) + if err != nil { + logEventAndExit(ctx, eventRecorder, pod, secretErrorReason, err) + } staticSSLPath := nginxManager.GetSecretsDir() + isWildcardEnabled, err := processWildcardSecret(kubeClient, nginxManager) + if err != nil { + logEventAndExit(ctx, eventRecorder, pod, secretErrorReason, err) + } globalConfigurationValidator := createGlobalConfigurationValidator() mustProcessGlobalConfiguration(ctx) @@ -562,14 +576,13 @@ func startChildProcesses(nginxManager nginx.Manager, appProtectV5 bool) childPro } } -func processDefaultServerSecret(ctx context.Context, kubeClient *kubernetes.Clientset, nginxManager nginx.Manager) bool { - l := nl.LoggerFromContext(ctx) +func processDefaultServerSecret(kubeClient *kubernetes.Clientset, nginxManager nginx.Manager) (bool, error) { var sslRejectHandshake bool if *defaultServerSecret != "" { secret, err := getAndValidateSecret(kubeClient, *defaultServerSecret, api_v1.SecretTypeTLS) if err != nil { - nl.Fatalf(l, "Error trying to get the default server TLS secret %v: %v", *defaultServerSecret, err) + return sslRejectHandshake, fmt.Errorf("error trying to get the default server TLS secret %v: %w", *defaultServerSecret, err) } bytes := configs.GenerateCertAndKeyFileContent(secret) @@ -581,25 +594,25 @@ func processDefaultServerSecret(ctx context.Context, kubeClient *kubernetes.Clie // file doesn't exist - it is OK! we will reject TLS connections in the default server sslRejectHandshake = true } else { - nl.Fatalf(l, "Error checking the default server TLS cert and key in %s: %v", configs.DefaultServerSecretPath, err) + return sslRejectHandshake, fmt.Errorf("error checking the default server TLS cert and key in %s: %w", configs.DefaultServerSecretPath, err) } } } - return sslRejectHandshake + return sslRejectHandshake, nil } -func processWildcardSecret(ctx context.Context, kubeClient *kubernetes.Clientset, nginxManager nginx.Manager) bool { - l := nl.LoggerFromContext(ctx) - if *wildcardTLSSecret != "" { +func processWildcardSecret(kubeClient *kubernetes.Clientset, nginxManager nginx.Manager) (bool, error) { + isWildcardEnabled := *wildcardTLSSecret != "" + if isWildcardEnabled { secret, err := getAndValidateSecret(kubeClient, *wildcardTLSSecret, api_v1.SecretTypeTLS) if err != nil { - nl.Fatalf(l, "Error trying to get the wildcard TLS secret %v: %v", *wildcardTLSSecret, err) + return false, fmt.Errorf("error trying to get the wildcard TLS secret %v: %w", *wildcardTLSSecret, err) } bytes := configs.GenerateCertAndKeyFileContent(secret) nginxManager.CreateSecret(configs.WildcardSecretFileName, bytes, nginx.ReadWriteOnlyFileMode) } - return *wildcardTLSSecret != "" + return isWildcardEnabled, nil } func createGlobalConfigurationValidator() *cr_validation.GlobalConfigurationValidator { @@ -946,6 +959,13 @@ func updateSelfWithVersionInfo(ctx context.Context, eventLog record.EventRecorde } } +func logEventAndExit(ctx context.Context, eventLog record.EventRecorder, obj pkg_runtime.Object, reason string, err error) { + l := nl.LoggerFromContext(ctx) + eventLog.Eventf(obj, api_v1.EventTypeWarning, reason, err.Error()) + time.Sleep(fatalEventFlushTime) // wait for the event to be flushed + nl.Fatal(l, err.Error()) +} + func initLogger(logFormat string, level slog.Level, out io.Writer) context.Context { programLevel := new(slog.LevelVar) // Info by default var h slog.Handler