blob: ad05e5a657d63b62a6450c6981d9800e50127fd5 [file] [log] [blame]
giof8acc612025-04-26 08:20:55 +04001package status
2
gioda708652025-04-30 14:57:38 +04003import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7)
8
giof8acc612025-04-26 08:20:55 +04009type InstanceMonitor struct {
10 m Monitor
gioda708652025-04-30 14:57:38 +040011 instances map[string]ResourceOuts
giof8acc612025-04-26 08:20:55 +040012}
13
14func NewInstanceMonitor(m Monitor) *InstanceMonitor {
15 return &InstanceMonitor{
16 m: m,
gioda708652025-04-30 14:57:38 +040017 instances: map[string]ResourceOuts{},
giof8acc612025-04-26 08:20:55 +040018 }
19}
20
gioda708652025-04-30 14:57:38 +040021func (m *InstanceMonitor) Monitor(id string, resources ResourceOuts) {
giof8acc612025-04-26 08:20:55 +040022 m.instances[id] = resources
23}
24
gioda708652025-04-30 14:57:38 +040025func (m *InstanceMonitor) Get(id string) (map[DodoResource]Status, error) {
26 ret := map[DodoResource]Status{}
27 namespace := m.instances[id].Release.Namespace
28 for _, out := range m.instances[id].Outs {
29 if _, err := m.monitor(namespace, DodoResource{"internal", out.Name}, out, ret); err != nil {
30 return nil, err
giof8acc612025-04-26 08:20:55 +040031 }
32 }
gioda708652025-04-30 14:57:38 +040033 for i := range ret {
34 if i.Type == "internal" {
35 delete(ret, i)
36 }
37 }
38 return ret, nil
39}
40
41func mergeStatus(a Status, b Status) Status {
42 if a > b {
43 return a
44 } else {
45 return b
46 }
47}
48
49// TODO(gio): handle volume
50func (m *InstanceMonitor) monitor(namespace string, resource DodoResource, out ResourceOut, ret map[DodoResource]Status) (Status, error) {
51 status := StatusNoStatus
52 for _, h := range out.Helm {
53 hs, err := m.m.Get(Resource{
54 Type: ResourceHelmRelease,
55 ResourceRef: ResourceRef{
56 Id: h.Id,
57 Name: h.Name,
58 Namespace: namespace,
59 },
60 })
61 fmt.Println(hs, err)
62 if err != nil {
63 return StatusNoStatus, err
64 }
65 status = mergeStatus(status, hs)
66 }
67 for _, i := range out.PostgreSQL {
68 if s, err := m.monitor(namespace, DodoResource{"postgresql", i.Name}, i, ret); err != nil {
69 return StatusNoStatus, err
70 } else {
71 s = mergeStatus(status, s)
72 }
73 }
74 for _, i := range out.MongoDB {
75 if s, err := m.monitor(namespace, DodoResource{"mongodb", i.Name}, i, ret); err != nil {
76 return StatusNoStatus, err
77 } else {
78 s = mergeStatus(status, s)
79 }
80 }
81 for _, i := range out.Ingress {
82 name := fmt.Sprintf("https://%s.%s", i.Subdomain, i.Network.Domain)
83 if s, err := m.monitor(namespace, DodoResource{"ingress", name}, i.ResourceOut, ret); err != nil {
84 return StatusNoStatus, err
85 } else {
86 s = mergeStatus(status, s)
87 }
88 }
89 ret[resource] = status
90 return status, nil
91}
92
93type resourceIngress struct {
94 ResourceOut
95 Network struct {
96 Domain string `json:"domain"`
97 } `json:"network"`
98 Subdomain string `json:"subdomain"`
99}
100
101type resourceHelm struct {
102 Id string `json:"id"`
103 Name string `json:"name"`
104}
105
106type ResourceOut struct {
107 Name string `json:"name"`
108 PostgreSQL map[string]ResourceOut `json:"postgresql"`
109 MongoDB map[string]ResourceOut `json:"mongodb"`
110 Ingress map[string]resourceIngress `json:"ingress"`
111 Helm map[string]resourceHelm `json:"helmR"`
112}
113
114type ResourceOuts struct {
115 Release struct {
116 Namespace string `json:"namespace"`
117 }
118 Outs map[string]ResourceOut `json:"outs"`
119}
120
121type DodoResource struct {
122 Type string
123 Name string
124}
125
126type DodoResourceStatus struct {
127 Type string `json:"type"`
128 Name string `json:"name"`
129 Status string `json:"status"`
130}
131
132func DecodeResourceOuts(raw []byte) (ResourceOuts, error) {
133 var outs ResourceOuts
134 if err := json.NewDecoder(bytes.NewReader(raw)).Decode(&outs); err != nil {
135 return ResourceOuts{}, err
136 }
137 return outs, nil
giof8acc612025-04-26 08:20:55 +0400138}