github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/runner/jujuc/status-get.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc
     5  
     6  import (
     7  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/gnuflag"
    10  
    11  	"github.com/juju/juju/status"
    12  )
    13  
    14  // StatusGetCommand implements the status-get command.
    15  type StatusGetCommand struct {
    16  	cmd.CommandBase
    17  	ctx         Context
    18  	includeData bool
    19  	serviceWide bool
    20  	out         cmd.Output
    21  }
    22  
    23  func NewStatusGetCommand(ctx Context) (cmd.Command, error) {
    24  	return &StatusGetCommand{ctx: ctx}, nil
    25  }
    26  
    27  func (c *StatusGetCommand) Info() *cmd.Info {
    28  	doc := `
    29  By default, only the status value is printed.
    30  If the --include-data flag is passed, the associated data are printed also.
    31  `
    32  	return &cmd.Info{
    33  		Name:    "status-get",
    34  		Args:    "[--include-data] [--application]",
    35  		Purpose: "print status information",
    36  		Doc:     doc,
    37  	}
    38  }
    39  
    40  func (c *StatusGetCommand) SetFlags(f *gnuflag.FlagSet) {
    41  	c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
    42  	f.BoolVar(&c.includeData, "include-data", false, "print all status data")
    43  	f.BoolVar(&c.serviceWide, "application", false, "print status for all units of this application if this unit is the leader")
    44  }
    45  
    46  func (c *StatusGetCommand) Init(args []string) error {
    47  	return cmd.CheckEmpty(args)
    48  }
    49  
    50  // StatusInfo is a record of the status information for a service or a unit's workload.
    51  type StatusInfo struct {
    52  	Tag    string
    53  	Status string
    54  	Info   string
    55  	Data   map[string]interface{}
    56  }
    57  
    58  // ApplicationStatusInfo holds StatusInfo for an Application and all its Units.
    59  type ApplicationStatusInfo struct {
    60  	Application StatusInfo
    61  	Units       []StatusInfo
    62  }
    63  
    64  func toDetails(info StatusInfo, includeData bool) map[string]interface{} {
    65  	details := make(map[string]interface{})
    66  	details["status"] = info.Status
    67  	if includeData {
    68  		data := make(map[string]interface{})
    69  		for k, v := range info.Data {
    70  			data[k] = v
    71  		}
    72  		details["status-data"] = data
    73  		details["message"] = info.Info
    74  	}
    75  	return details
    76  }
    77  
    78  func (c *StatusGetCommand) ApplicationStatus(ctx *cmd.Context) error {
    79  	serviceStatus, err := c.ctx.ApplicationStatus()
    80  	if err != nil {
    81  		if errors.IsNotImplemented(err) {
    82  			return c.out.Write(ctx, status.Unknown)
    83  		}
    84  		return errors.Annotatef(err, "finding service status")
    85  	}
    86  	if !c.includeData && c.out.Name() == "smart" {
    87  		return c.out.Write(ctx, serviceStatus.Application.Status)
    88  	}
    89  	statusDetails := make(map[string]interface{})
    90  	details := toDetails(serviceStatus.Application, c.includeData)
    91  
    92  	units := make(map[string]interface{}, len(serviceStatus.Units))
    93  	for _, unit := range serviceStatus.Units {
    94  		units[unit.Tag] = toDetails(unit, c.includeData)
    95  	}
    96  	details["units"] = units
    97  	statusDetails["application-status"] = details
    98  	c.out.Write(ctx, statusDetails)
    99  
   100  	return nil
   101  
   102  }
   103  
   104  func (c *StatusGetCommand) unitOrServiceStatus(ctx *cmd.Context) error {
   105  	var err error
   106  
   107  	if c.serviceWide {
   108  		return c.ApplicationStatus(ctx)
   109  	}
   110  
   111  	unitStatus, err := c.ctx.UnitStatus()
   112  	if err != nil {
   113  		if errors.IsNotImplemented(err) {
   114  			return c.out.Write(ctx, status.Unknown)
   115  		}
   116  		return errors.Annotatef(err, "finding workload status")
   117  	}
   118  	if !c.includeData && c.out.Name() == "smart" {
   119  		return c.out.Write(ctx, unitStatus.Status)
   120  	}
   121  	c.out.Write(ctx, toDetails(*unitStatus, c.includeData))
   122  	return nil
   123  }
   124  
   125  func (c *StatusGetCommand) Run(ctx *cmd.Context) error {
   126  	return c.unitOrServiceStatus(ctx)
   127  }