gerrit: auto configure ssh keys

Change-Id: I9c3091e4bb998fa6c846c3c60c2801c7daa45bcf
diff --git a/core/installer/schema.go b/core/installer/schema.go
index a692ecf..b96cc13 100644
--- a/core/installer/schema.go
+++ b/core/installer/schema.go
@@ -17,6 +17,7 @@
 	KindStruct       = 2
 	KindNetwork      = 3
 	KindAuth         = 5
+	KindSSHKey       = 6
 	KindNumber       = 4
 )
 
@@ -32,6 +33,13 @@
 	},
 }
 
+var SSHKeySchema Schema = structSchema{
+	fields: map[string]Schema{
+		"public":  basicSchema{KindString},
+		"private": basicSchema{KindString},
+	},
+}
+
 const networkSchema = `
 #Network: {
     name: string
@@ -82,6 +90,30 @@
 	return false
 }
 
+const sshKeySchema = `
+#SSHKey: {
+    public: string
+    private: string
+}
+
+value: { %s }
+`
+
+func isSSHKey(v cue.Value) bool {
+	if v.Value().Kind() != cue.StructKind {
+		return false
+	}
+	s := fmt.Sprintf(sshKeySchema, fmt.Sprintf("%#v", v))
+	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
+	}
+	return false
+}
+
 type basicSchema struct {
 	kind Kind
 }
@@ -119,6 +151,8 @@
 			return basicSchema{KindNetwork}, nil
 		} else if isAuth(v) {
 			return basicSchema{KindAuth}, nil
+		} else if isSSHKey(v) {
+			return basicSchema{KindSSHKey}, nil
 		}
 		s := structSchema{make(map[string]Schema)}
 		f, err := v.Fields(cue.Schema())