installer: install dns zone manager
diff --git a/charts/flux-bootstrap/templates/known-hosts.yaml b/charts/flux-bootstrap/templates/known-hosts.yaml
index dc40b39..072c0d6 100644
--- a/charts/flux-bootstrap/templates/known-hosts.yaml
+++ b/charts/flux-bootstrap/templates/known-hosts.yaml
@@ -3,5 +3,5 @@
metadata:
name: known-hosts
namespace: {{ .Release.Namespace }}
-data:
- known_hosts: {{ printf "%s %s" .Values.repositoryHost .Values.repositoryHostPublicKey | toYaml | indent 2 }}
+binaryData:
+ known_hosts: {{ .Values.repositoryHostPublicKeys | b64enc }}
diff --git a/charts/flux-bootstrap/values.yaml b/charts/flux-bootstrap/values.yaml
index 4b5fca1..8221196 100644
--- a/charts/flux-bootstrap/values.yaml
+++ b/charts/flux-bootstrap/values.yaml
@@ -4,7 +4,7 @@
pullPolicy: Always
repositoryAddress: ""
repositoryHost: ""
-positoryHostPublicKey: ""
+positoryHostPublicKeys: []
repository:
address: ssh://git@<host>/<org>/<repository>
branch: master
diff --git a/core/installer/app.go b/core/installer/app.go
index de294cb..3210667 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -114,6 +114,7 @@
CreateCSIDriverSMB(valuesTmpls, tmpls),
CreateResourceRendererController(valuesTmpls, tmpls),
CreateHeadscaleController(valuesTmpls, tmpls),
+ CreateDNSZoneManager(valuesTmpls, tmpls),
}
for _, a := range CreateStoreApps() {
ret = append(ret, a.App)
@@ -574,6 +575,24 @@
}
}
+func CreateDNSZoneManager(fs embed.FS, tmpls *template.Template) App {
+ schema, err := fs.ReadFile("values-tmpl/dns-zone-controller.jsonschema")
+ if err != nil {
+ panic(err)
+ }
+ return App{
+ "dns-zone-manager",
+ []string{"dns-zone-manager"},
+ []*template.Template{
+ tmpls.Lookup("dns-zone-storage.yaml"),
+ tmpls.Lookup("coredns.yaml"),
+ tmpls.Lookup("dns-zone-controller.yaml"),
+ },
+ string(schema),
+ tmpls.Lookup("dns-zone-controller.md"),
+ }
+}
+
type httpAppRepository struct {
apps []StoreApp
}
diff --git a/core/installer/bootstrapper.go b/core/installer/bootstrapper.go
index 4ad44d7..953666c 100644
--- a/core/installer/bootstrapper.go
+++ b/core/installer/bootstrapper.go
@@ -66,21 +66,31 @@
if err := b.installFluxcd(ss, env.Name); err != nil {
return err
}
+ fmt.Println("Fluxcd installed")
repo, err := ss.GetRepo("config")
if err != nil {
+ fmt.Println("Failed to get config repo")
return err
}
repoIO := NewRepoIO(repo, ss.Signer)
+ fmt.Println("Configuring main repo")
if err := configureMainRepo(repoIO, env); err != nil {
return err
}
+ fmt.Println("Installing infrastructure services")
nsGen := NewPrefixGenerator(env.NamespacePrefix)
if err := b.installInfrastructureServices(repoIO, nsGen, b.ns, env); err != nil {
return err
}
+ fmt.Println("Installing DNS Zone Manager")
+ if err := b.installDNSZoneManager(ss, repoIO, nsGen, b.ns, env); err != nil {
+ return err
+ }
+ fmt.Println("Installing env manager")
if err := b.installEnvManager(ss, repoIO, nsGen, b.ns, env); err != nil {
return err
}
+ fmt.Println("Environment ready to use")
return nil
}
@@ -304,7 +314,7 @@
return err
}
fmt.Println("Installing Flux")
- ssPublic, err := ss.GetPublicKey()
+ ssPublicKeys, err := ss.GetPublicKeys()
if err != nil {
return err
}
@@ -312,7 +322,7 @@
if err := b.installFluxBootstrap(
ss.GetRepoAddress("config"),
host,
- string(ssPublic),
+ ssPublicKeys,
string(keys.RawPrivateKey()),
envName,
); err != nil {
@@ -321,7 +331,7 @@
return nil
}
-func (b Bootstrapper) installFluxBootstrap(repoAddr, repoHost, repoHostPubKey, privateKey, envName string) error {
+func (b Bootstrapper) installFluxBootstrap(repoAddr, repoHost string, repoHostPubKeys []string, privateKey, envName string) error {
config, err := b.ha.New(envName)
if err != nil {
return err
@@ -330,17 +340,21 @@
if err != nil {
return err
}
+ var lines []string
+ for _, k := range repoHostPubKeys {
+ lines = append(lines, fmt.Sprintf("%s %s", repoHost, k))
+ }
values := map[string]any{
"image": map[string]any{
"repository": "fluxcd/flux-cli",
"tag": "v2.1.2",
"pullPolicy": "IfNotPresent",
},
- "repositoryAddress": repoAddr,
- "repositoryHost": repoHost,
- "repositoryHostPublicKey": repoHostPubKey,
- "privateKey": privateKey,
- "installationNamespace": fmt.Sprintf("%s-flux", envName),
+ "repositoryAddress": repoAddr,
+ "repositoryHost": repoHost,
+ "repositoryHostPublicKeys": strings.Join(lines, "\n"),
+ "privateKey": privateKey,
+ "installationNamespace": fmt.Sprintf("%s-flux", envName),
}
installer := action.NewInstall(config)
installer.Namespace = envName
@@ -499,6 +513,46 @@
return repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), derived.Values, derived)
}
+func (b Bootstrapper) installDNSZoneManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
+ const (
+ volumeClaimName = "dns-zone-configs"
+ volumeMountPath = "/etc/pcloud/dns-zone-configs"
+ )
+ ns, err := nsGen.Generate("dns-zone-manager")
+ if err != nil {
+ return err
+ }
+ if err := nsCreator.Create(ns); err != nil {
+ return err
+ }
+ appRepo := NewInMemoryAppRepository(CreateAllApps())
+ {
+ app, err := appRepo.Find("dns-zone-manager")
+ if err != nil {
+ return err
+ }
+ derived := Derived{
+ Global: Values{
+ PCloudEnvName: env.Name,
+ },
+ Values: map[string]any{
+ "Volume": map[string]any{
+ "ClaimName": volumeClaimName,
+ "MountPath": volumeMountPath,
+ "Size": "1Gi",
+ },
+ },
+ Release: Release{
+ Namespace: ns,
+ },
+ }
+ if err := repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), derived.Values, derived); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
type HelmActionConfigFactory interface {
New(namespace string) (*action.Configuration, error)
}
diff --git a/core/installer/soft/client.go b/core/installer/soft/client.go
index 5686ba5..ae1206d 100644
--- a/core/installer/soft/client.go
+++ b/core/installer/soft/client.go
@@ -49,7 +49,7 @@
if err != nil {
return err
}
- if _, err := client.GetPublicKey(); err != nil {
+ if _, err := client.GetPublicKeys(); err != nil {
return err
}
return nil
@@ -142,6 +142,7 @@
}
func CloneRepository(addr RepositoryAddress, signer ssh.Signer) (*Repository, error) {
+ fmt.Printf("Cloning repository: %s %s\n", addr.Addr, addr.Name)
c, err := git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
URL: addr.FullAddress(),
Auth: &gitssh.PublicKeys{
@@ -209,14 +210,14 @@
}
}
-func (ss *Client) GetPublicKey() ([]byte, error) {
- var ret []byte
+func (ss *Client) GetPublicKeys() ([]string, error) {
+ var ret []string
config := &ssh.ClientConfig{
Auth: []ssh.AuthMethod{
ssh.PublicKeys(ss.Signer),
},
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
- ret = ssh.MarshalAuthorizedKey(key)
+ ret = append(ret, string(ssh.MarshalAuthorizedKey(key)))
return nil
},
}
diff --git a/core/installer/values-tmpl/core-auth.yaml b/core/installer/values-tmpl/core-auth.yaml
index f38c2d1..219b6c4 100644
--- a/core/installer/values-tmpl/core-auth.yaml
+++ b/core/installer/values-tmpl/core-auth.yaml
@@ -113,7 +113,7 @@
default_browser_return_url: https://accounts-ui.{{ .Global.Domain }}/
registration:
lifespan: 10m
- ui_url: https://accounts-ui.{{ .Global.Domain }}/registration
+ ui_url: https://accounts-ui.{{ .Global.Domain }}/register
after:
password:
hooks:
diff --git a/core/installer/values-tmpl/coredns-config.yaml b/core/installer/values-tmpl/coredns-config.yaml
deleted file mode 100644
index 65aba69..0000000
--- a/core/installer/values-tmpl/coredns-config.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
----
-# Source: coredns/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: dodo-dns
- namespace: dodo-core-coredns
-data:
- dodo.conf: |-
- t10.lekva.me:53 {
- file /etc/dodo/t10.lekva.me.db
- errors
- log
- health {
- lameduck 5s
- }
- ready
- cache 30
- loop
- reload
- loadbalance
- }
-
- shve.li:53 {
- file /etc/dodo/shve.li.db
- dnssec {
- key file Kshve.li.+013+55992
- }
- errors
- log
- health {
- lameduck 5s
- }
- ready
- cache 30
- loop
- reload
- loadbalance
- }
-
- shve.li.db: |
- shve.li. IN SOA ns1.shve.li. hostmaster.shve.li. 2015082541 7200 3600 1209600 3600
- @ 10800 IN A 65.109.222.108
- * 10800 IN CNAME shve.li.
- p 10800 IN CNAME shve.li.
- *.p 10800 IN A 10.1.0.1
-
- t10.lekva.me.db: |
- t10.lekva.me. IN SOA ns1.lekva.me. hostmaster.lekva.me. 2015082541 7200 3600 1209600 3600
- * 10800 IN CNAME t10.lekva.me.
- @ 10800 IN A 65.109.222.107
- p 10800 IN CNAME t10.lekva.me.
- *.p 10800 IN A 10.1.0.1
diff --git a/core/installer/values-tmpl/coredns.yaml b/core/installer/values-tmpl/coredns.yaml
index 4310c38..cfd57e6 100644
--- a/core/installer/values-tmpl/coredns.yaml
+++ b/core/installer/values-tmpl/coredns.yaml
@@ -1,398 +1,85 @@
-# apiVersion: helm.toolkit.fluxcd.io/v2beta1
-# kind: HelmRelease
-# metadata:
-# name: rpuppy
-# namespace: {{ .Release.Namespace }}
-# spec:
-# chart:
-# spec:
-# chart: charts/rpuppy
-# sourceRef:
-# kind: GitRepository
-# name: pcloud
-# namespace: {{ .Global.Id }}
-# interval: 1m0s
-# values:
-# Default values for coredns.
-# This is a YAML-formatted file.
-# Declare variables to be passed into your templates.
-
-image:
- repository: coredns/coredns
- # Overrides the image tag whose default is the chart appVersion.
- tag: ""
- pullPolicy: IfNotPresent
- ## Optionally specify an array of imagePullSecrets.
- ## Secrets must be manually created in the namespace.
- ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
- ##
- pullSecrets: []
- # pullSecrets:
- # - name: myRegistryKeySecretName
-
-replicaCount: 1
-
-resources:
- limits:
- cpu: 100m
- memory: 128Mi
- requests:
- cpu: 100m
- memory: 128Mi
-
-rollingUpdate:
- maxUnavailable: 1
- maxSurge: 25%
-
-terminationGracePeriodSeconds: 30
-
-podAnnotations: {}
-# cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
-
-serviceType: "ClusterIP"
-
-prometheus:
- service:
- enabled: false
- annotations:
- prometheus.io/scrape: "true"
- prometheus.io/port: "9153"
- monitor:
- enabled: false
- additionalLabels: {}
- namespace: ""
- interval: ""
-
-service:
-# clusterIP: ""
-# clusterIPs: []
-# loadBalancerIP: ""
-# externalIPs: []
-# externalTrafficPolicy: ""
-# ipFamilyPolicy: ""
- # The name of the Service
- # If not set, a name is generated using the fullname template
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
name: coredns
- annotations: {}
- # metallb.universe.tf/address-pool: local
-
-serviceAccount:
- create: false
- # The name of the ServiceAccount to use
- # If not set and create is true, a name is generated using the fullname template
- name: ""
- annotations: {}
-
-rbac:
- # If true, create & use RBAC resources
- create: true
- # If true, create and use PodSecurityPolicy
- pspEnable: false
- # The name of the ServiceAccount to use.
- # If not set and create is true, a name is generated using the fullname template
- # name:
-
-# isClusterService specifies whether chart should be deployed as cluster-service or normal k8s app.
-isClusterService: true
-
-# Optional priority class to be used for the coredns pods. Used for autoscaler if autoscaler.priorityClassName not set.
-priorityClassName: ""
-
-# Configure the pod level securityContext.
-podSecurityContext: {}
-
-# Configure SecurityContext for Pod.
-# Ensure that required linux capability to bind port number below 1024 is assigned (`CAP_NET_BIND_SERVICE`).
-securityContext:
- capabilities:
- add:
- - NET_BIND_SERVICE
-
-# Default zone is what Kubernetes recommends:
-# https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns-configmap-options
-servers:
-- zones:
- - zone: .
- port: 53
- # If serviceType is nodePort you can specify nodePort here
- # nodePort: 30053
- # hostPort: 53
- plugins:
- - name: log
- # Serves a /health endpoint on :8080, required for livenessProbe
- - name: health
- configBlock: |-
- lameduck 5s
- # Serves a /ready endpoint on :8181, required for readinessProbe
- - name: ready
-
-# Complete example with all the options:
-# - zones: # the `zones` block can be left out entirely, defaults to "."
-# - zone: hello.world. # optional, defaults to "."
-# scheme: tls:// # optional, defaults to "" (which equals "dns://" in CoreDNS)
-# - zone: foo.bar.
-# scheme: dns://
-# use_tcp: true # set this parameter to optionally expose the port on tcp as well as udp for the DNS protocol
-# # Note that this will not work if you are also exposing tls or grpc on the same server
-# port: 12345 # optional, defaults to "" (which equals 53 in CoreDNS)
-# plugins: # the plugins to use for this server block
-# - name: kubernetes # name of plugin, if used multiple times ensure that the plugin supports it!
-# parameters: foo bar # list of parameters after the plugin
-# configBlock: |- # if the plugin supports extra block style config, supply it here
-# hello world
-# foo bar
-
-# Extra configuration that is applied outside of the default zone block.
-# Example to include additional config files, which may come from extraVolumes:
-# extraConfig:
-# import:
-# parameters: /opt/coredns/*.conf
-extraConfig:
- import:
- parameters: /etc/dodo/dodo.conf
-
-# To use the livenessProbe, the health plugin needs to be enabled in CoreDNS' server config
-livenessProbe:
- enabled: true
- initialDelaySeconds: 60
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- successThreshold: 1
-# To use the readinessProbe, the ready plugin needs to be enabled in CoreDNS' server config
-readinessProbe:
- enabled: true
- initialDelaySeconds: 30
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- successThreshold: 1
-
-# expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#affinity-v1-core
-# for example:
-# affinity:
-# nodeAffinity:
-# requiredDuringSchedulingIgnoredDuringExecution:
-# nodeSelectorTerms:
-# - matchExpressions:
-# - key: foo.bar.com/role
-# operator: In
-# values:
-# - master
-affinity: {}
-
-# expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#topologyspreadconstraint-v1-core
-# and supports Helm templating.
-# For example:
-# topologySpreadConstraints:
-# - labelSelector:
-# matchLabels:
-# app.kubernetes.io/name: '{{ template "coredns.name" . }}'
-# app.kubernetes.io/instance: '{{ .Release.Name }}'
-# topologyKey: topology.kubernetes.io/zone
-# maxSkew: 1
-# whenUnsatisfiable: ScheduleAnyway
-# - labelSelector:
-# matchLabels:
-# app.kubernetes.io/name: '{{ template "coredns.name" . }}'
-# app.kubernetes.io/instance: '{{ .Release.Name }}'
-# topologyKey: kubernetes.io/hostname
-# maxSkew: 1
-# whenUnsatisfiable: ScheduleAnyway
-topologySpreadConstraints: []
-
-# Node labels for pod assignment
-# Ref: https://kubernetes.io/docs/user-guide/node-selection/
-nodeSelector: {}
-
-# expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#toleration-v1-core
-# for example:
-# tolerations:
-# - key: foo.bar.com/role
-# operator: Equal
-# value: master
-# effect: NoSchedule
-tolerations: []
-
-# https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
-podDisruptionBudget: {}
-
-# configure custom zone files as per https://coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/
-zoneFiles: []
- # - filename: bar.ge.db
- # domain: bar.ge
- # contents: |
- # bar.ge. IN SOA sns.dns.icann.com. noc.dns.icann.com. 2015082541 7200 3600 1209600 3600
- # * 10800 IN CNAME bar.ge.
- # bar.ge. IN A 192.168.99.102
- # *.t1 10800 IN A 65.109.222.106
- # *.t2 10800 IN A 65.109.222.107
- # *.t3 10800 IN A 65.109.222.108
- # *.t4 10800 IN A 65.109.222.109
- # *.t5 10800 IN A 65.109.222.100
- # @ 10800 IN A 65.109.222.106
- # www 10800 IN CNAME bar.ge.
-
-# optional array of sidecar containers
-extraContainers: []
-# - name: rename-keys
-# image: giolekva/rename-keys:latest
-# imagePullPolicy: Always
-# command: ["/usr/bin/rename-keys.sh"]
-# volumeMounts:
-# - name: dodo
-# mountPath: /etc/dodo
-# optional array of extra volumes to create
-extraVolumes:
-- name: keys
- persistentVolumeClaim:
- claimName: keys
-# - name: dodo
-# configMap:
-# name: dodo-dns
-# - name: some-volume-name
-# emptyDir: {}
-# optional array of mount points for extraVolumes
-extraVolumeMounts:
-- name: keys
- mountPath: /etc/dodo
-# - name: dodo
-# mountPath: /etc/dodo
-# - name: some-volume-name
-# mountPath: /etc/wherever
-
-# optional array of secrets to mount inside coredns container
-# possible usecase: need for secure connection with etcd backend
-extraSecrets: []
-# - name: etcd-client-certs
-# mountPath: /etc/coredns/tls/etcd
-# defaultMode: 420
-# - name: some-fancy-secret
-# mountPath: /etc/wherever
-# defaultMode: 440
-
-# To support legacy deployments using CoreDNS with the "k8s-app: kube-dns" label selectors.
-# See https://github.com/coredns/helm/blob/master/charts/coredns/README.md#adopting-existing-coredns-resources
-# k8sAppLabelOverride: "kube-dns"
-
-# Custom labels to apply to Deployment, Pod, Configmap, Service, ServiceMonitor. Including autoscaler if enabled.
-customLabels: {}
-
-# Custom annotations to apply to Deployment, Pod, Configmap, Service, ServiceMonitor. Including autoscaler if enabled.
-customAnnotations: {}
-
-## Alternative configuration for HPA deployment if wanted
-## Create HorizontalPodAutoscaler object.
-##
-# hpa:
-# enabled: false
-# minReplicas: 1
-# maxReplicas: 10
-# metrics:
-# metrics:
-# - type: Resource
-# resource:
-# name: memory
-# target:
-# type: Utilization
-# averageUtilization: 60
-# - type: Resource
-# resource:
-# name: cpu
-# target:
-# type: Utilization
-# averageUtilization: 60
-
-hpa:
- enabled: false
- minReplicas: 1
- maxReplicas: 2
- metrics: []
-
-## Configue a cluster-proportional-autoscaler for coredns
-# See https://github.com/kubernetes-incubator/cluster-proportional-autoscaler
-autoscaler:
- # Enabled the cluster-proportional-autoscaler
- enabled: false
-
- # Number of cores in the cluster per coredns replica
- coresPerReplica: 256
- # Number of nodes in the cluster per coredns replica
- nodesPerReplica: 16
- # Min size of replicaCount
- min: 0
- # Max size of replicaCount (default of 0 is no max)
- max: 0
- # Whether to include unschedulable nodes in the nodes/cores calculations - this requires version 1.8.0+ of the autoscaler
- includeUnschedulableNodes: false
- # If true does not allow single points of failure to form
- preventSinglePointFailure: true
-
- # Annotations for the coredns proportional autoscaler pods
- podAnnotations: {}
-
- ## Optionally specify some extra flags to pass to cluster-proprtional-autoscaler.
- ## Useful for e.g. the nodelabels flag.
- # customFlags:
- # - --nodelabels=topology.kubernetes.io/zone=us-east-1a
-
- image:
- repository: registry.k8s.io/cpa/cluster-proportional-autoscaler
- tag: "1.8.5"
- pullPolicy: IfNotPresent
- ## Optionally specify an array of imagePullSecrets.
- ## Secrets must be manually created in the namespace.
- ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
- ##
- pullSecrets: []
- # pullSecrets:
- # - name: myRegistryKeySecretName
-
- # Optional priority class to be used for the autoscaler pods. priorityClassName used if not set.
- priorityClassName: ""
-
- # expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#affinity-v1-core
- affinity: {}
-
- # Node labels for pod assignment
- # Ref: https://kubernetes.io/docs/user-guide/node-selection/
- nodeSelector: {}
-
- # expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#toleration-v1-core
- tolerations: []
-
- # resources for autoscaler pod
- resources:
- requests:
- cpu: "20m"
- memory: "10Mi"
- limits:
- cpu: "20m"
- memory: "10Mi"
-
- # Options for autoscaler configmap
- configmap:
- ## Annotations for the coredns-autoscaler configmap
- # i.e. strategy.spinnaker.io/versioned: "false" to ensure configmap isn't renamed
- annotations: {}
-
- # Enables the livenessProbe for cluster-proportional-autoscaler - this requires version 1.8.0+ of the autoscaler
- livenessProbe:
- enabled: true
- initialDelaySeconds: 10
- periodSeconds: 5
- timeoutSeconds: 5
- failureThreshold: 3
- successThreshold: 1
-
- # optional array of sidecar containers
- extraContainers: []
- # - name: some-container-name
- # image: some-image:latest
- # imagePullPolicy: Always
-
-deployment:
- enabled: true
- name: ""
- ## Annotations for the coredns deployment
- annotations: {}
+ namespace: {{ .Release.Namespace }}
+spec:
+ chart:
+ spec:
+ chart: charts/coredns
+ sourceRef:
+ kind: GitRepository
+ name: pcloud
+ namespace: {{ .Global.PCloudEnvName }}
+ interval: 1m0s
+ values:
+ image:
+ repository: coredns/coredns
+ tag: 1.11.1
+ pullPolicy: IfNotPresent
+ replicaCount: 1
+ resources:
+ limits:
+ cpu: 100m
+ memory: 128Mi
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ rollingUpdate:
+ maxUnavailable: 1
+ maxSurge: 25%
+ terminationGracePeriodSeconds: 30
+ serviceType: "ClusterIP"
+ service:
+ name: coredns
+ serviceAccount:
+ create: false
+ rbac:
+ create: true
+ pspEnable: false
+ isClusterService: true
+ securityContext:
+ capabilities:
+ add:
+ - NET_BIND_SERVICE
+ servers:
+ - zones:
+ - zone: .
+ port: 53
+ plugins:
+ - name: log
+ - name: health
+ configBlock: |-
+ lameduck 5s
+ - name: ready
+ extraConfig:
+ import:
+ parameters: {{ .Values.Volume.MountPath }}/coredns.conf
+ extraVolumes:
+ - name: zone-configs
+ persistentVolumeClaim:
+ claimName: {{ .Values.Volume.ClaimName }}
+ extraVolumeMounts:
+ - name: zone-configs
+ mountPath: {{ .Values.Volume.MountPath}}
+ livenessProbe:
+ enabled: true
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 5
+ successThreshold: 1
+ readinessProbe:
+ enabled: true
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 5
+ successThreshold: 1
+ zoneFiles: []
+ hpa:
+ enabled: false
+ autoscaler:
+ enabled: false
+ deployment:
+ enabled: true
diff --git a/core/installer/values-tmpl/dns-zone-controller.jsonschema b/core/installer/values-tmpl/dns-zone-controller.jsonschema
new file mode 100644
index 0000000..7a71483
--- /dev/null
+++ b/core/installer/values-tmpl/dns-zone-controller.jsonschema
@@ -0,0 +1,14 @@
+{
+ "type": "object",
+ "properties": {
+ "Volume": {
+ "type": "object",
+ "properties": {
+ "ClaimName": { "type": "string" },
+ "MountPath": { "type": "string" }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/core/installer/values-tmpl/dns-zone-controller.md b/core/installer/values-tmpl/dns-zone-controller.md
new file mode 100644
index 0000000..a6abe91
--- /dev/null
+++ b/core/installer/values-tmpl/dns-zone-controller.md
@@ -0,0 +1 @@
+Sets up DNS zone controller to automatically generate zone files of registered domains.
diff --git a/core/installer/values-tmpl/dns-zone-controller.yaml b/core/installer/values-tmpl/dns-zone-controller.yaml
new file mode 100644
index 0000000..0df7edb
--- /dev/null
+++ b/core/installer/values-tmpl/dns-zone-controller.yaml
@@ -0,0 +1,23 @@
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: dns-zone-controller
+ namespace: {{ .Release.Namespace }}
+spec:
+ chart:
+ spec:
+ chart: charts/dns-ns-controller
+ sourceRef:
+ kind: GitRepository
+ name: pcloud
+ namespace: {{ .Global.PCloudEnvName }}
+ interval: 1m0s
+ values:
+ image:
+ repository: giolekva/dns-ns-controller
+ tag: latest
+ pullPolicy: Always
+ installCRDs: true
+ volume:
+ claimName: {{ .Values.Volume.ClaimName }}
+ mountPath: {{ .Values.Volume.MountPath }}
diff --git a/core/installer/values-tmpl/dns-zone-storage.yaml b/core/installer/values-tmpl/dns-zone-storage.yaml
new file mode 100644
index 0000000..72b7848
--- /dev/null
+++ b/core/installer/values-tmpl/dns-zone-storage.yaml
@@ -0,0 +1,18 @@
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: dns-zone-storage
+ namespace: {{ .Release.Namespace }}
+spec:
+ chart:
+ spec:
+ chart: charts/volumes
+ sourceRef:
+ kind: GitRepository
+ name: pcloud
+ namespace: {{ .Global.PCloudEnvName }}
+ interval: 10m0s
+ values:
+ name: {{ .Values.Volume.ClaimName }}
+ size: {{ .Values.Volume.Size }}
+ accessMode: ReadWriteMany
diff --git a/core/installer/values-tmpl/ingress-private.yaml b/core/installer/values-tmpl/ingress-private.yaml
index e1870af..fb15cd4 100644
--- a/core/installer/values-tmpl/ingress-private.yaml
+++ b/core/installer/values-tmpl/ingress-private.yaml
@@ -28,3 +28,5 @@
controllerValue: k8s.io/{{ .Global.Id }}-ingress-private
extraArgs:
default-ssl-certificate: "{{ .Global.Id }}-ingress-private/cert-wildcard.p.{{ .Global.Domain }}"
+ admissionWebhooks:
+ enabled: false
diff --git a/core/installer/values-tmpl/ingress-public.yaml b/core/installer/values-tmpl/ingress-public.yaml
index 94773e8..25379d4 100644
--- a/core/installer/values-tmpl/ingress-public.yaml
+++ b/core/installer/values-tmpl/ingress-public.yaml
@@ -15,10 +15,12 @@
values:
fullnameOverride: {{ .Global.PCloudEnvName }}-ingress-public
controller:
+ kind: DaemonSet
+ hostNetwork: true
+ hostPort:
+ enabled: true
service:
- type: LoadBalancer
- annotations:
- metallb.universe.tf/loadBalancerIPs: {{ .Values.IngressPublicIP }}
+ enabled: false
ingressClassByName: true
ingressClassResource:
name: {{ .Global.PCloudEnvName }}-ingress-public
@@ -27,3 +29,7 @@
controllerValue: k8s.io/{{ .Global.PCloudEnvName }}-ingress-public
config:
proxy-body-size: 100M # TODO(giolekva): configurable
+ tcp:
+ "53": "{{ .Global.PCloudEnvName }}-dns-zone-manager/coredns:53"
+ udp:
+ "53": "{{ .Global.PCloudEnvName }}-dns-zone-manager/coredns:53"
diff --git a/core/installer/welcome/env.go b/core/installer/welcome/env.go
index 2c5d332..06ac89f 100644
--- a/core/installer/welcome/env.go
+++ b/core/installer/welcome/env.go
@@ -1,6 +1,7 @@
package welcome
import (
+ "bytes"
"embed"
"encoding/base64"
"encoding/json"
@@ -332,7 +333,7 @@
}
}
{
- ssPubKey, err := ssClient.GetPublicKey()
+ ssPublicKeys, err := ssClient.GetPublicKeys()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -342,7 +343,7 @@
req,
strings.Split(ssClient.Addr, ":")[0],
keys,
- ssPubKey,
+ ssPublicKeys,
); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -628,7 +629,7 @@
req createEnvReq,
repoHost string,
keys *keygen.KeyPair,
- pcloudRepoPublicKey []byte,
+ configRepoPublicKeys []string,
) error {
kust, err := repoIO.ReadKustomization("environments/kustomization.yaml")
if err != nil {
@@ -639,6 +640,10 @@
if err != nil {
return err
}
+ var knownHosts bytes.Buffer
+ for _, key := range configRepoPublicKeys {
+ fmt.Fprintf(&knownHosts, "%s %s\n", repoHost, key)
+ }
for _, tmpl := range tmpls.Templates() {
dstPath := path.Join("environments", req.Name, tmpl.Name())
dst, err := repoIO.Writer(dstPath)
@@ -646,13 +651,14 @@
return err
}
defer dst.Close()
+
if err := tmpl.Execute(dst, map[string]string{
"Name": req.Name,
"PrivateKey": base64.StdEncoding.EncodeToString(keys.RawPrivateKey()),
"PublicKey": base64.StdEncoding.EncodeToString(keys.RawAuthorizedKey()),
"RepoHost": repoHost,
"RepoName": "config",
- "KnownHosts": base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s %s", repoHost, pcloudRepoPublicKey))),
+ "KnownHosts": base64.StdEncoding.EncodeToString(knownHosts.Bytes()),
}); err != nil {
return err
}