Skip to content

Commit

Permalink
Merge f8d0f23 into 661650e
Browse files Browse the repository at this point in the history
  • Loading branch information
bobheadxi committed Jun 24, 2018
2 parents 661650e + f8d0f23 commit 456ac2f
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 1 deletion.
48 changes: 47 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@
[[constraint]]
name = "github.com/gorilla/websocket"
version = "1.2.0"

[[constraint]]
name = "github.com/aws/aws-sdk-go"
version = "1.14.10"
59 changes: 59 additions & 0 deletions input.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
)

var (
errInvalidInput = errors.New("invalid input")

errInvalidUser = errors.New("invalid user")
errInvalidAddress = errors.New("invalid IP address")
errInvalidBuildType = errors.New("invalid build type")
Expand Down Expand Up @@ -114,3 +116,60 @@ func addProjectWalkthrough(in io.Reader) (buildType string, buildFilePath string
}
return
}

func enterEC2CredentialsWalkthrough(in io.Reader) (id, key string, err error) {
print(`To get your credentials:
1. Open the IAM console (https://console.aws.amazon.com/iam/home?#home).
2. In the navigation pane of the console, choose Users.
3. Choose your IAM user name (not the check box).
4. Choose the Security credentials tab and then choose Create access key.
5. To see the new access key, choose Show. Your credentials will look something like this:
Access key ID: AKIAIOSFODNN7EXAMPLE
Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
`)

var response string

print("\nKey ID: ")
_, err = fmt.Fscanln(in, &response)
if err != nil {
return
}
id = response

print("\nAccess Key: ")
_, err = fmt.Fscanln(in, &response)
if err != nil {
return
}
key = response
return
}

func chooseFromListWalkthrough(in io.Reader, optionName string, options []string) (string, error) {
fmt.Printf("Available %ss:\n", optionName)
for _, o := range options {
println("> " + o)
}
print("Please enter your desired %s:", optionName)

var response string
_, err := fmt.Fscanln(in, &response)
if err != nil {
return "", errInvalidInput
}

var contains bool
for _, r := range options {
if r == response {
contains = true
break
}
}
if !contains {
return "", fmt.Errorf("invalid %s - please choose from options", optionName)
}

return response, nil
}
5 changes: 5 additions & 0 deletions local/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,8 @@ func GetClient(name string, cmd ...*cobra.Command) (*client.Client, error) {

return client, nil
}

// SaveKey writes a key to given path
func SaveKey(keyMaterial string, path string) error {
return ioutil.WriteFile(path, []byte(keyMaterial), 0644)
}
47 changes: 47 additions & 0 deletions local/storage_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package local

import (
"io/ioutil"
"os"
"path"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -72,3 +74,48 @@ func TestConfigCreateAndWriteAndRead(t *testing.T) {
err = os.Remove(configPath)
assert.Nil(t, err)
}

func TestSaveKey(t *testing.T) {
keyMaterial := `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAw+14SQTAidfYPDizCYPv0gWq4+wFeInCrZGo4BFbMcP7xhH+
htmm0qx7ctYbCS0tQmCvCnt4W5jwhqH9v65/b1PWv1qQbXbJq0iyeSspgpaB8xq+
AkWoBkUOT8iaUzESDgJfEpC9q1s7dAUpmRDD0JMVzdsv1VQqpR22VWtnpcFtAkNk
3CIXiKFYJ5677dVSrc45dhO4R67LguSPxpXNRcg26/cFKWQO+y2StnYVEEUtvoWN
z2tGQu2hftJtjzzCFXckH8VTJ8EgX0+3Co5jXEbm1idFGFgcAP1WT3xuGh+wpCXM
LYVdF18VxGzZe0bxStZ/+bhsaYfFLyU8qL7RnQIDAQABAoIBAFELWLczjQU30I1Q
ktZ7yebhS0gOaFDtAydS2j0dUNCsFehfpx5Wx8fbaxEceYB5PIB5h85ZNncFM3Et
bs4sOzBsyKbMqnNtMIx2fMTcUsZexZAu3qwH7jHxvLLJ8vQ4lxRObM88KgjIqzYZ
sJRNOAJ95QYLBaVDtIQqXzLEQ9JvDnB5++i18eIF31UXbcjvhNn4M2Goku2EZ9T8
ny0KnRDh9W/Is6ndsBGkDEbXFVMCs6ubIeL7LdJ1W/QNK4HB3ZeRWHMR+lElp+o5
4BY+5bQN7RrTPQmzU0lD1UAIOuPNQeUiGQs4jsV4Oz21z6AWMgg/qAjn91LaWcCH
JnDv++ECgYEA/zJbzNhxF7Kk64U1//XWhtZ3EdlbiapLq26Z10emtED9FrPJxGCz
+fDR2BwWUEpZDY3TBMmjeQeO+VN++PYGMjFogZIKNIuOhu2Qs7u92nCLyeB1aeTm
h90/5II64qCy5KN2fvU6Q2cxNNrCs0Dchh1GYYCH7+IR5NkelTQWRuUCgYEAxItZ
8JYoxfegJmK3RpzYWrbuK2tP7msA9VNSbzMdgFpLG9I+bSJPuQfdOfnhfZG/YG40
MBpUH1X9Jn06Ie6YsbQTeEWUY4H5RKdNKSyyJYepw6C/ndRCuInGPaqQ6FSfccld
mwB3ziaIZVjSaaLGpDFaSgosW4a8hDBbe+4wvFkCgYEAhfGKmWPpSATt5uhORYBl
DvS2Hlo1X3ZQrTQp7wKejvGlZSsMddRD4qXxnjpvw8iiISkVXufus3GyK08Vz9ph
uiqQraFXVekB7/P1BUE/Ds4PsO/s8J3CGgGYrXllKtopyzO42D4iTIp3G0TO+ILM
vF/VNwvdTZ0cwz7qfGmQX7kCgYAJqOOpvGeSm0IGwPFLCihkBPudrK+IA0BPzmGN
z5BSn51zZ5jj2jza1jUcRVi8yC4EukXcW17pD1vayWrTAhwFF9mhHqJVZazvn91d
+bFjwNAqKjtgsW76DONuYnSuxoHzoLb2CEbbHe+0M3Jb+MEUjsxmOSvG789SG+JT
K/i/OQKBgQD3rq8dDSVYaLcSFwg9RfRKF+Ahtml86lm4FrfZlLEfwb6TaR/Unsh0
XF56ZdrKh0nbOW/125RSc8STCv5klDGnBCD56Qzbin9+W6j1TWyJFMdNeaxjWK+U
lq07qdr3cY+O1F4otlDitNuhLE88dtGJM5lEyumokiH1yXwhbBtZ4w==
-----END RSA PRIVATE KEY-----`
cwd, _ := os.Getwd()
testKeyPath := path.Join(cwd, "test_key_save")

// Write
err := SaveKey(keyMaterial, testKeyPath)
assert.Nil(t, err)

// Read
bytes, err := ioutil.ReadFile(testKeyPath)
assert.Nil(t, err)
assert.Equal(t, keyMaterial, string(bytes))

// Test config remove
err = os.Remove(testKeyPath)
assert.Nil(t, err)
}
110 changes: 110 additions & 0 deletions provision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

// initCmd represents the init command
import (
"os"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/ubclaunchpad/inertia/client"
"github.com/ubclaunchpad/inertia/common"
"github.com/ubclaunchpad/inertia/local"
"github.com/ubclaunchpad/inertia/provision"
)

// Initialize "inertia" commands regarding basic configuration
func init() {
cmdProvisionECS.Flags().StringP(
"type", "t", "m3.medium", "The ec2 instance type to instantiate",
)
cmdProvisionECS.Flags().Bool(
"from-env", false, "Load ec2 credentials from environment - requires AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY to be set.",
)
cmdProvision.AddCommand(cmdProvisionECS)
cmdRoot.AddCommand(cmdProvision)
}

var cmdProvision = &cobra.Command{
Use: "provision",
Short: "[BETA] Provision a new VPS setup for Inertia",
Long: `[BETA] Provision a new VPS instance set up for continuous deployment with Inertia.`,
}

var cmdProvisionECS = &cobra.Command{
Use: "ec2 [name]",
Short: "[BETA] Provision a new Amazon EC2 instance",
Long: `[BETA] Provision a new Amazon EC2 instance and set it up for continuous deployment
with Inertia.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
// Ensure project initialized.
config, path, err := local.GetProjectConfigFromDisk()
if err != nil {
log.Fatal(err)
}

// Load flags
fromEnv, _ := cmd.Flags().GetBool("from-env")
instanceType, _ := cmd.Flags().GetString("type")

// Create VPS instance
var prov *provision.EC2Provisioner
if !fromEnv {
id, key, err := enterEC2CredentialsWalkthrough(os.Stdin)
if err != nil {
log.Fatal(err)
}
prov = provision.NewEC2Provisioner(id, key)
} else {
prov = provision.NewEC2ProvisionerFromEnv()
}

// List regions and prompt for input
regions, err := prov.ListRegions()
if err != nil {
log.Fatal(err)
}
region, err := chooseFromListWalkthrough(os.Stdin, "region", regions)
if err != nil {
log.Fatal(err)
}

// List image options and prompt for input
images, err := prov.ListImageOptions(region)
if err != nil {
log.Fatal(err)
}
image, err := chooseFromListWalkthrough(os.Stdin, "image", images)
if err != nil {
log.Fatal(err)
}

// Create instance from input
remote, err := prov.CreateInstance(args[0], image, instanceType, region)
if err != nil {
log.Fatal(err)
}

// Save new remote to configuration
remote.Branch, err = local.GetRepoCurrentBranch()
if err != nil {
log.Fatal(err)
}
config.AddRemote(remote)
config.Write(path)

// Init the new instance
inertia, found := client.NewClient(args[0], config)
if !found {
log.Fatal("vps setup did not complete properly")
}
gitURL, err := local.GetRepoRemote("origin")
if err != nil {
log.Fatal(err)
}
err = inertia.BootstrapRemote(common.ExtractRepository(gitURL))
if err != nil {
log.Fatal(err)
}
},
}
2 changes: 2 additions & 0 deletions provision/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package provision contains Inertia's VPS instance provisioning API
package provision
Loading

0 comments on commit 456ac2f

Please sign in to comment.