1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
11
"launchpad.net/gnuflag"
14
"github.com/juju/errors"
15
"github.com/juju/juju/cmd/modelcmd"
16
"github.com/juju/utils"
17
"gopkg.in/macaroon-bakery.v1/httpbakery"
19
api "github.com/juju/romulus/api/budget"
22
var budgetWithLimitRe = regexp.MustCompile(`^[a-zA-Z0-9\-]+:[0-9]+$`)
24
type allocateCommand struct {
25
modelcmd.ModelCommandBase
33
// NewAllocateCommand returns a new allocateCommand
34
func NewAllocateCommand() modelcmd.ModelCommand {
35
return &allocateCommand{}
39
Allocate budget for the specified applications, replacing any prior allocations
40
made for the specified applications.
43
# Assigns application "db" to an allocation on budget "somebudget" with
45
juju allocate somebudget:42 db
47
# Application names assume the current selected model, unless otherwise
49
juju allocate -m [<controller name:]<model name> ...
51
# Models may also be referenced by UUID when necessary:
52
juju allocate --model-uuid <uuid> ...
55
// SetFlags implements cmd.Command.SetFlags.
56
func (c *allocateCommand) SetFlags(f *gnuflag.FlagSet) {
57
f.StringVar(&c.ModelUUID, "model-uuid", "", "Model UUID of allocation")
60
// Info implements cmd.Command.Info.
61
func (c *allocateCommand) Info() *cmd.Info {
64
Args: "<budget>:<value> <application> [<application2> ...]",
65
Purpose: "Allocate budget to applications.",
70
// Init implements cmd.Command.Init.
71
func (c *allocateCommand) Init(args []string) error {
73
return errors.New("budget and application name required")
75
budgetWithLimit := args[0]
77
c.Budget, c.Limit, err = parseBudgetWithLimit(budgetWithLimit)
79
return errors.Annotate(err, `expected args in the form "budget:limit [application ...]"`)
81
if c.ModelUUID == "" {
82
c.ModelUUID, err = c.modelUUID()
87
if !utils.IsValidUUIDString(c.ModelUUID) {
88
return errors.NotValidf("model UUID %q", c.ModelUUID)
96
// Run implements cmd.Command.Run and has most of the logic for the run command.
97
func (c *allocateCommand) Run(ctx *cmd.Context) error {
98
client, err := c.BakeryClient()
100
return errors.Annotate(err, "failed to create an http client")
102
api, err := c.newAPIClient(client)
104
return errors.Annotate(err, "failed to create an api client")
106
resp, err := api.CreateAllocation(c.Budget, c.Limit, c.ModelUUID, c.Services)
108
return errors.Annotate(err, "failed to create allocation")
110
fmt.Fprintln(ctx.Stdout, resp)
114
func (c *allocateCommand) modelUUID() (string, error) {
115
model, err := c.ClientStore().ModelByName(c.ControllerName(), c.ModelName())
117
return "", errors.Trace(err)
119
return model.ModelUUID, nil
122
func parseBudgetWithLimit(bl string) (string, string, error) {
123
if !budgetWithLimitRe.MatchString(bl) {
124
return "", "", errors.New("invalid budget specification, expecting <budget>:<limit>")
126
parts := strings.Split(bl, ":")
127
return parts[0], parts[1], nil
130
func (c *allocateCommand) newAPIClient(bakery *httpbakery.Client) (apiClient, error) {
134
c.api = api.NewClient(bakery)
138
type apiClient interface {
139
CreateAllocation(string, string, string, []string) (string, error)