diff --git a/cmd/k8s-operator/ingress.go b/cmd/k8s-operator/ingress.go index 1e042c1f7..72291afe8 100644 --- a/cmd/k8s-operator/ingress.go +++ b/cmd/k8s-operator/ingress.go @@ -125,6 +125,10 @@ func (a *IngressReconciler) maybeProvision(ctx context.Context, logger *zap.Suga gaugeIngressResources.Set(int64(a.managedIngresses.Len())) a.mu.Unlock() + if !a.ssr.IsHTTPSEnabledOnTailnet() { + a.recorder.Event(ing, corev1.EventTypeWarning, "HTTPSNotEnabled", "HTTPS is not enabled on the tailnet; ingress may not work") + } + // magic443 is a fake hostname that we can use to tell containerboot to swap // out with the real hostname once it's known. const magic443 = "${TS_CERT_DOMAIN}:443" diff --git a/cmd/k8s-operator/operator.go b/cmd/k8s-operator/operator.go index 139101cc8..5d78f4c25 100644 --- a/cmd/k8s-operator/operator.go +++ b/cmd/k8s-operator/operator.go @@ -73,7 +73,7 @@ func main() { if shouldRunAuthProxy { launchAuthProxy(zlog, restConfig, s) } - startReconcilers(zlog, tsNamespace, restConfig, tsClient, image, priorityClassName, tags) + startReconcilers(zlog, s, tsNamespace, restConfig, tsClient, image, priorityClassName, tags) } // initTSNet initializes the tsnet.Server and logs in to Tailscale. It uses the @@ -182,7 +182,7 @@ waitOnline: // startReconcilers starts the controller-runtime manager and registers the // ServiceReconciler. -func startReconcilers(zlog *zap.SugaredLogger, tsNamespace string, restConfig *rest.Config, tsClient *tailscale.Client, image, priorityClassName, tags string) { +func startReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string, restConfig *rest.Config, tsClient *tailscale.Client, image, priorityClassName, tags string) { var ( isDefaultLoadBalancer = defaultBool("OPERATOR_DEFAULT_LOAD_BALANCER", false) ) @@ -225,6 +225,7 @@ func startReconcilers(zlog *zap.SugaredLogger, tsNamespace string, restConfig *r eventRecorder := mgr.GetEventRecorderFor("tailscale-operator") ssr := &tailscaleSTSReconciler{ Client: mgr.GetClient(), + tsnetServer: s, tsClient: tsClient, defaultTags: strings.Split(tags, ","), operatorNamespace: tsNamespace, diff --git a/cmd/k8s-operator/sts.go b/cmd/k8s-operator/sts.go index a706835a2..31aa6bad7 100644 --- a/cmd/k8s-operator/sts.go +++ b/cmd/k8s-operator/sts.go @@ -24,6 +24,7 @@ import ( "tailscale.com/client/tailscale" "tailscale.com/ipn" "tailscale.com/tailcfg" + "tailscale.com/tsnet" "tailscale.com/types/opt" "tailscale.com/util/dnsname" "tailscale.com/util/mak" @@ -71,6 +72,7 @@ type tailscaleSTSConfig struct { type tailscaleSTSReconciler struct { client.Client + tsnetServer *tsnet.Server tsClient tsClient defaultTags []string operatorNamespace string @@ -78,6 +80,11 @@ type tailscaleSTSReconciler struct { proxyPriorityClassName string } +// IsHTTPSEnabledOnTailnet reports whether HTTPS is enabled on the tailnet. +func (a *tailscaleSTSReconciler) IsHTTPSEnabledOnTailnet() bool { + return len(a.tsnetServer.CertDomains()) > 0 +} + // Provision ensures that the StatefulSet for the given service is running and // up to date. func (a *tailscaleSTSReconciler) Provision(ctx context.Context, logger *zap.SugaredLogger, sts *tailscaleSTSConfig) (*corev1.Service, error) {