AppManager: App installation status monitoring

Change-Id: I64f4ae0d27892b74f8827a275907cb75da09a758
diff --git a/core/installer/status/status.go b/core/installer/status/status.go
new file mode 100644
index 0000000..ebec72f
--- /dev/null
+++ b/core/installer/status/status.go
@@ -0,0 +1,87 @@
+package status
+
+import (
+	"fmt"
+)
+
+type Status int
+
+const (
+	StatusNoStatus Status = iota
+	StatusNotFound
+	StatusPending
+	StatusProcessing
+	StatusSuccess
+	StatusFailure
+)
+
+func IsStatusTerminal(s Status) bool {
+	return s == StatusSuccess || s == StatusFailure
+}
+
+func StatusString(s Status) string {
+	switch s {
+	case StatusNoStatus:
+		return "no_status"
+	case StatusNotFound:
+		return "not_found"
+	case StatusPending:
+		return "pending"
+	case StatusProcessing:
+		return "processing"
+	case StatusSuccess:
+		return "success"
+	case StatusFailure:
+		return "failure"
+	default:
+		panic("MUST NOT REACH!")
+	}
+}
+
+type ResourceType int
+
+const (
+	ResourceHelmRelease ResourceType = iota
+)
+
+type ResourceRef struct {
+	Name      string
+	Namespace string
+}
+
+type Resource struct {
+	ResourceRef
+	Type ResourceType
+}
+
+type Monitor interface {
+	Get(r Resource) (Status, error)
+}
+
+type ResourceMonitor interface {
+	Get(r ResourceRef) (Status, error)
+}
+
+type delegatingMonitor struct {
+	m map[ResourceType]ResourceMonitor
+}
+
+func NewDelegatingMonitor(kubeconfig string) (Monitor, error) {
+	helm, err := NewHelmReleaseMonitor(kubeconfig)
+	if err != nil {
+		return nil, err
+	}
+	return delegatingMonitor{
+		map[ResourceType]ResourceMonitor{
+			ResourceHelmRelease: helm,
+		},
+	}, nil
+}
+
+func (m delegatingMonitor) Get(r Resource) (Status, error) {
+	if rm, ok := m.m[r.Type]; !ok {
+		return StatusNoStatus, fmt.Errorf("unknown resource type: %d", r.Type)
+	} else {
+		return rm.Get(r.ResourceRef)
+	}
+}