blob: 9ad2ff0ee078e2cb612be58db499e18fdf6108ce [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 }
gio0af17d62025-05-01 15:36:00 +040067 for _, i := range out.Volume {
68 if s, err := m.monitor(namespace, DodoResource{"volume", i.Name}, i, ret); err != nil {
69 return StatusNoStatus, err
70 } else {
71 s = mergeStatus(status, s)
72 }
73 }
gioda708652025-04-30 14:57:38 +040074 for _, i := range out.PostgreSQL {
75 if s, err := m.monitor(namespace, DodoResource{"postgresql", i.Name}, i, ret); err != nil {
76 return StatusNoStatus, err
77 } else {
78 s = mergeStatus(status, s)
79 }
80 }
81 for _, i := range out.MongoDB {
82 if s, err := m.monitor(namespace, DodoResource{"mongodb", i.Name}, i, ret); err != nil {
83 return StatusNoStatus, err
84 } else {
85 s = mergeStatus(status, s)
86 }
87 }
88 for _, i := range out.Ingress {
89 name := fmt.Sprintf("https://%s.%s", i.Subdomain, i.Network.Domain)
90 if s, err := m.monitor(namespace, DodoResource{"ingress", name}, i.ResourceOut, ret); err != nil {
91 return StatusNoStatus, err
92 } else {
93 s = mergeStatus(status, s)
94 }
95 }
gioa6024622025-05-01 18:37:16 +040096 for _, i := range out.Services {
97 if s, err := m.monitor(namespace, DodoResource{"service", i.Name}, i, ret); err != nil {
98 return StatusNoStatus, err
99 } else {
100 s = mergeStatus(status, s)
101 }
102 }
gioda708652025-04-30 14:57:38 +0400103 ret[resource] = status
104 return status, nil
105}
106
107type resourceIngress struct {
108 ResourceOut
109 Network struct {
110 Domain string `json:"domain"`
111 } `json:"network"`
112 Subdomain string `json:"subdomain"`
113}
114
115type resourceHelm struct {
116 Id string `json:"id"`
117 Name string `json:"name"`
118}
119
120type ResourceOut struct {
121 Name string `json:"name"`
gio0af17d62025-05-01 15:36:00 +0400122 Volume map[string]ResourceOut `json:"volume"`
gioda708652025-04-30 14:57:38 +0400123 PostgreSQL map[string]ResourceOut `json:"postgresql"`
124 MongoDB map[string]ResourceOut `json:"mongodb"`
125 Ingress map[string]resourceIngress `json:"ingress"`
gioa6024622025-05-01 18:37:16 +0400126 Services map[string]ResourceOut `json:"services"`
gioda708652025-04-30 14:57:38 +0400127 Helm map[string]resourceHelm `json:"helmR"`
128}
129
130type ResourceOuts struct {
131 Release struct {
132 Namespace string `json:"namespace"`
133 }
134 Outs map[string]ResourceOut `json:"outs"`
135}
136
137type DodoResource struct {
138 Type string
139 Name string
140}
141
142type DodoResourceStatus struct {
143 Type string `json:"type"`
144 Name string `json:"name"`
145 Status string `json:"status"`
146}
147
148func DecodeResourceOuts(raw []byte) (ResourceOuts, error) {
149 var outs ResourceOuts
150 if err := json.NewDecoder(bytes.NewReader(raw)).Decode(&outs); err != nil {
151 return ResourceOuts{}, err
152 }
153 return outs, nil
giof8acc612025-04-26 08:20:55 +0400154}