Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 21 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,17 @@ import (

// State represents a desired system state
type State struct {
Targets task.Targets `json:"targets"`
Env map[string]string `json:"env"`
Targets task.Targets `json:"targets"`
AuthMethods []AuthMethod `json:"auths"`
Env map[string]string `json:"env"`
}

// AuthMethod represents a method of authentication for a target
type AuthMethod struct {
Name string `json:"name"` // name of the auth method
Path string `json:"path"` // path within the secret store
UserKey string `json:"user_key"` // key for username
PassKey string `json:"pass_key"` // key for password
}

// ConfigFromDirectory searches a directory for configuration files and
Expand Down Expand Up @@ -72,6 +81,7 @@ func (cb *configBuilder) construct(hostname string) (err error) {
cb.vm.Run(`'use strict';
var STATE = {
targets: [],
auths: [],
env: {}
};

Expand All @@ -90,6 +100,15 @@ function T(t) {
function E(k, v) {
STATE.env[k] = v
}

function A(a) {
if(a.name === undefined) { throw "auth name undefined"; }
if(a.path === undefined) { throw "auth path undefined"; }
if(a.user_key === undefined) { throw "auth user_key undefined"; }
if(a.pass_key === undefined) { throw "auth pass_key undefined"; }

STATE.auths.push(a);
}
`)

cb.vm.Set("HOSTNAME", hostname) //nolint:errcheck
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/picostack/pico
go 1.13

require (
github.com/Southclaws/gitwatch v1.3.2
github.com/Southclaws/gitwatch v1.3.3
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/eapache/go-resiliency v1.2.0
github.com/frankban/quicktest v1.4.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/Southclaws/gitwatch v1.3.1 h1:4XtiujsnxHKSKze3Tb5sWwTdBxSVW/JLbK54ruJ
github.com/Southclaws/gitwatch v1.3.1/go.mod h1:xCudUiwWxkDYZ69cEhlTwAKIzbG1OpnA/s/pjPIW6gU=
github.com/Southclaws/gitwatch v1.3.2 h1:zmt571n8ItXgkRJPyCFtFjcymvsFOGcm7JnHNpFDP+8=
github.com/Southclaws/gitwatch v1.3.2/go.mod h1:xCudUiwWxkDYZ69cEhlTwAKIzbG1OpnA/s/pjPIW6gU=
github.com/Southclaws/gitwatch v1.3.3 h1:w5AI9IcMEVqb6cPyDjM9tvOI4r26m4UHAl5BVEvgKac=
github.com/Southclaws/gitwatch v1.3.3/go.mod h1:xCudUiwWxkDYZ69cEhlTwAKIzbG1OpnA/s/pjPIW6gU=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
Expand Down
2 changes: 1 addition & 1 deletion service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func Initialise(c Config) (app *App, err error) {
app.config.Directory,
app.bus,
app.config.CheckInterval,
authMethod,
secretStore,
)

return
Expand Down
3 changes: 3 additions & 0 deletions task/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type Target struct {

// Whether or not to run `Command` on first run, useful if the command is `docker-compose up`
InitialRun bool `json:"initial_run"`

// Auth method to use from the auth store
Auth string `json:"auth"`
}

// Execute runs the target's command in the specified directory with the
Expand Down
40 changes: 36 additions & 4 deletions watcher/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"github.com/pkg/errors"
"go.uber.org/zap"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"

"github.com/picostack/pico/config"
"github.com/picostack/pico/secret"
"github.com/picostack/pico/task"
)

Expand All @@ -24,7 +26,7 @@ type GitWatcher struct {
directory string
bus chan task.ExecutionTask
checkInterval time.Duration
ssh transport.AuthMethod
secrets secret.Store

targetsWatcher *gitwatch.Session
state config.State
Expand All @@ -42,13 +44,13 @@ func NewGitWatcher(
directory string,
bus chan task.ExecutionTask,
checkInterval time.Duration,
ssh transport.AuthMethod,
secrets secret.Store,
) *GitWatcher {
return &GitWatcher{
directory: directory,
bus: bus,
checkInterval: checkInterval,
ssh: ssh,
secrets: secrets,

initialise: make(chan bool),
newState: make(chan config.State, 16),
Expand Down Expand Up @@ -161,11 +163,16 @@ func (w *GitWatcher) watchTargets() (err error) {
if t.Branch != "" {
dir = fmt.Sprintf("%s_%s", t.Name, t.Branch)
}
auth, err := w.getAuthForTarget(t)
if err != nil {
return err
}
zap.L().Debug("assigned target", zap.String("url", t.RepoURL), zap.String("directory", dir))
targetRepos[i] = gitwatch.Repository{
URL: t.RepoURL,
Branch: t.Branch,
Directory: dir,
Auth: auth,
}
}

Expand All @@ -177,7 +184,7 @@ func (w *GitWatcher) watchTargets() (err error) {
targetRepos,
w.checkInterval,
w.directory,
w.ssh,
nil,
false)
if err != nil {
return errors.Wrap(err, "failed to watch targets")
Expand Down Expand Up @@ -211,6 +218,31 @@ func (w *GitWatcher) handle(e gitwatch.Event) (err error) {
return nil
}

func (w GitWatcher) getAuthForTarget(t task.Target) (transport.AuthMethod, error) {
for _, a := range w.state.AuthMethods {
if a.Name == t.Auth {
s, err := w.secrets.GetSecretsForTarget(a.Path)
if err != nil {
return nil, err
}
username, ok := s[a.UserKey]
if !ok {
return nil, errors.Errorf("auth object 'user_key' did not point to a valid element in the specified secret at '%s'", a.Path)
}
password, ok := s[a.PassKey]
if !ok {
return nil, errors.Errorf("auth object 'pass_key' did not point to a valid element in the specified secret at '%s'", a.Path)
}
zap.L().Debug("using auth method for target", zap.String("name", a.Name))
return &http.BasicAuth{
Username: username,
Password: password,
}, nil
}
}
return nil, nil
}

func (w GitWatcher) executeTargets(targets []task.Target, shutdown bool) {
zap.L().Debug("executing all targets",
zap.Bool("shutdown", shutdown),
Expand Down