blob: a8ed275936a8782e38fbe98b9126d67d5c398d57 [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
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040034type realNamespaceCreator struct {
35 clientset *kubernetes.Clientset
36}
37
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040038func (n *realNamespaceCreator) Create(name string) error {
39 _, err := n.clientset.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{
40 TypeMeta: metav1.TypeMeta{
41 Kind: " ",
42 APIVersion: "",
43 },
44 ObjectMeta: metav1.ObjectMeta{
45 Name: name,
46 },
47 }, metav1.CreateOptions{})
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040048 if err != nil && errors.IsAlreadyExists(err) {
49 return nil
50 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040051 return err
52}
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040053
gioe72b54f2024-04-22 10:44:41 +040054// TODO(gio): take http client
55type realZoneStatusFetcher struct{}
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040056
gioe72b54f2024-04-22 10:44:41 +040057func (f *realZoneStatusFetcher) Fetch(addr string) (string, error) {
58 fmt.Printf("--- %s\n", addr)
59 resp, err := http.Get(addr)
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040060 if err != nil {
gioe72b54f2024-04-22 10:44:41 +040061 return "", err
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040062 }
gioe72b54f2024-04-22 10:44:41 +040063 var buf bytes.Buffer
64 if _, err := io.Copy(&buf, resp.Body); err != nil {
65 return "", err
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040066 }
gioe72b54f2024-04-22 10:44:41 +040067 return buf.String(), nil
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040068}
69
70func NewNamespaceCreator(kubeconfig string) (NamespaceCreator, error) {
71 clientset, err := NewKubeConfig(kubeconfig)
72 if err != nil {
73 return nil, err
74 }
75 return &realNamespaceCreator{clientset}, nil
76}
77
78func NewZoneStatusFetcher(kubeconfig string) (ZoneStatusFetcher, error) {
gioe72b54f2024-04-22 10:44:41 +040079 return &realZoneStatusFetcher{}, nil
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +040080}
81
gio778577f2024-04-29 09:44:38 +040082type HelmReleaseMonitor interface {
83 IsReleased(namespace, name string) (bool, error)
84}
85
86type realHelmReleaseMonitor struct {
87 d dynamic.Interface
88}
89
90func (m *realHelmReleaseMonitor) IsReleased(namespace, name string) (bool, error) {
91 ctx := context.Background()
92 res, err := m.d.Resource(schema.GroupVersionResource{"helm.toolkit.fluxcd.io", "v2beta1", "helmreleases"}).Namespace(namespace).Get(ctx, name, metav1.GetOptions{})
93 if err != nil {
94 return false, err
95 }
96 b, err := res.MarshalJSON()
97 if err != nil {
98 return false, err
99 }
100 var hr helmRelease
101 if err := json.Unmarshal(b, &hr); err != nil {
102 return false, err
103 }
104 for _, c := range hr.Status.Conditions {
105 if c.Type == "Ready" && c.Status == "True" {
106 return true, nil
107 }
108 }
109 return false, nil
110}
111
112func NewHelmReleaseMonitor(kubeconfig string) (HelmReleaseMonitor, error) {
113 c, err := NewKubeConfig(kubeconfig)
114 if err != nil {
115 return nil, err
116 }
117 d := dynamic.New(c.RESTClient())
118 return &realHelmReleaseMonitor{d}, nil
119}
120
Giorgi Lekveishvilicd9e42c2023-12-13 09:49:44 +0400121func NewKubeConfig(kubeconfig string) (*kubernetes.Clientset, error) {
122 if kubeconfig == "" {
123 config, err := rest.InClusterConfig()
124 if err != nil {
125 return nil, err
126 }
127 return kubernetes.NewForConfig(config)
128
129 } else {
130 config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
131 if err != nil {
132 return nil, err
133 }
134 return kubernetes.NewForConfig(config)
135 }
136}