| package status |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "fmt" |
| ) |
| |
| type InstanceMonitor struct { |
| m Monitor |
| instances map[string]ResourceOuts |
| } |
| |
| func NewInstanceMonitor(m Monitor) *InstanceMonitor { |
| return &InstanceMonitor{ |
| m: m, |
| instances: map[string]ResourceOuts{}, |
| } |
| } |
| |
| func (m *InstanceMonitor) Monitor(id string, resources ResourceOuts) { |
| m.instances[id] = resources |
| } |
| |
| func (m *InstanceMonitor) Get(id string) (map[DodoResource]Status, error) { |
| ret := map[DodoResource]Status{} |
| namespace := m.instances[id].Release.Namespace |
| for _, out := range m.instances[id].Outs { |
| if _, err := m.monitor(namespace, DodoResource{"internal", out.Name}, out, ret); err != nil { |
| return nil, err |
| } |
| } |
| for i := range ret { |
| if i.Type == "internal" { |
| delete(ret, i) |
| } |
| } |
| return ret, nil |
| } |
| |
| func mergeStatus(a Status, b Status) Status { |
| if a > b { |
| return a |
| } else { |
| return b |
| } |
| } |
| |
| // TODO(gio): handle volume |
| func (m *InstanceMonitor) monitor(namespace string, resource DodoResource, out ResourceOut, ret map[DodoResource]Status) (Status, error) { |
| status := StatusNoStatus |
| for _, h := range out.Helm { |
| hs, err := m.m.Get(Resource{ |
| Type: ResourceHelmRelease, |
| ResourceRef: ResourceRef{ |
| Id: h.Id, |
| Name: h.Name, |
| Namespace: namespace, |
| }, |
| }) |
| fmt.Println(hs, err) |
| if err != nil { |
| return StatusNoStatus, err |
| } |
| status = mergeStatus(status, hs) |
| } |
| for _, i := range out.Volume { |
| if s, err := m.monitor(namespace, DodoResource{"volume", i.Name}, i, ret); err != nil { |
| return StatusNoStatus, err |
| } else { |
| s = mergeStatus(status, s) |
| } |
| } |
| for _, i := range out.PostgreSQL { |
| if s, err := m.monitor(namespace, DodoResource{"postgresql", i.Name}, i, ret); err != nil { |
| return StatusNoStatus, err |
| } else { |
| s = mergeStatus(status, s) |
| } |
| } |
| for _, i := range out.MongoDB { |
| if s, err := m.monitor(namespace, DodoResource{"mongodb", i.Name}, i, ret); err != nil { |
| return StatusNoStatus, err |
| } else { |
| s = mergeStatus(status, s) |
| } |
| } |
| for _, i := range out.Ingress { |
| name := fmt.Sprintf("https://%s.%s", i.Subdomain, i.Network.Domain) |
| if s, err := m.monitor(namespace, DodoResource{"ingress", name}, i.ResourceOut, ret); err != nil { |
| return StatusNoStatus, err |
| } else { |
| s = mergeStatus(status, s) |
| } |
| } |
| ret[resource] = status |
| return status, nil |
| } |
| |
| type resourceIngress struct { |
| ResourceOut |
| Network struct { |
| Domain string `json:"domain"` |
| } `json:"network"` |
| Subdomain string `json:"subdomain"` |
| } |
| |
| type resourceHelm struct { |
| Id string `json:"id"` |
| Name string `json:"name"` |
| } |
| |
| type ResourceOut struct { |
| Name string `json:"name"` |
| Volume map[string]ResourceOut `json:"volume"` |
| PostgreSQL map[string]ResourceOut `json:"postgresql"` |
| MongoDB map[string]ResourceOut `json:"mongodb"` |
| Ingress map[string]resourceIngress `json:"ingress"` |
| Helm map[string]resourceHelm `json:"helmR"` |
| } |
| |
| type ResourceOuts struct { |
| Release struct { |
| Namespace string `json:"namespace"` |
| } |
| Outs map[string]ResourceOut `json:"outs"` |
| } |
| |
| type DodoResource struct { |
| Type string |
| Name string |
| } |
| |
| type DodoResourceStatus struct { |
| Type string `json:"type"` |
| Name string `json:"name"` |
| Status string `json:"status"` |
| } |
| |
| func DecodeResourceOuts(raw []byte) (ResourceOuts, error) { |
| var outs ResourceOuts |
| if err := json.NewDecoder(bytes.NewReader(raw)).Decode(&outs); err != nil { |
| return ResourceOuts{}, err |
| } |
| return outs, nil |
| } |