AppManager: monitor installed HelmRelease resources
Change-Id: Ia036e7dda8136ad696d8222e799c4d1b6a9018a9
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 871dae5..8ca42f2 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -12,11 +12,15 @@
"github.com/giolekva/pcloud/core/installer/io"
"github.com/giolekva/pcloud/core/installer/soft"
+
+ "sigs.k8s.io/yaml"
)
const configFileName = "config.yaml"
const kustomizationFileName = "kustomization.yaml"
+var ErrorNotFound = errors.New("not found")
+
type AppManager struct {
repoIO soft.RepoIO
nsCreator NamespaceCreator
@@ -85,22 +89,22 @@
return ret, nil
}
-func (m *AppManager) FindInstance(id string) (AppInstanceConfig, error) {
+func (m *AppManager) FindInstance(id string) (*AppInstanceConfig, error) {
kust, err := soft.ReadKustomization(m.repoIO, filepath.Join(m.appDirRoot, "kustomization.yaml"))
if err != nil {
- return AppInstanceConfig{}, err
+ return nil, err
}
for _, app := range kust.Resources {
if app == id {
cfg, err := m.appConfig(filepath.Join(m.appDirRoot, app, "config.json"))
if err != nil {
- return AppInstanceConfig{}, err
+ return nil, err
}
cfg.Id = id
- return cfg, nil
+ return &cfg, nil
}
}
- return AppInstanceConfig{}, nil
+ return nil, ErrorNotFound
}
func (m *AppManager) AppConfig(name string) (AppInstanceConfig, error) {
@@ -163,6 +167,15 @@
return nil
}
+type Resource struct {
+ Name string `json:"name"`
+ Namespace string `json:"namespace"`
+}
+
+type ReleaseResources struct {
+ Helm []Resource
+}
+
// TODO(gio): rename to CommitApp
func InstallApp(
repo soft.RepoIO,
@@ -172,11 +185,12 @@
ports []PortForward,
resources CueAppData,
data CueAppData,
- opts ...soft.DoOption) error {
+ opts ...soft.DoOption,
+) (ReleaseResources, error) {
// if err := openPorts(rendered.Ports); err != nil {
// return err
// }
- return repo.Do(func(r soft.RepoFS) (string, error) {
+ return ReleaseResources{}, repo.Do(func(r soft.RepoFS) (string, error) {
if err := r.RemoveDir(appDir); err != nil {
return "", err
}
@@ -230,17 +244,17 @@
}
// TODO(gio): commit instanceId -> appDir mapping as well
-func (m *AppManager) Install(app EnvApp, instanceId string, appDir string, namespace string, values map[string]any) error {
+func (m *AppManager) Install(app EnvApp, instanceId string, appDir string, namespace string, values map[string]any) (ReleaseResources, error) {
appDir = filepath.Clean(appDir)
if err := m.repoIO.Pull(); err != nil {
- return err
+ return ReleaseResources{}, err
}
if err := m.nsCreator.Create(namespace); err != nil {
- return err
+ return ReleaseResources{}, err
}
env, err := m.Config()
if err != nil {
- return err
+ return ReleaseResources{}, err
}
release := Release{
AppInstanceId: instanceId,
@@ -250,24 +264,51 @@
}
rendered, err := app.Render(release, env, values)
if err != nil {
- return err
+ return ReleaseResources{}, err
}
- return InstallApp(m.repoIO, appDir, rendered.Name, rendered.Config, rendered.Ports, rendered.Resources, rendered.Data)
+ if _, err := InstallApp(m.repoIO, appDir, rendered.Name, rendered.Config, rendered.Ports, rendered.Resources, rendered.Data); err != nil {
+ return ReleaseResources{}, err
+ }
+ return ReleaseResources{
+ Helm: extractHelm(rendered.Resources),
+ }, nil
}
-func (m *AppManager) Update(app EnvApp, instanceId string, values map[string]any, opts ...soft.DoOption) error {
+type helmRelease struct {
+ Metadata Resource `json:"metadata"`
+ Status struct {
+ Conditions []struct {
+ Type string `json:"type"`
+ Status string `json:"status"`
+ } `json:"conditions"`
+ } `json:"status,omitempty"`
+}
+
+func extractHelm(resources CueAppData) []Resource {
+ ret := make([]Resource, 0, len(resources))
+ for _, contents := range resources {
+ var h helmRelease
+ if err := yaml.Unmarshal(contents, &h); err != nil {
+ panic(err) // TODO(gio): handle
+ }
+ ret = append(ret, h.Metadata)
+ }
+ return ret
+}
+
+func (m *AppManager) Update(app EnvApp, instanceId string, values map[string]any, opts ...soft.DoOption) (ReleaseResources, error) {
if err := m.repoIO.Pull(); err != nil {
- return err
+ return ReleaseResources{}, err
}
env, err := m.Config()
if err != nil {
- return err
+ return ReleaseResources{}, err
}
instanceDir := filepath.Join(m.appDirRoot, instanceId)
instanceConfigPath := filepath.Join(instanceDir, "config.json")
config, err := m.appConfig(instanceConfigPath)
if err != nil {
- return err
+ return ReleaseResources{}, err
}
release := Release{
AppInstanceId: instanceId,
@@ -277,7 +318,7 @@
}
rendered, err := app.Render(release, env, values)
if err != nil {
- return err
+ return ReleaseResources{}, err
}
return InstallApp(m.repoIO, instanceDir, rendered.Name, rendered.Config, rendered.Ports, rendered.Resources, rendered.Data, opts...)
}
@@ -368,17 +409,17 @@
return InfraAppInstanceConfig{}, nil
}
-func (m *InfraAppManager) Install(app InfraApp, appDir string, namespace string, values map[string]any) error {
+func (m *InfraAppManager) Install(app InfraApp, appDir string, namespace string, values map[string]any) (ReleaseResources, error) {
appDir = filepath.Clean(appDir)
if err := m.repoIO.Pull(); err != nil {
- return err
+ return ReleaseResources{}, err
}
if err := m.nsCreator.Create(namespace); err != nil {
- return err
+ return ReleaseResources{}, err
}
infra, err := m.Config()
if err != nil {
- return err
+ return ReleaseResources{}, err
}
release := Release{
Namespace: namespace,
@@ -387,24 +428,24 @@
}
rendered, err := app.Render(release, infra, values)
if err != nil {
- return err
+ return ReleaseResources{}, err
}
return InstallApp(m.repoIO, appDir, rendered.Name, rendered.Config, rendered.Ports, rendered.Resources, rendered.Data)
}
-func (m *InfraAppManager) Update(app InfraApp, instanceId string, values map[string]any, opts ...soft.DoOption) error {
+func (m *InfraAppManager) Update(app InfraApp, instanceId string, values map[string]any, opts ...soft.DoOption) (ReleaseResources, error) {
if err := m.repoIO.Pull(); err != nil {
- return err
+ return ReleaseResources{}, err
}
env, err := m.Config()
if err != nil {
- return err
+ return ReleaseResources{}, err
}
instanceDir := filepath.Join("/infrastructure", instanceId)
instanceConfigPath := filepath.Join(instanceDir, "config.json")
config, err := m.appConfig(instanceConfigPath)
if err != nil {
- return err
+ return ReleaseResources{}, err
}
release := Release{
AppInstanceId: instanceId,
@@ -414,7 +455,7 @@
}
rendered, err := app.Render(release, env, values)
if err != nil {
- return err
+ return ReleaseResources{}, err
}
return InstallApp(m.repoIO, instanceDir, rendered.Name, rendered.Config, rendered.Ports, rendered.Resources, rendered.Data, opts...)
}