github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 // CharmID identifies the charm to deploy. 65 CharmID charmstore.CharmID 66 // ApplicationName is the name to give the application. 67 ApplicationName string 68 // Series to be used for the machine. 69 Series string 70 // NumUnits is the number of units to deploy. 71 NumUnits int 72 // ConfigYAML is a string that overrides the default config.yml. 73 ConfigYAML string 74 // Cons contains constraints on where units of this application may be 75 // placed. 76 Cons constraints.Value 77 // Placement directives on where the machines for the unit must be 78 // created. 79 Placement []*instance.Placement 80 // Storage contains Constraints specifying how storage should be 81 // handled. 82 Storage map[string]storage.Constraints 83 // EndpointBindings 84 EndpointBindings map[string]string 85 // Collection of resource names for the application, with the value being the 86 // unique ID of a pre-uploaded resources in storage. 87 Resources map[string]string 88 } 89 90 // Deploy obtains the charm, either locally or from the charm store, and deploys 91 // it. Placement directives, if provided, specify the machine on which the charm 92 // is deployed. 93 func (c *Client) Deploy(args DeployArgs) error { 94 deployArgs := params.ApplicationsDeploy{ 95 Applications: []params.ApplicationDeploy{{ 96 ApplicationName: args.ApplicationName, 97 Series: args.Series, 98 CharmURL: args.CharmID.URL.String(), 99 Channel: string(args.CharmID.Channel), 100 NumUnits: args.NumUnits, 101 ConfigYAML: args.ConfigYAML, 102 Constraints: args.Cons, 103 Placement: args.Placement, 104 Storage: args.Storage, 105 EndpointBindings: args.EndpointBindings, 106 Resources: args.Resources, 107 }}, 108 } 109 var results params.ErrorResults 110 var err error 111 err = c.facade.FacadeCall("Deploy", deployArgs, &results) 112 if err != nil { 113 return err 114 } 115 return results.OneError() 116 } 117 118 // GetCharmURL returns the charm URL the given service is 119 // running at present. 120 func (c *Client) GetCharmURL(serviceName string) (*charm.URL, error) { 121 result := new(params.StringResult) 122 args := params.ApplicationGet{ApplicationName: serviceName} 123 err := c.facade.FacadeCall("GetCharmURL", args, result) 124 if err != nil { 125 return nil, err 126 } 127 if result.Error != nil { 128 return nil, result.Error 129 } 130 return charm.ParseURL(result.Result) 131 } 132 133 // SetCharmConfig holds the configuration for setting a new revision of a charm 134 // on a service. 135 type SetCharmConfig struct { 136 // ApplicationName is the name of the application to set the charm on. 137 ApplicationName string 138 139 // CharmID identifies the charm. 140 CharmID charmstore.CharmID 141 142 // ConfigSettings is the charm settings to set during the upgrade. 143 // This field is only understood by Application facade version 2 144 // and greater. 145 ConfigSettings map[string]string `json:"config-settings,omitempty"` 146 147 // ConfigSettingsYAML is the charm settings in YAML format to set 148 // during the upgrade. If this is non-empty, it will take precedence 149 // over ConfigSettings. This field is only understood by Application 150 // facade version 2 151 ConfigSettingsYAML string `json:"config-settings-yaml,omitempty"` 152 153 // ForceSeries forces the use of the charm even if it doesn't match the 154 // series of the unit. 155 ForceSeries bool 156 157 // ForceUnits forces the upgrade on units in an error state. 158 ForceUnits bool 159 160 // ResourceIDs is a map of resource names to resource IDs to activate during 161 // the upgrade. 162 ResourceIDs map[string]string 163 164 // StorageConstraints is a map of storage names to storage constraints to 165 // update during the upgrade. This field is only understood by Application 166 // facade version 2 and greater. 167 StorageConstraints map[string]storage.Constraints `json:"storage-constraints,omitempty"` 168 } 169 170 // SetCharm sets the charm for a given service. 171 func (c *Client) SetCharm(cfg SetCharmConfig) error { 172 var storageConstraints map[string]params.StorageConstraints 173 if len(cfg.StorageConstraints) > 0 { 174 storageConstraints = make(map[string]params.StorageConstraints) 175 for name, cons := range cfg.StorageConstraints { 176 size, count := cons.Size, cons.Count 177 var sizePtr, countPtr *uint64 178 if size > 0 { 179 sizePtr = &size 180 } 181 if count > 0 { 182 countPtr = &count 183 } 184 storageConstraints[name] = params.StorageConstraints{ 185 Pool: cons.Pool, 186 Size: sizePtr, 187 Count: countPtr, 188 } 189 } 190 } 191 args := params.ApplicationSetCharm{ 192 ApplicationName: cfg.ApplicationName, 193 CharmURL: cfg.CharmID.URL.String(), 194 Channel: string(cfg.CharmID.Channel), 195 ConfigSettings: cfg.ConfigSettings, 196 ConfigSettingsYAML: cfg.ConfigSettingsYAML, 197 ForceSeries: cfg.ForceSeries, 198 ForceUnits: cfg.ForceUnits, 199 ResourceIDs: cfg.ResourceIDs, 200 StorageConstraints: storageConstraints, 201 } 202 return c.facade.FacadeCall("SetCharm", args, nil) 203 } 204 205 // Update updates the application attributes, including charm URL, 206 // minimum number of units, settings and constraints. 207 func (c *Client) Update(args params.ApplicationUpdate) error { 208 return c.facade.FacadeCall("Update", args, nil) 209 } 210 211 // AddUnits adds a given number of units to an application using the specified 212 // placement directives to assign units to machines. 213 func (c *Client) AddUnits(application string, numUnits int, placement []*instance.Placement) ([]string, error) { 214 args := params.AddApplicationUnits{ 215 ApplicationName: application, 216 NumUnits: numUnits, 217 Placement: placement, 218 } 219 results := new(params.AddApplicationUnitsResults) 220 err := c.facade.FacadeCall("AddUnits", args, results) 221 return results.Units, err 222 } 223 224 // DestroyUnits decreases the number of units dedicated to an application. 225 func (c *Client) DestroyUnits(unitNames ...string) error { 226 params := params.DestroyApplicationUnits{unitNames} 227 return c.facade.FacadeCall("DestroyUnits", params, nil) 228 } 229 230 // Destroy destroys a given application. 231 func (c *Client) Destroy(application string) error { 232 params := params.ApplicationDestroy{ 233 ApplicationName: application, 234 } 235 return c.facade.FacadeCall("Destroy", params, nil) 236 } 237 238 // GetConstraints returns the constraints for the given application. 239 func (c *Client) GetConstraints(service string) (constraints.Value, error) { 240 results := new(params.GetConstraintsResults) 241 err := c.facade.FacadeCall("GetConstraints", params.GetApplicationConstraints{service}, results) 242 return results.Constraints, err 243 } 244 245 // SetConstraints specifies the constraints for the given application. 246 func (c *Client) SetConstraints(application string, constraints constraints.Value) error { 247 params := params.SetConstraints{ 248 ApplicationName: application, 249 Constraints: constraints, 250 } 251 return c.facade.FacadeCall("SetConstraints", params, nil) 252 } 253 254 // Expose changes the juju-managed firewall to expose any ports that 255 // were also explicitly marked by units as open. 256 func (c *Client) Expose(application string) error { 257 params := params.ApplicationExpose{ApplicationName: application} 258 return c.facade.FacadeCall("Expose", params, nil) 259 } 260 261 // Unexpose changes the juju-managed firewall to unexpose any ports that 262 // were also explicitly marked by units as open. 263 func (c *Client) Unexpose(application string) error { 264 params := params.ApplicationUnexpose{ApplicationName: application} 265 return c.facade.FacadeCall("Unexpose", params, nil) 266 } 267 268 // Get returns the configuration for the named application. 269 func (c *Client) Get(application string) (*params.ApplicationGetResults, error) { 270 var results params.ApplicationGetResults 271 params := params.ApplicationGet{ApplicationName: application} 272 err := c.facade.FacadeCall("Get", params, &results) 273 return &results, err 274 } 275 276 // Set sets configuration options on an application. 277 func (c *Client) Set(application string, options map[string]string) error { 278 p := params.ApplicationSet{ 279 ApplicationName: application, 280 Options: options, 281 } 282 return c.facade.FacadeCall("Set", p, nil) 283 } 284 285 // Unset resets configuration options on an application. 286 func (c *Client) Unset(application string, options []string) error { 287 p := params.ApplicationUnset{ 288 ApplicationName: application, 289 Options: options, 290 } 291 return c.facade.FacadeCall("Unset", p, nil) 292 } 293 294 // CharmRelations returns the application's charms relation names. 295 func (c *Client) CharmRelations(application string) ([]string, error) { 296 var results params.ApplicationCharmRelationsResults 297 params := params.ApplicationCharmRelations{ApplicationName: application} 298 err := c.facade.FacadeCall("CharmRelations", params, &results) 299 return results.CharmRelations, err 300 } 301 302 // AddRelation adds a relation between the specified endpoints and returns the relation info. 303 func (c *Client) AddRelation(endpoints ...string) (*params.AddRelationResults, error) { 304 var addRelRes params.AddRelationResults 305 params := params.AddRelation{Endpoints: endpoints} 306 err := c.facade.FacadeCall("AddRelation", params, &addRelRes) 307 return &addRelRes, err 308 } 309 310 // DestroyRelation removes the relation between the specified endpoints. 311 func (c *Client) DestroyRelation(endpoints ...string) error { 312 params := params.DestroyRelation{Endpoints: endpoints} 313 return c.facade.FacadeCall("DestroyRelation", params, nil) 314 }