Example #1
0
File: list.go Project: bac/juju
func (c *listCommand) formatModelUsers(writer io.Writer, value interface{}) error {
	users, ok := value.(map[string]common.ModelUserInfo)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", users, value)
	}
	modelUsers := set.NewStrings()
	for name := range users {
		modelUsers.Add(name)
	}
	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Name", "Display name", "Access", "Last connection")
	for _, name := range modelUsers.SortedValues() {
		user := users[name]

		var highlight *ansiterm.Context
		userName := name
		if c.isLoggedInUser(name) {
			userName += "*"
			highlight = output.CurrentHighlight
		}
		w.PrintColor(highlight, userName)
		w.Println(user.DisplayName, user.Access, user.LastConnection)
	}
	tw.Flush()
	return nil
}
Example #2
0
// formatConfigTabular writes a tabular summary of config information.
func formatConfigTabular(writer io.Writer, value interface{}) error {
	configValues, ok := value.(config.ConfigValues)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", configValues, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}

	var valueNames []string
	for name := range configValues {
		valueNames = append(valueNames, name)
	}
	sort.Strings(valueNames)
	w.Println("Attribute", "From", "Value")

	for _, name := range valueNames {
		info := configValues[name]
		out := &bytes.Buffer{}
		err := cmd.FormatYaml(out, info.Value)
		if err != nil {
			return errors.Annotatef(err, "formatting value for %q", name)
		}
		// Some attribute values have a newline appended
		// which makes the output messy.
		valString := strings.TrimSuffix(out.String(), "\n")
		w.Println(name, info.Source, valString)
	}

	tw.Flush()
	return nil
}
Example #3
0
func printMachines(tw *ansiterm.TabWriter, machines map[string]machineStatus) {
	w := output.Wrapper{tw}
	w.Println("MACHINE", "STATE", "DNS", "INS-ID", "SERIES", "AZ")
	for _, name := range utils.SortStringsNaturally(stringKeysFromMap(machines)) {
		printMachine(w, machines[name])
	}
}
Example #4
0
func printMachines(tw *ansiterm.TabWriter, machines map[string]machineStatus) {
	w := output.Wrapper{tw}
	w.Println("Machine", "State", "DNS", "Inst id", "Series", "AZ")
	for _, name := range utils.SortStringsNaturally(stringKeysFromMap(machines)) {
		printMachine(w, machines[name])
	}
}
Example #5
0
File: regions.go Project: bac/juju
func formatRegionsTabular(writer io.Writer, regions yaml.MapSlice) error {
	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	for _, r := range regions {
		w.Println(r.Key)
	}
	tw.Flush()
	return nil
}
Example #6
0
File: list.go Project: bac/juju
func (c *listCommand) formatControllerUsers(writer io.Writer, value interface{}) error {
	users, valueConverted := value.([]UserInfo)
	if !valueConverted {
		return errors.Errorf("expected value of type %T, got %T", users, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Controller: " + c.ControllerName())
	w.Println()
	w.Println("Name", "Display name", "Access", "Date created", "Last connection")
	for _, user := range users {
		conn := user.LastConnection
		if user.Disabled {
			conn += " (disabled)"
		}
		var highlight *ansiterm.Context
		userName := user.Username
		if c.isLoggedInUser(user.Username) {
			userName += "*"
			highlight = output.CurrentHighlight
		}
		w.PrintColor(highlight, userName)
		w.Println(user.DisplayName, user.Access, user.DateCreated, conn)
	}
	tw.Flush()
	return nil
}
Example #7
0
File: list.go Project: bac/juju
// FormatTabularBlockedModels writes out tabular format for blocked models.
// This method is exported as it is also used by destroy-model.
func FormatTabularBlockedModels(writer io.Writer, value interface{}) error {
	models, ok := value.([]modelBlockInfo)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", models, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Name", "Model UUID", "Owner", "Disabled commands")
	for _, model := range models {
		w.Println(model.Name, model.UUID, model.Owner, strings.Join(model.CommandSets, ", "))
	}
	tw.Flush()
	return nil
}
Example #8
0
func printMachine(w output.Wrapper, m machineStatus) {
	// We want to display availability zone so extract from hardware info".
	hw, err := instance.ParseHardware(m.Hardware)
	if err != nil {
		logger.Warningf("invalid hardware info %s for machine %v", m.Hardware, m)
	}
	az := ""
	if hw.AvailabilityZone != nil {
		az = *hw.AvailabilityZone
	}
	w.Print(m.Id)
	w.PrintStatus(m.JujuStatus.Current)
	w.Println(m.DNSName, m.InstanceId, m.Series, az)
	for _, name := range utils.SortStringsNaturally(stringKeysFromMap(m.Containers)) {
		printMachine(w, m.Containers[name])
	}
}
Example #9
0
// formatCredentialsTabular writes a tabular summary of cloud information.
func formatCredentialsTabular(writer io.Writer, value interface{}) error {
	credentials, ok := value.(credentialsMap)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", credentials, value)
	}

	if len(credentials.Credentials) == 0 {
		fmt.Fprintln(writer, "No credentials to display.")
		return nil
	}

	// For tabular we'll sort alphabetically by cloud, and then by credential name.
	var cloudNames []string
	for name := range credentials.Credentials {
		cloudNames = append(cloudNames, name)
	}
	sort.Strings(cloudNames)

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Cloud", "Credentials")
	for _, cloudName := range cloudNames {
		var haveDefault bool
		var credentialNames []string
		credentials := credentials.Credentials[cloudName]
		for credentialName := range credentials.Credentials {
			if credentialName == credentials.DefaultCredential {
				credentialNames = append([]string{credentialName + "*"}, credentialNames...)
				haveDefault = true
			} else {
				credentialNames = append(credentialNames, credentialName)
			}
		}
		if haveDefault {
			sort.Strings(credentialNames[1:])
		} else {
			sort.Strings(credentialNames)
		}
		w.Println(cloudName, strings.Join(credentialNames, ", "))
	}
	tw.Flush()

	return nil
}
Example #10
0
File: list.go Project: bac/juju
// formatBlocks writes block list representation.
func formatBlocks(writer io.Writer, value interface{}) error {
	blocks, ok := value.([]BlockInfo)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", blocks, value)
	}

	if len(blocks) == 0 {
		fmt.Fprintf(writer, "No commands are currently disabled.")
		return nil
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Disabled commands", "Message")
	for _, info := range blocks {
		w.Println(info.Commands, info.Message)
	}
	tw.Flush()

	return nil
}
Example #11
0
// formatConfigTabular writes a tabular summary of default config information.
func formatDefaultConfigTabular(writer io.Writer, value interface{}) error {
	defaultValues, ok := value.(config.ModelDefaultAttributes)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", defaultValues, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}

	p := func(name string, value config.AttributeDefaultValues) {
		var c, d interface{}
		switch value.Default {
		case nil:
			d = "-"
		case "":
			d = `""`
		default:
			d = value.Default
		}
		switch value.Controller {
		case nil:
			c = "-"
		case "":
			c = `""`
		default:
			c = value.Controller
		}
		w.Println(name, d, c)
		for _, region := range value.Regions {
			w.Println("  "+region.Name, region.Value, "-")
		}
	}
	var valueNames []string
	for name := range defaultValues {
		valueNames = append(valueNames, name)
	}
	sort.Strings(valueNames)

	w.Println("Attribute", "Default", "Controller")

	for _, name := range valueNames {
		info := defaultValues[name]
		out := &bytes.Buffer{}
		err := cmd.FormatYaml(out, info)
		if err != nil {
			return errors.Annotatef(err, "formatting value for %q", name)
		}
		p(name, info)
	}

	tw.Flush()
	return nil
}
Example #12
0
// formatControllersTabular returns a tabular summary of controller/model items
// sorted by controller name alphabetically.
func formatControllersTabular(writer io.Writer, set ControllerSet, promptRefresh bool) error {
	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}

	if promptRefresh && len(set.Controllers) > 0 {
		fmt.Fprintln(writer, "Use --refresh to see the latest information.")
		fmt.Fprintln(writer)
	}
	w.Println("CONTROLLER", "MODEL", "USER", "ACCESS", "CLOUD/REGION", "MODELS", "MACHINES", "HA", "VERSION")
	tw.SetColumnAlignRight(5)
	tw.SetColumnAlignRight(6)
	tw.SetColumnAlignRight(7)

	names := []string{}
	for name := range set.Controllers {
		names = append(names, name)
	}
	sort.Strings(names)

	for _, name := range names {
		c := set.Controllers[name]
		modelName := noValueDisplay
		if c.ModelName != "" {
			modelName = c.ModelName
		}
		userName := noValueDisplay
		access := noValueDisplay
		if c.User != "" {
			userName = c.User
			access = notKnownDisplay
			if c.Access != "" {
				access = c.Access
			}
		}
		if name == set.CurrentController {
			name += "*"
			w.PrintColor(output.CurrentHighlight, name)
		} else {
			w.Print(name)
		}
		cloudRegion := c.Cloud
		if c.CloudRegion != "" {
			cloudRegion += "/" + c.CloudRegion
		}
		agentVersion := c.AgentVersion
		staleVersion := false
		if agentVersion == "" {
			agentVersion = notKnownDisplay
		} else {
			agentVersionNum, err := version.Parse(agentVersion)
			staleVersion = err == nil && jujuversion.Current.Compare(agentVersionNum) > 0
		}
		machineCount := noValueDisplay
		if c.MachineCount != nil && *c.MachineCount > 0 {
			machineCount = fmt.Sprintf("%d", *c.MachineCount)
		}
		modelCount := noValueDisplay
		if c.ModelCount != nil && *c.ModelCount > 0 {
			modelCount = fmt.Sprintf("%d", *c.ModelCount)
		}
		w.Print(modelName, userName, access, cloudRegion, modelCount, machineCount)
		controllerMachineInfo, warn := controllerMachineStatus(c.ControllerMachines)
		if warn {
			w.PrintColor(output.WarningHighlight, controllerMachineInfo)
		} else {
			w.Print(controllerMachineInfo)
		}
		if staleVersion {
			w.PrintColor(output.WarningHighlight, agentVersion)
		} else {
			w.Print(agentVersion)
		}
		w.Println()
	}
	tw.Flush()
	return nil
}
Example #13
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
}
Example #14
0
File: list.go Project: bac/juju
// formatCloudsTabular writes a tabular summary of cloud information.
func formatCloudsTabular(writer io.Writer, value interface{}) error {
	clouds, ok := value.(*cloudList)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", clouds, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}
	w.Println("Cloud", "Regions", "Default", "Type", "Description")
	w.SetColumnAlignRight(1)

	cloudNamesSorted := func(someClouds map[string]*cloudDetails) []string {
		// For tabular we'll sort alphabetically, user clouds last.
		var names []string
		for name, _ := range someClouds {
			names = append(names, name)
		}
		sort.Strings(names)
		return names
	}

	printClouds := func(someClouds map[string]*cloudDetails, color *ansiterm.Context) {
		cloudNames := cloudNamesSorted(someClouds)

		for _, name := range cloudNames {
			info := someClouds[name]
			defaultRegion := ""
			if len(info.Regions) > 0 {
				defaultRegion = info.RegionsMap[info.Regions[0].Key.(string)].Name
			}
			description := info.CloudDescription
			if len(description) > 40 {
				description = description[:39]
			}
			w.PrintColor(color, name)
			w.Println(len(info.Regions), defaultRegion, info.CloudType, description)
		}
	}
	printClouds(clouds.public, nil)
	printClouds(clouds.builtin, nil)
	printClouds(clouds.personal, ansiterm.Foreground(ansiterm.BrightBlue))

	w.Println("\nTry 'list-regions <cloud>' to see available regions.")
	w.Println("'show-cloud <cloud>' or 'regions --format yaml <cloud>' can be used to see region endpoints.")
	w.Println("'add-cloud' can add private clouds or private infrastructure.")
	w.Println("Update the known public clouds with 'update-clouds'.")
	tw.Flush()
	return nil
}