github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/status/status.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package status
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"strconv"
    10  
    11  	"github.com/juju/cmd"
    12  	"github.com/juju/errors"
    13  	"github.com/juju/loggo"
    14  	"launchpad.net/gnuflag"
    15  
    16  	"github.com/juju/juju/apiserver/params"
    17  	"github.com/juju/juju/cmd/envcmd"
    18  	"github.com/juju/juju/juju/osenv"
    19  )
    20  
    21  var logger = loggo.GetLogger("juju.cmd.juju.status")
    22  
    23  type StatusCommand struct {
    24  	envcmd.EnvCommandBase
    25  	out      cmd.Output
    26  	patterns []string
    27  	isoTime  bool
    28  }
    29  
    30  var statusDoc = `
    31  This command will report on the runtime state of various system entities.
    32  
    33  There are a number of ways to format the status output:
    34  
    35  - {short|line|oneline}: List units and their subordinates. For each
    36             unit, the IP address and agent status are listed.
    37  - summary: Displays the subnet(s) and port(s) the environment utilises.
    38             Also displays aggregate information about:
    39             - MACHINES: total #, and # in each state.
    40             - UNITS: total #, and # in each state.
    41             - SERVICES: total #, and # exposed of each service.
    42  - tabular: Displays information in a tabular format in these sections:
    43             - Machines: ID, STATE, VERSION, DNS, INS-ID, SERIES, HARDWARE
    44             - Services: NAME, EXPOSED, CHARM
    45             - Units: ID, STATE, VERSION, MACHINE, PORTS, PUBLIC-ADDRESS
    46               - Also displays subordinate units.
    47  - yaml (DEFAULT): Displays information on machines, services, and units
    48                    in the yaml format.
    49  
    50  Service or unit names may be specified to filter the status to only those
    51  services and units that match, along with the related machines, services
    52  and units. If a subordinate unit is matched, then its principal unit will
    53  be displayed. If a principal unit is matched, then all of its subordinates
    54  will be displayed.
    55  
    56  Wildcards ('*') may be specified in service/unit names to match any sequence
    57  of characters. For example, 'nova-*' will match any service whose name begins
    58  with 'nova-': 'nova-compute', 'nova-volume', etc.
    59  `
    60  
    61  func (c *StatusCommand) Info() *cmd.Info {
    62  	return &cmd.Info{
    63  		Name:    "status",
    64  		Args:    "[pattern ...]",
    65  		Purpose: "output status information about an environment",
    66  		Doc:     statusDoc,
    67  		Aliases: []string{"stat"},
    68  	}
    69  }
    70  
    71  func (c *StatusCommand) SetFlags(f *gnuflag.FlagSet) {
    72  	f.BoolVar(&c.isoTime, "utc", false, "display time as UTC in RFC3339 format")
    73  
    74  	oneLineFormatter := FormatOneline
    75  	defaultFormat := "yaml"
    76  	if c.CompatVersion() > 1 {
    77  		defaultFormat = "tabular"
    78  		oneLineFormatter = FormatOnelineV2
    79  	}
    80  
    81  	c.out.AddFlags(f, defaultFormat, map[string]cmd.Formatter{
    82  		"yaml":    cmd.FormatYaml,
    83  		"json":    cmd.FormatJson,
    84  		"short":   oneLineFormatter,
    85  		"oneline": oneLineFormatter,
    86  		"line":    oneLineFormatter,
    87  		"tabular": FormatTabular,
    88  		"summary": FormatSummary,
    89  	})
    90  }
    91  
    92  func (c *StatusCommand) Init(args []string) error {
    93  	c.patterns = args
    94  	// If use of ISO time not specified on command line,
    95  	// check env var.
    96  	if !c.isoTime {
    97  		var err error
    98  		envVarValue := os.Getenv(osenv.JujuStatusIsoTimeEnvKey)
    99  		if envVarValue != "" {
   100  			if c.isoTime, err = strconv.ParseBool(envVarValue); err != nil {
   101  				return errors.Annotatef(err, "invalid %s env var, expected true|false", osenv.JujuStatusIsoTimeEnvKey)
   102  			}
   103  		}
   104  	}
   105  	return nil
   106  }
   107  
   108  var connectionError = `Unable to connect to environment %q.
   109  Please check your credentials or use 'juju bootstrap' to create a new environment.
   110  
   111  Error details:
   112  %v
   113  `
   114  
   115  type statusAPI interface {
   116  	Status(patterns []string) (*params.FullStatus, error)
   117  	Close() error
   118  }
   119  
   120  var newApiClientForStatus = func(c *StatusCommand) (statusAPI, error) {
   121  	return c.NewAPIClient()
   122  }
   123  
   124  func (c *StatusCommand) Run(ctx *cmd.Context) error {
   125  
   126  	apiclient, err := newApiClientForStatus(c)
   127  	if err != nil {
   128  		return errors.Errorf(connectionError, c.ConnectionName(), err)
   129  	}
   130  	defer apiclient.Close()
   131  
   132  	status, err := apiclient.Status(c.patterns)
   133  	if err != nil {
   134  		if status == nil {
   135  			// Status call completely failed, there is nothing to report
   136  			return err
   137  		}
   138  		// Display any error, but continue to print status if some was returned
   139  		fmt.Fprintf(ctx.Stderr, "%v\n", err)
   140  	} else if status == nil {
   141  		return errors.Errorf("unable to obtain the current status")
   142  	}
   143  
   144  	formatter := newStatusFormatter(status, c.CompatVersion(), c.isoTime)
   145  	formatted := formatter.format()
   146  	return c.out.Write(ctx, formatted)
   147  }