// NewAPIRoot returns a new connection to the API server for the given // model or controller. func (c *JujuCommandBase) NewAPIRoot( store jujuclient.ClientStore, controllerName, modelName string, ) (api.Connection, error) { accountDetails, err := store.AccountDetails(controllerName) if err != nil && !errors.IsNotFound(err) { return nil, errors.Trace(err) } // If there are no account details or there's no logged-in // user or the user is external, then trigger macaroon authentication // by using an empty AccountDetails. if accountDetails == nil || accountDetails.User == "" { accountDetails = &jujuclient.AccountDetails{} } else { u := names.NewUserTag(accountDetails.User) if !u.IsLocal() { accountDetails = &jujuclient.AccountDetails{} } } param, err := c.NewAPIConnectionParams( store, controllerName, modelName, accountDetails, ) if err != nil { return nil, errors.Trace(err) } conn, err := juju.NewAPIConnection(param) if modelName != "" && params.ErrCode(err) == params.CodeModelNotFound { return nil, c.missingModelError(store, controllerName, modelName) } return conn, err }
func (s *cmdControllerSuite) TestAddModel(c *gc.C) { // The JujuConnSuite doesn't set up an ssh key in the fake home dir, // so fake one on the command line. The dummy provider also expects // a config value for 'controller'. context := s.run(c, "add-model", "new-model", "authorized-keys=fake-key", "controller=false") c.Check(testing.Stdout(context), gc.Equals, "") c.Check(testing.Stderr(context), gc.Equals, "added model \"new-model\"\n") // Make sure that the saved server details are sufficient to connect // to the api server. accountDetails, err := s.ControllerStore.AccountByName("kontroll", "admin@local") c.Assert(err, jc.ErrorIsNil) modelDetails, err := s.ControllerStore.ModelByName("kontroll", "admin@local", "new-model") c.Assert(err, jc.ErrorIsNil) api, err := juju.NewAPIConnection(juju.NewAPIConnectionParams{ Store: s.ControllerStore, ControllerName: "kontroll", AccountDetails: accountDetails, ModelUUID: modelDetails.ModelUUID, BootstrapConfig: noBootstrapConfig, DialOpts: api.DefaultDialOpts(), }) c.Assert(err, jc.ErrorIsNil) api.Close() }
func (s *cmdControllerSuite) testAddModel(c *gc.C, args ...string) { // The JujuConnSuite doesn't set up an ssh key in the fake home dir, // so fake one on the command line. The dummy provider also expects // a config value for 'controller'. args = append([]string{"add-model", "new-model"}, args...) args = append(args, "--config", "authorized-keys=fake-key", "--config", "controller=false", ) context := s.run(c, args...) c.Check(testing.Stdout(context), gc.Equals, "") c.Check(testing.Stderr(context), gc.Equals, ` Added 'new-model' model on dummy/dummy-region with credential 'cred' for user 'admin' `[1:]) // Make sure that the saved server details are sufficient to connect // to the api server. accountDetails, err := s.ControllerStore.AccountDetails("kontroll") c.Assert(err, jc.ErrorIsNil) modelDetails, err := s.ControllerStore.ModelByName("kontroll", "admin@local/new-model") c.Assert(err, jc.ErrorIsNil) api, err := juju.NewAPIConnection(juju.NewAPIConnectionParams{ Store: s.ControllerStore, ControllerName: "kontroll", AccountDetails: accountDetails, ModelUUID: modelDetails.ModelUUID, DialOpts: api.DefaultDialOpts(), OpenAPI: api.Open, }) c.Assert(err, jc.ErrorIsNil) api.Close() }
// NewLoginCommand returns a new cmd.Command to handle "juju login". func NewLoginCommand() cmd.Command { return modelcmd.WrapController(&loginCommand{ newLoginAPI: func(args juju.NewAPIConnectionParams) (LoginAPI, ConnectionAPI, error) { api, err := juju.NewAPIConnection(args) if err != nil { return nil, nil, errors.Trace(err) } return usermanager.NewClient(api), api, nil }, }) }
// NewAPIRoot returns a new connection to the API server for the given // model or controller. func (c *JujuCommandBase) NewAPIRoot( store jujuclient.ClientStore, controllerName, accountName, modelName string, ) (api.Connection, error) { params, err := c.NewAPIConnectionParams( store, controllerName, accountName, modelName, ) if err != nil { return nil, errors.Trace(err) } return juju.NewAPIConnection(params) }
func (s *cmdRegistrationSuite) TestAddUserAndRegister(c *gc.C) { // First, add user "bob", and record the "juju register" command // that is printed out. context := s.run(c, nil, "add-user", "bob", "Bob Dobbs") c.Check(testing.Stderr(context), gc.Equals, "") stdout := testing.Stdout(context) c.Check(stdout, gc.Matches, ` User "Bob Dobbs \(bob\)" added Please send this command to bob: juju register .* "Bob Dobbs \(bob\)" has not been granted access to any models(.|\n)* `[1:]) jujuRegisterCommand := strings.Fields(strings.TrimSpace( strings.SplitN(stdout[strings.Index(stdout, "juju register"):], "\n", 2)[0], )) c.Logf("%q", jujuRegisterCommand) // Now run the "juju register" command. We need to pass the // controller name and password to set. stdin := strings.NewReader("bob-controller\nhunter2\nhunter2\n") args := jujuRegisterCommand[1:] // drop the "juju" context = s.run(c, stdin, args...) c.Check(testing.Stdout(context), gc.Equals, "") c.Check(testing.Stderr(context), gc.Equals, ` Please set a name for this controller: Enter password: Confirm password: Welcome, bob. You are now logged into "bob-controller". There are no models available. You can create models with "juju create-model", or you can ask an administrator or owner of a model to grant access to that model with "juju grant". `[1:]) // Make sure that the saved server details are sufficient to connect // to the api server. accountDetails, err := s.ControllerStore.AccountByName("bob-controller", "bob@local") c.Assert(err, jc.ErrorIsNil) api, err := juju.NewAPIConnection(juju.NewAPIConnectionParams{ Store: s.ControllerStore, ControllerName: "bob-controller", AccountDetails: accountDetails, BootstrapConfig: noBootstrapConfig, DialOpts: api.DefaultDialOpts(), }) c.Assert(err, jc.ErrorIsNil) c.Assert(api.Close(), jc.ErrorIsNil) }
func (d *Dialer) Dial() (api.Connection, error) { c, err := juju.NewAPIConnection(juju.NewAPIConnectionParams{ ControllerName: d.controller, Store: d.ctxt.store, OpenAPI: api.Open, DialOpts: d.ctxt.dialOpts, AccountDetails: d.account, ModelUUID: d.modelUUID, }) if err != nil { return nil, errors.Trace(err) } return c, nil }
func newAPIConnectionFromNames( c *gc.C, controller, model string, store jujuclient.ClientStore, apiOpen api.OpenFunc, ) (api.Connection, error) { params := juju.NewAPIConnectionParams{ Store: store, ControllerName: controller, DialOpts: api.DefaultDialOpts(), OpenAPI: apiOpen, } accountDetails, err := store.AccountDetails(controller) if !errors.IsNotFound(err) { c.Assert(err, jc.ErrorIsNil) params.AccountDetails = accountDetails } if model != "" { modelDetails, err := store.ModelByName(controller, model) c.Assert(err, jc.ErrorIsNil) params.ModelUUID = modelDetails.ModelUUID } return juju.NewAPIConnection(params) }
func (s *cmdRegistrationSuite) TestAddUserAndRegister(c *gc.C) { // First, add user "bob", and record the "juju register" command // that is printed out. context := s.run(c, nil, "add-user", "bob", "Bob Dobbs") c.Check(testing.Stderr(context), gc.Equals, "") stdout := testing.Stdout(context) c.Check(stdout, gc.Matches, ` User "Bob Dobbs \(bob\)" added Please send this command to bob: juju register .* "Bob Dobbs \(bob\)" has not been granted access to any models(.|\n)* `[1:]) jujuRegisterCommand := strings.Fields(strings.TrimSpace( strings.SplitN(stdout[strings.Index(stdout, "juju register"):], "\n", 2)[0], )) c.Logf("%q", jujuRegisterCommand) // Now run the "juju register" command. We need to pass the // controller name and password to set, and we need a different // file store to mimic a different local OS user. userHomeParams := jujutesting.UserHomeParams{Username: "******"} s.CreateUserHome(c, &userHomeParams) stdin := strings.NewReader("bob-controller\nhunter2\nhunter2\n") args := jujuRegisterCommand[1:] // drop the "juju" // The expected prompt does not include a warning about the controller // name, as this new local user does not have a controller named // "kontroll" registered. expectedPrompt := ` Enter a name for this controller [kontroll]: Enter a new password: Confirm password: Welcome, bob. You are now logged into "bob-controller". There are no models available. You can add models with "juju add-model", or you can ask an administrator or owner of a model to grant access to that model with "juju grant". `[1:] context = s.run(c, stdin, args...) c.Check(testing.Stdout(context), gc.Equals, "") c.Check(testing.Stderr(context), gc.Equals, expectedPrompt) // Make sure that the saved server details are sufficient to connect // to the api server. jar, err := cookiejar.New(&cookiejar.Options{ Filename: cookiejar.DefaultCookieFile(), }) c.Assert(err, jc.ErrorIsNil) dialOpts := api.DefaultDialOpts() dialOpts.BakeryClient = httpbakery.NewClient() dialOpts.BakeryClient.Jar = jar accountDetails, err := s.ControllerStore.AccountDetails("bob-controller") c.Assert(err, jc.ErrorIsNil) api, err := juju.NewAPIConnection(juju.NewAPIConnectionParams{ Store: s.ControllerStore, ControllerName: "bob-controller", AccountDetails: accountDetails, DialOpts: dialOpts, OpenAPI: api.Open, }) c.Assert(err, jc.ErrorIsNil) c.Assert(api.Close(), jc.ErrorIsNil) }
func (s *cmdRegistrationSuite) TestAddUserAndRegister(c *gc.C) { // First, add user "bob", and record the "juju register" command // that is printed out. context := run(c, nil, "add-user", "bob", "Bob Dobbs") c.Check(testing.Stderr(context), gc.Equals, "") stdout := testing.Stdout(context) expectPat := ` User "Bob Dobbs \(bob\)" added Please send this command to bob: juju register (.+) "Bob Dobbs \(bob\)" has not been granted access to any models(.|\n)* `[1:] c.Assert(stdout, gc.Matches, expectPat) arg := regexp.MustCompile("^" + expectPat + "$").FindStringSubmatch(stdout)[1] c.Logf("juju register %q", arg) // Now run the "juju register" command. We need to pass the // controller name and password to set, and we need a different // file store to mimic a different local OS user. s.CreateUserHome(c, &jujutesting.UserHomeParams{ Username: "******", }) // The expected prompt does not include a warning about the controller // name, as this new local user does not have a controller named // "kontroll" registered. prompter := cmdtesting.NewSeqPrompter(c, "»", ` Enter a new password: »hunter2 Confirm password: »hunter2 Initial password successfully set for bob. Enter a name for this controller \[kontroll\]: »bob-controller Welcome, bob. You are now logged into "bob-controller". There are no models available. (.|\n)* `[1:]) context = run(c, prompter, "register", arg) prompter.AssertDone() // Make sure that the saved server details are sufficient to connect // to the api server. jar, err := cookiejar.New(&cookiejar.Options{ Filename: cookiejar.DefaultCookieFile(), }) c.Assert(err, jc.ErrorIsNil) dialOpts := api.DefaultDialOpts() dialOpts.BakeryClient = httpbakery.NewClient() dialOpts.BakeryClient.Jar = jar accountDetails, err := s.ControllerStore.AccountDetails("bob-controller") c.Assert(err, jc.ErrorIsNil) api, err := juju.NewAPIConnection(juju.NewAPIConnectionParams{ Store: s.ControllerStore, ControllerName: "bob-controller", AccountDetails: accountDetails, DialOpts: dialOpts, OpenAPI: api.Open, }) c.Assert(err, jc.ErrorIsNil) c.Assert(api.Close(), jc.ErrorIsNil) }