Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR 1 for fogg #1

Merged
merged 69 commits into from
Jun 26, 2018
Merged
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
7c6d523
basic config impl
ryanking Dec 1, 2017
9df8fe6
wire up init to main()
ryanking Dec 1, 2017
1862c13
add test for default config
ryanking Apr 19, 2018
36ac5f6
wip
ryanking Apr 19, 2018
45ceded
basic account plan resolution
ryanking Apr 19, 2018
66a956c
resolving other accounts
ryanking Apr 24, 2018
0a3268b
wip
ryanking Jun 14, 2018
04fb86a
add owner and account ids to example
ryanking Jun 14, 2018
26c6b51
remove out of date comment
ryanking Jun 14, 2018
209d222
test resolveStringArray
ryanking Jun 14, 2018
e86868b
a basic test for plan.Plan
ryanking Jun 14, 2018
39e5a31
remove unused function
ryanking Jun 14, 2018
a976184
remove shared-infra stuff for now
ryanking Jun 14, 2018
155618a
fix comment
ryanking Jun 14, 2018
72e8161
init basically working
ryanking Jun 15, 2018
e1b9bf5
move init to a module
ryanking Jun 15, 2018
b5a87d9
version variable
ryanking Jun 15, 2018
6d6910c
refactor to use cobra for commands and flags
ryanking Jun 15, 2018
58a3afc
add ldflags for install
ryanking Jun 15, 2018
a85ac1d
add flag to override config file
ryanking Jun 15, 2018
96db5cf
print out "other accounts" better
ryanking Jun 15, 2018
6e200e1
add terraform version
ryanking Jun 15, 2018
67975e2
get infra bucket working for accounts
ryanking Jun 15, 2018
552221f
add owner to account
ryanking Jun 15, 2018
a55f7d7
add project to account
ryanking Jun 15, 2018
3e3e3e5
fix plan for provider profile
ryanking Jun 15, 2018
991d551
add version to plan
ryanking Jun 18, 2018
70807c5
move to czi github
ryanking Jun 18, 2018
04fae34
add plan for modules
ryanking Jun 18, 2018
6a7cc4b
add modules to plan.Print
ryanking Jun 18, 2018
578f413
minimal error handling for plan command
ryanking Jun 18, 2018
5af52d5
wip env plan
ryanking Jun 19, 2018
f0ad55a
wip env plan
ryanking Jun 19, 2018
b60f38c
print envs plan
ryanking Jun 19, 2018
95b17fb
test components in plan
ryanking Jun 19, 2018
0ecc579
gofmt -s -w
ryanking Jun 19, 2018
3eada62
add `make lint`
ryanking Jun 19, 2018
e14b2f2
rename plan.Plan to plan.Eval
ryanking Jun 19, 2018
a7d42da
very basis repo-level stuff
ryanking Jun 19, 2018
0b061ea
remove extension properly
ryanking Jun 19, 2018
431fb1a
add scripts to repo
ryanking Jun 19, 2018
928810d
remove rm functionality for now
ryanking Jun 19, 2018
8dcde23
simplify plan data type
ryanking Jun 20, 2018
735afe8
rename ssh_config script
ryanking Jun 20, 2018
4c228a6
only touch if it doesn't exist
ryanking Jun 20, 2018
485f372
add .create
ryanking Jun 20, 2018
ec4f93e
basic templating + ssh_config template
ryanking Jun 20, 2018
0b9907f
templating working with ssh_config envs
ryanking Jun 20, 2018
f0c68d0
working top-level makefile template
ryanking Jun 20, 2018
5c12c06
move test helper to util
ryanking Jun 20, 2018
f1574d8
cleanup
ryanking Jun 20, 2018
ba81959
small refactoring
ryanking Jun 21, 2018
bf39717
add makefile to accounts
ryanking Jun 22, 2018
5201aa8
sicc.tf working in accounts
ryanking Jun 22, 2018
eb77e9d
env templating working
ryanking Jun 22, 2018
989154f
cleanup some debug prints
ryanking Jun 22, 2018
08868d7
apply for components
ryanking Jun 23, 2018
5953c28
remove debug output
ryanking Jun 25, 2018
e058123
configure gometalinter to avoid comment notes
ryanking Jun 25, 2018
cffe6aa
more error handling
ryanking Jun 25, 2018
535f6c2
fix version in tests
ryanking Jun 25, 2018
3f061e1
naming for AccountID
ryanking Jun 25, 2018
44fc433
naming for AccountID
ryanking Jun 25, 2018
001b181
remove unused joinEnvs
ryanking Jun 25, 2018
ae42585
lint cleanup
ryanking Jun 25, 2018
cf14b1f
also ignore vars
ryanking Jun 25, 2018
9cc291d
remove unused resolveOptional
ryanking Jun 25, 2018
ecd7384
another pass at lint stuff
ryanking Jun 26, 2018
0aca0bb
remove unneccessary panic
ryanking Jun 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
fogg
fogg
coverage.out
5 changes: 5 additions & 0 deletions .gometalinter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Exclude": [
"exported (\\w+) (\\w+) should have comment or be unexported"
]
}
26 changes: 25 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
SHA=$(shell git rev-parse --short HEAD)
VERSION=$(shell cat VERSION)
DIRTY=$(shell if `git diff-index --quiet HEAD --`; then echo false; else echo true; fi)
# TODO add release flag
LDFLAGS=-ldflags "-w -s -X github.com/chanzuckerberg/fogg/util.GitSha=${SHA} -X github.com/chanzuckerberg/fogg/util.Version=${VERSION} -X github.com/chanzuckerberg/fogg/util.Dirty=${DIRTY}"

all: test install

lint:
gometalinter --fast ./...

lint-slow:
gometalinter ./...

build:
go build .
go build ${LDFLAGS} .

coverage:
go tool cover -html=coverage.out

test:
go test -cover ./...

install:
go install ${LDFLAGS} .

.PHONY: build coverage test install lint lint-slow
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
158 changes: 158 additions & 0 deletions apply/apply.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package apply

import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"

"github.com/chanzuckerberg/fogg/plan"
"github.com/chanzuckerberg/fogg/templates"
"github.com/chanzuckerberg/fogg/util"
"github.com/gobuffalo/packr"
"github.com/spf13/afero"
)

const rootPath = "terraform"

func Apply(fs afero.Fs, configFile string, tmp *templates.T) error {
p, err := plan.Eval(fs, configFile)
if err != nil {
return err
}

e := applyRepo(fs, p, &tmp.Repo)
if e != nil {
return e
}

e = applyAccounts(fs, p, &tmp.Account)
if e != nil {
return e
}

e = applyEnvs(fs, p, &tmp.Env, &tmp.Component)
if e != nil {
return e
}

// TODO global

return nil
}

func applyRepo(fs afero.Fs, p *plan.Plan, repoBox *packr.Box) error {
return applyTree(repoBox, fs, p)
}

func applyAccounts(fs afero.Fs, p *plan.Plan, accountBox *packr.Box) (e error) {
for account, accountPlan := range p.Accounts {
path := fmt.Sprintf("%s/accounts/%s", rootPath, account)
e = fs.MkdirAll(path, 0755)
if e != nil {
return e
}
e = applyTree(accountBox, afero.NewBasePathFs(fs, path), accountPlan)
if e != nil {
return e
}
}
return nil
}

func applyEnvs(fs afero.Fs, p *plan.Plan, envBox *packr.Box, componentBox *packr.Box) (e error) {
for env, envPlan := range p.Envs {
path := fmt.Sprintf("%s/envs/%s", rootPath, env)
e = fs.MkdirAll(path, 0755)
if e != nil {
return e
}
e := applyTree(envBox, afero.NewBasePathFs(fs, path), envPlan)
if e != nil {
return e
}
for component, componentPlan := range envPlan.Components {
path := fmt.Sprintf("%s/envs/%s/%s", rootPath, env, component)
e = fs.MkdirAll(path, 0755)
if e != nil {
return e
}
e := applyTree(componentBox, afero.NewBasePathFs(fs, path), componentPlan)
if e != nil {
return e
}
}
}
return nil
}

func applyTree(source *packr.Box, dest afero.Fs, subst interface{}) (e error) {
return source.Walk(func(path string, sourceFile packr.File) error {
extension := filepath.Ext(path)
if extension == ".tmpl" {

err := applyTemplate(sourceFile, dest, path, subst)
if err != nil {
panic(err)
}

// if dest.endswith('.tf'):
// subprocess.call(['terraform', 'fmt', dest])
} else if extension == ".touch" {
d := removeExtension(path)
_, err := dest.Stat(d)
if err != nil { // TODO we might not want to do this for all errors
log.Printf("touching %s", d)
_, e = dest.Create(d)
if e != nil {
return e
Copy link
Contributor

@edulop91 edulop91 Jun 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be worth errors.Wrap these to capture stacks/potentially easier debugging?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's a good idea. This is a large diff already, so I will add a follow-up task to handle that https://app.asana.com/0/335732894489412/723850669292560

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's a good idea. This is a large diff already, so I will add a follow-up task to handle that https://app.asana.com/0/335732894489412/723850669292560

}
} else {
log.Printf("skipping touch on existing file %s", d)
}
// if dest.endswith('.tf'):
// subprocess.call(['terraform', 'fmt', dest])

} else if extension == ".create" {
d := removeExtension(path)
_, err := dest.Stat(d)
if err != nil { // TODO we might not want to do this for all errors
log.Printf("creating %s", d)
e = afero.WriteReader(dest, path, sourceFile)
if e != nil {
return e
}
} else {
log.Printf("skipping create on existing file %s", d)
}
// if dest.endswith('.tf'):
// subprocess.call(['terraform', 'fmt', dest])

} else {
log.Printf("copying %s", path)
e = afero.WriteReader(dest, path, sourceFile)
if e != nil {
return e
}
}
return nil
})

}

func removeExtension(path string) string {
return strings.TrimSuffix(path, filepath.Ext(path))
}

func applyTemplate(sourceFile io.Reader, dest afero.Fs, path string, overrides interface{}) error {
d := removeExtension(path)
log.Printf("templating %s", d)
writer, err := dest.OpenFile(d, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
panic(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why panic vs return the error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question – I don't know why I did this, I will change it.

}
t := util.OpenTemplate(sourceFile)
return t.Execute(writer, overrides)
}
18 changes: 18 additions & 0 deletions apply/apply_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package apply

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestRemoveExtension(t *testing.T) {
x := removeExtension("foo")
assert.Equal(t, "foo", x)

x = removeExtension("foo.txt")
assert.Equal(t, "foo", x)

x = removeExtension("foo.txt.asdf")
assert.Equal(t, "foo.txt", x)
}
38 changes: 38 additions & 0 deletions cmd/apply.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cmd

import (
"os"

"github.com/chanzuckerberg/fogg/apply"
"github.com/chanzuckerberg/fogg/templates"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)

func init() {
applyCmd.Flags().StringP("config", "c", "fogg.json", "Use this to override the fogg config file.")
rootCmd.AddCommand(applyCmd)
}

var applyCmd = &cobra.Command{
Use: "apply",
Short: "Run an apply",
Run: func(cmd *cobra.Command, args []string) {
var e error
pwd, e := os.Getwd()
if e != nil {
panic(e)
}
fs := afero.NewBasePathFs(afero.NewOsFs(), pwd)
configFile, e := cmd.Flags().GetString("config")
if e != nil {
panic(e)
}

e = apply.Apply(fs, configFile, templates.Templates)
if e != nil {
panic(e)
}
// apply.Print(p)
},
}
31 changes: 31 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package cmd

import (
"os"

fogg_init "github.com/chanzuckerberg/fogg/init"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(initCmd)
}

var initCmd = &cobra.Command{
Use: "init",
Short: "Run init",
Run: func(cmd *cobra.Command, args []string) {
var e error
pwd, e := os.Getwd()
if e != nil {
panic(e)
}
fs := afero.NewBasePathFs(afero.NewOsFs(), pwd)

e = fogg_init.Init(fs)
if e != nil {
panic(e)
}
},
}
40 changes: 40 additions & 0 deletions cmd/plan.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cmd

import (
"os"

"github.com/chanzuckerberg/fogg/plan"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)

func init() {
planCmd.Flags().StringP("config", "c", "fogg.json", "Use this to override the fogg config file.")
rootCmd.AddCommand(planCmd)
}

var planCmd = &cobra.Command{
Use: "plan",
Short: "Run a plan",
Run: func(cmd *cobra.Command, args []string) {
var e error
pwd, e := os.Getwd()
if e != nil {
panic(e)
}
fs := afero.NewBasePathFs(afero.NewOsFs(), pwd)
configFile, e := cmd.Flags().GetString("config")
if e != nil {
panic(e)
}

p, e := plan.Eval(fs, configFile)
if e != nil {
panic(e)
}
e = plan.Print(p)
if e != nil {
panic(e)
}
},
}
23 changes: 23 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "fogg",
Short: "",
Run: func(cmd *cobra.Command, args []string) {
// Do Stuff Here
},
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
24 changes: 24 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cmd

import (
"fmt"

"github.com/chanzuckerberg/fogg/util"
"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of fogg",
Run: func(cmd *cobra.Command, args []string) {
v, e := util.VersionString()
if e != nil {
panic(e)
}
fmt.Println(v)
},
}
Loading