// 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 }