Merge pull request #5995 from vvoland/swarm-init-cacert
swarm/init: Fix `--external-ca` ignoring `cacert` option
This commit is contained in:
commit
0ee20b8543
@ -96,7 +96,7 @@ func runCA(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, opt
|
|||||||
func updateSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, opts caOptions) {
|
func updateSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, opts caOptions) {
|
||||||
caCert := opts.rootCACert.Contents()
|
caCert := opts.rootCACert.Contents()
|
||||||
caKey := opts.rootCAKey.Contents()
|
caKey := opts.rootCAKey.Contents()
|
||||||
opts.mergeSwarmSpecCAFlags(spec, flags, caCert)
|
opts.mergeSwarmSpecCAFlags(spec, flags, &caCert)
|
||||||
|
|
||||||
spec.CAConfig.SigningCACert = caCert
|
spec.CAConfig.SigningCACert = caCert
|
||||||
spec.CAConfig.SigningCAKey = caKey
|
spec.CAConfig.SigningCAKey = caKey
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
type fakeClient struct {
|
type fakeClient struct {
|
||||||
client.Client
|
client.Client
|
||||||
infoFunc func() (system.Info, error)
|
infoFunc func() (system.Info, error)
|
||||||
swarmInitFunc func() (string, error)
|
swarmInitFunc func(req swarm.InitRequest) (string, error)
|
||||||
swarmInspectFunc func() (swarm.Swarm, error)
|
swarmInspectFunc func() (swarm.Swarm, error)
|
||||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||||
@ -35,9 +35,9 @@ func (cli *fakeClient) NodeInspectWithRaw(context.Context, string) (swarm.Node,
|
|||||||
return swarm.Node{}, []byte{}, nil
|
return swarm.Node{}, []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *fakeClient) SwarmInit(context.Context, swarm.InitRequest) (string, error) {
|
func (cli *fakeClient) SwarmInit(_ context.Context, req swarm.InitRequest) (string, error) {
|
||||||
if cli.swarmInitFunc != nil {
|
if cli.swarmInitFunc != nil {
|
||||||
return cli.swarmInitFunc()
|
return cli.swarmInitFunc(req)
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,14 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,7 +19,7 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) {
|
|||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
flags map[string]string
|
flags map[string]string
|
||||||
swarmInitFunc func() (string, error)
|
swarmInitFunc func(swarm.InitRequest) (string, error)
|
||||||
swarmInspectFunc func() (swarm.Swarm, error)
|
swarmInspectFunc func() (swarm.Swarm, error)
|
||||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||||
@ -24,14 +27,14 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "init-failed",
|
name: "init-failed",
|
||||||
swarmInitFunc: func() (string, error) {
|
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||||
return "", errors.New("error initializing the swarm")
|
return "", errors.New("error initializing the swarm")
|
||||||
},
|
},
|
||||||
expectedError: "error initializing the swarm",
|
expectedError: "error initializing the swarm",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "init-failed-with-ip-choice",
|
name: "init-failed-with-ip-choice",
|
||||||
swarmInitFunc: func() (string, error) {
|
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||||
return "", errors.New("could not choose an IP address to advertise")
|
return "", errors.New("could not choose an IP address to advertise")
|
||||||
},
|
},
|
||||||
expectedError: "could not choose an IP address to advertise - specify one with --advertise-addr",
|
expectedError: "could not choose an IP address to advertise - specify one with --advertise-addr",
|
||||||
@ -85,14 +88,14 @@ func TestSwarmInit(t *testing.T) {
|
|||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
flags map[string]string
|
flags map[string]string
|
||||||
swarmInitFunc func() (string, error)
|
swarmInitFunc func(req swarm.InitRequest) (string, error)
|
||||||
swarmInspectFunc func() (swarm.Swarm, error)
|
swarmInspectFunc func() (swarm.Swarm, error)
|
||||||
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
swarmGetUnlockKeyFunc func() (swarm.UnlockKeyResponse, error)
|
||||||
nodeInspectFunc func() (swarm.Node, []byte, error)
|
nodeInspectFunc func() (swarm.Node, []byte, error)
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "init",
|
name: "init",
|
||||||
swarmInitFunc: func() (string, error) {
|
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||||
return "nodeID", nil
|
return "nodeID", nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -101,7 +104,7 @@ func TestSwarmInit(t *testing.T) {
|
|||||||
flags: map[string]string{
|
flags: map[string]string{
|
||||||
flagAutolock: "true",
|
flagAutolock: "true",
|
||||||
},
|
},
|
||||||
swarmInitFunc: func() (string, error) {
|
swarmInitFunc: func(swarm.InitRequest) (string, error) {
|
||||||
return "nodeID", nil
|
return "nodeID", nil
|
||||||
},
|
},
|
||||||
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
swarmGetUnlockKeyFunc: func() (swarm.UnlockKeyResponse, error) {
|
||||||
@ -131,3 +134,28 @@ func TestSwarmInit(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSwarmInitWithExternalCA(t *testing.T) {
|
||||||
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
|
swarmInitFunc: func(req swarm.InitRequest) (string, error) {
|
||||||
|
if assert.Check(t, is.Len(req.Spec.CAConfig.ExternalCAs, 1)) {
|
||||||
|
assert.Equal(t, req.Spec.CAConfig.ExternalCAs[0].CACert, cert)
|
||||||
|
assert.Equal(t, req.Spec.CAConfig.ExternalCAs[0].Protocol, swarm.ExternalCAProtocolCFSSL)
|
||||||
|
assert.Equal(t, req.Spec.CAConfig.ExternalCAs[0].URL, "https://example.com")
|
||||||
|
}
|
||||||
|
return "nodeID", nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
certFile := filepath.Join(tempDir, "cert.pem")
|
||||||
|
err := os.WriteFile(certFile, []byte(cert), 0o644)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
cmd := newInitCommand(cli)
|
||||||
|
cmd.SetArgs([]string{})
|
||||||
|
cmd.SetOut(io.Discard)
|
||||||
|
cmd.SetErr(io.Discard)
|
||||||
|
assert.NilError(t, cmd.Flags().Set(flagExternalCA, "protocol=cfssl,url=https://example.com,cacert="+certFile))
|
||||||
|
assert.NilError(t, cmd.Execute())
|
||||||
|
}
|
||||||
|
@ -231,7 +231,7 @@ func addSwarmFlags(flags *pflag.FlagSet, options *swarmOptions) {
|
|||||||
addSwarmCAFlags(flags, &options.swarmCAOptions)
|
addSwarmCAFlags(flags, &options.swarmCAOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) {
|
func (o *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, caCert *string) {
|
||||||
if flags.Changed(flagTaskHistoryLimit) {
|
if flags.Changed(flagTaskHistoryLimit) {
|
||||||
spec.Orchestration.TaskHistoryRetentionLimit = &o.taskHistoryLimit
|
spec.Orchestration.TaskHistoryRetentionLimit = &o.taskHistoryLimit
|
||||||
}
|
}
|
||||||
@ -255,20 +255,24 @@ type swarmCAOptions struct {
|
|||||||
externalCA ExternalCAOption
|
externalCA ExternalCAOption
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) {
|
func (o *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet, caCert *string) {
|
||||||
if flags.Changed(flagCertExpiry) {
|
if flags.Changed(flagCertExpiry) {
|
||||||
spec.CAConfig.NodeCertExpiry = o.nodeCertExpiry
|
spec.CAConfig.NodeCertExpiry = o.nodeCertExpiry
|
||||||
}
|
}
|
||||||
if flags.Changed(flagExternalCA) {
|
if flags.Changed(flagExternalCA) {
|
||||||
spec.CAConfig.ExternalCAs = o.externalCA.Value()
|
spec.CAConfig.ExternalCAs = o.externalCA.Value()
|
||||||
for _, ca := range spec.CAConfig.ExternalCAs {
|
if caCert != nil {
|
||||||
ca.CACert = caCert
|
for _, ca := range spec.CAConfig.ExternalCAs {
|
||||||
|
if ca.CACert == "" {
|
||||||
|
ca.CACert = *caCert
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec {
|
func (o *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec {
|
||||||
var spec swarm.Spec
|
var spec swarm.Spec
|
||||||
o.mergeSwarmSpec(&spec, flags, "")
|
o.mergeSwarmSpec(&spec, flags, nil)
|
||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ func runUpdate(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet,
|
|||||||
|
|
||||||
prevAutoLock := swarmInspect.Spec.EncryptionConfig.AutoLockManagers
|
prevAutoLock := swarmInspect.Spec.EncryptionConfig.AutoLockManagers
|
||||||
|
|
||||||
opts.mergeSwarmSpec(&swarmInspect.Spec, flags, swarmInspect.ClusterInfo.TLSInfo.TrustRoot)
|
opts.mergeSwarmSpec(&swarmInspect.Spec, flags, &swarmInspect.ClusterInfo.TLSInfo.TrustRoot)
|
||||||
|
|
||||||
curAutoLock := swarmInspect.Spec.EncryptionConfig.AutoLockManagers
|
curAutoLock := swarmInspect.Spec.EncryptionConfig.AutoLockManagers
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user