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  }