github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/cloud/show.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloud 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/gnuflag" 10 "gopkg.in/yaml.v2" 11 12 jujucloud "github.com/juju/juju/cloud" 13 ) 14 15 type showCloudCommand struct { 16 cmd.CommandBase 17 out cmd.Output 18 19 CloudName string 20 } 21 22 var showCloudDoc = ` 23 Provided information includes 'defined' (public, built-in), 'type', 24 'auth-type', 'regions', and 'endpoints'. 25 26 Examples: 27 28 juju show-cloud google 29 juju show-cloud azure-china --output ~/azure_cloud_details.txt 30 31 See also: 32 clouds 33 update-clouds 34 ` 35 36 // NewShowCloudCommand returns a command to list cloud information. 37 func NewShowCloudCommand() cmd.Command { 38 return &showCloudCommand{} 39 } 40 41 func (c *showCloudCommand) SetFlags(f *gnuflag.FlagSet) { 42 c.CommandBase.SetFlags(f) 43 // We only support yaml for display purposes. 44 c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{ 45 "yaml": cmd.FormatYaml, 46 }) 47 } 48 49 func (c *showCloudCommand) Init(args []string) error { 50 switch len(args) { 51 case 1: 52 c.CloudName = args[0] 53 default: 54 return errors.New("no cloud specified") 55 } 56 return cmd.CheckEmpty(args[1:]) 57 } 58 59 func (c *showCloudCommand) Info() *cmd.Info { 60 return &cmd.Info{ 61 Name: "show-cloud", 62 Args: "<cloud name>", 63 Purpose: "Shows detailed information on a cloud.", 64 Doc: showCloudDoc, 65 } 66 } 67 68 func (c *showCloudCommand) Run(ctxt *cmd.Context) error { 69 details, err := getCloudDetails() 70 if err != nil { 71 return err 72 } 73 cloud, ok := details[c.CloudName] 74 if !ok { 75 return errors.NotFoundf("cloud %q", c.CloudName) 76 } 77 return c.out.Write(ctxt, cloud) 78 } 79 80 type regionDetails struct { 81 Name string `yaml:"-" json:"-"` 82 Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` 83 IdentityEndpoint string `yaml:"identity-endpoint,omitempty" json:"identity-endpoint,omitempty"` 84 StorageEndpoint string `yaml:"storage-endpoint,omitempty" json:"storage-endpoint,omitempty"` 85 } 86 87 type cloudDetails struct { 88 Source string `yaml:"defined,omitempty" json:"defined,omitempty"` 89 CloudType string `yaml:"type" json:"type"` 90 AuthTypes []string `yaml:"auth-types,omitempty,flow" json:"auth-types,omitempty"` 91 Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` 92 IdentityEndpoint string `yaml:"identity-endpoint,omitempty" json:"identity-endpoint,omitempty"` 93 StorageEndpoint string `yaml:"storage-endpoint,omitempty" json:"storage-endpoint,omitempty"` 94 // Regions is for when we want to print regions in order for yaml or tabular output. 95 Regions yaml.MapSlice `yaml:"regions,omitempty" json:"-"` 96 // Regions map is for json marshalling where format is important but not order. 97 RegionsMap map[string]regionDetails `yaml:"-" json:"regions,omitempty"` 98 Config map[string]interface{} `yaml:"config,omitempty" json:"config,omitempty"` 99 RegionConfig jujucloud.RegionConfig `yaml:"region-config,omitempty" json:"region-config,omitempty"` 100 } 101 102 func makeCloudDetails(cloud jujucloud.Cloud) *cloudDetails { 103 result := &cloudDetails{ 104 Source: "public", 105 CloudType: cloud.Type, 106 Endpoint: cloud.Endpoint, 107 IdentityEndpoint: cloud.IdentityEndpoint, 108 StorageEndpoint: cloud.StorageEndpoint, 109 Config: cloud.Config, 110 RegionConfig: cloud.RegionConfig, 111 } 112 result.AuthTypes = make([]string, len(cloud.AuthTypes)) 113 for i, at := range cloud.AuthTypes { 114 result.AuthTypes[i] = string(at) 115 } 116 result.RegionsMap = make(map[string]regionDetails) 117 for _, region := range cloud.Regions { 118 r := regionDetails{Name: region.Name} 119 if region.Endpoint != result.Endpoint { 120 r.Endpoint = region.Endpoint 121 } 122 if region.IdentityEndpoint != result.IdentityEndpoint { 123 r.IdentityEndpoint = region.IdentityEndpoint 124 } 125 if region.StorageEndpoint != result.StorageEndpoint { 126 r.StorageEndpoint = region.StorageEndpoint 127 } 128 result.Regions = append(result.Regions, yaml.MapItem{r.Name, r}) 129 result.RegionsMap[region.Name] = r 130 } 131 return result 132 } 133 134 func getCloudDetails() (map[string]*cloudDetails, error) { 135 result, err := listCloudDetails() 136 if err != nil { 137 return nil, errors.Trace(err) 138 } 139 return result.all(), nil 140 }