Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
justinrlee committed Jan 8, 2018
1 parent 9a291c9 commit 6d2df98
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 113 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ This is a minimal viable product / work in progress. It works, but it has sever
* This will create secrets that don't exist, and update existing ones (**it will overwrite existing ones - be careful here**)
* If you try to restore with invalid/non-matching cipherkey, I *think* it will fail but I haven't put any actual checks in there (it fails because it's trying to post something that isn't actual JSON and saying it's JSON).
* There is minimal error checking throughout.
* Very minimal testing has occurred. Try on a non-prod cluster.
* Very minimal testing has occurred. Try on a non-prod cluster.

## Todo:
Add certificate verification
Parallelize processing
30 changes: 18 additions & 12 deletions cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"os"
"encoding/json"
"net/http"

"github.com/spf13/cobra"
)
Expand All @@ -34,17 +35,21 @@ Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
// fmt.Println("backup called")
validateCipher()
if (destfile == "secrets.tar" && sourcefile != "secrets.tar") {
fmt.Println("You specified a source file in a backup command. Did you mean to specify a destination file?")
os.Exit(1)
}

cluster, err := NewCluster(hostname, username, password)
if err != nil {
fmt.Println("Unable to connect to cluster")
os.Exit(1)
}

b, err := cluster.Get("/secrets/v1/secret/default/?list=true")
if err != nil {
// secretList, err := cluster.Get("/secrets/v1/secret/default/?list=true")
secretList, returnCode, err := cluster.Call("GET", "/secrets/v1/secret/default/?list=true", nil)
if (err != nil || returnCode != http.StatusOK) {
fmt.Println("Unable to obtain list of secrets")
os.Exit(1)
}
Expand All @@ -53,25 +58,26 @@ to quickly create a Cobra application.`,
Array []string `json:array`
}

json.Unmarshal(b, &secrets)
json.Unmarshal(secretList, &secrets)

files := []Secret {}
secretSlice := []Secret {}

// Get all secrets, add them to the files array
for _, secretPath := range secrets.Array {
fmt.Printf("Getting secret '%s'\n", secretPath)
secretValue, err := cluster.Get("/secrets/v1/secret/default/" + secretPath)
if err != nil {
for _, secretID := range secrets.Array {
fmt.Printf("Getting secret '%s'\n", secretID)
// secretValue, err := cluster.Get("/secrets/v1/secret/default/" + secretPath)
secretJSON, returnCode, err := cluster.Call("GET", "/secrets/v1/secret/default/" + secretID, nil)
if (err != nil || returnCode != http.StatusOK) {
fmt.Println("TODO: error handling here")
panic(err)
}

e := encrypt(string(secretValue), cipherkey)
files = append(files, Secret{ID: secretPath, EncryptedJSON: e})
e := encrypt(string(secretJSON), cipherkey)
secretSlice = append(secretSlice, Secret{ID: secretID, EncryptedJSON: e})
}

fmt.Println("Writing to tar at " + destfile)
writeTar(files, destfile)
writeTar(secretSlice, destfile)

os.Exit(0)

Expand Down
21 changes: 19 additions & 2 deletions cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package cmd
import (
"fmt"
"os"
"encoding/json"

"github.com/spf13/cobra"
)
Expand All @@ -33,18 +34,34 @@ This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
validateCipher()
if (destfile != "secrets.tar" && sourcefile == "secrets.tar") {
fmt.Println("You specified a destination file in a restore command. Did you mean to specify a source file?")
os.Exit(1)
}

cluster, err := NewCluster(hostname, username, password)
if err != nil {
fmt.Println("Unable to connect to cluster")
os.Exit(1)
}

files := readTar(sourcefile)
for _, item := range files {
secrets := readTar(sourcefile)
for _, item := range secrets {
plaintext := decrypt(item.EncryptedJSON, cipherkey)

// Prior to restore, will try to unmarshal. If unable to unmarshal, we have invalid cipherkey.
var t struct{
Value string `json:"value"`
}
err := json.Unmarshal([]byte(plaintext), &t)
if (err != nil || t.Value == "") {
fmt.Println("Unable to decrypt. You likely have an invalid cipherkey.")
os.Exit(1)
}

fmt.Printf("Processing [%s] ...\n", item.ID)
secretPath := "/secrets/v1/secret/default/" + item.ID

resp, code, err := cluster.Call("PUT", secretPath, []byte(plaintext))
if code == 201 {
fmt.Println("Secret" + item.ID + "successfully created.")
Expand Down
95 changes: 3 additions & 92 deletions cmd/utility-cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ type Cluster struct{
user User
}

// File >> Secret
// Consists of the path to the secret ("ID") and the AES-encrypted JSON definition.
//JSON format is dependent on DC/OS version, but generally will have a 'value' field.
type Secret struct {
ID, EncryptedJSON string
// Path >> ID
// Body > EncryptedJSON
}

func createClient() *http.Client {
Expand Down Expand Up @@ -99,34 +98,6 @@ func (c *Cluster) Login(path string, buf []byte) (err error) {
return err
}

func (c *Cluster) Get(path string) (body []byte, err error) {
url := c.cluster_url + path
req, err := http.NewRequest("GET", url, nil)
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "token=" + string(c.user.Token))

resp, err := c.client.Do(req)

if err != nil {
fmt.Println("TODO: error handling here")
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
fmt.Println("TODO: error handling here")
return nil, err
}

body, err = ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("TODO: error handling here")
return nil, err
}

return body, nil
}

// Basic wrapper that includes specifying the auth token
func (c *Cluster) Call(verb string, path string, buf []byte) (body []byte, returnCode int, err error) {
url := c.cluster_url + path
Expand All @@ -145,64 +116,4 @@ func (c *Cluster) Call(verb string, path string, buf []byte) (body []byte, retur
body, err = ioutil.ReadAll(resp.Body)

return body, resp.StatusCode, err
}

// func (c *Cluster) Patch(path string, buf []byte) (body []byte, returnCode int, err error) {
// url := c.cluster_url + path
// req, err := http.NewRequest("PATCH", url, bytes.NewBuffer(buf))
// req.Header.Set("Content-Type", "application/json")
// req.Header.Set("Authorization", "token=" + string(c.user.Token))

// resp, err := c.client.Do(req)

// if err != nil {
// fmt.Println("TODO: error handling here3")
// return nil, 0, err
// }
// defer resp.Body.Close()

// if resp.StatusCode != http.StatusOK {
// fmt.Println("TODO: error handling here6")
// fmt.Println(resp.StatusCode)
// fmt.Println(resp)
// return nil, resp.StatusCode, err
// }

// body, _ = ioutil.ReadAll(resp.Body)

// err = json.Unmarshal(body, &c.user)
// fmt.Println(c.user)
// // fmt.Println(body)

// return body, resp.StatusCode, nil
// }

// func (c *Cluster) Put(path string, buf []byte) (body []byte, returnCode int, err error) {
// url := c.cluster_url + path
// req, err := http.NewRequest("PUT", url, bytes.NewBuffer(buf))
// req.Header.Set("Content-Type", "application/json")
// req.Header.Set("Authorization", "token=" + string(c.user.Token))

// resp, err := c.client.Do(req)

// if err != nil {
// fmt.Println("TODO: error handling here5")
// return nil, 0, err
// }
// defer resp.Body.Close()

// if resp.StatusCode != http.StatusOK {
// fmt.Println("TODO: error handling here6")
// fmt.Println(resp.StatusCode)
// fmt.Println(resp)
// return nil, resp.StatusCode, err
// }

// body, _ = ioutil.ReadAll(resp.Body)

// err = json.Unmarshal(body, &c.user)
// fmt.Println(c.user)
// // fmt.Println(body)

// return body, resp.StatusCode, nil
// }
}
12 changes: 6 additions & 6 deletions cmd/utility-file.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
// "path/filepath"

"archive/tar"
"bytes"
Expand Down Expand Up @@ -163,11 +163,11 @@ func readTar(filename string) (files []Secret){
return files
}

func createDirFor(path string) {
dir := filepath.Dir(path)
// fmt.Println(dir)
os.MkdirAll(dir, os.ModePerm)
}
// func createDirFor(path string) {
// dir := filepath.Dir(path)
// // fmt.Println(dir)
// os.MkdirAll(dir, os.ModePerm)
// }

func validateCipher() {
if cipherkey == "" {
Expand Down

0 comments on commit 6d2df98

Please sign in to comment.