appmanager: replace svelte implementation with go based one
diff --git a/core/installer/repoio.go b/core/installer/repoio.go
index b01cd82..0582594 100644
--- a/core/installer/repoio.go
+++ b/core/installer/repoio.go
@@ -31,9 +31,10 @@
Writer(path string) (io.WriteCloser, error)
CreateDir(path string) error
RemoveDir(path string) error
- InstallApp(app App, path string, values map[string]any) error
- FindAllInstances(root string, name string) ([]AppConfig, error)
- FindInstance(root string, name string) (AppConfig, error)
+ InstallApp(app App, path string, values map[string]any, derived Derived) error
+ RemoveApp(path string) error
+ FindAllInstances(root string, appId string) ([]AppConfig, error)
+ FindInstance(root string, id string) (AppConfig, error)
}
type repoIO struct {
@@ -181,12 +182,24 @@
return err
}
-type AppConfig struct {
- Id string `json:"id"`
- Config map[string]any `json:"config"`
+type Release struct {
+ Namespace string `json:"Namespace"`
}
-func (r *repoIO) InstallApp(app App, appRootDir string, values map[string]any) error {
+type Derived struct {
+ Release Release `json:"Release"`
+ Global Values `json:"Global"`
+ Values map[string]any `json:"Values"`
+}
+
+type AppConfig struct {
+ Id string `json:"id"`
+ AppId string `json:"appId"`
+ Config map[string]any `json:"config"`
+ Derived Derived `json:"derived"`
+}
+
+func (r *repoIO) InstallApp(app App, appRootDir string, values map[string]any, derived Derived) error {
if !filepath.IsAbs(appRootDir) {
return fmt.Errorf("Expected absolute path: %s", appRootDir)
}
@@ -217,8 +230,9 @@
return err
}
cfg := AppConfig{
- Id: app.Name,
- Config: values,
+ AppId: app.Name,
+ Config: values,
+ Derived: derived,
}
if err := r.WriteYaml(path.Join(appRootDir, configFileName), cfg); err != nil {
return err
@@ -233,7 +247,7 @@
return err
}
defer out.Close()
- if err := t.Execute(out, values); err != nil {
+ if err := t.Execute(out, derived); err != nil {
return err
}
}
@@ -244,6 +258,19 @@
return r.CommitAndPush(fmt.Sprintf("install: %s", app.Name))
}
+func (r *repoIO) RemoveApp(appRootDir string) error {
+ r.RemoveDir(appRootDir)
+ parent, child := filepath.Split(appRootDir)
+ kustPath := filepath.Join(parent, "kustomization.yaml")
+ kust, err := r.ReadKustomization(kustPath)
+ if err != nil {
+ return err
+ }
+ kust.RemoveResources(child)
+ r.WriteKustomization(kustPath, *kust)
+ return r.CommitAndPush(fmt.Sprintf("uninstall: %s", child))
+}
+
func (r *repoIO) FindAllInstances(root string, name string) ([]AppConfig, error) {
if !filepath.IsAbs(root) {
return nil, fmt.Errorf("Expected absolute path: %s", root)
@@ -258,14 +285,15 @@
if err != nil {
return nil, err
}
- if cfg.Id == name {
+ cfg.Id = app
+ if cfg.AppId == name {
ret = append(ret, cfg)
}
}
return ret, nil
}
-func (r *repoIO) FindInstance(root string, name string) (AppConfig, error) {
+func (r *repoIO) FindInstance(root string, id string) (AppConfig, error) {
if !filepath.IsAbs(root) {
return AppConfig{}, fmt.Errorf("Expected absolute path: %s", root)
}
@@ -274,8 +302,13 @@
return AppConfig{}, err
}
for _, app := range kust.Resources {
- if app == name {
- return r.ReadAppConfig(filepath.Join(root, app, "config.yaml"))
+ if app == id {
+ cfg, err := r.ReadAppConfig(filepath.Join(root, app, "config.yaml"))
+ if err != nil {
+ return AppConfig{}, err
+ }
+ cfg.Id = id
+ return cfg, nil
}
}
return AppConfig{}, nil
@@ -301,3 +334,71 @@
return yaml.UnmarshalStrict(contents, o)
}
}
+
+func deriveValues(values any, schema map[string]any, networks []Network) (map[string]any, error) {
+ ret := make(map[string]any)
+ for k, v := range values.(map[string]any) { // TODO(giolekva): validate
+ def, err := fieldSchema(schema, k)
+ if err != nil {
+ return nil, err
+ }
+ t, ok := def["type"]
+ if !ok {
+ return nil, fmt.Errorf("Found field with undefined type: %s", k)
+ }
+ if t == "string" {
+ role, ok := def["role"]
+ if ok && role == "network" {
+ n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = n
+ } else {
+ ret[k] = v
+ }
+ } else {
+ ret[k], err = deriveValues(v, def, networks)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ return ret, nil
+}
+
+func findNetwork(networks []Network, name string) (Network, error) {
+ for _, n := range networks {
+ if n.Name == name {
+ return n, nil
+ }
+ }
+ return Network{}, fmt.Errorf("Network not found: %s", name)
+}
+
+func fieldSchema(schema map[string]any, key string) (map[string]any, error) {
+ properties, ok := schema["properties"]
+ if !ok {
+ return nil, fmt.Errorf("Properties not found")
+ }
+ propMap, ok := properties.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("Expected properties to be map")
+ }
+ def, ok := propMap[key]
+ if !ok {
+ return nil, fmt.Errorf("Unknown field: %s", key)
+ }
+ ret, ok := def.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("Invalid schema")
+ }
+ return ret, nil
+}
+
+type Network struct {
+ Name string
+ IngressClass string
+ CertificateIssuer string
+ Domain string
+}