2023-12-04 10:18:07 +00:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
|
|
|
|
//go:build !plan9
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
)
|
|
|
|
|
2024-01-10 14:20:22 +00:00
|
|
|
const (
|
2024-02-13 05:27:54 +00:00
|
|
|
operatorDeploymentFilesPath = "cmd/k8s-operator/deploy"
|
|
|
|
connectorCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_connectors.yaml"
|
|
|
|
proxyClassCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_proxyclasses.yaml"
|
cmd/{k8s-nameserver,k8s-operator},k8s-operator: add a kube nameserver, make operator deploy it (#11017)
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy/crds,k8s-operator: add DNSConfig CustomResource Definition
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator,k8s-operator: optionally reconcile nameserver resources
Adds a new reconciler that reconciles DNSConfig resources.
If a DNSConfig is deployed to cluster,
the reconciler creates kube nameserver resources.
This reconciler is only responsible for creating
nameserver resources and not for populating nameserver's records.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/{k8s-operator,k8s-nameserver}: generate DNSConfig CRD for charts, append to static manifests
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-03-27 20:18:17 +00:00
|
|
|
dnsConfigCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_dnsconfigs.yaml"
|
2024-02-13 05:27:54 +00:00
|
|
|
helmTemplatesPath = operatorDeploymentFilesPath + "/chart/templates"
|
|
|
|
connectorCRDHelmTemplatePath = helmTemplatesPath + "/connector.yaml"
|
|
|
|
proxyClassCRDHelmTemplatePath = helmTemplatesPath + "/proxyclass.yaml"
|
cmd/{k8s-nameserver,k8s-operator},k8s-operator: add a kube nameserver, make operator deploy it (#11017)
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy/crds,k8s-operator: add DNSConfig CustomResource Definition
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator,k8s-operator: optionally reconcile nameserver resources
Adds a new reconciler that reconciles DNSConfig resources.
If a DNSConfig is deployed to cluster,
the reconciler creates kube nameserver resources.
This reconciler is only responsible for creating
nameserver resources and not for populating nameserver's records.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/{k8s-operator,k8s-nameserver}: generate DNSConfig CRD for charts, append to static manifests
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-03-27 20:18:17 +00:00
|
|
|
dnsConfigCRDHelmTemplatePath = helmTemplatesPath + "/dnsconfig.yaml"
|
2024-01-10 14:20:22 +00:00
|
|
|
|
|
|
|
helmConditionalStart = "{{ if .Values.installCRDs -}}\n"
|
|
|
|
helmConditionalEnd = "{{- end -}}"
|
|
|
|
)
|
|
|
|
|
2023-12-04 10:18:07 +00:00
|
|
|
func main() {
|
2024-01-10 14:20:22 +00:00
|
|
|
if len(os.Args) < 2 {
|
|
|
|
log.Fatalf("usage ./generate [staticmanifests|helmcrd]")
|
|
|
|
}
|
2023-12-04 10:18:07 +00:00
|
|
|
repoRoot := "../../"
|
2024-01-10 14:20:22 +00:00
|
|
|
switch os.Args[1] {
|
|
|
|
case "helmcrd": // insert CRD to Helm templates behind a installCRDs=true conditional check
|
|
|
|
log.Print("Adding Connector CRD to Helm templates")
|
|
|
|
if err := generate("./"); err != nil {
|
|
|
|
log.Fatalf("error adding Connector CRD to Helm templates: %v", err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
case "staticmanifests": // generate static manifests from Helm templates (including the CRD)
|
|
|
|
default:
|
|
|
|
log.Fatalf("unknown option %s, known options are 'staticmanifests', 'helmcrd'", os.Args[1])
|
|
|
|
}
|
2024-02-13 05:27:54 +00:00
|
|
|
log.Printf("Inserting CRDs Helm templates")
|
2024-01-10 14:20:22 +00:00
|
|
|
if err := generate(repoRoot); err != nil {
|
2024-02-13 05:27:54 +00:00
|
|
|
log.Fatalf("error adding CRDs to Helm templates: %v", err)
|
2024-01-10 14:20:22 +00:00
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
if err := cleanup(repoRoot); err != nil {
|
|
|
|
log.Fatalf("error cleaning up generated resources")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
log.Print("Templating Helm chart contents")
|
|
|
|
helmTmplCmd := exec.Command("./tool/helm", "template", "operator", "./cmd/k8s-operator/deploy/chart",
|
2023-12-04 10:18:07 +00:00
|
|
|
"--namespace=tailscale")
|
2024-01-10 14:20:22 +00:00
|
|
|
helmTmplCmd.Dir = repoRoot
|
2023-12-04 10:18:07 +00:00
|
|
|
var out bytes.Buffer
|
2024-01-10 14:20:22 +00:00
|
|
|
helmTmplCmd.Stdout = &out
|
|
|
|
helmTmplCmd.Stderr = os.Stderr
|
|
|
|
if err := helmTmplCmd.Run(); err != nil {
|
2023-12-04 10:18:07 +00:00
|
|
|
log.Fatalf("error templating helm manifests: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var final bytes.Buffer
|
|
|
|
|
|
|
|
templatePath := filepath.Join(repoRoot, "cmd/k8s-operator/deploy/manifests/templates")
|
|
|
|
fileInfos, err := os.ReadDir(templatePath)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error reading templates: %v", err)
|
|
|
|
}
|
|
|
|
for _, fi := range fileInfos {
|
|
|
|
templateBytes, err := os.ReadFile(filepath.Join(templatePath, fi.Name()))
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error reading template: %v", err)
|
|
|
|
}
|
|
|
|
final.Write(templateBytes)
|
|
|
|
}
|
|
|
|
decoder := yaml.NewDecoder(&out)
|
|
|
|
for {
|
|
|
|
var document any
|
|
|
|
err := decoder.Decode(&document)
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed read from input data: %v", err)
|
|
|
|
}
|
|
|
|
bytes, err := yaml.Marshal(document)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to marshal YAML document: %v", err)
|
|
|
|
}
|
|
|
|
if strings.TrimSpace(string(bytes)) == "null" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if _, err = final.Write(bytes); err != nil {
|
|
|
|
log.Fatalf("error marshaling yaml: %v", err)
|
|
|
|
}
|
|
|
|
fmt.Fprint(&final, "---\n")
|
|
|
|
}
|
|
|
|
finalString, _ := strings.CutSuffix(final.String(), "---\n")
|
|
|
|
if err := os.WriteFile(filepath.Join(repoRoot, "cmd/k8s-operator/deploy/manifests/operator.yaml"), []byte(finalString), 0664); err != nil {
|
|
|
|
log.Fatalf("error writing new file: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2024-01-10 14:20:22 +00:00
|
|
|
|
cmd/{k8s-nameserver,k8s-operator},k8s-operator: add a kube nameserver, make operator deploy it (#11017)
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy/crds,k8s-operator: add DNSConfig CustomResource Definition
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator,k8s-operator: optionally reconcile nameserver resources
Adds a new reconciler that reconciles DNSConfig resources.
If a DNSConfig is deployed to cluster,
the reconciler creates kube nameserver resources.
This reconciler is only responsible for creating
nameserver resources and not for populating nameserver's records.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/{k8s-operator,k8s-nameserver}: generate DNSConfig CRD for charts, append to static manifests
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-03-27 20:18:17 +00:00
|
|
|
// generate places tailscale.com CRDs (currently Connector, ProxyClass and DNSConfig) into
|
2024-02-13 05:27:54 +00:00
|
|
|
// the Helm chart templates behind .Values.installCRDs=true condition (true by
|
|
|
|
// default).
|
2024-01-10 14:20:22 +00:00
|
|
|
func generate(baseDir string) error {
|
2024-02-13 05:27:54 +00:00
|
|
|
addCRDToHelm := func(crdPath, crdTemplatePath string) error {
|
|
|
|
chartBytes, err := os.ReadFile(filepath.Join(baseDir, crdPath))
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error reading CRD contents: %w", err)
|
|
|
|
}
|
|
|
|
// Place a new temporary Helm template file with the templated CRD
|
|
|
|
// contents into Helm templates.
|
|
|
|
file, err := os.Create(filepath.Join(baseDir, crdTemplatePath))
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error creating CRD template file: %w", err)
|
|
|
|
}
|
|
|
|
if _, err := file.Write([]byte(helmConditionalStart)); err != nil {
|
|
|
|
return fmt.Errorf("error writing helm if statement start: %w", err)
|
|
|
|
}
|
|
|
|
if _, err := file.Write(chartBytes); err != nil {
|
|
|
|
return fmt.Errorf("error writing chart bytes: %w", err)
|
|
|
|
}
|
|
|
|
if _, err := file.Write([]byte(helmConditionalEnd)); err != nil {
|
|
|
|
return fmt.Errorf("error writing helm if-statement end: %w", err)
|
|
|
|
}
|
|
|
|
return nil
|
2024-01-10 14:20:22 +00:00
|
|
|
}
|
2024-02-13 05:27:54 +00:00
|
|
|
if err := addCRDToHelm(connectorCRDPath, connectorCRDHelmTemplatePath); err != nil {
|
|
|
|
return fmt.Errorf("error adding Connector CRD to Helm templates: %w", err)
|
2024-01-10 14:20:22 +00:00
|
|
|
}
|
2024-02-13 05:27:54 +00:00
|
|
|
if err := addCRDToHelm(proxyClassCRDPath, proxyClassCRDHelmTemplatePath); err != nil {
|
|
|
|
return fmt.Errorf("error adding ProxyClass CRD to Helm templates: %w", err)
|
2024-01-10 14:20:22 +00:00
|
|
|
}
|
cmd/{k8s-nameserver,k8s-operator},k8s-operator: add a kube nameserver, make operator deploy it (#11017)
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy/crds,k8s-operator: add DNSConfig CustomResource Definition
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator,k8s-operator: optionally reconcile nameserver resources
Adds a new reconciler that reconciles DNSConfig resources.
If a DNSConfig is deployed to cluster,
the reconciler creates kube nameserver resources.
This reconciler is only responsible for creating
nameserver resources and not for populating nameserver's records.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/{k8s-operator,k8s-nameserver}: generate DNSConfig CRD for charts, append to static manifests
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-03-27 20:18:17 +00:00
|
|
|
if err := addCRDToHelm(dnsConfigCRDPath, dnsConfigCRDHelmTemplatePath); err != nil {
|
|
|
|
return fmt.Errorf("error adding DNSConfig CRD to Helm templates: %w", err)
|
|
|
|
}
|
2024-01-10 14:20:22 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func cleanup(baseDir string) error {
|
|
|
|
log.Print("Cleaning up CRD from Helm templates")
|
2024-02-13 05:27:54 +00:00
|
|
|
if err := os.Remove(filepath.Join(baseDir, connectorCRDHelmTemplatePath)); err != nil && !os.IsNotExist(err) {
|
|
|
|
return fmt.Errorf("error cleaning up Connector CRD template: %w", err)
|
|
|
|
}
|
|
|
|
if err := os.Remove(filepath.Join(baseDir, proxyClassCRDHelmTemplatePath)); err != nil && !os.IsNotExist(err) {
|
|
|
|
return fmt.Errorf("error cleaning up ProxyClass CRD template: %w", err)
|
2024-01-10 14:20:22 +00:00
|
|
|
}
|
cmd/{k8s-nameserver,k8s-operator},k8s-operator: add a kube nameserver, make operator deploy it (#11017)
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy/crds,k8s-operator: add DNSConfig CustomResource Definition
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator,k8s-operator: optionally reconcile nameserver resources
Adds a new reconciler that reconciles DNSConfig resources.
If a DNSConfig is deployed to cluster,
the reconciler creates kube nameserver resources.
This reconciler is only responsible for creating
nameserver resources and not for populating nameserver's records.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/{k8s-operator,k8s-nameserver}: generate DNSConfig CRD for charts, append to static manifests
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-03-27 20:18:17 +00:00
|
|
|
if err := os.Remove(filepath.Join(baseDir, dnsConfigCRDHelmTemplatePath)); err != nil && !os.IsNotExist(err) {
|
|
|
|
return fmt.Errorf("error cleaning up DNSConfig CRD template: %w", err)
|
|
|
|
}
|
2024-01-10 14:20:22 +00:00
|
|
|
return nil
|
|
|
|
}
|