github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/application/constraints.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package application
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/gnuflag"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/api/application"
    16  	jujucmd "github.com/juju/juju/cmd"
    17  	"github.com/juju/juju/cmd/juju/block"
    18  	"github.com/juju/juju/cmd/modelcmd"
    19  	"github.com/juju/juju/core/constraints"
    20  )
    21  
    22  var usageGetConstraintsSummary = `
    23  Displays machine constraints for an application.`[1:]
    24  
    25  var usageGetConstraintsDetails = `
    26  Shows machine constraints that have been set for an application with ` + "`juju set-\nconstraints`" + `.
    27  By default, the model is the current model.
    28  Application constraints are combined with model constraints, set with ` +
    29  	"`juju \nset-model-constraints`" + `, for commands (such as 'deploy') that provision
    30  machines for applications. Where model and application constraints overlap, the
    31  application constraints take precedence.
    32  Constraints for a specific model can be viewed with ` + "`juju get-model-\nconstraints`" + `.
    33  
    34  Examples:
    35      juju get-constraints mysql
    36      juju get-constraints -m mymodel apache2
    37  
    38  See also: 
    39      set-constraints
    40      get-model-constraints
    41      set-model-constraints`
    42  
    43  var usageSetConstraintsSummary = `
    44  Sets machine constraints for an application.`[1:]
    45  
    46  // setConstraintsDoc is multi-line since we need to use ` to denote
    47  // commands for ease in markdown.
    48  var usageSetConstraintsDetails = `
    49  Sets constraints for an application, which are used for all new machines 
    50  provisioned for that application. They can be viewed with `[1:] + "`juju get-\nconstraints`" + `.
    51  By default, the model is the current model.
    52  Application constraints are combined with model constraints, set with ` +
    53  	"`juju \nset-model-constraints`" + `, for commands (such as 'juju deploy') that 
    54  provision machines for applications. Where model and application constraints
    55  overlap, the application constraints take precedence.
    56  Constraints for a specific model can be viewed with ` + "`juju get-model-\nconstraints`" + `.
    57  This command requires that the application to have at least one unit. To apply 
    58  constraints to
    59  the first unit set them at the model level or pass them as an argument
    60  when deploying.
    61  
    62  Examples:
    63      juju set-constraints mysql mem=8G cores=4
    64      juju set-constraints -m mymodel apache2 mem=8G arch=amd64
    65  
    66  See also: 
    67      get-constraints
    68      get-model-constraints
    69      set-model-constraints`
    70  
    71  // NewApplicationGetConstraintsCommand returns a command which gets application constraints.
    72  func NewApplicationGetConstraintsCommand() modelcmd.ModelCommand {
    73  	return modelcmd.Wrap(&applicationGetConstraintsCommand{})
    74  }
    75  
    76  type applicationConstraintsAPI interface {
    77  	Close() error
    78  	GetConstraints(...string) ([]constraints.Value, error)
    79  	SetConstraints(string, constraints.Value) error
    80  }
    81  
    82  type applicationConstraintsCommand struct {
    83  	modelcmd.ModelCommandBase
    84  	ApplicationName string
    85  	out             cmd.Output
    86  	api             applicationConstraintsAPI
    87  }
    88  
    89  func (c *applicationConstraintsCommand) getAPI() (applicationConstraintsAPI, error) {
    90  	if c.api != nil {
    91  		return c.api, nil
    92  	}
    93  	root, err := c.NewAPIRoot()
    94  	if err != nil {
    95  		return nil, errors.Trace(err)
    96  	}
    97  	return application.NewClient(root), nil
    98  }
    99  
   100  type applicationGetConstraintsCommand struct {
   101  	applicationConstraintsCommand
   102  }
   103  
   104  func (c *applicationGetConstraintsCommand) Info() *cmd.Info {
   105  	return jujucmd.Info(&cmd.Info{
   106  		Name:    "get-constraints",
   107  		Args:    "<application>",
   108  		Purpose: usageGetConstraintsSummary,
   109  		Doc:     usageGetConstraintsDetails,
   110  	})
   111  }
   112  
   113  func formatConstraints(writer io.Writer, value interface{}) error {
   114  	fmt.Fprint(writer, value.(constraints.Value).String())
   115  	return nil
   116  }
   117  
   118  func (c *applicationGetConstraintsCommand) SetFlags(f *gnuflag.FlagSet) {
   119  	c.ModelCommandBase.SetFlags(f)
   120  	c.out.AddFlags(f, "constraints", map[string]cmd.Formatter{
   121  		"constraints": formatConstraints,
   122  		"yaml":        cmd.FormatYaml,
   123  		"json":        cmd.FormatJson,
   124  	})
   125  }
   126  
   127  func (c *applicationGetConstraintsCommand) Init(args []string) error {
   128  	if len(args) == 0 {
   129  		return errors.Errorf("no application name specified")
   130  	}
   131  	if !names.IsValidApplication(args[0]) {
   132  		return errors.Errorf("invalid application name %q", args[0])
   133  	}
   134  
   135  	c.ApplicationName, args = args[0], args[1:]
   136  	return cmd.CheckEmpty(args)
   137  }
   138  
   139  func (c *applicationGetConstraintsCommand) Run(ctx *cmd.Context) error {
   140  	apiclient, err := c.getAPI()
   141  	if err != nil {
   142  		return err
   143  	}
   144  	defer apiclient.Close()
   145  
   146  	cons, err := apiclient.GetConstraints(c.ApplicationName)
   147  	if err != nil {
   148  		return err
   149  	}
   150  	return c.out.Write(ctx, cons[0])
   151  }
   152  
   153  type applicationSetConstraintsCommand struct {
   154  	applicationConstraintsCommand
   155  	Constraints constraints.Value
   156  }
   157  
   158  // NewApplicationSetConstraintsCommand returns a command which sets application constraints.
   159  func NewApplicationSetConstraintsCommand() modelcmd.ModelCommand {
   160  	return modelcmd.Wrap(&applicationSetConstraintsCommand{})
   161  }
   162  
   163  func (c *applicationSetConstraintsCommand) Info() *cmd.Info {
   164  	return jujucmd.Info(&cmd.Info{
   165  		Name:    "set-constraints",
   166  		Args:    "<application> <constraint>=<value> ...",
   167  		Purpose: usageSetConstraintsSummary,
   168  		Doc:     usageSetConstraintsDetails,
   169  	})
   170  }
   171  
   172  func (c *applicationSetConstraintsCommand) Init(args []string) (err error) {
   173  	if len(args) == 0 {
   174  		return errors.Errorf("no application name specified")
   175  	}
   176  	if !names.IsValidApplication(args[0]) {
   177  		return errors.Errorf("invalid application name %q", args[0])
   178  	}
   179  
   180  	c.ApplicationName, args = args[0], args[1:]
   181  
   182  	c.Constraints, err = constraints.Parse(args...)
   183  	return err
   184  }
   185  
   186  func (c *applicationSetConstraintsCommand) Run(_ *cmd.Context) (err error) {
   187  	apiclient, err := c.getAPI()
   188  	if err != nil {
   189  		return err
   190  	}
   191  	defer apiclient.Close()
   192  
   193  	err = apiclient.SetConstraints(c.ApplicationName, c.Constraints)
   194  	return block.ProcessBlockedError(err, block.BlockChange)
   195  }