github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/api/application/client.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // Package application provides access to the application api facade. 5 // This facade contains api calls that are specific to applications. 6 // As a rule of thumb, if the argument for an api requires an application name 7 // and affects only that application then the call belongs here. 8 package application 9 10 import ( 11 "github.com/juju/errors" 12 "github.com/juju/loggo" 13 "gopkg.in/juju/charm.v6-unstable" 14 15 "github.com/juju/juju/api" 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/charmstore" 19 "github.com/juju/juju/constraints" 20 "github.com/juju/juju/instance" 21 "github.com/juju/juju/storage" 22 ) 23 24 var logger = loggo.GetLogger("juju.api.application") 25 26 // Client allows access to the service API end point. 27 type Client struct { 28 base.ClientFacade 29 st api.Connection 30 facade base.FacadeCaller 31 } 32 33 // NewClient creates a new client for accessing the application api. 34 func NewClient(st api.Connection) *Client { 35 frontend, backend := base.NewClientFacade(st, "Application") 36 return &Client{ClientFacade: frontend, st: st, facade: backend} 37 } 38 39 // SetMetricCredentials sets the metric credentials for the application specified. 40 func (c *Client) SetMetricCredentials(service string, credentials []byte) error { 41 creds := []params.ApplicationMetricCredential{ 42 {service, credentials}, 43 } 44 p := params.ApplicationMetricCredentials{creds} 45 results := new(params.ErrorResults) 46 err := c.facade.FacadeCall("SetMetricCredentials", p, results) 47 if err != nil { 48 return errors.Trace(err) 49 } 50 return errors.Trace(results.OneError()) 51 } 52 53 // ModelUUID returns the model UUID from the client connection. 54 func (c *Client) ModelUUID() string { 55 tag, ok := c.st.ModelTag() 56 if !ok { 57 logger.Warningf("controller-only API connection has no model tag") 58 } 59 return tag.Id() 60 } 61 62 // DeployArgs holds the arguments to be sent to Client.ServiceDeploy. 63 type DeployArgs struct { 64 65 // CharmID identifies the charm to deploy. 66 CharmID charmstore.CharmID 67 68 // ApplicationName is the name to give the application. 69 ApplicationName string 70 71 // Series to be used for the machine. 72 Series string 73 74 // NumUnits is the number of units to deploy. 75 NumUnits int 76 77 // ConfigYAML is a string that overrides the default config.yml. 78 ConfigYAML string 79 80 // Cons contains constraints on where units of this application 81 // may be placed. 82 Cons constraints.Value 83 84 // Placement directives on where the machines for the unit must be 85 // created. 86 Placement []*instance.Placement 87 88 // Storage contains Constraints specifying how storage should be 89 // handled. 90 Storage map[string]storage.Constraints 91 92 // EndpointBindings 93 EndpointBindings map[string]string 94 95 // Collection of resource names for the application, with the 96 // value being the unique ID of a pre-uploaded resources in 97 // storage. 98 Resources map[string]string 99 } 100 101 // Deploy obtains the charm, either locally or from the charm store, and deploys 102 // it. Placement directives, if provided, specify the machine on which the charm 103 // is deployed. 104 func (c *Client) Deploy(args DeployArgs) error { 105 deployArgs := params.ApplicationsDeploy{ 106 Applications: []params.ApplicationDeploy{{ 107 ApplicationName: args.ApplicationName, 108 Series: args.Series, 109 CharmURL: args.CharmID.URL.String(), 110 Channel: string(args.CharmID.Channel), 111 NumUnits: args.NumUnits, 112 ConfigYAML: args.ConfigYAML, 113 Constraints: args.Cons, 114 Placement: args.Placement, 115 Storage: args.Storage, 116 EndpointBindings: args.EndpointBindings, 117 Resources: args.Resources, 118 }}, 119 } 120 var results params.ErrorResults 121 var err error 122 err = c.facade.FacadeCall("Deploy", deployArgs, &results) 123 if err != nil { 124 return errors.Trace(err) 125 } 126 return errors.Trace(results.OneError()) 127 } 128 129 // GetCharmURL returns the charm URL the given service is 130 // running at present. 131 func (c *Client) GetCharmURL(serviceName string) (*charm.URL, error) { 132 result := new(params.StringResult) 133 args := params.ApplicationGet{ApplicationName: serviceName} 134 err := c.facade.FacadeCall("GetCharmURL", args, result) 135 if err != nil { 136 return nil, errors.Trace(err) 137 } 138 if result.Error != nil { 139 return nil, errors.Trace(result.Error) 140 } 141 return charm.ParseURL(result.Result) 142 } 143 144 // SetCharmConfig holds the configuration for setting a new revision of a charm 145 // on a service. 146 type SetCharmConfig struct { 147 // ApplicationName is the name of the application to set the charm on. 148 ApplicationName string 149 150 // CharmID identifies the charm. 151 CharmID charmstore.CharmID 152 153 // ConfigSettings is the charm settings to set during the upgrade. 154 // This field is only understood by Application facade version 2 155 // and greater. 156 ConfigSettings map[string]string `json:"config-settings,omitempty"` 157 158 // ConfigSettingsYAML is the charm settings in YAML format to set 159 // during the upgrade. If this is non-empty, it will take precedence 160 // over ConfigSettings. This field is only understood by Application 161 // facade version 2 162 ConfigSettingsYAML string `json:"config-settings-yaml,omitempty"` 163 164 // ForceSeries forces the use of the charm even if it doesn't match the 165 // series of the unit. 166 ForceSeries bool 167 168 // ForceUnits forces the upgrade on units in an error state. 169 ForceUnits bool 170 171 // ResourceIDs is a map of resource names to resource IDs to activate during 172 // the upgrade. 173 ResourceIDs map[string]string 174 175 // StorageConstraints is a map of storage names to storage constraints to 176 // update during the upgrade. This field is only understood by Application 177 // facade version 2 and greater. 178 StorageConstraints map[string]storage.Constraints `json:"storage-constraints,omitempty"` 179 } 180 181 // SetCharm sets the charm for a given service. 182 func (c *Client) SetCharm(cfg SetCharmConfig) error { 183 var storageConstraints map[string]params.StorageConstraints 184 if len(cfg.StorageConstraints) > 0 { 185 storageConstraints = make(map[string]params.StorageConstraints) 186 for name, cons := range cfg.StorageConstraints { 187 size, count := cons.Size, cons.Count 188 var sizePtr, countPtr *uint64 189 if size > 0 { 190 sizePtr = &size 191 } 192 if count > 0 { 193 countPtr = &count 194 } 195 storageConstraints[name] = params.StorageConstraints{ 196 Pool: cons.Pool, 197 Size: sizePtr, 198 Count: countPtr, 199 } 200 } 201 } 202 args := params.ApplicationSetCharm{ 203 ApplicationName: cfg.ApplicationName, 204 CharmURL: cfg.CharmID.URL.String(), 205 Channel: string(cfg.CharmID.Channel), 206 ConfigSettings: cfg.ConfigSettings, 207 ConfigSettingsYAML: cfg.ConfigSettingsYAML, 208 ForceSeries: cfg.ForceSeries, 209 ForceUnits: cfg.ForceUnits, 210 ResourceIDs: cfg.ResourceIDs, 211 StorageConstraints: storageConstraints, 212 } 213 return c.facade.FacadeCall("SetCharm", args, nil) 214 } 215 216 // Update updates the application attributes, including charm URL, 217 // minimum number of units, settings and constraints. 218 func (c *Client) Update(args params.ApplicationUpdate) error { 219 return c.facade.FacadeCall("Update", args, nil) 220 } 221 222 // AddUnits adds a given number of units to an application using the specified 223 // placement directives to assign units to machines. 224 func (c *Client) AddUnits(application string, numUnits int, placement []*instance.Placement) ([]string, error) { 225 args := params.AddApplicationUnits{ 226 ApplicationName: application, 227 NumUnits: numUnits, 228 Placement: placement, 229 } 230 results := new(params.AddApplicationUnitsResults) 231 err := c.facade.FacadeCall("AddUnits", args, results) 232 return results.Units, err 233 } 234 235 // DestroyUnits decreases the number of units dedicated to an application. 236 func (c *Client) DestroyUnits(unitNames ...string) error { 237 params := params.DestroyApplicationUnits{unitNames} 238 return c.facade.FacadeCall("DestroyUnits", params, nil) 239 } 240 241 // Destroy destroys a given application. 242 func (c *Client) Destroy(application string) error { 243 params := params.ApplicationDestroy{ 244 ApplicationName: application, 245 } 246 return c.facade.FacadeCall("Destroy", params, nil) 247 } 248 249 // GetConstraints returns the constraints for the given application. 250 func (c *Client) GetConstraints(service string) (constraints.Value, error) { 251 results := new(params.GetConstraintsResults) 252 err := c.facade.FacadeCall("GetConstraints", params.GetApplicationConstraints{service}, results) 253 return results.Constraints, err 254 } 255 256 // SetConstraints specifies the constraints for the given application. 257 func (c *Client) SetConstraints(application string, constraints constraints.Value) error { 258 params := params.SetConstraints{ 259 ApplicationName: application, 260 Constraints: constraints, 261 } 262 return c.facade.FacadeCall("SetConstraints", params, nil) 263 } 264 265 // Expose changes the juju-managed firewall to expose any ports that 266 // were also explicitly marked by units as open. 267 func (c *Client) Expose(application string) error { 268 params := params.ApplicationExpose{ApplicationName: application} 269 return c.facade.FacadeCall("Expose", params, nil) 270 } 271 272 // Unexpose changes the juju-managed firewall to unexpose any ports that 273 // were also explicitly marked by units as open. 274 func (c *Client) Unexpose(application string) error { 275 params := params.ApplicationUnexpose{ApplicationName: application} 276 return c.facade.FacadeCall("Unexpose", params, nil) 277 } 278 279 // Get returns the configuration for the named application. 280 func (c *Client) Get(application string) (*params.ApplicationGetResults, error) { 281 var results params.ApplicationGetResults 282 params := params.ApplicationGet{ApplicationName: application} 283 err := c.facade.FacadeCall("Get", params, &results) 284 return &results, err 285 } 286 287 // Set sets configuration options on an application. 288 func (c *Client) Set(application string, options map[string]string) error { 289 p := params.ApplicationSet{ 290 ApplicationName: application, 291 Options: options, 292 } 293 return c.facade.FacadeCall("Set", p, nil) 294 } 295 296 // Unset resets configuration options on an application. 297 func (c *Client) Unset(application string, options []string) error { 298 p := params.ApplicationUnset{ 299 ApplicationName: application, 300 Options: options, 301 } 302 return c.facade.FacadeCall("Unset", p, nil) 303 } 304 305 // CharmRelations returns the application's charms relation names. 306 func (c *Client) CharmRelations(application string) ([]string, error) { 307 var results params.ApplicationCharmRelationsResults 308 params := params.ApplicationCharmRelations{ApplicationName: application} 309 err := c.facade.FacadeCall("CharmRelations", params, &results) 310 return results.CharmRelations, err 311 } 312 313 // AddRelation adds a relation between the specified endpoints and returns the relation info. 314 func (c *Client) AddRelation(endpoints ...string) (*params.AddRelationResults, error) { 315 var addRelRes params.AddRelationResults 316 params := params.AddRelation{Endpoints: endpoints} 317 err := c.facade.FacadeCall("AddRelation", params, &addRelRes) 318 return &addRelRes, err 319 } 320 321 // DestroyRelation removes the relation between the specified endpoints. 322 func (c *Client) DestroyRelation(endpoints ...string) error { 323 params := params.DestroyRelation{Endpoints: endpoints} 324 return c.facade.FacadeCall("DestroyRelation", params, nil) 325 }