AppManager: Recursively monitor dodo resources
Change-Id: I23f3014e416f5b68f8909dbfbcba27db66eaee3f
diff --git a/core/installer/status/instance.go b/core/installer/status/instance.go
index 285f68c..ad05e5a 100644
--- a/core/installer/status/instance.go
+++ b/core/installer/status/instance.go
@@ -1,28 +1,138 @@
package status
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+)
+
type InstanceMonitor struct {
m Monitor
- instances map[string][]Resource
+ instances map[string]ResourceOuts
}
func NewInstanceMonitor(m Monitor) *InstanceMonitor {
return &InstanceMonitor{
m: m,
- instances: map[string][]Resource{},
+ instances: map[string]ResourceOuts{},
}
}
-func (m *InstanceMonitor) Monitor(id string, resources []Resource) {
+func (m *InstanceMonitor) Monitor(id string, resources ResourceOuts) {
m.instances[id] = resources
}
-func (m *InstanceMonitor) Get(id string) (ret map[Resource]Status, err error) {
- ret = map[Resource]Status{}
- for _, r := range m.instances[id] {
- ret[r], err = m.m.Get(r)
- if err != nil {
- break
+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
}
}
- return
+ 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.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"`
+ 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
}