Installer: Clean up RepoIO interface
Change-Id: If80d7be1460c725b7df9d1d27c9354cb9141acfe
diff --git a/core/installer/derived.go b/core/installer/derived.go
new file mode 100644
index 0000000..813939e
--- /dev/null
+++ b/core/installer/derived.go
@@ -0,0 +1,168 @@
+package installer
+
+import (
+ "fmt"
+)
+
+type Release struct {
+ Namespace string `json:"namespace"`
+ RepoAddr string `json:"repoAddr"`
+ AppDir string `json:"appDir"`
+}
+
+type Derived struct {
+ Release Release `json:"release"`
+ Global Values `json:"global"`
+ Values map[string]any `json:"input"` // TODO(gio): rename to input
+}
+
+type Network struct {
+ Name string `json:"name,omitempty"`
+ IngressClass string `json:"ingressClass,omitempty"`
+ CertificateIssuer string `json:"certificateIssuer,omitempty"`
+ Domain string `json:"domain,omitempty"`
+ AllocatePortAddr string `json:"allocatePortAddr,omitempty"`
+}
+
+type AppConfig struct {
+ Id string `json:"id"`
+ AppId string `json:"appId"`
+ Config map[string]any `json:"config"`
+ Derived Derived `json:"derived"`
+}
+
+func (a AppConfig) Input(schema Schema) map[string]any {
+ ret, err := derivedToConfig(a.Derived.Values, schema)
+ if err != nil {
+ panic(err) // TODO(gio): handle
+ }
+ return ret
+}
+
+func deriveValues(values any, schema Schema, networks []Network) (map[string]any, error) {
+ ret := make(map[string]any)
+ for k, def := range schema.Fields() {
+ // TODO(gio): validate that it is map
+ v, ok := values.(map[string]any)[k]
+ // TODO(gio): if missing use default value
+ if !ok {
+ if def.Kind() == KindSSHKey {
+ key, err := NewECDSASSHKeyPair("tmp")
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = map[string]string{
+ "public": string(key.RawAuthorizedKey()),
+ "private": string(key.RawPrivateKey()),
+ }
+ }
+ continue
+ }
+ switch def.Kind() {
+ case KindBoolean:
+ ret[k] = v
+ case KindString:
+ ret[k] = v
+ case KindInt:
+ ret[k] = v
+ case KindNetwork:
+ n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = n
+ case KindAuth:
+ r, err := deriveValues(v, AuthSchema, networks)
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = r
+ case KindSSHKey:
+ r, err := deriveValues(v, SSHKeySchema, networks)
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = r
+ case KindStruct:
+ r, err := deriveValues(v, def, networks)
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = r
+ default:
+ return nil, fmt.Errorf("Should not reach!")
+ }
+ }
+ return ret, nil
+}
+
+func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
+ ret := make(map[string]any)
+ for k, def := range schema.Fields() {
+ v, ok := derived[k]
+ // TODO(gio): if missing use default value
+ if !ok {
+ continue
+ }
+ switch def.Kind() {
+ case KindBoolean:
+ ret[k] = v
+ case KindString:
+ ret[k] = v
+ case KindInt:
+ ret[k] = v
+ case KindNetwork:
+ vm, ok := v.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("expected map")
+ }
+ name, ok := vm["name"]
+ if !ok {
+ return nil, fmt.Errorf("expected network name")
+ }
+ ret[k] = name
+ case KindAuth:
+ vm, ok := v.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("expected map")
+ }
+ r, err := derivedToConfig(vm, AuthSchema)
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = r
+ case KindSSHKey:
+ vm, ok := v.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("expected map")
+ }
+ r, err := derivedToConfig(vm, SSHKeySchema)
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = r
+ case KindStruct:
+ vm, ok := v.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("expected map")
+ }
+ r, err := derivedToConfig(vm, def)
+ if err != nil {
+ return nil, err
+ }
+ ret[k] = r
+ default:
+ return nil, fmt.Errorf("Should not reach!")
+ }
+ }
+ 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)
+}