github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/cmd/juju/apiinfo.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"launchpad.net/gnuflag"
    13  
    14  	"github.com/juju/juju/cmd/envcmd"
    15  	"github.com/juju/juju/environs/configstore"
    16  )
    17  
    18  // APIInfoCommand returns the fields used to connect to an API server.
    19  type APIInfoCommand struct {
    20  	envcmd.EnvCommandBase
    21  	out      cmd.Output
    22  	refresh  bool
    23  	user     bool
    24  	password bool
    25  	cacert   bool
    26  	servers  bool
    27  	envuuid  bool
    28  	fields   []string
    29  }
    30  
    31  const apiInfoDoc = `
    32  Print the field values used to connect to the environment's API servers"
    33  
    34  The exact fields to output can be specified on the command line.  The
    35  available fields are:
    36    user
    37    password
    38    environ-uuid
    39    state-servers
    40    ca-cert
    41  
    42  If "password" is included as a field, or the --password option is given, the
    43  password value will be shown.
    44  
    45  
    46  Examples:
    47    $ juju api-info
    48    user: admin
    49    environ-uuid: 373b309b-4a86-4f13-88e2-c213d97075b8
    50    state-servers:
    51    - localhost:17070
    52    - 10.0.3.1:17070
    53    - 192.168.2.21:17070
    54    ca-cert: '-----BEGIN CERTIFICATE-----
    55      ...
    56      -----END CERTIFICATE-----
    57    '
    58  
    59    $ juju api-info user
    60    admin
    61  
    62    $ juju api-info user password
    63    user: admin
    64    password: sekrit
    65  
    66  
    67  `
    68  
    69  func (c *APIInfoCommand) Info() *cmd.Info {
    70  	return &cmd.Info{
    71  		Name:    "api-info",
    72  		Args:    "[field ...]",
    73  		Purpose: "print the field values used to connect to the environment's API servers",
    74  		Doc:     apiInfoDoc,
    75  	}
    76  }
    77  
    78  func (c *APIInfoCommand) Init(args []string) error {
    79  	c.fields = args
    80  	if len(args) == 0 {
    81  		c.user = true
    82  		c.envuuid = true
    83  		c.servers = true
    84  		c.cacert = true
    85  		return nil
    86  	}
    87  
    88  	var unknown []string
    89  	for _, name := range args {
    90  		switch name {
    91  		case "user":
    92  			c.user = true
    93  		case "password":
    94  			c.password = true
    95  		case "environ-uuid":
    96  			c.envuuid = true
    97  		case "state-servers":
    98  			c.servers = true
    99  		case "ca-cert":
   100  			c.cacert = true
   101  		default:
   102  			unknown = append(unknown, fmt.Sprintf("%q", name))
   103  		}
   104  	}
   105  	if len(unknown) > 0 {
   106  		return errors.Errorf("unknown fields: %s", strings.Join(unknown, ", "))
   107  	}
   108  
   109  	return nil
   110  }
   111  
   112  func (c *APIInfoCommand) SetFlags(f *gnuflag.FlagSet) {
   113  	c.out.AddFlags(f, "default", map[string]cmd.Formatter{
   114  		"default": c.format,
   115  		"yaml":    cmd.FormatYaml,
   116  		"json":    cmd.FormatJson,
   117  	})
   118  	f.BoolVar(&c.refresh, "refresh", false, "connect to the API to ensure an up-to-date endpoint location")
   119  	f.BoolVar(&c.password, "password", false, "include the password in the output fields")
   120  }
   121  
   122  func connectionEndpoint(c envcmd.EnvCommandBase, refresh bool) (configstore.APIEndpoint, error) {
   123  	return c.ConnectionEndpoint(refresh)
   124  }
   125  
   126  func connectionCredentials(c envcmd.EnvCommandBase) (configstore.APICredentials, error) {
   127  	return c.ConnectionCredentials()
   128  }
   129  
   130  var (
   131  	endpoint = connectionEndpoint
   132  	creds    = connectionCredentials
   133  )
   134  
   135  // Print out the addresses of the API server endpoints.
   136  func (c *APIInfoCommand) Run(ctx *cmd.Context) error {
   137  	apiendpoint, err := endpoint(c.EnvCommandBase, c.refresh)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	credentials, err := creds(c.EnvCommandBase)
   142  	if err != nil {
   143  		return err
   144  	}
   145  
   146  	var result InfoData
   147  	if c.user {
   148  		result.User = credentials.User
   149  	}
   150  	if c.password {
   151  		result.Password = credentials.Password
   152  	}
   153  	if c.envuuid {
   154  		result.EnvironUUID = apiendpoint.EnvironUUID
   155  	}
   156  	if c.servers {
   157  		result.StateServers = apiendpoint.Addresses
   158  	}
   159  	if c.cacert {
   160  		result.CACert = apiendpoint.CACert
   161  	}
   162  
   163  	return c.out.Write(ctx, result)
   164  }
   165  
   166  func (c *APIInfoCommand) format(value interface{}) ([]byte, error) {
   167  	if len(c.fields) == 1 {
   168  		data := value.(InfoData)
   169  		field, err := data.field(c.fields[0])
   170  		if err != nil {
   171  			return nil, err
   172  		}
   173  		switch value := field.(type) {
   174  		case []string:
   175  			return []byte(strings.Join(value, "\n")), nil
   176  		case string:
   177  			return []byte(value), nil
   178  		default:
   179  			return nil, errors.Errorf("Unsupported type %T", field)
   180  		}
   181  	}
   182  
   183  	return cmd.FormatYaml(value)
   184  }
   185  
   186  type InfoData struct {
   187  	User         string   `json:"user,omitempty" yaml:",omitempty"`
   188  	Password     string   `json:"password,omitempty" yaml:",omitempty"`
   189  	EnvironUUID  string   `json:"environ-uuid,omitempty" yaml:"environ-uuid,omitempty"`
   190  	StateServers []string `json:"state-servers,omitempty" yaml:"state-servers,omitempty"`
   191  	CACert       string   `json:"ca-cert,omitempty" yaml:"ca-cert,omitempty"`
   192  }
   193  
   194  func (i *InfoData) field(name string) (interface{}, error) {
   195  	switch name {
   196  	case "user":
   197  		return i.User, nil
   198  	case "password":
   199  		return i.Password, nil
   200  	case "environ-uuid":
   201  		return i.EnvironUUID, nil
   202  	case "state-servers":
   203  		return i.StateServers, nil
   204  	case "ca-cert":
   205  		return i.CACert, nil
   206  	default:
   207  		return "", errors.Errorf("unknown field %q", name)
   208  	}
   209  }