Skip to content

Commit

Permalink
Merge pull request spiffe#403 from evan2645/add-watch-flag-to-api-fetch
Browse files Browse the repository at this point in the history
Add CLI command to watch Workload API
  • Loading branch information
evan2645 authored Apr 2, 2018
2 parents b90d108 + 1eb5849 commit 766aad7
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (f *FetchCLI) Run(args []string) int {
}

if !f.config.silent {
f.printResponse(resp, respTime)
printX509SVIDResponse(resp, respTime)
}

if f.config.writePath != "" {
Expand Down Expand Up @@ -102,50 +102,6 @@ func (f *FetchCLI) fetchX509SVID(c workload.SpiffeWorkloadAPIClient) (*workload.
return stream.Recv()
}

func (f FetchCLI) printResponse(resp *workload.X509SVIDResponse, respTime time.Duration) {
lenMsg := fmt.Sprintf("Fetched %v bundle", len(resp.Svids))
if len(resp.Svids) != 1 {
lenMsg = lenMsg + "s"
}
lenMsg = lenMsg + fmt.Sprintf(" in %s", respTime)

fmt.Println(lenMsg)
for _, s := range resp.Svids {
fmt.Println()
f.printSVID(s)
}

fmt.Println()
}

func (f FetchCLI) printSVID(msg *workload.X509SVID) {
// Print SPIFFE ID first so if we run into a problem, we
// get to know which record it was
fmt.Printf("SPIFFE ID:\t\t%s\n", msg.SpiffeId)

// Parse SVID and CA bundle. If we encounter an error,
// simply print it and return so we can go to the next bundle
svid, err := x509.ParseCertificate(msg.X509Svid)
if err != nil {
fmt.Printf("ERROR: Could not parse SVID: %s\n", err)
return
}

svidBundle, err := x509.ParseCertificates(msg.Bundle)
if err != nil {
fmt.Printf("ERROR: Could not parse CA Certificates: %s\n", err)
return
}

fmt.Printf("SVID Valid After:\t%v\n", svid.NotBefore)
fmt.Printf("SVID Valid Until:\t%v\n", svid.NotAfter)
for i, ca := range svidBundle {
num := i + 1
fmt.Printf("CA #%v Valid After:\t%v\n", num, ca.NotBefore)
fmt.Printf("CA #%v Valid Until:\t%v\n", num, ca.NotAfter)
}
}

func (f FetchCLI) writeResponse(resp *workload.X509SVIDResponse) error {
for i, svid := range resp.Svids {
svidName := fmt.Sprintf("svid.%v.pem", i)
Expand Down
53 changes: 53 additions & 0 deletions cmd/spire-agent/cli/api/printer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package api

import (
"crypto/x509"
"fmt"
"time"

"github.com/spiffe/spire/proto/api/workload"
)

func printX509SVIDResponse(resp *workload.X509SVIDResponse, respTime time.Duration) {
lenMsg := fmt.Sprintf("Received %v bundle", len(resp.Svids))
if len(resp.Svids) != 1 {
lenMsg = lenMsg + "s"
}
lenMsg = lenMsg + fmt.Sprintf(" after %s", respTime)

fmt.Println(lenMsg)
for _, s := range resp.Svids {
fmt.Println()
printX509SVID(s)
}

fmt.Println()
}

func printX509SVID(msg *workload.X509SVID) {
// Print SPIFFE ID first so if we run into a problem, we
// get to know which record it was
fmt.Printf("SPIFFE ID:\t\t%s\n", msg.SpiffeId)

// Parse SVID and CA bundle. If we encounter an error,
// simply print it and return so we can go to the next bundle
svid, err := x509.ParseCertificate(msg.X509Svid)
if err != nil {
fmt.Printf("ERROR: Could not parse SVID: %s\n", err)
return
}

svidBundle, err := x509.ParseCertificates(msg.Bundle)
if err != nil {
fmt.Printf("ERROR: Could not parse CA Certificates: %s\n", err)
return
}

fmt.Printf("SVID Valid After:\t%v\n", svid.NotBefore)
fmt.Printf("SVID Valid Until:\t%v\n", svid.NotAfter)
for i, ca := range svidBundle {
num := i + 1
fmt.Printf("CA #%v Valid After:\t%v\n", num, ca.NotBefore)
fmt.Printf("CA #%v Valid Until:\t%v\n", num, ca.NotAfter)
}
}
93 changes: 93 additions & 0 deletions cmd/spire-agent/cli/api/watch_cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package api

import (
"flag"
"fmt"
"log"
"net"
"os"
"os/signal"
"syscall"
"time"

"github.com/spiffe/spire/api/workload"
)

type WatchConfig struct {
socketPath string
}

type WatchCLI struct {
config *WatchConfig

stopChan chan struct{}
}

func (WatchCLI) Synopsis() string {
return "Attaches to the Workload API and prints updates as they're received"
}

func (w WatchCLI) Help() string {
err := w.parseConfig([]string{"-h"})
return err.Error()
}

func (w *WatchCLI) Run(args []string) int {
err := w.parseConfig(args)
if err != nil {
fmt.Println(err)
return 1
}

client, err := w.startClient()
if err != nil {
fmt.Println(err)
return 1
}

updateTime := time.Now()
go w.signalListener()
for {
select {
case <-w.stopChan:
return 0
case u := <-client.UpdateChan():
printX509SVIDResponse(u, time.Since(updateTime))
updateTime = time.Now()
}
}
}

func (w *WatchCLI) parseConfig(args []string) error {
fs := flag.NewFlagSet("watch", flag.ContinueOnError)
c := &WatchConfig{}
fs.StringVar(&c.socketPath, "socketPath", "/tmp/agent.sock", "Path to the Workload API socket")

w.config = c
return fs.Parse(args)
}

func (w *WatchCLI) startClient() (workload.Client, error) {
addr := &net.UnixAddr{
Net: "unix",
Name: w.config.socketPath,
}

l := log.New(os.Stdout, "", log.LstdFlags)

c := &workload.ClientConfig{
Addr: addr,
Logger: l,
}

client := workload.NewClient(c)
return client, client.Start()
}

func (w *WatchCLI) signalListener() {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

<-signalChan
close(w.stopChan)
}
3 changes: 3 additions & 0 deletions cmd/spire-agent/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ func Run(args []string) int {
"api fetch": func() (cli.Command, error) {
return &api.FetchCLI{}, nil
},
"api watch": func() (cli.Command, error) {
return &api.WatchCLI{}, nil
},
"run": func() (cli.Command, error) {
return &run.RunCLI{}, nil
},
Expand Down
2 changes: 1 addition & 1 deletion script/e2e_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ sleep 2

set +e
RESULT=$(./cmd/spire-agent/spire-agent api fetch)
echo $RESULT | grep "Fetched 1 bundle"
echo $RESULT | grep "Received 1 bundle"
if [ $? != 0 ]; then
CODE=1
echo
Expand Down

0 comments on commit 766aad7

Please sign in to comment.