Skip to content

Commit

Permalink
add aws-region in yaml config (#28)
Browse files Browse the repository at this point in the history
* add region config

* support yaml and yml configs

* configure aws session

* fix shared vars interpolstion

* improve interpolation error

* release v1.3.4

* fix deprecated goreleaser configs
  • Loading branch information
adikari committed Jul 11, 2023
1 parent df99d8f commit b1d738b
Show file tree
Hide file tree
Showing 16 changed files with 163 additions and 86 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
with:
distribution: goreleaser
version: latest
args: release --rm-dist
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,6 @@ dist

# End of https://www.toptal.com/developers/gitignore/api/node

.env
env.json
types
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ brews:
bash_completion.install "completions/safebox.bash" => "safebox"
zsh_completion.install "completions/safebox.zsh" => "_safebox"
fish_completion.install "completions/safebox.fish"
tap:
repository:
owner: adikari
name: homebrew-taps
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
Expand Down
19 changes: 9 additions & 10 deletions aws/cloudformation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudformation"
)

Expand All @@ -13,6 +14,14 @@ type Cloudformation struct {
client *cloudformation.CloudFormation
}

func NewCloudformation(session *session.Session) Cloudformation {
if cfClient == nil {
cfClient = cloudformation.New(session)
}

return Cloudformation{client: cfClient}
}

func (c *Cloudformation) GetOutput(stackname string) (map[string]string, error) {
result := map[string]string{}

Expand Down Expand Up @@ -50,13 +59,3 @@ func (c *Cloudformation) GetOutputs(stacknames []string) (map[string]string, err

return result, nil
}

func NewCloudformation() Cloudformation {
if cfClient == nil {
cfClient = cloudformation.New(Session, &aws.Config{
Retryer: Retryer,
})
}

return Cloudformation{client: cfClient}
}
29 changes: 22 additions & 7 deletions aws/session.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
package aws

import (
"os"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/session"
)

var Session = session.Must(session.NewSession())
var ses *session.Session

var (
numberOfRetries = 10
throttleDelay = client.DefaultRetryerMinRetryDelay
)
func NewSession(cfg aws.Config) *session.Session {
if ses == nil {
if cfg.Retryer == nil {
cfg.Retryer = Retryer
}

if cfg.Region == nil {
region := os.Getenv("AWS_REGION")
cfg.Region = &region
}

ses = session.Must(session.NewSession(&cfg))
}

return ses
}

var Retryer = client.DefaultRetryer{
NumMaxRetries: numberOfRetries,
MinThrottleDelay: throttleDelay,
NumMaxRetries: 2,
MinThrottleDelay: client.DefaultRetryerMaxRetryDelay,
}
11 changes: 3 additions & 8 deletions aws/sts.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
package aws

import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
)

type Sts struct {
client *sts.STS
}

var stsClient *sts.STS

func NewSts() Sts {
if stsClient == nil {
stsClient = sts.New(Session)
}

return Sts{client: stsClient}
func NewSts(session *session.Session) Sts {
return Sts{client: sts.New(session)}
}

func (s *Sts) GetCallerIdentity() (*sts.GetCallerIdentityOutput, error) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func deploy(_ *cobra.Command, _ []string) error {
return errors.Wrap(err, "failed to load config")
}

st, err := store.GetStore(config.Provider)
st, err := store.GetStore(store.StoreConfig{Session: config.Session, Provider: config.Provider})

if err != nil {
return errors.Wrap(err, "failed to instantiate store")
Expand Down Expand Up @@ -120,7 +120,7 @@ func deploy(_ *cobra.Command, _ []string) error {
fmt.Printf("%d orphans removed.\n", len(orphans))
}

fmt.Printf("%d new configs deployed. service = %s, stage = %s\n", len(configsToDeploy), config.Service, stage)
fmt.Printf("%d new configs deployed. service = %s, stage = %s, region = %s\n", len(configsToDeploy), config.Service, stage, *config.Session.Config.Region)

if len(config.Generate) > 0 {
for _, t := range config.Generate {
Expand Down
2 changes: 1 addition & 1 deletion cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type ExportParams struct {
}

func exportToFile(p ExportParams) error {
store, err := store.GetStore(p.config.Provider)
store, err := store.GetStore(store.StoreConfig{Session: p.config.Session, Provider: p.config.Provider})

if err != nil {
return errors.Wrap(err, "failed to instantiate store")
Expand Down
2 changes: 1 addition & 1 deletion cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func list(_ *cobra.Command, _ []string) error {
return errors.Wrap(err, "failed to load config")
}

store, err := store.GetStore(config.Provider)
store, err := store.GetStore(store.StoreConfig{Session: config.Session, Provider: config.Provider})

if err != nil {
return errors.Wrap(err, "failed to instantiate store")
Expand Down
8 changes: 3 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var rootCmd = &cobra.Command{
func init() {
rootCmd.PersistentFlags().StringVarP(&stage, "stage", "s", "dev", "stage to deploy to")

rootCmd.PersistentFlags().StringVarP(&pathToConfig, "config", "c", "safebox.yml", "path to safebox configuration file")
rootCmd.PersistentFlags().StringVarP(&pathToConfig, "config", "c", "", "path to safebox configuration file")
rootCmd.MarkFlagFilename("config")
}

Expand All @@ -44,10 +44,8 @@ func Execute(version string) {
}

func loadConfig() (*c.Config, error) {
params := c.LoadConfigInput{
return c.Load(c.LoadConfigInput{
Path: pathToConfig,
Stage: stage,
}

return c.Load(params)
})
}
49 changes: 41 additions & 8 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import (
"fmt"
"html/template"
"io/ioutil"
"strings"

"github.com/adikari/safebox/v2/aws"
"github.com/adikari/safebox/v2/store"
a "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
Expand All @@ -20,6 +23,7 @@ type rawConfig struct {
Config map[string]map[string]string
Secret map[string]map[string]string
CloudformationStacks []string `yaml:"cloudformation-stacks"`
Region string `yaml:"region"`
}

type Config struct {
Expand All @@ -32,6 +36,7 @@ type Config struct {
Configs []store.ConfigInput
Secrets []store.ConfigInput
Stacks []string
Session *session.Session
}

type Generate struct {
Expand All @@ -44,11 +49,13 @@ type LoadConfigInput struct {
Stage string
}

var defaultConfigPaths = []string{"safebox.yml", "safebox.yaml"}

func Load(param LoadConfigInput) (*Config, error) {
yamlFile, err := ioutil.ReadFile(param.Path)
yamlFile, err := readConfigFile(param.Path)

if err != nil {
return nil, fmt.Errorf("missing safebox config file %s", param.Path)
return nil, fmt.Errorf(err.Error())
}

rc := rawConfig{}
Expand Down Expand Up @@ -77,6 +84,8 @@ func Load(param LoadConfigInput) (*Config, error) {
c.Provider = store.SsmProvider
}

c.Session = aws.NewSession(a.Config{Region: &rc.Region})

variables, err := loadVariables(c, rc)

if err != nil {
Expand All @@ -92,7 +101,7 @@ func Load(param LoadConfigInput) (*Config, error) {
val, err := Interpolate(value, variables)

if err != nil {
return nil, errors.Wrap(err, "failed to interpolate template variables")
return nil, errors.Wrap(err, fmt.Sprintf("failed to interpolate config.defaults.%s", key))
}

c.Configs = append(c.Configs, store.ConfigInput{
Expand All @@ -103,9 +112,15 @@ func Load(param LoadConfigInput) (*Config, error) {
}

for key, value := range rc.Config["shared"] {
val, err := Interpolate(value, variables)

if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("failed to interpolate config.shared.%s", key))
}

c.Configs = append(c.Configs, store.ConfigInput{
Name: formatSharedPath(param.Stage, key),
Value: value,
Value: val,
Secret: false,
})
}
Expand Down Expand Up @@ -171,7 +186,7 @@ func validateConfig(rc rawConfig) error {
}

func loadVariables(c Config, rc rawConfig) (map[string]string, error) {
st := aws.NewSts()
st := aws.NewSts(c.Session)

id, err := st.GetCallerIdentity()

Expand All @@ -182,21 +197,21 @@ func loadVariables(c Config, rc rawConfig) (map[string]string, error) {
variables := map[string]string{
"stage": c.Stage,
"service": c.Service,
"region": *aws.Session.Config.Region,
"region": *c.Session.Config.Region,
"account": *id.Account,
}

for _, name := range rc.CloudformationStacks {
value, err := Interpolate(name, variables)
if err != nil {
return nil, err
return nil, errors.Wrap(err, fmt.Sprintf("failed to interpolate cloudformation-stacks[%s]", name))
}
c.Stacks = append(c.Stacks, value)
}

// add cloudformation outputs to variables available for interpolation
if len(c.Stacks) > 0 {
cf := aws.NewCloudformation()
cf := aws.NewCloudformation(c.Session)
outputs, err := cf.GetOutputs(c.Stacks)

if err != nil {
Expand Down Expand Up @@ -240,3 +255,21 @@ loop:

return unique
}

func readConfigFile(path string) ([]byte, error) {
if path != "" {
s, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("missing file %s", path)
}
return s, nil
}

for _, c := range defaultConfigPaths {
if s, err := ioutil.ReadFile(c); err == nil {
return s, nil
}
}

return nil, fmt.Errorf("missing file %s", strings.Join(defaultConfigPaths, " or "))
}
2 changes: 1 addition & 1 deletion npm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adikari/safebox",
"version": "1.3.3",
"version": "1.3.4",
"description": "A Fast and Flexible secret manager built with love by adikari in Go",
"main": "index.js",
"bin": "./run.js",
Expand Down
Loading

0 comments on commit b1d738b

Please sign in to comment.