github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/api/service/client.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // Package service provides access to the service api facade. 5 // This facade contains api calls that are specific to services. 6 // As a rule of thumb, if the argument for an api requries a service name 7 // and affects only that service then the call belongs here. 8 package service 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.service") 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 service api. 34 func NewClient(st api.Connection) *Client { 35 frontend, backend := base.NewClientFacade(st, "Service") 36 return &Client{ClientFacade: frontend, st: st, facade: backend} 37 } 38 39 // SetMetricCredentials sets the metric credentials for the service specified. 40 func (c *Client) SetMetricCredentials(service string, credentials []byte) error { 41 creds := []params.ServiceMetricCredential{ 42 {service, credentials}, 43 } 44 p := params.ServiceMetricCredentials{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, err := c.st.ModelTag() 56 if err != nil { 57 logger.Warningf("model tag not an model: %v", err) 58 return "" 59 } 60 return tag.Id() 61 } 62 63 // DeployArgs holds the arguments to be sent to Client.ServiceDeploy. 64 type DeployArgs struct { 65 // CharmID identifies the charm to deploy. 66 CharmID charmstore.CharmID 67 // ServiceName is the name to give the service. 68 ServiceName string 69 // Series to be used for the machine. 70 Series string 71 // NumUnits is the number of units to deploy. 72 NumUnits int 73 // ConfigYAML is a string that overrides the default config.yml. 74 ConfigYAML string 75 // Cons contains constraints on where units of this service may be 76 // placed. 77 Cons constraints.Value 78 // Placement directives on where the machines for the unit must be 79 // created. 80 Placement []*instance.Placement 81 // Storage contains Constraints specifying how storage should be 82 // handled. 83 Storage map[string]storage.Constraints 84 // EndpointBindings 85 EndpointBindings map[string]string 86 // Collection of resource names for the service, with the value being the 87 // unique ID of a pre-uploaded resources in storage. 88 Resources map[string]string 89 } 90 91 // Deploy obtains the charm, either locally or from the charm store, and deploys 92 // it. Placement directives, if provided, specify the machine on which the charm 93 // is deployed. 94 func (c *Client) Deploy(args DeployArgs) error { 95 deployArgs := params.ServicesDeploy{ 96 Services: []params.ServiceDeploy{{ 97 ServiceName: args.ServiceName, 98 Series: args.Series, 99 CharmUrl: args.CharmID.URL.String(), 100 Channel: string(args.CharmID.Channel), 101 NumUnits: args.NumUnits, 102 ConfigYAML: args.ConfigYAML, 103 Constraints: args.Cons, 104 Placement: args.Placement, 105 Storage: args.Storage, 106 EndpointBindings: args.EndpointBindings, 107 Resources: args.Resources, 108 }}, 109 } 110 var results params.ErrorResults 111 var err error 112 err = c.facade.FacadeCall("Deploy", deployArgs, &results) 113 if err != nil { 114 return err 115 } 116 return results.OneError() 117 } 118 119 // GetCharmURL returns the charm URL the given service is 120 // running at present. 121 func (c *Client) GetCharmURL(serviceName string) (*charm.URL, error) { 122 result := new(params.StringResult) 123 args := params.ServiceGet{ServiceName: serviceName} 124 err := c.facade.FacadeCall("GetCharmURL", args, result) 125 if err != nil { 126 return nil, err 127 } 128 if result.Error != nil { 129 return nil, result.Error 130 } 131 return charm.ParseURL(result.Result) 132 } 133 134 // SetCharmConfig holds the configuration for setting a new revision of a charm 135 // on a service. 136 type SetCharmConfig struct { 137 // ServiceName is the name of the service to set the charm on. 138 ServiceName string 139 // CharmID identifies the charm. 140 CharmID charmstore.CharmID 141 // ForceSeries forces the use of the charm even if it doesn't match the 142 // series of the unit. 143 ForceSeries bool 144 // ForceUnits forces the upgrade on units in an error state. 145 ForceUnits bool 146 // ResourceIDs is a map of resource names to resource IDs to activate during 147 // the upgrade. 148 ResourceIDs map[string]string 149 } 150 151 // SetCharm sets the charm for a given service. 152 func (c *Client) SetCharm(cfg SetCharmConfig) error { 153 args := params.ServiceSetCharm{ 154 ServiceName: cfg.ServiceName, 155 CharmUrl: cfg.CharmID.URL.String(), 156 Channel: string(cfg.CharmID.Channel), 157 ForceSeries: cfg.ForceSeries, 158 ForceUnits: cfg.ForceUnits, 159 ResourceIDs: cfg.ResourceIDs, 160 } 161 return c.facade.FacadeCall("SetCharm", args, nil) 162 } 163 164 // Update updates the service attributes, including charm URL, 165 // minimum number of units, settings and constraints. 166 func (c *Client) Update(args params.ServiceUpdate) error { 167 return c.facade.FacadeCall("Update", args, nil) 168 } 169 170 // AddUnits adds a given number of units to a service using the specified 171 // placement directives to assign units to machines. 172 func (c *Client) AddUnits(service string, numUnits int, placement []*instance.Placement) ([]string, error) { 173 args := params.AddServiceUnits{ 174 ServiceName: service, 175 NumUnits: numUnits, 176 Placement: placement, 177 } 178 results := new(params.AddServiceUnitsResults) 179 err := c.facade.FacadeCall("AddUnits", args, results) 180 return results.Units, err 181 } 182 183 // DestroyUnits decreases the number of units dedicated to a service. 184 func (c *Client) DestroyUnits(unitNames ...string) error { 185 params := params.DestroyServiceUnits{unitNames} 186 return c.facade.FacadeCall("DestroyUnits", params, nil) 187 } 188 189 // Destroy destroys a given service. 190 func (c *Client) Destroy(service string) error { 191 params := params.ServiceDestroy{ 192 ServiceName: service, 193 } 194 return c.facade.FacadeCall("Destroy", params, nil) 195 } 196 197 // GetConstraints returns the constraints for the given service. 198 func (c *Client) GetConstraints(service string) (constraints.Value, error) { 199 results := new(params.GetConstraintsResults) 200 err := c.facade.FacadeCall("GetConstraints", params.GetServiceConstraints{service}, results) 201 return results.Constraints, err 202 } 203 204 // SetConstraints specifies the constraints for the given service. 205 func (c *Client) SetConstraints(service string, constraints constraints.Value) error { 206 params := params.SetConstraints{ 207 ServiceName: service, 208 Constraints: constraints, 209 } 210 return c.facade.FacadeCall("SetConstraints", params, nil) 211 } 212 213 // Expose changes the juju-managed firewall to expose any ports that 214 // were also explicitly marked by units as open. 215 func (c *Client) Expose(service string) error { 216 params := params.ServiceExpose{ServiceName: service} 217 return c.facade.FacadeCall("Expose", params, nil) 218 } 219 220 // Unexpose changes the juju-managed firewall to unexpose any ports that 221 // were also explicitly marked by units as open. 222 func (c *Client) Unexpose(service string) error { 223 params := params.ServiceUnexpose{ServiceName: service} 224 return c.facade.FacadeCall("Unexpose", params, nil) 225 } 226 227 // Get returns the configuration for the named service. 228 func (c *Client) Get(service string) (*params.ServiceGetResults, error) { 229 var results params.ServiceGetResults 230 params := params.ServiceGet{ServiceName: service} 231 err := c.facade.FacadeCall("Get", params, &results) 232 return &results, err 233 } 234 235 // Set sets configuration options on a service. 236 func (c *Client) Set(service string, options map[string]string) error { 237 p := params.ServiceSet{ 238 ServiceName: service, 239 Options: options, 240 } 241 return c.facade.FacadeCall("Set", p, nil) 242 } 243 244 // Unset resets configuration options on a service. 245 func (c *Client) Unset(service string, options []string) error { 246 p := params.ServiceUnset{ 247 ServiceName: service, 248 Options: options, 249 } 250 return c.facade.FacadeCall("Unset", p, nil) 251 } 252 253 // CharmRelations returns the service's charms relation names. 254 func (c *Client) CharmRelations(service string) ([]string, error) { 255 var results params.ServiceCharmRelationsResults 256 params := params.ServiceCharmRelations{ServiceName: service} 257 err := c.facade.FacadeCall("CharmRelations", params, &results) 258 return results.CharmRelations, err 259 } 260 261 // AddRelation adds a relation between the specified endpoints and returns the relation info. 262 func (c *Client) AddRelation(endpoints ...string) (*params.AddRelationResults, error) { 263 var addRelRes params.AddRelationResults 264 params := params.AddRelation{Endpoints: endpoints} 265 err := c.facade.FacadeCall("AddRelation", params, &addRelRes) 266 return &addRelRes, err 267 } 268 269 // DestroyRelation removes the relation between the specified endpoints. 270 func (c *Client) DestroyRelation(endpoints ...string) error { 271 params := params.DestroyRelation{Endpoints: endpoints} 272 return c.facade.FacadeCall("DestroyRelation", params, nil) 273 }