blob: c8251ffc49aafba5d470985d4b6e0aab989ee0d6 [file] [log] [blame]
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +04001package installer
2
3import (
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +04004 "bytes"
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +04005 "context"
gio778577f2024-04-29 09:44:38 +04006 "encoding/json"
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +04007 "fmt"
gioe72b54f2024-04-22 10:44:41 +04008 "io"
9 "net/http"
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040010
11 corev1 "k8s.io/api/core/v1"
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040012 "k8s.io/apimachinery/pkg/api/errors"
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040013 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gio778577f2024-04-29 09:44:38 +040014 "k8s.io/apimachinery/pkg/runtime/schema"
15 "k8s.io/client-go/dynamic"
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040016 "k8s.io/client-go/kubernetes"
17 "k8s.io/client-go/rest"
18 "k8s.io/client-go/tools/clientcmd"
19)
20
21type NamespaceCreator interface {
22 Create(name string) error
23}
24
Giorgi Lekveishvili1caed362023-12-13 16:29:43 +040025type ZoneInfo struct {
26 Zone string
27 Records string
28}
29
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040030type ZoneStatusFetcher interface {
gioe72b54f2024-04-22 10:44:41 +040031 Fetch(addr string) (string, error)
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040032}
33
gio0eaf2712024-04-14 13:08:46 +040034type noOpNamespaceCreator struct{}
35
36func (n *noOpNamespaceCreator) Create(name string) error {
37 return nil
38}
39
40func NewNoOpNamespaceCreator() NamespaceCreator {
41 return &noOpNamespaceCreator{}
42}
43
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040044type realNamespaceCreator struct {
45 clientset *kubernetes.Clientset
46}
47
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040048func (n *realNamespaceCreator) Create(name string) error {
49 _, err := n.clientset.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{
50 TypeMeta: metav1.TypeMeta{
51 Kind: " ",
52 APIVersion: "",
53 },
54 ObjectMeta: metav1.ObjectMeta{
55 Name: name,
56 },
57 }, metav1.CreateOptions{})
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040058 if err != nil && errors.IsAlreadyExists(err) {
59 return nil
60 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040061 return err
62}
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040063
gioe72b54f2024-04-22 10:44:41 +040064// TODO(gio): take http client
65type realZoneStatusFetcher struct{}
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040066
gioe72b54f2024-04-22 10:44:41 +040067func (f *realZoneStatusFetcher) Fetch(addr string) (string, error) {
68 fmt.Printf("--- %s\n", addr)
69 resp, err := http.Get(addr)
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040070 if err != nil {
gioe72b54f2024-04-22 10:44:41 +040071 return "", err
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040072 }
gioe72b54f2024-04-22 10:44:41 +040073 var buf bytes.Buffer
74 if _, err := io.Copy(&buf, resp.Body); err != nil {
75 return "", err
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040076 }
gioe72b54f2024-04-22 10:44:41 +040077 return buf.String(), nil
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040078}
79
80func NewNamespaceCreator(kubeconfig string) (NamespaceCreator, error) {
81 clientset, err := NewKubeConfig(kubeconfig)
82 if err != nil {
83 return nil, err
84 }
85 return &realNamespaceCreator{clientset}, nil
86}
87
88func NewZoneStatusFetcher(kubeconfig string) (ZoneStatusFetcher, error) {
gioe72b54f2024-04-22 10:44:41 +040089 return &realZoneStatusFetcher{}, nil
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040090}
91
gio778577f2024-04-29 09:44:38 +040092type HelmReleaseMonitor interface {
93 IsReleased(namespace, name string) (bool, error)
94}
95
96type realHelmReleaseMonitor struct {
97 d dynamic.Interface
98}
99
100func (m *realHelmReleaseMonitor) IsReleased(namespace, name string) (bool, error) {
101 ctx := context.Background()
102 res, err := m.d.Resource(schema.GroupVersionResource{"helm.toolkit.fluxcd.io", "v2beta1", "helmreleases"}).Namespace(namespace).Get(ctx, name, metav1.GetOptions{})
103 if err != nil {
104 return false, err
105 }
106 b, err := res.MarshalJSON()
107 if err != nil {
108 return false, err
109 }
110 var hr helmRelease
111 if err := json.Unmarshal(b, &hr); err != nil {
112 return false, err
113 }
114 for _, c := range hr.Status.Conditions {
115 if c.Type == "Ready" && c.Status == "True" {
116 return true, nil
117 }
118 }
119 return false, nil
120}
121
122func NewHelmReleaseMonitor(kubeconfig string) (HelmReleaseMonitor, error) {
123 c, err := NewKubeConfig(kubeconfig)
124 if err != nil {
125 return nil, err
126 }
127 d := dynamic.New(c.RESTClient())
128 return &realHelmReleaseMonitor{d}, nil
129}
130
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +0400131func NewKubeConfig(kubeconfig string) (*kubernetes.Clientset, error) {
132 if kubeconfig == "" {
133 config, err := rest.InClusterConfig()
134 if err != nil {
135 return nil, err
136 }
137 return kubernetes.NewForConfig(config)
138
139 } else {
140 config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
141 if err != nil {
142 return nil, err
143 }
144 return kubernetes.NewForConfig(config)
145 }
146}