Esempio n. 1
0
func (s *filesSuite) TestSetCurrentSystem(c *gc.C) {
	ctx := testing.Context(c)
	err := envcmd.SetCurrentSystem(ctx, "new-sys")
	c.Assert(err, jc.ErrorIsNil)
	s.assertCurrentSystem(c, "new-sys")
	c.Assert(testing.Stderr(ctx), gc.Equals, "-> new-sys (system)\n")
}
Esempio n. 2
0
func (s *filesSuite) TestSetCurrentSystemExistingEnv(c *gc.C) {
	err := envcmd.WriteCurrentEnvironment("fubar")
	c.Assert(err, jc.ErrorIsNil)
	ctx := testing.Context(c)
	err = envcmd.SetCurrentSystem(ctx, "new-sys")
	c.Assert(err, jc.ErrorIsNil)
	s.assertCurrentSystem(c, "new-sys")
	c.Assert(testing.Stderr(ctx), gc.Equals, "fubar -> new-sys (system)\n")
}
Esempio n. 3
0
// Run implements Command.Run
func (c *LoginCommand) Run(ctx *cmd.Context) error {
	// TODO(thumper): as we support the user and address
	// change this check here.
	if c.Server.Path == "" {
		return errors.New("no server file specified")
	}

	serverYAML, err := c.Server.Read(ctx)
	if err != nil {
		return errors.Trace(err)
	}

	var serverDetails envcmd.ServerFile
	if err := goyaml.Unmarshal(serverYAML, &serverDetails); err != nil {
		return errors.Trace(err)
	}

	// Construct the api.Info struct from the provided values
	// and attempt to connect to the remote server before we do anything else.
	if !names.IsValidUser(serverDetails.Username) {
		return errors.Errorf("%q is not a valid username", serverDetails.Username)
	}

	userTag := names.NewUserTag(serverDetails.Username)
	if userTag.Provider() != names.LocalProvider {
		// Remove users do not have their passwords stored in Juju
		// so we never attempt to change them.
		c.KeepPassword = true
	}

	info := api.Info{
		Addrs:    serverDetails.Addresses,
		CACert:   serverDetails.CACert,
		Tag:      userTag,
		Password: serverDetails.Password,
	}

	apiState, err := c.apiOpen(&info, api.DefaultDialOpts())
	if err != nil {
		return errors.Trace(err)
	}
	defer apiState.Close()

	// If we get to here, the credentials supplied were sufficient to connect
	// to the Juju System and login. Now we cache the details.
	serverInfo, err := c.cacheConnectionInfo(serverDetails, apiState)
	if err != nil {
		return errors.Trace(err)
	}
	ctx.Infof("cached connection details as system %q", c.Name)

	// If we get to here, we have been able to connect to the API server, and
	// also have been able to write the cached information. Now we can change
	// the user's password to a new randomly generated strong password, and
	// update the cached information knowing that the likelihood of failure is
	// minimal.
	if !c.KeepPassword {
		if err := c.updatePassword(ctx, apiState, userTag, serverInfo); err != nil {
			return errors.Trace(err)
		}
	}

	return errors.Trace(envcmd.SetCurrentSystem(ctx, c.Name))
}
Esempio n. 4
0
func (c *switchCommand) Run(ctx *cmd.Context) error {
	// Switch is an alternative way of dealing with environments than using
	// the JUJU_ENV environment setting, and as such, doesn't play too well.
	// If JUJU_ENV is set we should report that as the current environment,
	// and not allow switching when it is set.

	// Passing through the empty string reads the default environments.yaml file.
	// If the environments.yaml file doesn't exist, just list environments in
	// the configstore.
	envFileExists := true
	names := set.NewStrings()
	environments, err := environs.ReadEnvirons("")
	if err != nil {
		if !environs.IsNoEnv(err) {
			return errors.Annotate(err, "couldn't read the environment")
		}
		envFileExists = false
	} else {
		for _, name := range environments.Names() {
			names.Add(name)
		}
	}

	configEnvirons, configSystems, err := getConfigstoreOptions()
	if err != nil {
		return err
	}
	names = names.Union(configEnvirons)
	names = names.Union(configSystems)

	if c.List {
		// List all environments and systems.
		if c.EnvName != "" {
			return errors.New("cannot switch and list at the same time")
		}
		for _, name := range names.SortedValues() {
			if configSystems.Contains(name) && !configEnvirons.Contains(name) {
				name += systemSuffix
			}
			fmt.Fprintf(ctx.Stdout, "%s\n", name)
		}
		return nil
	}

	jujuEnv := os.Getenv("JUJU_ENV")
	if jujuEnv != "" {
		if c.EnvName == "" {
			fmt.Fprintf(ctx.Stdout, "%s\n", jujuEnv)
			return nil
		} else {
			return errors.Errorf("cannot switch when JUJU_ENV is overriding the environment (set to %q)", jujuEnv)
		}
	}

	current, isSystem, err := envcmd.CurrentConnectionName()
	if err != nil {
		return errors.Trace(err)
	}
	if current == "" {
		if envFileExists {
			current = environments.Default
		}
	} else if isSystem {
		current += systemSuffix
	}

	// Handle the different operation modes.
	switch {
	case c.EnvName == "" && current == "":
		// Nothing specified and nothing to switch to.
		return errors.New("no currently specified environment")
	case c.EnvName == "":
		// Simply print the current environment.
		fmt.Fprintf(ctx.Stdout, "%s\n", current)
		return nil
	default:
		// Switch the environment.
		if !names.Contains(c.EnvName) {
			return errors.Errorf("%q is not a name of an existing defined environment or system", c.EnvName)
		}
		// If the name is not in the environment set, but is in the system
		// set, then write the name into the current system file.
		logger.Debugf("systems: %v", configSystems)
		logger.Debugf("environs: %v", configEnvirons)
		newEnv := c.EnvName
		if configSystems.Contains(newEnv) && !configEnvirons.Contains(newEnv) {
			return envcmd.SetCurrentSystem(ctx, newEnv)
		}
		return envcmd.SetCurrentEnvironment(ctx, newEnv)
	}
}