DodoApp: Support remote clusters

Change-Id: I6f4e6a0a32cc723b47c96518d83b1ffdb5169f14
diff --git a/core/installer/schema.go b/core/installer/schema.go
index 5a70519..3c9e237 100644
--- a/core/installer/schema.go
+++ b/core/installer/schema.go
@@ -6,6 +6,7 @@
 
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/cuecontext"
+	"cuelang.org/go/cue/format"
 )
 
 type Kind int
@@ -64,6 +65,7 @@
     ingressClassName: string
 }
 
+value: #Cluster
 value: { %s }
 `
 
@@ -71,18 +73,23 @@
 	if v.Value().Kind() != cue.StructKind {
 		return false
 	}
-	s := fmt.Sprintf(clusterSchema, fmt.Sprintf("%#v", v))
+	vb, err := format.Node(v.Syntax(cue.All()), format.TabIndent(true))
+	if err != nil {
+		return false
+	}
+	s := fmt.Sprintf(clusterSchema, string(vb))
 	c := cuecontext.New()
 	u := c.CompileString(s)
+	if err := u.Err(); err != nil {
+		return false
+	}
 	if err := u.Validate(); err != nil {
 		return false
 	}
-	cluster := u.LookupPath(cue.ParsePath("#Cluster"))
-	vv := u.LookupPath(cue.ParsePath("value"))
-	if err := cluster.Subsume(vv); err == nil {
-		return true
+	if err := u.Eval().Err(); err != nil {
+		return false
 	}
-	return false
+	return true
 }
 
 const networkSchema = `
@@ -96,6 +103,7 @@
 	deallocatePortAddr: string
 }
 
+value: #Network
 value: { %s }
 `
 
@@ -103,15 +111,23 @@
 	if v.Value().Kind() != cue.StructKind {
 		return false
 	}
-	s := fmt.Sprintf(networkSchema, fmt.Sprintf("%#v", v))
+	vb, err := format.Node(v.Syntax(cue.All()), format.TabIndent(true))
+	if err != nil {
+		return false
+	}
+	s := fmt.Sprintf(networkSchema, string(vb))
 	c := cuecontext.New()
 	u := c.CompileString(s)
-	network := u.LookupPath(cue.ParsePath("#Network"))
-	vv := u.LookupPath(cue.ParsePath("value"))
-	if err := network.Subsume(vv); err == nil {
-		return true
+	if err := u.Err(); err != nil {
+		return false
 	}
-	return false
+	if err := u.Validate(); err != nil {
+		return false
+	}
+	if err := u.Eval().Err(); err != nil {
+		return false
+	}
+	return true
 }
 
 const multiNetworkSchema = `
@@ -127,6 +143,7 @@
 
 #Networks: [...#Network]
 
+value: #Networks
 value: %s
 `
 
@@ -134,15 +151,23 @@
 	if v.Value().IncompleteKind() != cue.ListKind {
 		return false
 	}
-	s := fmt.Sprintf(multiNetworkSchema, fmt.Sprintf("%#v", v))
+	vb, err := format.Node(v.Syntax(cue.All()), format.TabIndent(true))
+	if err != nil {
+		return false
+	}
+	s := fmt.Sprintf(multiNetworkSchema, string(vb))
 	c := cuecontext.New()
 	u := c.CompileString(s)
-	networks := u.LookupPath(cue.ParsePath("#Networks"))
-	vv := u.LookupPath(cue.ParsePath("value"))
-	if err := networks.Subsume(vv); err == nil {
-		return true
+	if err := u.Err(); err != nil {
+		return false
 	}
-	return false
+	if err := u.Validate(); err != nil {
+		return false
+	}
+	if err := u.Eval().Err(); err != nil {
+		return false
+	}
+	return true
 }
 
 const authSchema = `
@@ -151,6 +176,7 @@
     groups: string | *""
 }
 
+value: #Auth
 value: { %s }
 `
 
@@ -158,15 +184,23 @@
 	if v.Value().Kind() != cue.StructKind {
 		return false
 	}
-	s := fmt.Sprintf(authSchema, fmt.Sprintf("%#v", v))
+	vb, err := format.Node(v.Syntax(cue.All()), format.TabIndent(true))
+	if err != nil {
+		return false
+	}
+	s := fmt.Sprintf(authSchema, string(vb))
 	c := cuecontext.New()
 	u := c.CompileString(s)
-	auth := u.LookupPath(cue.ParsePath("#Auth"))
-	vv := u.LookupPath(cue.ParsePath("value"))
-	if err := auth.Subsume(vv); err == nil {
-		return true
+	if err := u.Err(); err != nil {
+		return false
 	}
-	return false
+	if err := u.Validate(); err != nil {
+		return false
+	}
+	if err := u.Eval().Err(); err != nil {
+		return false
+	}
+	return true
 }
 
 const sshKeySchema = `
@@ -175,6 +209,7 @@
     private: string
 }
 
+value: #SSHKey
 value: { %s }
 `
 
@@ -182,15 +217,23 @@
 	if v.Value().Kind() != cue.StructKind {
 		return false
 	}
-	s := fmt.Sprintf(sshKeySchema, fmt.Sprintf("%#v", v))
+	vb, err := format.Node(v.Syntax(cue.All()), format.TabIndent(true))
+	if err != nil {
+		return false
+	}
+	s := fmt.Sprintf(sshKeySchema, string(vb))
 	c := cuecontext.New()
 	u := c.CompileString(s)
-	sshKey := u.LookupPath(cue.ParsePath("#SSHKey"))
-	vv := u.LookupPath(cue.ParsePath("value"))
-	if err := sshKey.Subsume(vv); err == nil {
-		return true
+	if err := u.Err(); err != nil {
+		return false
 	}
-	return false
+	if err := u.Validate(); err != nil {
+		return false
+	}
+	if err := u.Eval().Err(); err != nil {
+		return false
+	}
+	return true
 }
 
 type basicSchema struct {
@@ -318,7 +361,7 @@
 		}
 		return s, nil
 	default:
-		return nil, fmt.Errorf("SHOULD NOT REACH!")
+		return nil, fmt.Errorf("SHOULD NOT REACH! field: %s, value: %s", name, v)
 	}
 }