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  }