Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quick refactor of the controller-info command #995

Merged
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
36 changes: 23 additions & 13 deletions cmd/jimmctl/cmd/controllerinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ var (
controller-info command writes controller information contained
in the juju client store to a yaml file.

If a --public-address flag is specified the output controller
information will include this public address. The controller
information will also omit the ca-certrificate.
If a --local flag is specified, the output controller
public address will use the first available local API address
and the local CA cert of the controller, see examples below
for usage.

Example:
jimmctl controller-info <name> <filename>
jimmctl controller-info --public-address=<dns-name>:443 <name> <filename>
Examples:
jimmctl controller-info <name> <filename> <public address>
jimmctl controller-info <name> <filename> --local
`
)

Expand All @@ -50,6 +51,7 @@ type controllerInfoCommand struct {
controllerName string
publicAddress string
file cmd.FileVar
local bool
}

func (c *controllerInfoCommand) Info() *cmd.Info {
Expand All @@ -63,7 +65,7 @@ func (c *controllerInfoCommand) Info() *cmd.Info {
// SetFlags implements Command.SetFlags.
func (c *controllerInfoCommand) SetFlags(f *gnuflag.FlagSet) {
c.CommandBase.SetFlags(f)
f.StringVar(&c.publicAddress, "public-address", "", "The preferred controller address for public access.")
f.BoolVar(&c.local, "local", false, "If local flag is specified, then the local API address and CA cert of the controller will be used.")
}

// Init implements the cmd.Command interface.
Expand All @@ -72,7 +74,10 @@ func (c *controllerInfoCommand) Init(args []string) error {
return errors.New("controller name or filename not specified")
}
c.controllerName, c.file.Path = args[0], args[1]
if len(args) > 2 {
if len(args) == 3 {
alesstimec marked this conversation as resolved.
Show resolved Hide resolved
c.publicAddress = args[2]
}
if len(args) > 3 {
return errors.New("too many args")
}
return nil
Expand All @@ -94,14 +99,19 @@ func (c *controllerInfoCommand) Run(ctxt *cmd.Context) error {
Username: account.User,
Password: account.Password,
}
if c.publicAddress != "" {
info.PublicAddress = c.publicAddress
} else if controller.PublicDNSName != "" {
info.PublicAddress = controller.PublicDNSName
} else {

info.PublicAddress = c.publicAddress
if c.local {
info.PublicAddress = controller.APIEndpoints[0]
info.CACertificate = controller.CACert
}
if info.PublicAddress == "" {
return errors.New("public address must be set")
}
if c.local && len(c.publicAddress) > 0 {
return errors.New("please do not set both the address argument and the local flag")
}

data, err := yaml.Marshal(info)
if err != nil {
return errors.Mask(err)
Expand Down
128 changes: 122 additions & 6 deletions cmd/jimmctl/cmd/controllerinfo_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Canonical Ltd.
// Copyright 2023 Canonical Ltd.

package cmd_test

Expand Down Expand Up @@ -61,7 +61,7 @@ func (s *controllerInfoSuite) TestControllerInfo(c *gc.C) {

fname := path.Join(dir, "test.yaml")

_, err = cmdtesting.RunCommand(c, cmd.NewControllerInfoCommandForTesting(store), "controller-1", fname)
_, err = cmdtesting.RunCommand(c, cmd.NewControllerInfoCommandForTesting(store), "controller-1", fname, "controller1.example.com")
c.Assert(err, gc.IsNil)

data, err := ioutil.ReadFile(fname)
Expand All @@ -75,10 +75,11 @@ username: test-user
`)
}

func (s *controllerInfoSuite) TestControllerInfoSpecifiedPublicAddress(c *gc.C) {
func (s *controllerInfoSuite) TestControllerInfoWithLocalFlag(c *gc.C) {
store := s.ClientStore()
store.Controllers["controller-1"] = jujuclient.ControllerDetails{
APIEndpoints: []string{"127.0.0.1:17070"},
APIEndpoints: []string{"127.0.0.1:17070"},
PublicDNSName: "controller1.example.com",
CACert: `-----BEGIN CERTIFICATE-----
MIID/jCCAmagAwIBAgIVANxsMrzsXrdpjjUoxWQm1RCkmWcqMA0GCSqGSIb3DQEB
CwUAMCYxDTALBgNVBAoTBEp1anUxFTATBgNVBAMTDGp1anUgdGVzdGluZzAeFw0y
Expand Down Expand Up @@ -115,16 +116,131 @@ func (s *controllerInfoSuite) TestControllerInfoSpecifiedPublicAddress(c *gc.C)

fname := path.Join(dir, "test.yaml")

_, err = cmdtesting.RunCommand(c, cmd.NewControllerInfoCommandForTesting(store), "--public-address=controller2.example.com", "controller-1", fname)
_, err = cmdtesting.RunCommand(c, cmd.NewControllerInfoCommandForTesting(store), "controller-1", fname, "--local")
c.Assert(err, gc.IsNil)

data, err := ioutil.ReadFile(fname)
c.Assert(err, gc.IsNil)
c.Assert(string(data), gc.Matches, `api-addresses:
- 127.0.0.1:17070
ca-certificate: |-
-----BEGIN CERTIFICATE-----
MIID/jCCAmagAwIBAgIVANxsMrzsXrdpjjUoxWQm1RCkmWcqMA0GCSqGSIb3DQEB
CwUAMCYxDTALBgNVBAoTBEp1anUxFTATBgNVBAMTDGp1anUgdGVzdGluZzAeFw0y
MDA0MDgwNTI3NTBaFw0zMDA0MDgwNTMyNTBaMCYxDTALBgNVBAoTBEp1anUxFTAT
BgNVBAMTDGp1anUgdGVzdGluZzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
ggGBAOW4k2bmXXU3tJ8H5AsGkp8ENLJXzU4SCOCB+X0jPQRVpFtywBVD96z+l+qW
ndGLIg5zMQTtZm71CaOw+8Sl03XU0f28Xrjf+FZCAPID1c7NBttUShbu84euFoCS
C8yobj6JzLz7QswvkshYQ7JEZ88UXtVHqg6MGYFdu+cX/dE1jC7aHg9bus/P6bFH
PVFcHVVxNbLy98Id1iB7i0s97H17nu9O7ZKMrAQAX6dfAELAFQVicdN3WpfwNXEj
M2KIrqttpM8s6/57mi9UJFYGdAEDNkJr/dI506VdGLpiqTFhQK6ztfDfY08QbWk6
iJn8vzWvNW8WthmBtEDpv+DL+a5SJSLSAIZn9sbuBBpiX+csZb66fYhKFFIUrIa5
lrjw8yiHJ4kgsEZJSYaAn7guqmOv8clvy1E2JjsOfGycest6+1/mNdMRFgrMxdzD
0M2yZ96zrdfF/QXpi7Hk7jFLzimuujNUpKFv7k+XObQFxeXnoFrYVkj3YT8hhYF0
mGRkAwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAN
BgkqhkiG9w0BAQsFAAOCAYEAd7GrziPRmjoK3HDF10S+5NgoKYvkOuk2jDap2Qaq
ZFjDvrDA2tr6U0FGY+Hz+QfvtgT+YpJB5IvABvSXdq37llwKGsiSOZSrpHyTsOB0
VcZAF3GMk1nHYMr0o1xRV2gm/ax+vUEStj0k2gTs/p57uhKcCUXR0p3PWXKcRj9a
nVf5bdVkt6ghGs7/uEvj303raUFSf5dJ4C9RTgBK2E9/wlBYNyj5vcsshNpz8kt6
RuARM6Boq2EwKkpRlbvImDM8ZJJLwtpijYrx3egfOSEA7Wfwgwn+B359XcosOee5
n5BC62EjaP85cM9HCtp2DwKjNSosxja723qZPY6Z0Y7IVn3JVjgC2kWP6GViwb+v
l9uwx9ASHPz9ilh6gpjgIifOKZYCaBSS9g8VxHpO5Izxj4vi4AX5cebDg3SzDVik
hZuWHpuOT120okoutwuUSU9448cXLGZfoCZjjdMKXmOj8EEec1diDP4mhegYGezD
LQRNNlaY2ajLt0paowf/Xxb8
-----END CERTIFICATE-----
name: controller-1
password: super-secret-password
public-address: controller2.example.com
public-address: 127.0.0.1:17070
username: test-user
`)
}

func (s *controllerInfoSuite) TestControllerInfoMissingPublicAddressAndNoLocalFlag(c *gc.C) {
store := s.ClientStore()
store.Controllers["controller-1"] = jujuclient.ControllerDetails{
APIEndpoints: []string{"127.0.0.1:17070"},
PublicDNSName: "controller1.example.com",
CACert: `-----BEGIN CERTIFICATE-----
MIID/jCCAmagAwIBAgIVANxsMrzsXrdpjjUoxWQm1RCkmWcqMA0GCSqGSIb3DQEB
CwUAMCYxDTALBgNVBAoTBEp1anUxFTATBgNVBAMTDGp1anUgdGVzdGluZzAeFw0y
MDA0MDgwNTI3NTBaFw0zMDA0MDgwNTMyNTBaMCYxDTALBgNVBAoTBEp1anUxFTAT
BgNVBAMTDGp1anUgdGVzdGluZzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
ggGBAOW4k2bmXXU3tJ8H5AsGkp8ENLJXzU4SCOCB+X0jPQRVpFtywBVD96z+l+qW
ndGLIg5zMQTtZm71CaOw+8Sl03XU0f28Xrjf+FZCAPID1c7NBttUShbu84euFoCS
C8yobj6JzLz7QswvkshYQ7JEZ88UXtVHqg6MGYFdu+cX/dE1jC7aHg9bus/P6bFH
PVFcHVVxNbLy98Id1iB7i0s97H17nu9O7ZKMrAQAX6dfAELAFQVicdN3WpfwNXEj
M2KIrqttpM8s6/57mi9UJFYGdAEDNkJr/dI506VdGLpiqTFhQK6ztfDfY08QbWk6
iJn8vzWvNW8WthmBtEDpv+DL+a5SJSLSAIZn9sbuBBpiX+csZb66fYhKFFIUrIa5
lrjw8yiHJ4kgsEZJSYaAn7guqmOv8clvy1E2JjsOfGycest6+1/mNdMRFgrMxdzD
0M2yZ96zrdfF/QXpi7Hk7jFLzimuujNUpKFv7k+XObQFxeXnoFrYVkj3YT8hhYF0
mGRkAwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAN
BgkqhkiG9w0BAQsFAAOCAYEAd7GrziPRmjoK3HDF10S+5NgoKYvkOuk2jDap2Qaq
ZFjDvrDA2tr6U0FGY+Hz+QfvtgT+YpJB5IvABvSXdq37llwKGsiSOZSrpHyTsOB0
VcZAF3GMk1nHYMr0o1xRV2gm/ax+vUEStj0k2gTs/p57uhKcCUXR0p3PWXKcRj9a
nVf5bdVkt6ghGs7/uEvj303raUFSf5dJ4C9RTgBK2E9/wlBYNyj5vcsshNpz8kt6
RuARM6Boq2EwKkpRlbvImDM8ZJJLwtpijYrx3egfOSEA7Wfwgwn+B359XcosOee5
n5BC62EjaP85cM9HCtp2DwKjNSosxja723qZPY6Z0Y7IVn3JVjgC2kWP6GViwb+v
l9uwx9ASHPz9ilh6gpjgIifOKZYCaBSS9g8VxHpO5Izxj4vi4AX5cebDg3SzDVik
hZuWHpuOT120okoutwuUSU9448cXLGZfoCZjjdMKXmOj8EEec1diDP4mhegYGezD
LQRNNlaY2ajLt0paowf/Xxb8
-----END CERTIFICATE-----`,
}
store.Accounts["controller-1"] = jujuclient.AccountDetails{
User: "test-user",
Password: "super-secret-password",
}

dir, err := ioutil.TempDir("", "controller-info-test")
c.Assert(err, gc.Equals, nil)
defer os.RemoveAll(dir)

fname := path.Join(dir, "test.yaml")

_, err = cmdtesting.RunCommand(c, cmd.NewControllerInfoCommandForTesting(store), "controller-1", fname)
c.Assert(err, gc.ErrorMatches, "public address must be set")
}

func (s *controllerInfoSuite) TestControllerInfoCannotProvideAddrAndLocalFlag(c *gc.C) {
store := s.ClientStore()
store.Controllers["controller-1"] = jujuclient.ControllerDetails{
APIEndpoints: []string{"127.0.0.1:17070"},
PublicDNSName: "controller1.example.com",
CACert: `-----BEGIN CERTIFICATE-----
MIID/jCCAmagAwIBAgIVANxsMrzsXrdpjjUoxWQm1RCkmWcqMA0GCSqGSIb3DQEB
CwUAMCYxDTALBgNVBAoTBEp1anUxFTATBgNVBAMTDGp1anUgdGVzdGluZzAeFw0y
MDA0MDgwNTI3NTBaFw0zMDA0MDgwNTMyNTBaMCYxDTALBgNVBAoTBEp1anUxFTAT
BgNVBAMTDGp1anUgdGVzdGluZzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
ggGBAOW4k2bmXXU3tJ8H5AsGkp8ENLJXzU4SCOCB+X0jPQRVpFtywBVD96z+l+qW
ndGLIg5zMQTtZm71CaOw+8Sl03XU0f28Xrjf+FZCAPID1c7NBttUShbu84euFoCS
C8yobj6JzLz7QswvkshYQ7JEZ88UXtVHqg6MGYFdu+cX/dE1jC7aHg9bus/P6bFH
PVFcHVVxNbLy98Id1iB7i0s97H17nu9O7ZKMrAQAX6dfAELAFQVicdN3WpfwNXEj
M2KIrqttpM8s6/57mi9UJFYGdAEDNkJr/dI506VdGLpiqTFhQK6ztfDfY08QbWk6
iJn8vzWvNW8WthmBtEDpv+DL+a5SJSLSAIZn9sbuBBpiX+csZb66fYhKFFIUrIa5
lrjw8yiHJ4kgsEZJSYaAn7guqmOv8clvy1E2JjsOfGycest6+1/mNdMRFgrMxdzD
0M2yZ96zrdfF/QXpi7Hk7jFLzimuujNUpKFv7k+XObQFxeXnoFrYVkj3YT8hhYF0
mGRkAwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAN
BgkqhkiG9w0BAQsFAAOCAYEAd7GrziPRmjoK3HDF10S+5NgoKYvkOuk2jDap2Qaq
ZFjDvrDA2tr6U0FGY+Hz+QfvtgT+YpJB5IvABvSXdq37llwKGsiSOZSrpHyTsOB0
VcZAF3GMk1nHYMr0o1xRV2gm/ax+vUEStj0k2gTs/p57uhKcCUXR0p3PWXKcRj9a
nVf5bdVkt6ghGs7/uEvj303raUFSf5dJ4C9RTgBK2E9/wlBYNyj5vcsshNpz8kt6
RuARM6Boq2EwKkpRlbvImDM8ZJJLwtpijYrx3egfOSEA7Wfwgwn+B359XcosOee5
n5BC62EjaP85cM9HCtp2DwKjNSosxja723qZPY6Z0Y7IVn3JVjgC2kWP6GViwb+v
l9uwx9ASHPz9ilh6gpjgIifOKZYCaBSS9g8VxHpO5Izxj4vi4AX5cebDg3SzDVik
hZuWHpuOT120okoutwuUSU9448cXLGZfoCZjjdMKXmOj8EEec1diDP4mhegYGezD
LQRNNlaY2ajLt0paowf/Xxb8
-----END CERTIFICATE-----`,
}
store.Accounts["controller-1"] = jujuclient.AccountDetails{
User: "test-user",
Password: "super-secret-password",
}

dir, err := ioutil.TempDir("", "controller-info-test")
c.Assert(err, gc.Equals, nil)
defer os.RemoveAll(dir)

fname := path.Join(dir, "test.yaml")

_, err = cmdtesting.RunCommand(c, cmd.NewControllerInfoCommandForTesting(store), "controller-1", fname, "myaddress", "--local")
c.Assert(err, gc.ErrorMatches, "please do not set both the address argument and the local flag")
}