Add a hosts create command (#25)
This commit is contained in:
1 parent
17fffe7c23
commit
e3c7ca3070
8 files changed
+341
-94
No files matched your search
+124
-36
@@ -7,12 +7,14 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
@@ -29,27 +31,103 @@ const (
|
||||
var reRemoveWhitespace = regexp.MustCompile(`[\s]+`)
|
||||
|
||||
type Command struct {
|
||||
UI cli.Ui
|
||||
Address string
|
||||
Context context.Context
|
||||
Context context.Context
|
||||
UI cli.Ui
|
||||
ShutdownCh chan struct{}
|
||||
|
||||
flags *FlagSets
|
||||
flagsOnce sync.Once
|
||||
|
||||
flagCACert string
|
||||
flagCAPath string
|
||||
flagClientCert string
|
||||
flagClientKey string
|
||||
flagAddress string
|
||||
flagOrg string
|
||||
flagProject string
|
||||
|
||||
flagTLSCACert string
|
||||
flagTLSCAPath string
|
||||
flagTLSClientCert string
|
||||
flagTLSClientKey string
|
||||
flagTLSServerName string
|
||||
flagTLSInsecure bool
|
||||
|
||||
flagFormat string
|
||||
flagField string
|
||||
flagOutputCurlString bool
|
||||
|
||||
client *api.Client
|
||||
}
|
||||
|
||||
func (c *Command) SetAddress(addr string) {
|
||||
c.Address = addr
|
||||
// Client returns the HTTP API client. The client is cached on the command to
|
||||
// save performance on future calls.
|
||||
func (c *Command) Client() (*api.Client, error) {
|
||||
// Read the test client if present
|
||||
if c.client != nil {
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
config, err := api.DefaultConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.flagOutputCurlString {
|
||||
config.OutputCurlString = c.flagOutputCurlString
|
||||
}
|
||||
|
||||
c.client, err = api.NewClient(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.flagAddress != NotSetValue {
|
||||
c.client.SetAddress(c.flagAddress)
|
||||
}
|
||||
if c.flagOrg != NotSetValue {
|
||||
c.client.SetOrg(c.flagOrg)
|
||||
}
|
||||
if c.flagProject != NotSetValue {
|
||||
c.client.SetProject(c.flagProject)
|
||||
}
|
||||
|
||||
// If we need custom TLS configuration, then set it
|
||||
var modifiedTLS bool
|
||||
tlsConfig := config.TLSConfig
|
||||
if c.flagTLSCACert != NotSetValue {
|
||||
tlsConfig.CACert = c.flagTLSCACert
|
||||
modifiedTLS = true
|
||||
}
|
||||
if c.flagTLSCAPath != NotSetValue {
|
||||
tlsConfig.CAPath = c.flagTLSCAPath
|
||||
modifiedTLS = true
|
||||
}
|
||||
if c.flagTLSClientCert != NotSetValue {
|
||||
tlsConfig.ClientCert = c.flagTLSClientCert
|
||||
modifiedTLS = true
|
||||
}
|
||||
if c.flagTLSClientKey != NotSetValue {
|
||||
tlsConfig.ClientKey = c.flagTLSClientKey
|
||||
modifiedTLS = true
|
||||
}
|
||||
if c.flagTLSServerName != NotSetValue {
|
||||
tlsConfig.ServerName = c.flagTLSServerName
|
||||
modifiedTLS = true
|
||||
}
|
||||
if c.flagTLSInsecure {
|
||||
tlsConfig.Insecure = c.flagTLSInsecure
|
||||
modifiedTLS = true
|
||||
}
|
||||
if modifiedTLS {
|
||||
// Setup TLS config
|
||||
if err := c.client.SetTLSConfig(tlsConfig); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to setup TLS config")
|
||||
}
|
||||
}
|
||||
|
||||
// Turn off retries on the CLI
|
||||
if os.Getenv(api.EnvWatchtowerMaxRetries) == "" {
|
||||
c.client.SetMaxRetries(0)
|
||||
}
|
||||
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
type FlagSetBit uint
|
||||
@@ -73,26 +151,39 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
bit = bit | FlagSetHTTP
|
||||
|
||||
if bit&FlagSetHTTP != 0 {
|
||||
f := set.NewFlagSet("HTTP Options")
|
||||
f := set.NewFlagSet("Connection Options")
|
||||
|
||||
addrStringVar := &StringVar{
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameAddress,
|
||||
Target: &c.Address,
|
||||
Target: &c.flagAddress,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerAddress,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "Address of the Watchtower controller.",
|
||||
}
|
||||
if c.Address != "" {
|
||||
addrStringVar.Default = c.Address
|
||||
} else {
|
||||
addrStringVar.Default = "https://127.0.0.1:9200"
|
||||
}
|
||||
f.StringVar(addrStringVar)
|
||||
})
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameOrg,
|
||||
Target: &c.flagOrg,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerOrg,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "Organization in which to make the request; overrides any set in the address.",
|
||||
})
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameProject,
|
||||
Target: &c.flagProject,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerProject,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "Project in which to make the request; overrides any set in the address.",
|
||||
})
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameCACert,
|
||||
Target: &c.flagCACert,
|
||||
Default: "",
|
||||
Target: &c.flagTLSCACert,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerCACert,
|
||||
Completion: complete.PredictFiles("*"),
|
||||
Usage: "Path on the local disk to a single PEM-encoded CA " +
|
||||
@@ -102,8 +193,8 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameCAPath,
|
||||
Target: &c.flagCAPath,
|
||||
Default: "",
|
||||
Target: &c.flagTLSCAPath,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerCAPath,
|
||||
Completion: complete.PredictDirs("*"),
|
||||
Usage: "Path on the local disk to a directory of PEM-encoded CA " +
|
||||
@@ -112,8 +203,8 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameClientCert,
|
||||
Target: &c.flagClientCert,
|
||||
Default: "",
|
||||
Target: &c.flagTLSClientCert,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerClientCert,
|
||||
Completion: complete.PredictFiles("*"),
|
||||
Usage: "Path on the local disk to a single PEM-encoded CA " +
|
||||
@@ -123,8 +214,8 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagNameClientKey,
|
||||
Target: &c.flagClientKey,
|
||||
Default: "",
|
||||
Target: &c.flagTLSClientKey,
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerClientKey,
|
||||
Completion: complete.PredictFiles("*"),
|
||||
Usage: "Path on the local disk to a single PEM-encoded private key " +
|
||||
@@ -134,7 +225,7 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
f.StringVar(&StringVar{
|
||||
Name: FlagTLSServerName,
|
||||
Target: &c.flagTLSServerName,
|
||||
Default: "",
|
||||
Default: NotSetValue,
|
||||
EnvVar: api.EnvWatchtowerTLSServerName,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "Name to use as the SNI host when connecting to the Watchtower " +
|
||||
@@ -142,23 +233,20 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
})
|
||||
|
||||
f.BoolVar(&BoolVar{
|
||||
Name: FlagNameTLSInsecure,
|
||||
Target: &c.flagTLSInsecure,
|
||||
Default: false,
|
||||
EnvVar: api.EnvWatchtowerTLSInsecure,
|
||||
Name: FlagNameTLSInsecure,
|
||||
Target: &c.flagTLSInsecure,
|
||||
EnvVar: api.EnvWatchtowerTLSInsecure,
|
||||
Usage: "Disable verification of TLS certificates. Using this option " +
|
||||
"is highly discouraged as it decreases the security of data " +
|
||||
"transmissions to and from the Watchtower server.",
|
||||
})
|
||||
|
||||
f.BoolVar(&BoolVar{
|
||||
Name: "output-curl-string",
|
||||
Target: &c.flagOutputCurlString,
|
||||
Default: false,
|
||||
Name: "output-curl-string",
|
||||
Target: &c.flagOutputCurlString,
|
||||
Usage: "Instead of executing the request, print an equivalent cURL " +
|
||||
"command string and exit.",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if bit&(FlagSetOutputField|FlagSetOutputFormat) != 0 {
|
||||
|
||||
+19
-12
@@ -1,29 +1,36 @@
|
||||
package base
|
||||
|
||||
const (
|
||||
// flagNameAddress is the flag used in the base command to read in the
|
||||
// FlagNameAddress is the flag used in the base command to read in the
|
||||
// address of the Watchtower server.
|
||||
FlagNameAddress = "address"
|
||||
// flagnameCACert is the flag used in the base command to read in the CA
|
||||
// FlagNameOrg is the flag used in the base command to read in the org in
|
||||
// which to make a request.
|
||||
FlagNameOrg = "org"
|
||||
// FlagNameProject is the flag used in the base command to read in the
|
||||
// project in which to make a request.
|
||||
FlagNameProject = "project"
|
||||
// FlagnameCACert is the flag used in the base command to read in the CA
|
||||
// cert.
|
||||
FlagNameCACert = "ca-cert"
|
||||
// flagnameCAPath is the flag used in the base command to read in the CA
|
||||
// FlagnameCAPath is the flag used in the base command to read in the CA
|
||||
// cert path.
|
||||
FlagNameCAPath = "ca-path"
|
||||
//flagNameClientCert is the flag used in the base command to read in the
|
||||
//client key
|
||||
// FlagNameClientCert is the flag used in the base command to read in the
|
||||
// client key
|
||||
FlagNameClientKey = "client-key"
|
||||
//flagNameClientCert is the flag used in the base command to read in the
|
||||
//client cert
|
||||
// FlagNameClientCert is the flag used in the base command to read in the
|
||||
// client cert
|
||||
FlagNameClientCert = "client-cert"
|
||||
// flagNameTLSInsecure is the flag used in the base command to read in
|
||||
// FlagNameTLSInsecure is the flag used in the base command to read in
|
||||
// the option to ignore TLS certificate verification.
|
||||
FlagNameTLSInsecure = "tls-insecure"
|
||||
// flagTLSServerName is the flag used in the base command to read in
|
||||
// FlagTLSServerName is the flag used in the base command to read in
|
||||
// the TLS server name.
|
||||
FlagTLSServerName = "tls-server-name"
|
||||
)
|
||||
|
||||
const EnvWatchtowerCLINoColor = `WATCHTOWER_CLI_NO_COLOR`
|
||||
const EnvWatchtowerCLIFormat = `WATCHTOWER_CLI_FORMAT`
|
||||
|
||||
const (
|
||||
EnvWatchtowerCLINoColor = `WATCHTOWER_CLI_NO_COLOR`
|
||||
EnvWatchtowerCLIFormat = `WATCHTOWER_CLI_FORMAT`
|
||||
)
|
||||
+33
-22
@@ -1,6 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
@@ -8,6 +9,7 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/controller"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/dev"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/hosts"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/worker"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
@@ -16,47 +18,56 @@ import (
|
||||
var Commands map[string]cli.CommandFactory
|
||||
|
||||
func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
|
||||
/*
|
||||
getBaseCommand := func() *base.Command {
|
||||
return &base.Command{
|
||||
UI: ui,
|
||||
Address: runOpts.Address,
|
||||
}
|
||||
getBaseCommand := func() *base.Command {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ret := &base.Command{
|
||||
UI: ui,
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
Context: ctx,
|
||||
}
|
||||
*/
|
||||
|
||||
go func() {
|
||||
<-ret.ShutdownCh
|
||||
cancel()
|
||||
}()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
Commands = map[string]cli.CommandFactory{
|
||||
"controller": func() (cli.Command, error) {
|
||||
return &controller.Command{
|
||||
Command: &base.Command{
|
||||
UI: serverCmdUi,
|
||||
Address: runOpts.Address,
|
||||
UI: serverCmdUi,
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
},
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
SighupCh: MakeSighupCh(),
|
||||
SigUSR2Ch: MakeSigUSR2Ch(),
|
||||
SighupCh: MakeSighupCh(),
|
||||
SigUSR2Ch: MakeSigUSR2Ch(),
|
||||
}, nil
|
||||
},
|
||||
"worker": func() (cli.Command, error) {
|
||||
return &worker.Command{
|
||||
Command: &base.Command{
|
||||
UI: serverCmdUi,
|
||||
Address: runOpts.Address,
|
||||
UI: serverCmdUi,
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
},
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
SighupCh: MakeSighupCh(),
|
||||
SigUSR2Ch: MakeSigUSR2Ch(),
|
||||
SighupCh: MakeSighupCh(),
|
||||
SigUSR2Ch: MakeSigUSR2Ch(),
|
||||
}, nil
|
||||
},
|
||||
"dev": func() (cli.Command, error) {
|
||||
return &dev.Command{
|
||||
Command: &base.Command{
|
||||
UI: serverCmdUi,
|
||||
Address: runOpts.Address,
|
||||
UI: serverCmdUi,
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
},
|
||||
ShutdownCh: MakeShutdownCh(),
|
||||
SighupCh: MakeSighupCh(),
|
||||
SigUSR2Ch: MakeSigUSR2Ch(),
|
||||
SighupCh: MakeSighupCh(),
|
||||
SigUSR2Ch: MakeSigUSR2Ch(),
|
||||
}, nil
|
||||
},
|
||||
"hosts create": func() (cli.Command, error) {
|
||||
return &hosts.CreateCommand{
|
||||
Command: getBaseCommand(),
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ type Command struct {
|
||||
*base.Command
|
||||
*base.Server
|
||||
|
||||
ShutdownCh chan struct{}
|
||||
SighupCh chan struct{}
|
||||
ReloadedCh chan struct{}
|
||||
SigUSR2Ch chan struct{}
|
||||
ExtShutdownCh chan struct{}
|
||||
SighupCh chan struct{}
|
||||
ReloadedCh chan struct{}
|
||||
SigUSR2Ch chan struct{}
|
||||
|
||||
cleanupGuard sync.Once
|
||||
|
||||
@@ -343,9 +343,14 @@ func (c *Command) WaitForInterrupt() int {
|
||||
// Wait for shutdown
|
||||
shutdownTriggered := false
|
||||
|
||||
shutdownCh := c.ShutdownCh
|
||||
if c.ExtShutdownCh != nil {
|
||||
shutdownCh = c.ExtShutdownCh
|
||||
}
|
||||
|
||||
for !shutdownTriggered {
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
case <-shutdownCh:
|
||||
c.UI.Output("==> Watchtower controller shutdown triggered")
|
||||
|
||||
if err := c.controller.Shutdown(); err != nil {
|
||||
|
||||
@@ -21,7 +21,6 @@ type Command struct {
|
||||
*base.Command
|
||||
*base.Server
|
||||
|
||||
ShutdownCh chan struct{}
|
||||
SighupCh chan struct{}
|
||||
childSighupCh []chan struct{}
|
||||
ReloadedCh chan struct{}
|
||||
@@ -244,11 +243,11 @@ func (c *Command) Run(args []string) int {
|
||||
c.childSighupCh = append(c.childSighupCh, controllerSighupCh)
|
||||
|
||||
devController := &controllercmd.Command{
|
||||
Command: c.Command,
|
||||
Server: c.Server,
|
||||
ShutdownCh: childShutdownCh,
|
||||
SighupCh: controllerSighupCh,
|
||||
Config: devConfig,
|
||||
Command: c.Command,
|
||||
Server: c.Server,
|
||||
ExtShutdownCh: childShutdownCh,
|
||||
SighupCh: controllerSighupCh,
|
||||
Config: devConfig,
|
||||
}
|
||||
if err := devController.Start(); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
@@ -258,11 +257,11 @@ func (c *Command) Run(args []string) int {
|
||||
workerSighupCh := make(chan struct{})
|
||||
c.childSighupCh = append(c.childSighupCh, workerSighupCh)
|
||||
devWorker := &workercmd.Command{
|
||||
Command: c.Command,
|
||||
Server: c.Server,
|
||||
ShutdownCh: childShutdownCh,
|
||||
SighupCh: workerSighupCh,
|
||||
Config: devConfig,
|
||||
Command: c.Command,
|
||||
Server: c.Server,
|
||||
ExtShutdownCh: childShutdownCh,
|
||||
SighupCh: workerSighupCh,
|
||||
Config: devConfig,
|
||||
}
|
||||
if err := devWorker.Start(); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
@@ -286,7 +285,8 @@ func (c *Command) Run(args []string) int {
|
||||
case <-c.ShutdownCh:
|
||||
c.UI.Output("==> Watchtower dev environment shutdown triggered")
|
||||
|
||||
close(childShutdownCh)
|
||||
childShutdownCh <- struct{}{}
|
||||
childShutdownCh <- struct{}{}
|
||||
|
||||
shutdownTriggered = true
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package hosts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/api/hosts"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/kr/pretty"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
var _ cli.Command = (*CreateCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*CreateCommand)(nil)
|
||||
|
||||
type CreateCommand struct {
|
||||
*base.Command
|
||||
|
||||
flagHost string
|
||||
flagName string
|
||||
flagCatalog string
|
||||
}
|
||||
|
||||
func (c *CreateCommand) Synopsis() string {
|
||||
return "Creates a host in the given host catalog"
|
||||
}
|
||||
|
||||
func (c *CreateCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: watchtower hosts create
|
||||
|
||||
Creates a host in the given host catalog. This command will result in an
|
||||
error for any catalog that does not support manual host creation.
|
||||
|
||||
Example:
|
||||
|
||||
$ watchtower hosts create -catalog=<id> -host=<addr> -name=<name>
|
||||
|
||||
` + c.Flags().Help()
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *CreateCommand) Flags() *base.FlagSets {
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetOutputFormat)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "host",
|
||||
Target: &c.flagHost,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "The host's address; can be an IP address or DNS name",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "name",
|
||||
Target: &c.flagName,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "A friendly name for the host for display purposes",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "catalog",
|
||||
Target: &c.flagCatalog,
|
||||
Completion: complete.PredictAnything,
|
||||
Usage: "The ID of the host catalog in which the host should be created",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *CreateCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *CreateCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *CreateCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
switch {
|
||||
case c.flagCatalog == "":
|
||||
c.UI.Error("Catalog ID must be provided via -catalog")
|
||||
return 1
|
||||
case c.flagHost == "":
|
||||
c.UI.Error("Host address must be provided via -host")
|
||||
return 1
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
if err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 2
|
||||
}
|
||||
|
||||
catalog := &hosts.HostCatalog{
|
||||
Client: client,
|
||||
Id: api.String(c.flagCatalog),
|
||||
}
|
||||
|
||||
host := &hosts.Host{
|
||||
FriendlyName: api.StringOrNil(c.flagName),
|
||||
Address: api.String(c.flagHost),
|
||||
}
|
||||
|
||||
var apiErr *api.Error
|
||||
host, apiErr, err = catalog.CreateHost(c.Context, host)
|
||||
|
||||
switch {
|
||||
case err != nil:
|
||||
c.UI.Error(fmt.Errorf("error creating host: %w", err).Error())
|
||||
return 2
|
||||
case apiErr != nil:
|
||||
c.UI.Error(pretty.Sprint(apiErr))
|
||||
return 2
|
||||
default:
|
||||
c.UI.Info(pretty.Sprint(host))
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -23,10 +23,10 @@ type Command struct {
|
||||
*base.Command
|
||||
*base.Server
|
||||
|
||||
ShutdownCh chan struct{}
|
||||
SighupCh chan struct{}
|
||||
ReloadedCh chan struct{}
|
||||
SigUSR2Ch chan struct{}
|
||||
ExtShutdownCh chan struct{}
|
||||
SighupCh chan struct{}
|
||||
ReloadedCh chan struct{}
|
||||
SigUSR2Ch chan struct{}
|
||||
|
||||
cleanupGuard sync.Once
|
||||
|
||||
@@ -254,9 +254,14 @@ func (c *Command) WaitForInterrupt() int {
|
||||
// Wait for shutdown
|
||||
shutdownTriggered := false
|
||||
|
||||
shutdownCh := c.ShutdownCh
|
||||
if c.ExtShutdownCh != nil {
|
||||
shutdownCh = c.ExtShutdownCh
|
||||
}
|
||||
|
||||
for !shutdownTriggered {
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
case <-shutdownCh:
|
||||
c.UI.Output("==> Watchtower worker shutdown triggered")
|
||||
|
||||
if err := c.worker.Shutdown(); err != nil {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
colorable "github.com/mattn/go-colorable"
|
||||
"github.com/mitchellh/cli"
|
||||
@@ -178,7 +178,7 @@ func RunCustom(args []string, runOpts *RunOptions) int {
|
||||
exitCode, err := cli.Run()
|
||||
if outputCurlString {
|
||||
if exitCode == 0 {
|
||||
fmt.Fprint(runOpts.Stderr, "Could not generate cURL command")
|
||||
fmt.Fprint(runOpts.Stderr, "Could not generate cURL command\n")
|
||||
return 1
|
||||
} else {
|
||||
if api.LastOutputStringError == nil {
|
||||
|
||||
Reference in new issue
Block a user