blob: 08cb863a42742539eba08ebd111e313194e628c8 [file] [log] [blame]
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +04001package tasks
2
3import (
4 "context"
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +04005 "net"
6 "text/template"
7 "time"
8
9 "github.com/Masterminds/sprig/v3"
10
11 "github.com/giolekva/pcloud/core/installer"
12)
13
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040014type Check func(ch Check) error
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040015
16func NewDNSResolverTask(
17 name string,
18 expected []net.IP,
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040019 env Env,
20 st *state,
21) Task {
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040022 ctx := context.TODO()
23 t := newLeafTask("Configure DNS", func() error {
24 repo, err := st.ssClient.GetRepo("config")
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040025 if err != nil {
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040026 return err
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040027 }
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040028 r := installer.NewRepoIO(repo, st.ssClient.Signer)
29 {
30 key, err := newDNSSecKey(env.Domain)
31 if err != nil {
32 return err
33 }
34 out, err := r.Writer("dns-zone.yaml")
35 if err != nil {
36 return err
37 }
38 defer out.Close()
39 dnsZoneTmpl, err := template.New("config").Funcs(sprig.TxtFuncMap()).Parse(`
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040040apiVersion: dodo.cloud.dodo.cloud/v1
41kind: DNSZone
42metadata:
43 name: dns-zone
44 namespace: {{ .namespace }}
45spec:
46 zone: {{ .zone }}
47 privateIP: 10.1.0.1
48 publicIPs:
49{{ range .publicIPs }}
50 - {{ .String }}
51{{ end }}
52 nameservers:
53{{ range .publicIPs }}
54 - {{ .String }}
55{{ end }}
56 dnssec:
57 enabled: true
58 secretName: dnssec-key
59---
60apiVersion: v1
61kind: Secret
62metadata:
63 name: dnssec-key
64 namespace: {{ .namespace }}
65type: Opaque
66data:
67 basename: {{ .dnssec.Basename | b64enc }}
68 key: {{ .dnssec.Key | toString | b64enc }}
69 private: {{ .dnssec.Private | toString | b64enc }}
70 ds: {{ .dnssec.DS | toString | b64enc }}
71`)
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040072 if err != nil {
73 return err
74 }
75 if err := dnsZoneTmpl.Execute(out, map[string]any{
76 "namespace": env.Name,
77 "zone": env.Domain,
78 "dnssec": key,
79 "publicIPs": st.publicIPs,
80 }); err != nil {
81 return err
82 }
83 rootKust := installer.NewKustomization()
84 rootKust.AddResources("dns-zone.yaml")
85 if err := r.WriteKustomization("kustomization.yaml", rootKust); err != nil {
86 return err
87 }
88 r.CommitAndPush("configure dns zone")
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040089 }
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040090
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040091 gotExpectedIPs := func(actual []net.IP) bool {
92 for _, a := range actual {
93 found := false
94 for _, e := range expected {
95 if a.Equal(e) {
96 found = true
97 break
98 }
99 }
100 if !found {
101 return false
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +0400102 }
103 }
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +0400104 return true
105 }
106 check := func(check Check) error {
107 addrs, err := net.LookupIP(name)
108 if err == nil && gotExpectedIPs(addrs) {
109 return err
110 }
111 select {
112 case <-ctx.Done():
113 return nil
114 case <-time.After(5 * time.Second):
115 return check(check)
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +0400116 }
117 }
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +0400118 return check(check)
119 })
120 return &t
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +0400121}