-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatabase_handlers.go
160 lines (143 loc) · 4.91 KB
/
database_handlers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
resp "github.com/vano2903/ipaas/responser"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// ! still under development
// new database handler, let the user create a new database given the default db name (can be null)
// credentials will be autogenerated
// the body should contain:
// 1) db name
// 2) db type (mysql, mariadb, mongodb)
// ! 3) (not implemented) db version (can be null which will mean the latest version)
func (h Handler) NewDBHandler(w http.ResponseWriter, r *http.Request) {
//connect to the db
conn, err := connectToDB()
if err != nil {
resp.Errorf(w, http.StatusInternalServerError, "error connecting to the database: %v", err.Error())
return
}
defer conn.Client().Disconnect(context.TODO())
//get the student from the cookies
student, err := h.util.GetUserFromCookie(r, conn)
if err != nil {
resp.Errorf(w, http.StatusInternalServerError, "error getting the user from cookies: %v", err.Error())
return
}
//read post body
var dbPost dbPost
err = json.NewDecoder(r.Body).Decode(&dbPost)
if err != nil {
resp.Errorf(w, http.StatusBadRequest, "error decoding the json: %v", err.Error())
return
}
//generate env variables for the container
password := generateRandomString(16)
var env []string
switch dbPost.DbType {
case "mysql", "mariadb":
//root password
env = []string{
"MYSQL_ROOT_PASSWORD=" + password,
}
//set a database if it's not empty
if dbPost.DbName != "" {
env = append(env, "MYSQL_DATABASE="+dbPost.DbName)
}
case "mongodb":
//root password
env = []string{
"MONGO_INITDB_ROOT_USERNAME=" + "root",
"MONGO_INITDB_ROOT_PASSWORD=" + password,
}
//set a database if it's not empty
//!apparently this part doesn't work, the user can create the db on its own though
if dbPost.DbName != "" {
env = append(env, "MONGO_INITDB_DATABASE="+dbPost.DbName)
}
default:
resp.Error(w, http.StatusBadRequest, "Invalid db type, must be mysql, mariadb or mongodb")
return
}
//create the database container
id, err := h.cc.CreateNewDB(h.cc.dbContainersConfigs[dbPost.DbType], env)
if err != nil {
resp.Errorf(w, http.StatusInternalServerError, "error creating a new database: %v", err.Error())
return
}
//get the external port
port, err := h.cc.GetContainerExternalPort(id, h.cc.dbContainersConfigs[dbPost.DbType].port)
if err != nil {
resp.Errorf(w, http.StatusInternalServerError, "error getting the external port: %v", err.Error())
return
}
var Db Application
Db.ID = primitive.NewObjectID()
Db.ContainerID = id
Db.Status = "up"
Db.StudentID = student.ID
Db.Type = "database"
Db.Name = fmt.Sprintf("%d:%s/%s", student.ID, dbPost.DbType, dbPost.DbName)
Db.Description = dbPost.DbDescription
Db.Port = h.cc.dbContainersConfigs[dbPost.DbType].port
Db.ExternalPort = port
Db.CreatedAt = time.Now()
// Db.Envs =
_, err = conn.Collection("applications").InsertOne(context.TODO(), Db)
if err != nil {
resp.Errorf(w, http.StatusInternalServerError, "error inserting the application: %v", err.Error())
return
}
json := map[string]interface{}{
"important": "the password is for root user of the server",
"user": "root",
"port": port,
"pass": password,
}
if dbPost.DbType == "mongodb" {
json["uri"] = fmt.Sprintf("mongodb://root:%s@%s:%s", password, os.Getenv("IP"), port)
}
resp.SuccessParse(w, http.StatusOK, "New DB created", json)
}
//! under development, not implementing it now
//! if you want to export the database use an external tool
// /user/
// func (h Handler) ExportDBHandler(w http.ResponseWriter, r *http.Request) {
// vars := mux.Vars(r)
// containerID := vars["containerID"]
// //read the post body
// var dbPost dbPost
// err := json.NewDecoder(r.Body).Decode(&dbPost)
// if err != nil {
// resp.Errorf(w, http.StatusBadRequest, "error decoding the json: %v", err.Error())
// return
// }
// //connect to the db
// conn, err := connectToDB()
// if err != nil {
// resp.Errorf(w, http.StatusInternalServerError, "error connecting to the database: %v", err.Error())
// return
// }
// defer conn.Close()
// //get the student from the cookies'
// student, err := h.util.GetUserFromCookie(r, conn)
// if err != nil {
// resp.Errorf(w, http.StatusInternalServerError, "error getting the user from cookies: %v", err.Error())
// return
// }
// //check if the user owns the db container
// var app Application
// err = conn.QueryRow(`SELECT * FROM applications WHERE type='database' AND studentID = ? AND containerID = ?`, student.ID, containerID).Scan(&app.ID, &app.ContainerID, &app.Status, &app.StudentID, &app.Type, &app.Name, &app.Description)
// if err != nil {
// if err == sql.ErrNoRows {
// resp.Error(w, http.StatusBadRequest, "application not found, check if the container id is correct and make sure you own this database")
// }
// }
// dbPost.DbType = strings.Split(strings.Split(app.Name, ":")[1], "/")[0]
// }