Canvas: build application infrastructure with drag and drop
Change-Id: I5cfd12e67794f3376c5c025af29470d52d77cf16
diff --git a/apps/canvas/server/main.go b/apps/canvas/server/main.go
new file mode 100644
index 0000000..7608049
--- /dev/null
+++ b/apps/canvas/server/main.go
@@ -0,0 +1,118 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "os"
+)
+
+type deployReq struct {
+ State any `json:"state"`
+ Config map[string]any `json:"config"`
+}
+
+type req struct {
+ Id string `json:"id"`
+ SSHPrivateKey string `json:"sshPrivateKey"`
+ Config map[string]any `json:"config"`
+}
+
+const publicKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPK58vMu0MwIzdZT+mqpIBkhl48p9+/YwDCZv7MgTesF`
+const privateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDyufLzLtDMCM3WU/pqqSAZIZePKffv2MAwmb+zIE3rBQAAAKA42oIlONqC
+JQAAAAtzc2gtZWQyNTUxOQAAACDyufLzLtDMCM3WU/pqqSAZIZePKffv2MAwmb+zIE3rBQ
+AAAEC2CdpXtaFfqA8/mqjf9uITU1mrPOI4CeWgiQFEefFW1/K58vMu0MwIzdZT+mqpIBkh
+l48p9+/YwDCZv7MgTesFAAAAGXJvb3RAY2FudmFzYnVpbGRlci1tYXN0ZXIBAgME
+-----END OPENSSH PRIVATE KEY-----`
+
+func handleSave(w http.ResponseWriter, r *http.Request) {
+ var state map[string]any
+ if err := json.NewDecoder(r.Body).Decode(&state); err != nil {
+ panic(err)
+ }
+ out, err := os.Create("/tmp/state.json")
+ if err != nil {
+ panic(err)
+ }
+ defer out.Close()
+ if err := json.NewEncoder(out).Encode(state); err != nil {
+ panic(err)
+ }
+}
+
+func handleSavedGet(w http.ResponseWriter, r *http.Request) {
+ inp, err := os.Open("/tmp/state.json")
+ if err != nil {
+ panic(err)
+ }
+ defer inp.Close()
+ io.Copy(w, inp)
+}
+
+func handleDeploy(w http.ResponseWriter, r *http.Request) {
+ var dr deployReq
+ if err := json.NewDecoder(r.Body).Decode(&dr); err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+ req := req{
+ Id: "test",
+ SSHPrivateKey: privateKey,
+ Config: dr.Config,
+ }
+ var buf bytes.Buffer
+ if err := json.NewEncoder(&buf).Encode(req); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ resp, err := http.Post("http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app", "application/json", &buf)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ var b bytes.Buffer
+ io.Copy(&b, resp.Body)
+ if resp.StatusCode != http.StatusOK {
+ http.Error(w, b.String(), http.StatusInternalServerError)
+ return
+ }
+}
+
+type Network struct {
+ Name string `json:"name"`
+ Domain string `json:"domain"`
+}
+
+type envResp struct {
+ DeployKey string `json:"deployKey"`
+ Networks []Network `json:"networks"`
+}
+
+func handleEnv(w http.ResponseWriter, r *http.Request) {
+ resp := envResp{
+ DeployKey: publicKey,
+ Networks: []Network{{
+ Name: "Public",
+ Domain: "v1.dodo.cloud",
+ }, {
+ Name: "Private",
+ Domain: "p.v1.dodo.cloud",
+ }},
+ }
+ fmt.Println(resp)
+ json.NewEncoder(w).Encode(resp)
+}
+
+func main() {
+ http.HandleFunc("GET /saved", handleSavedGet)
+ http.HandleFunc("POST /saved", handleSave)
+ http.HandleFunc("GET /env", handleEnv)
+ http.HandleFunc("POST /deploy", handleDeploy)
+ http.Handle("/", http.FileServer(http.Dir("/home/gio/code/dist")))
+ log.Fatal(http.ListenAndServe(":3000", nil))
+}