diff options
Diffstat (limited to 'src/k8splugin/internal/connection')
-rw-r--r-- | src/k8splugin/internal/connection/connection.go | 37 | ||||
-rw-r--r-- | src/k8splugin/internal/connection/connectionhandler.go | 40 |
2 files changed, 68 insertions, 9 deletions
diff --git a/src/k8splugin/internal/connection/connection.go b/src/k8splugin/internal/connection/connection.go index dbd1c2e1..b2bdca32 100644 --- a/src/k8splugin/internal/connection/connection.go +++ b/src/k8splugin/internal/connection/connection.go @@ -17,7 +17,11 @@ package connection import ( + "encoding/base64" "encoding/json" + "io/ioutil" + "path/filepath" + "k8splugin/internal/db" pkgerrors "github.com/pkg/errors" @@ -27,7 +31,7 @@ import ( type Connection struct { CloudRegion string `json:"cloud-region"` CloudOwner string `json:"cloud-owner"` - Kubeconfig map[string]interface{} `json:"kubeconfig"` + Kubeconfig string `json:"kubeconfig"` OtherConnectivityList map[string]interface{} `json:"other-connectivity-list"` } @@ -47,14 +51,14 @@ func (dk ConnectionKey) String() string { return string(out) } -// ConnectionManager is an interface exposes the Connection functionality +// ConnectionManager is an interface exposes the Connection functionality type ConnectionManager interface { Create(c Connection) (Connection, error) Get(name string) (Connection, error) Delete(name string) error } -// ConnectionClient implements the ConnectionManager +// ConnectionClient implements the ConnectionManager // It will also be used to maintain some localized state type ConnectionClient struct { storeName string @@ -113,7 +117,7 @@ func (v *ConnectionClient) Get(name string) (Connection, error) { return Connection{}, pkgerrors.New("Error getting Connection") } -// Delete the Connection from database +// Delete the Connection from database func (v *ConnectionClient) Delete(name string) error { //Construct the composite key to select the entry @@ -124,3 +128,28 @@ func (v *ConnectionClient) Delete(name string) error { } return nil } + +// Download the connection information onto a kubeconfig file +// The file is named after the name of the connection and will +// be placed in the provided parent directory +func (v *ConnectionClient) Download(name string, parentdir string) (string, error) { + + conn, err := v.Get(name) + if err != nil { + return "", pkgerrors.Wrap(err, "Getting Connection info") + } + + //Decode the kubeconfig from base64 to string + kubeContent, err := base64.StdEncoding.DecodeString(conn.Kubeconfig) + if err != nil { + return "", pkgerrors.Wrap(err, "Converting from base64") + } + + target := filepath.Join(parentdir, conn.CloudRegion) + err = ioutil.WriteFile(target, kubeContent, 0644) + if err != nil { + return "", pkgerrors.Wrap(err, "Writing kubeconfig to file") + } + + return target, nil +} diff --git a/src/k8splugin/internal/connection/connectionhandler.go b/src/k8splugin/internal/connection/connectionhandler.go index 0f8014fa..8c860d31 100644 --- a/src/k8splugin/internal/connection/connectionhandler.go +++ b/src/k8splugin/internal/connection/connectionhandler.go @@ -17,8 +17,11 @@ package connection import ( + "bytes" + "encoding/base64" "encoding/json" "io" + "io/ioutil" "net/http" "github.com/gorilla/mux" @@ -32,11 +35,25 @@ type ConnectionHandler struct { Client ConnectionManager } -// createHandler handles creation of the connectivity entry in the database +// CreateHandler handles creation of the connectivity entry in the database +// This is a multipart handler. See following example curl request +// curl -i -F "metadata={\"cloud-region\":\"kud\",\"cloud-owner\":\"me\"};type=application/json" \ +// -F file=@/home/user/.kube/config \ +// -X POST http://localhost:8081/v1/connectivity-info func (h ConnectionHandler) CreateHandler(w http.ResponseWriter, r *http.Request) { var v Connection - err := json.NewDecoder(r.Body).Decode(&v) + // Implemenation using multipart form + // Review and enable/remove at a later date + // Set Max size to 16mb here + err := r.ParseMultipartForm(16777216) + if err != nil { + http.Error(w, err.Error(), http.StatusUnprocessableEntity) + return + } + + jsn := bytes.NewBuffer([]byte(r.FormValue("metadata"))) + err = json.NewDecoder(jsn).Decode(&v) switch { case err == io.EOF: http.Error(w, "Empty body", http.StatusBadRequest) @@ -58,11 +75,24 @@ func (h ConnectionHandler) CreateHandler(w http.ResponseWriter, r *http.Request) return } - // Kubeconfig is required. - if v.Kubeconfig == nil { - http.Error(w, "Missing Kubeconfig in POST request", http.StatusBadRequest) + //Read the file section and ignore the header + file, _, err := r.FormFile("file") + if err != nil { + http.Error(w, "Unable to process file", http.StatusUnprocessableEntity) return } + + defer file.Close() + + //Convert the file content to base64 for storage + content, err := ioutil.ReadAll(file) + if err != nil { + http.Error(w, "Unable to read file", http.StatusUnprocessableEntity) + return + } + + v.Kubeconfig = base64.StdEncoding.EncodeToString(content) + ret, err := h.Client.Create(v) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) |