Skip to content

Commit

Permalink
Implement implicit provisioning with config file; move cmd folder
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Jun 9, 2016
1 parent e096b44 commit 33d13c4
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 96 deletions.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,27 @@ Save this file as `config.json` in your working directory.

### Setting up storage on S3

The easiest way to do this is to create an IAM user that has these two privileges:
The easiest way to do this is to give an IAM user these two privileges (keep the credentials secret):

- arn:aws:iam::aws:policy/**IAMFullAccess**
- arn:aws:iam::aws:policy/**AmazonS3FullAccess**

Keep its credentials secret, but export the following information to environment variables and run the provisioning command:
##### Implicit Provisioning

If you give these permissions to the same user as with the credentials in your JSON config above, then you can simply run:

```bash
$ checkup provision
```

and checkup will read the config file and provision S3 for you. If the user is different, you may want to use explicit provisioning instead.

This command creates a new IAM user with read-only permission to S3 and also creates a new bucket just for your check files. The credentials of the new user are printed to your screen. **Make note of the Public Access Key ID and Public Access Key!** You won't be able to see them again.


##### Explicit Provisioning

If you do not prefer implicit provisioning using your checkup.json file, do this instead. Export the information to environment variables and run the provisioning command:

```bash
$ export AWS_ACCESS_KEY_ID=...
Expand All @@ -78,8 +93,6 @@ $ export AWS_BUCKET_NAME=...
$ checkup provision s3
```

This command creates a new IAM user with read-only permission to S3 and also creates a new bucket just for your check files. The credentials of the new user are printed to your screen. **Make note of the Public Access Key ID and Public Access Key!** You won't be able to see them again.


### Setting up the status page

Expand Down
7 changes: 0 additions & 7 deletions checkup/cmd/checkup/main.go

This file was deleted.

85 changes: 0 additions & 85 deletions checkup/cmd/provision.go

This file was deleted.

7 changes: 7 additions & 0 deletions cmd/checkup/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "github.com/sourcegraph/checkup/cmd"

func main() {
cmd.Execute()
}
File renamed without changes.
File renamed without changes.
114 changes: 114 additions & 0 deletions cmd/provision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package cmd

import (
"fmt"
"log"
"os"
"strings"

"github.com/sourcegraph/checkup"
"github.com/spf13/cobra"
)

var provisionCmd = &cobra.Command{
Use: "provision",
Short: "Provision a storage service",
Long: `Use the provision command to provision storage for your
check files on any supported provider. Provisioning need
only be done once per status page. After provisioning,
you will be provided some credentials; use those to
configure your status page and/or checker.
By default, checkup.json will be loaded and used, if it
exists in the current working directory. Otherwise, you
may provision your storage manually according to the
instructions below.
To do it manually, run 'checkup provision <provider>'
with your provider of choice after setting the required
environment variables.
PROVIDERS
s3
Create an IAM user with at least these two permissions:
- arn:aws:iam::aws:policy/IAMFullAccess
- arn:aws:iam::aws:policy/AmazonS3FullAccess
Then set these env variables:
- AWS_ACCESS_KEY_ID=<AccessKeyID of user>
- AWS_SECRET_ACCESS_KEY=<SecretAccessKey of user>
- AWS_BUCKET_NAME=<unique bucket name>`,
Run: func(cmd *cobra.Command, args []string) {
var prov checkup.Provisioner
var err error

switch len(args) {
case 0:
prov, err = provisionerConfig()
case 1:
prov, err = provisionerEnvVars(cmd, args)
default:
fmt.Println(cmd.Long)
os.Exit(1)
}
if err != nil {
log.Fatal(err)
}

fmt.Println("One sec...")

info, err := prov.Provision()
if err != nil {
log.Fatal(err)
}

fmt.Printf("Provision successful\n\n")
fmt.Printf(" User ID: %s\n", info.UserID)
fmt.Printf(" Username: %s\n", info.Username)
fmt.Printf("Public Access Key ID: %s\n", info.PublicAccessKeyID)
fmt.Printf(" Public Access Key: %s\n\n", info.PublicAccessKey)
fmt.Println(`IMPORTANT: Copy the Public Access Key ID and Public Access
Key into the config.js file for your status page. You will
not be shown these credentials again.`)
},
}

func provisionerConfig() (checkup.Provisioner, error) {
c := loadCheckup()
if c.Storage == nil {
return nil, fmt.Errorf("no storage configuration found")
}
prov, ok := c.Storage.(checkup.Provisioner)
if !ok {
return nil, fmt.Errorf("configured storage type does not have provisioning capabilities")
}
return prov, nil
}

func provisionerEnvVars(cmd *cobra.Command, args []string) (checkup.Provisioner, error) {
providerName := strings.ToLower(args[0])
switch providerName {
case "s3":
keyID := os.Getenv("AWS_ACCESS_KEY_ID")
secretKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
bucket := os.Getenv("AWS_BUCKET_NAME")
if keyID == "" || secretKey == "" || bucket == "" {
fmt.Println(cmd.Long)
os.Exit(1)
}
return checkup.S3{
AccessKeyID: keyID,
SecretAccessKey: secretKey,
Bucket: bucket,
}, nil
default:
return nil, fmt.Errorf("unknown storage provider '%s'", providerName)
}
}

func init() {
RootCmd.AddCommand(provisionCmd)
}
File renamed without changes.
5 changes: 5 additions & 0 deletions s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ func (s S3) Maintain() error {

var objsToDelete []*s3.ObjectIdentifier
for _, o := range listResp.Contents {
if o == nil || o.LastModified == nil {
continue
}
// TODO: This next line panicked once with nil ptr deref. Why?
// (at the time we did not have the if statement above checking for nils)
if time.Since(*o.LastModified) > s.CheckExpiry {
objsToDelete = append(objsToDelete, &s3.ObjectIdentifier{Key: o.Key})
}
Expand Down

0 comments on commit 33d13c4

Please sign in to comment.