Skip to content

Commit 0b5016c

Browse files
committed
Merge branch 'release/0.1.0'
2 parents 92731c0 + a68ecc0 commit 0b5016c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+4705
-1
lines changed

.github/workflows/go.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Go
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- develop
8+
- feature/*
9+
pull_request:
10+
branches: [ main, develop ]
11+
12+
jobs:
13+
14+
build:
15+
name: Build
16+
runs-on: ubuntu-latest
17+
steps:
18+
19+
- name: Set up Go 1.x
20+
uses: actions/setup-go@v2
21+
with:
22+
go-version: ^1.16
23+
id: go
24+
25+
- name: Check out code into the Go module directory
26+
uses: actions/checkout@v2
27+
with:
28+
fetch-depth: 0
29+
30+
- name: Get dependencies
31+
run: |
32+
go get -v -t -d ./...
33+
if [ -f Gopkg.toml ]; then
34+
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
35+
dep ensure
36+
fi
37+
- name: Test
38+
run: go test -v ./... -coverpkg ./...

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@
1313

1414
# Dependency directories (remove the comment below to include it)
1515
# vendor/
16+
17+
BACKLOG.md
18+
.idea/
19+
dist/
20+
*.dat
21+
22+
tests-internal/

.goreleaser.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
before:
2+
hooks:
3+
- go mod download
4+
builds:
5+
- main: ./cmd/cmd.go
6+
archives:
7+
- replacements:
8+
linux: Linux
9+
386: i386
10+
amd64: x86_64
11+
checksum:
12+
name_template: 'checksums.txt'
13+
snapshot:
14+
name_template: "{{ .Tag }}-next"
15+
changelog:
16+
sort: asc
17+
filters:
18+
exclude:
19+
- '^docs:'
20+
- '^test:'
21+
- '^tests:'

Makefile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
SOURCES ?= $(shell find . -name "*.go" -type f)
2+
BINARY_NAME = go-secretshelper
3+
MAIN_GO_PATH=cmd/cmd.go
4+
COMMIT:=$(shell git describe --tags 2>/dev/null || git rev-parse --short HEAD)
5+
NOW:=$(shell date +"%Y-%m-%d_%H-%M-%S")
6+
7+
all: clean lint build
8+
9+
.PHONY: build
10+
build:
11+
CGO_ENABLED=0 go build -v -ldflags "-X main.commit=$(COMMIT) -X main.date=$(NOW)" -o dist/${BINARY_NAME} ${MAIN_GO_PATH}
12+
13+
.PHONY: staticcheck
14+
staticcheck:
15+
staticcheck ./...
16+
17+
.PHONY: lint
18+
lint:
19+
@for file in ${SOURCES} ; do \
20+
golint $$file ; \
21+
done
22+
23+
.PHONY: test
24+
test:
25+
@go test -coverprofile=cover.out -coverpkg=./... ./...
26+
@go tool cover -func=cover.out
27+
28+
.PHONY: gen
29+
gen:
30+
go generate -v ./...
31+
32+
.PHONY: release
33+
release:
34+
goreleaser --snapshot --rm-dist
35+
36+
.PHONY: clean
37+
clean:
38+
rm -rf dist/*
39+
rm -f cover.out
40+
go clean -testcache

README.md

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,107 @@
11
# go-secretshelper
2-
CLI for accessing cloud-based vaults and secrets managers
2+
3+
`go-secretshelper` is both a library and a CLI to access secrets stored in vaults such as Cloud-based secrets managers, transform them and store them in files.
4+
5+
[![Go](https://github.com/aschmidt75/go-secretshelper/actions/workflows/go.yaml/badge.svg)](https://github.com/aschmidt75/go-secretshelper/actions/workflows/go.yaml)
6+
7+
## Usage
8+
9+
`go-secretshelper` expects a yaml-based configuration file, which it processes. The configuration contains four major elements:
10+
11+
* **Vaults** specify, where secrets are stored. Examples are Azure Key Vault or AWS Secrets Manager
12+
* **Secrets** define, what data is read from which vault.
13+
* **Transformation** describe,how secrets are modified, e.g. to decode base64 or render a template
14+
* **Sinks** specify where and how secrets are written. At present, only files are supported as sinks.
15+
16+
To run a configuration, use:
17+
18+
```bash
19+
$ go-secretshelper run -c <config file>
20+
```
21+
22+
Sample configuration file:
23+
```yaml
24+
vaults:
25+
- name: myvault
26+
type: aws-secretsmanager
27+
spec:
28+
region: us-east-2
29+
30+
secrets:
31+
- type: secret
32+
vault: myvault
33+
name: sample
34+
35+
transformations:
36+
- type: template
37+
in:
38+
- sample
39+
out: sample-ini
40+
spec:
41+
template: |
42+
thesecret={{ .sample }}
43+
44+
sinks:
45+
- type: file
46+
var: sample-ini
47+
spec:
48+
path: ./sample.ini
49+
mode: 400
50+
```
51+
52+
The above configuration defines a secret named `sample`, which is read from the AWS Secrets Manager instance in `us-east-2`. The secret is then transformed by the
53+
template and stored in a new secret named `sample-ini`. The new secret is written to a file named `./sample.ini` with file mode 400. Such a configuration may define
54+
multiple vaults, secrets, multiple transformations and sinks.
55+
56+
See [docs/](docs/README.md) for more details. A configuration file may contain environment variables, which are expanded before processing by using the `-e` switch, e.g.:
57+
58+
```yaml
59+
secrets:
60+
- type: secret
61+
vault: ${VAULT_NAME}
62+
name: sample
63+
```
64+
65+
This will expand the vault name of the environment variable `VAULT_NAME` and continue. This makes it possible to use the same configuration
66+
file for multiple environments.
67+
68+
## Building
69+
70+
The Makefile's `build` target builds an executable in `dist/`.
71+
72+
```bash
73+
$ make build
74+
```
75+
76+
To build exectuables for several platforms, the `release` target uses [goreleaser](https://goreleaser.com/):
77+
78+
```bash
79+
$ make release
80+
```
81+
82+
83+
## Testing
84+
85+
### Unit tests
86+
87+
```bash
88+
$ go test -v ./...
89+
```
90+
91+
### CLI tests
92+
93+
CLI tests are shell-based and written using bats. The executable is expected to be present in `dist/`. so `make build`
94+
is necessary before. To run the tests:
95+
96+
```bash
97+
$ cd tests
98+
$ bats .
99+
```
100+
101+
## Contributing
102+
103+
Pull requests are welcome!
104+
105+
## License
106+
107+
(C) 2021 @aschmidt75, MIT License

cmd/cmd.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Package main contains the main command
2+
//
3+
// MIT License
4+
//
5+
// Copyright (c) 2021 Andreas Schmidt
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
package main
25+
26+
import (
27+
"context"
28+
"flag"
29+
"fmt"
30+
"github.com/spf13/afero"
31+
"go-secretshelper/pkg/adapters"
32+
"go-secretshelper/pkg/core"
33+
"io/ioutil"
34+
"log"
35+
"os"
36+
)
37+
38+
var (
39+
commit = "none"
40+
date = "unknown"
41+
)
42+
43+
const (
44+
// ExitCodeOk is ok
45+
ExitCodeOk = 0
46+
47+
// ExitCodeNoOrUnknownCommand we're not able to run the command
48+
ExitCodeNoOrUnknownCommand = 1
49+
50+
// ExitCodeInvalidConfig something wrong with config
51+
ExitCodeInvalidConfig = 2
52+
)
53+
54+
func usage() {
55+
fmt.Println("Usage: go-secretshelper [-v] [-e] [-c config] <command>")
56+
fmt.Println("where commands are")
57+
fmt.Println(" version print out version")
58+
fmt.Println(" run run specified config")
59+
}
60+
61+
func main() {
62+
63+
verboseFlag := flag.Bool("v", false, "Enables verbose output")
64+
envFlag := flag.Bool("e", false, "Enables environment variable substitution")
65+
flag.Parse()
66+
67+
var l *log.Logger
68+
if *verboseFlag {
69+
l = log.New(os.Stderr, "", log.LstdFlags)
70+
} else {
71+
l = log.New(ioutil.Discard, "", 0)
72+
}
73+
74+
values := flag.Args()
75+
if len(values) == 0 {
76+
usage()
77+
os.Exit(ExitCodeNoOrUnknownCommand)
78+
}
79+
80+
switch values[0] {
81+
case "version":
82+
fmt.Printf("%s (%s)\n", commit, date)
83+
os.Exit(ExitCodeOk)
84+
85+
case "run":
86+
87+
fs := flag.NewFlagSet("run", flag.ExitOnError)
88+
configFlag := fs.String("c", "", "configuration file")
89+
90+
if err := fs.Parse(values[1:]); err != nil {
91+
fmt.Fprintf(os.Stderr, "error parsind commands: %s\n", err)
92+
os.Exit(ExitCodeNoOrUnknownCommand)
93+
}
94+
95+
// read config
96+
config, err := core.NewConfigFromFile(*configFlag, *envFlag)
97+
if err != nil {
98+
fmt.Printf("Unable to read config from file %s: %s\n", *configFlag, err)
99+
os.Exit(ExitCodeInvalidConfig)
100+
}
101+
102+
// validate
103+
f := adapters.NewBuiltinFactory(l, afero.NewOsFs())
104+
if err := config.Validate(f); err != nil {
105+
fmt.Fprintf(os.Stderr, "Error validating configuration: %s\n", err)
106+
os.Exit(ExitCodeInvalidConfig)
107+
}
108+
109+
// run
110+
cmd := core.NewMainUseCaseImpl(l)
111+
112+
err = cmd.Process(context.Background(), f,
113+
&config.Defaults,
114+
&config.Vaults,
115+
&config.Secrets,
116+
&config.Transformations,
117+
&config.Sinks)
118+
119+
if err != nil {
120+
fmt.Println(err)
121+
os.Exit(4)
122+
}
123+
os.Exit(ExitCodeOk)
124+
default:
125+
fmt.Fprintf(os.Stderr, "unknown command: %s\n", values[0])
126+
usage()
127+
os.Exit(ExitCodeNoOrUnknownCommand)
128+
}
129+
130+
}

docs/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Documentation
2+
3+
## Overview
4+
5+
* [Vaults](/docs/vaults.md) describes valid vault types and their configuration
6+
* [Transformations](/docs/transformations.md) is about transformation steps.
7+
* [Sinks](/docs/sinks.md)describe the use of sinks.
8+
9+
## Running
10+
11+
```bash
12+
$ go-secretshelper
13+
Usage: go-secretshelper [-v] [-e] <command>
14+
where commands are
15+
version print out version
16+
run run specified config
17+
```
18+
19+
Global flags are:
20+
* -v: be more verbose
21+
* -e: substitute environment variables when processing configuration files
22+
23+
```bash
24+
$ go-secretshelper run -h
25+
Usage of run:
26+
-c string
27+
configuration file
28+
```
29+
30+
The `run` command takes the name of a yaml-based configuration file in `-c`, and starts processing the file.

0 commit comments

Comments
 (0)