Skip to content

Commit

Permalink
Updated spire to handle entries via options (#258)
Browse files Browse the repository at this point in the history
Turns out, spire-agent only polls spire-server
every 5 seconds.  This means that if we run spire-server, then
spire-agent, then add entries... it can take up to six seconds
to get our SVID.

By moving to options, we can:
1.  Start spire-server
2.  Create entries
3.  Start spire-agent

And spire-agent *starts* with the entries and can thus issue ids.

Signed-off-by: Ed Warnicke <hagbard@gmail.com>
  • Loading branch information
edwarnicke committed May 27, 2020
1 parent 6d771f4 commit 392d4af
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Expand Up @@ -227,4 +227,4 @@ issues:
- path: pkg/tools/spire/start.go
linters:
- funlen
text: "Function 'Start' has too many statements"
- gocyclo
3 changes: 2 additions & 1 deletion pkg/tools/callback/callback.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/tools/spire/agent.conf.go
Expand Up @@ -41,6 +41,7 @@ plugins {
}
WorkloadAttestor "unix" {
plugin_data {
discover_workload_path = true
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions pkg/tools/spire/options.go
@@ -0,0 +1,43 @@
package spire

import (
"context"
)

type entry struct {
spiffeID string
selector string
}

type option struct {
ctx context.Context
agentID string
entries []*entry
}

// Option for spire
type Option func(*option)

// WithContext - use ctx as context for starting spire
func WithContext(ctx context.Context) Option {
return func(o *option) {
o.ctx = ctx
}
}

// WithAgentID - agentID for starting spire
func WithAgentID(agentID string) Option {
return func(o *option) {
o.agentID = agentID
}
}

// WithEntry - Option to add Entry to spire-server. May be used multiple times.
func WithEntry(spiffeID, selector string) Option {
return func(o *option) {
o.entries = append(o.entries, &entry{
spiffeID: spiffeID,
selector: selector,
})
}
}
50 changes: 33 additions & 17 deletions pkg/tools/spire/start.go
Expand Up @@ -29,11 +29,10 @@ import (
"sync"

"github.com/edwarnicke/exechelper"
"github.com/matryer/try"
"github.com/sirupsen/logrus"
"github.com/spiffe/go-spiffe/workload"

"github.com/matryer/try"

"github.com/networkservicemesh/sdk/pkg/tools/log"
)

Expand All @@ -51,7 +50,15 @@ func AddEntry(ctx context.Context, parentID, spiffeID, selector string) error {
var spireRoot string = ""

// Start - start a spire-server and spire-agent with the given agentId
func Start(ctx context.Context, agentID string) <-chan error {
func Start(options ...Option) <-chan error {
opt := &option{
ctx: context.Background(),
agentID: "spiffe://example.org/agent",
}
for _, o := range options {
o(opt)
}

errCh := make(chan error, 4)
var err error
spireRoot, err = ioutil.TempDir("", "spire")
Expand All @@ -63,7 +70,7 @@ func Start(ctx context.Context, agentID string) <-chan error {

// Write the config files (if not present)
var spireSocketPath string
spireSocketPath, err = writeDefaultConfigFiles(ctx, spireRoot)
spireSocketPath, err = writeDefaultConfigFiles(opt.ctx, spireRoot)
if err != nil {
errCh <- err
close(errCh)
Expand All @@ -80,9 +87,9 @@ func Start(ctx context.Context, agentID string) <-chan error {
spireCmd := fmt.Sprintf("spire-server run -config %s", path.Join(spireRoot, spireServerConfFileName))
spireServerErrCh := exechelper.Start(spireCmd,
exechelper.WithDir(spireRoot),
exechelper.WithContext(ctx),
exechelper.WithStdout(log.Entry(ctx).WithField("cmd", "spire-server run").Writer()),
exechelper.WithStderr(log.Entry(ctx).WithField("cmd", "spire-server run").Writer()),
exechelper.WithContext(opt.ctx),
exechelper.WithStdout(log.Entry(opt.ctx).WithField("cmd", "spire-server run").Writer()),
exechelper.WithStderr(log.Entry(opt.ctx).WithField("cmd", "spire-server run").Writer()),
)
select {
case spireServerErr := <-spireServerErrCh:
Expand All @@ -96,8 +103,8 @@ func Start(ctx context.Context, agentID string) <-chan error {
err = try.Do(func(attempts int) (bool, error) {
return attempts < 10, exechelper.Run(
fmt.Sprintf("spire-server healthcheck -registrationUDSPath %s/spire-registration.sock", spireRoot),
exechelper.WithStdout(log.Entry(ctx).WithField("cmd", "spire-server healthcheck").Writer()),
exechelper.WithStderr(log.Entry(ctx).WithField("cmd", "spire-server healthcheck").Writer()),
exechelper.WithStdout(log.Entry(opt.ctx).WithField("cmd", "spire-server healthcheck").Writer()),
exechelper.WithStderr(log.Entry(opt.ctx).WithField("cmd", "spire-server healthcheck").Writer()),
)
})
if err != nil {
Expand All @@ -106,12 +113,21 @@ func Start(ctx context.Context, agentID string) <-chan error {
return errCh
}

// Add Entries
for _, entry := range opt.entries {
if err = AddEntry(opt.ctx, opt.agentID, entry.spiffeID, entry.selector); err != nil {
errCh <- err
close(errCh)
return errCh
}
}

// Get the SpireServers Token
cmdStr := "spire-server token generate -spiffeID %s -registrationUDSPath %s/spire-registration.sock"
cmdStr = fmt.Sprintf(cmdStr, agentID, spireRoot)
cmdStr = fmt.Sprintf(cmdStr, opt.agentID, spireRoot)
outputBytes, err := exechelper.Output(cmdStr,
exechelper.WithStdout(log.Entry(ctx).WithField("cmd", cmdStr).Writer()),
exechelper.WithStderr(log.Entry(ctx).WithField("cmd", cmdStr).Writer()),
exechelper.WithStdout(log.Entry(opt.ctx).WithField("cmd", cmdStr).Writer()),
exechelper.WithStderr(log.Entry(opt.ctx).WithField("cmd", cmdStr).Writer()),
)
if err != nil {
errCh <- err
Expand All @@ -124,9 +140,9 @@ func Start(ctx context.Context, agentID string) <-chan error {
// Start the Spire Agent
spireAgentErrCh := exechelper.Start("spire-agent run"+" -config "+spireAgentConfFilename+" -joinToken "+spireToken,
exechelper.WithDir(spireRoot),
exechelper.WithContext(ctx),
exechelper.WithStdout(log.Entry(ctx).WithField("cmd", "spire-agent run").Writer()),
exechelper.WithStderr(log.Entry(ctx).WithField("cmd", "spire-agent run").Writer()),
exechelper.WithContext(opt.ctx),
exechelper.WithStdout(log.Entry(opt.ctx).WithField("cmd", "spire-agent run").Writer()),
exechelper.WithStderr(log.Entry(opt.ctx).WithField("cmd", "spire-agent run").Writer()),
)
select {
case spireAgentErr := <-spireAgentErrCh:
Expand All @@ -140,8 +156,8 @@ func Start(ctx context.Context, agentID string) <-chan error {
err = try.Do(func(attempts int) (bool, error) {
cmdStr := fmt.Sprintf("spire-agent healthcheck -socketPath %s", spireSocketPath)
return attempts < 10, exechelper.Run(cmdStr,
exechelper.WithStdout(log.Entry(ctx).WithField("cmd", "spire-agent healthcheck").Writer()),
exechelper.WithStderr(log.Entry(ctx).WithField("cmd", "spire-agent healthcheck").Writer()),
exechelper.WithStdout(log.Entry(opt.ctx).WithField("cmd", "spire-agent healthcheck").Writer()),
exechelper.WithStderr(log.Entry(opt.ctx).WithField("cmd", "spire-agent healthcheck").Writer()),
)
})
if err != nil {
Expand Down

0 comments on commit 392d4af

Please sign in to comment.