Beispiel #1
0
func (c *registerCommand) maybeSetCurrentModel(ctx *cmd.Context, store jujuclient.ClientStore, controllerName, userName string, models []base.UserModel) error {
	if len(models) == 0 {
		fmt.Fprintf(ctx.Stderr, "\n%s\n\n", errNoModels.Error())
		return nil
	}

	// If we get to here, there is at least one model.
	if len(models) == 1 {
		// There is exactly one model shared,
		// so set it as the current model.
		model := models[0]
		owner := names.NewUserTag(model.Owner)
		modelName := jujuclient.JoinOwnerModelName(owner, model.Name)
		err := store.SetCurrentModel(controllerName, modelName)
		if err != nil {
			return errors.Trace(err)
		}
		fmt.Fprintf(ctx.Stderr, "\nCurrent model set to %q.\n\n", modelName)
	} else {
		fmt.Fprintf(ctx.Stderr, `
There are %d models available. Use "juju switch" to select
one of them:
`, len(models))
		user := names.NewUserTag(userName)
		ownerModelNames := make(set.Strings)
		otherModelNames := make(set.Strings)
		for _, model := range models {
			if model.Owner == userName {
				ownerModelNames.Add(model.Name)
				continue
			}
			owner := names.NewUserTag(model.Owner)
			modelName := common.OwnerQualifiedModelName(model.Name, owner, user)
			otherModelNames.Add(modelName)
		}
		for _, modelName := range ownerModelNames.SortedValues() {
			fmt.Fprintf(ctx.Stderr, "  - juju switch %s\n", modelName)
		}
		for _, modelName := range otherModelNames.SortedValues() {
			fmt.Fprintf(ctx.Stderr, "  - juju switch %s\n", modelName)
		}
		fmt.Fprintln(ctx.Stderr)
	}
	return nil
}
Beispiel #2
0
// Run implements Command.Run
func (c *whoAmICommand) Run(ctx *cmd.Context) error {
	controllerName, err := c.store.CurrentController()
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	if err != nil {
		fmt.Fprintln(ctx.Stderr, "There is no current controller.\nRun juju list-controllers to see available controllers.")
		return nil
	}
	modelName, err := c.store.CurrentModel(controllerName)
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	userDetails, err := c.store.AccountDetails(controllerName)
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	if err != nil {
		fmt.Fprintf(ctx.Stderr, "You are not logged in to controller %q and model %q.\nRun juju login if you want to login.\n", controllerName, modelName)
		return nil
	}
	// Only qualify model name if there is a current model.
	if modelName != "" {
		if unqualifiedModelName, owner, err := jujuclient.SplitModelName(modelName); err == nil {
			user := names.NewUserTag(userDetails.User)
			modelName = common.OwnerQualifiedModelName(unqualifiedModelName, owner, user)
		}
	}

	result := whoAmI{
		ControllerName: controllerName,
		ModelName:      modelName,
		UserName:       userDetails.User,
	}
	return c.out.Write(ctx, result)
}
Beispiel #3
0
// convertControllerDetails takes a map of Controllers and
// the recently used model for each and creates a list of
// amalgamated controller and model details.
func (c *listControllersCommand) convertControllerDetails(storeControllers map[string]jujuclient.ControllerDetails) (map[string]ControllerItem, []string) {
	if len(storeControllers) == 0 {
		return nil, nil
	}

	errs := []string{}
	addError := func(msg, controllerName string, err error) {
		logger.Errorf(fmt.Sprintf("getting current %s for controller %s: %v", msg, controllerName, err))
		errs = append(errs, msg)
	}

	controllers := map[string]ControllerItem{}
	for controllerName, details := range storeControllers {
		serverName := ""
		// The most recently connected-to address
		// is the first in the list.
		if len(details.APIEndpoints) > 0 {
			serverName = details.APIEndpoints[0]
		}

		var userName, access string
		accountDetails, err := c.store.AccountDetails(controllerName)
		if err != nil {
			if !errors.IsNotFound(err) {
				addError("account details", controllerName, err)
				continue
			}
		} else {
			userName = accountDetails.User
			access = accountDetails.LastKnownAccess
		}

		var modelName string
		currentModel, err := c.store.CurrentModel(controllerName)
		if err != nil {
			if !errors.IsNotFound(err) {
				addError("model", controllerName, err)
				continue
			}
		} else {
			modelName = currentModel
			if userName != "" {
				// There's a user logged in, so display the
				// model name relative to that user.
				if unqualifiedModelName, owner, err := jujuclient.SplitModelName(modelName); err == nil {
					user := names.NewUserTag(userName)
					modelName = common.OwnerQualifiedModelName(unqualifiedModelName, owner, user)
				}
			}
		}

		item := ControllerItem{
			ModelName:      modelName,
			User:           userName,
			Access:         access,
			Server:         serverName,
			APIEndpoints:   details.APIEndpoints,
			ControllerUUID: details.ControllerUUID,
			CACert:         details.CACert,
			Cloud:          details.Cloud,
			CloudRegion:    details.CloudRegion,
			AgentVersion:   details.AgentVersion,
		}
		if details.MachineCount != nil && *details.MachineCount > 0 {
			item.MachineCount = details.MachineCount
		}
		if details.ModelCount != nil && *details.ModelCount > 0 {
			item.ModelCount = details.ModelCount
		}
		if details.ControllerMachineCount > 0 {
			item.ControllerMachines = &ControllerMachines{
				Total:  details.ControllerMachineCount,
				Active: details.ActiveControllerMachineCount,
			}
		}
		controllers[controllerName] = item
	}
	return controllers, errs
}
Beispiel #4
0
// formatTabular takes an interface{} to adhere to the cmd.Formatter interface
func (c *modelsCommand) formatTabular(writer io.Writer, value interface{}) error {
	modelSet, ok := value.(ModelSet)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", modelSet, value)
	}

	// We need the tag of the user for which we're listing models,
	// and for the logged-in user. We use these below when formatting
	// the model display names.
	loggedInUser := names.NewUserTag(c.loggedInUser)
	userForLastConn := loggedInUser
	var userForListing names.UserTag
	if c.user != "" {
		userForListing = names.NewUserTag(c.user)
		userForLastConn = userForListing
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Controller: " + c.ControllerName())
	w.Println()
	w.Print("Model")
	if c.listUUID {
		w.Print("UUID")
	}
	// Only owners, or users with write access or above get to see machines and cores.
	haveMachineInfo := false
	for _, m := range modelSet.Models {
		if haveMachineInfo = len(m.Machines) > 0; haveMachineInfo {
			break
		}
	}
	if haveMachineInfo {
		w.Println("Owner", "Status", "Machines", "Cores", "Access", "Last connection")
		offset := 0
		if c.listUUID {
			offset++
		}
		tw.SetColumnAlignRight(3 + offset)
		tw.SetColumnAlignRight(4 + offset)
	} else {
		w.Println("Owner", "Status", "Access", "Last connection")
	}
	for _, model := range modelSet.Models {
		owner := names.NewUserTag(model.Owner)
		name := common.OwnerQualifiedModelName(model.Name, owner, userForListing)
		if jujuclient.JoinOwnerModelName(owner, model.Name) == modelSet.CurrentModelQualified {
			name += "*"
			w.PrintColor(output.CurrentHighlight, name)
		} else {
			w.Print(name)
		}
		if c.listUUID {
			w.Print(model.UUID)
		}
		lastConnection := model.Users[userForLastConn.Id()].LastConnection
		if lastConnection == "" {
			lastConnection = "never connected"
		}
		userForAccess := loggedInUser
		if c.user != "" {
			userForAccess = names.NewUserTag(c.user)
		}
		access := model.Users[userForAccess.Id()].Access
		w.Print(model.Owner, model.Status.Current)
		if haveMachineInfo {
			machineInfo := fmt.Sprintf("%d", len(model.Machines))
			cores := uint64(0)
			for _, m := range model.Machines {
				cores += m.Cores
			}
			coresInfo := "-"
			if cores > 0 {
				coresInfo = fmt.Sprintf("%d", cores)
			}
			w.Print(machineInfo, coresInfo)
		}
		w.Println(access, lastConnection)
	}
	tw.Flush()
	return nil
}
Beispiel #5
0
// Run implements Command.Run
func (c *modelsCommand) Run(ctx *cmd.Context) error {
	accountDetails, err := c.ClientStore().AccountDetails(c.ControllerName())
	if err != nil {
		return err
	}
	c.loggedInUser = accountDetails.User

	// First get a list of the models.
	var models []base.UserModel
	if c.all {
		models, err = c.getAllModels()
	} else {
		if c.user == "" {
			c.user = accountDetails.User
		}
		models, err = c.getUserModels()
	}
	if err != nil {
		return errors.Annotate(err, "cannot list models")
	}

	// And now get the full details of the models.
	paramsModelInfo, err := c.getModelInfo(models)
	if err != nil {
		return errors.Annotate(err, "cannot get model details")
	}

	// TODO(perrito666) 2016-05-02 lp:1558657
	now := time.Now()
	modelInfo := make([]common.ModelInfo, 0, len(models))
	for _, info := range paramsModelInfo {
		model, err := common.ModelInfoFromParams(info, now)
		if err != nil {
			return errors.Trace(err)
		}
		model.ControllerName = c.ControllerName()
		modelInfo = append(modelInfo, model)
	}

	modelSet := ModelSet{Models: modelInfo}
	current, err := c.ClientStore().CurrentModel(c.ControllerName())
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	modelSet.CurrentModelQualified = current
	modelSet.CurrentModel = current
	if c.user != "" {
		userForListing := names.NewUserTag(c.user)
		unqualifiedModelName, owner, err := jujuclient.SplitModelName(current)
		if err == nil {
			modelSet.CurrentModel = common.OwnerQualifiedModelName(
				unqualifiedModelName, owner, userForListing,
			)
		}
	}

	if err := c.out.Write(ctx, modelSet); err != nil {
		return err
	}
	if len(models) == 0 && c.out.Name() == "tabular" {
		// When the output is tabular, we inform the user when there
		// are no models available, and tell them how to go about
		// creating or granting access to them.
		fmt.Fprintln(ctx.Stderr, noModelsMessage)
	}
	return nil
}