github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/api/charms/client.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // charms provides a client for accessing the charms API.
     5  package charms
     6  
     7  import (
     8  	"github.com/juju/errors"
     9  	"github.com/juju/version"
    10  	"gopkg.in/juju/charm.v6"
    11  	"gopkg.in/juju/charm.v6/resource"
    12  
    13  	"github.com/juju/juju/api/base"
    14  	"github.com/juju/juju/apiserver/params"
    15  )
    16  
    17  // Client allows access to the charms API end point.
    18  type Client struct {
    19  	base.ClientFacade
    20  	facade base.FacadeCaller
    21  }
    22  
    23  // NewClient creates a new client for accessing the charms API.
    24  func NewClient(st base.APICallCloser) *Client {
    25  	frontend, backend := base.NewClientFacade(st, "Charms")
    26  	return &Client{ClientFacade: frontend, facade: backend}
    27  }
    28  
    29  // IsMetered returns whether or not the charm is metered.
    30  func (c *Client) IsMetered(charmURL string) (bool, error) {
    31  	args := params.CharmURL{URL: charmURL}
    32  	var metered params.IsMeteredResult
    33  	if err := c.facade.FacadeCall("IsMetered", args, &metered); err != nil {
    34  		return false, errors.Trace(err)
    35  	}
    36  	return metered.Metered, nil
    37  }
    38  
    39  // CharmInfo holds information about a charm.
    40  type CharmInfo struct {
    41  	Revision   int
    42  	URL        string
    43  	Config     *charm.Config
    44  	Meta       *charm.Meta
    45  	Actions    *charm.Actions
    46  	Metrics    *charm.Metrics
    47  	LXDProfile *charm.LXDProfile
    48  }
    49  
    50  // CharmInfo returns information about the requested charm.
    51  func (c *Client) CharmInfo(charmURL string) (*CharmInfo, error) {
    52  	args := params.CharmURL{URL: charmURL}
    53  	var info params.CharmInfo
    54  	if err := c.facade.FacadeCall("CharmInfo", args, &info); err != nil {
    55  		return nil, errors.Trace(err)
    56  	}
    57  	meta, err := convertCharmMeta(info.Meta)
    58  	if err != nil {
    59  		return nil, errors.Trace(err)
    60  	}
    61  	result := &CharmInfo{
    62  		Revision:   info.Revision,
    63  		URL:        info.URL,
    64  		Config:     convertCharmConfig(info.Config),
    65  		Meta:       meta,
    66  		Actions:    convertCharmActions(info.Actions),
    67  		Metrics:    convertCharmMetrics(info.Metrics),
    68  		LXDProfile: convertCharmLXDProfile(info.LXDProfile),
    69  	}
    70  	return result, nil
    71  }
    72  
    73  func convertCharmConfig(config map[string]params.CharmOption) *charm.Config {
    74  	if len(config) == 0 {
    75  		return nil
    76  	}
    77  	result := &charm.Config{
    78  		Options: make(map[string]charm.Option),
    79  	}
    80  	for key, value := range config {
    81  		result.Options[key] = convertCharmOption(value)
    82  	}
    83  	return result
    84  }
    85  
    86  func convertCharmOption(opt params.CharmOption) charm.Option {
    87  	return charm.Option{
    88  		Type:        opt.Type,
    89  		Description: opt.Description,
    90  		Default:     opt.Default,
    91  	}
    92  }
    93  
    94  func convertCharmMeta(meta *params.CharmMeta) (*charm.Meta, error) {
    95  	if meta == nil {
    96  		return nil, nil
    97  	}
    98  	minVersion, err := version.Parse(meta.MinJujuVersion)
    99  	if err != nil {
   100  		return nil, errors.Trace(err)
   101  	}
   102  	resources, err := convertCharmResourceMetaMap(meta.Resources)
   103  	if err != nil {
   104  		return nil, errors.Trace(err)
   105  	}
   106  	result := &charm.Meta{
   107  		Name:           meta.Name,
   108  		Summary:        meta.Summary,
   109  		Description:    meta.Description,
   110  		Subordinate:    meta.Subordinate,
   111  		Provides:       convertCharmRelationMap(meta.Provides),
   112  		Requires:       convertCharmRelationMap(meta.Requires),
   113  		Peers:          convertCharmRelationMap(meta.Peers),
   114  		ExtraBindings:  convertCharmExtraBindingMap(meta.ExtraBindings),
   115  		Categories:     meta.Categories,
   116  		Tags:           meta.Tags,
   117  		Series:         meta.Series,
   118  		Storage:        convertCharmStorageMap(meta.Storage),
   119  		PayloadClasses: convertCharmPayloadClassMap(meta.PayloadClasses),
   120  		Resources:      resources,
   121  		Terms:          meta.Terms,
   122  		MinJujuVersion: minVersion,
   123  	}
   124  	return result, nil
   125  }
   126  
   127  func convertCharmRelationMap(relations map[string]params.CharmRelation) map[string]charm.Relation {
   128  	if len(relations) == 0 {
   129  		return nil
   130  	}
   131  	result := make(map[string]charm.Relation)
   132  	for key, value := range relations {
   133  		result[key] = convertCharmRelation(value)
   134  	}
   135  	return result
   136  }
   137  
   138  func convertCharmRelation(relation params.CharmRelation) charm.Relation {
   139  	return charm.Relation{
   140  		Name:      relation.Name,
   141  		Role:      charm.RelationRole(relation.Role),
   142  		Interface: relation.Interface,
   143  		Optional:  relation.Optional,
   144  		Limit:     relation.Limit,
   145  		Scope:     charm.RelationScope(relation.Scope),
   146  	}
   147  }
   148  
   149  func convertCharmStorageMap(storage map[string]params.CharmStorage) map[string]charm.Storage {
   150  	if len(storage) == 0 {
   151  		return nil
   152  	}
   153  	result := make(map[string]charm.Storage)
   154  	for key, value := range storage {
   155  		result[key] = convertCharmStorage(value)
   156  	}
   157  	return result
   158  }
   159  
   160  func convertCharmStorage(storage params.CharmStorage) charm.Storage {
   161  	return charm.Storage{
   162  		Name:        storage.Name,
   163  		Description: storage.Description,
   164  		Type:        charm.StorageType(storage.Type),
   165  		Shared:      storage.Shared,
   166  		ReadOnly:    storage.ReadOnly,
   167  		CountMin:    storage.CountMin,
   168  		CountMax:    storage.CountMax,
   169  		MinimumSize: storage.MinimumSize,
   170  		Location:    storage.Location,
   171  		Properties:  storage.Properties,
   172  	}
   173  }
   174  
   175  func convertCharmPayloadClassMap(payload map[string]params.CharmPayloadClass) map[string]charm.PayloadClass {
   176  	if len(payload) == 0 {
   177  		return nil
   178  	}
   179  	result := make(map[string]charm.PayloadClass)
   180  	for key, value := range payload {
   181  		result[key] = convertCharmPayloadClass(value)
   182  	}
   183  	return result
   184  }
   185  
   186  func convertCharmPayloadClass(payload params.CharmPayloadClass) charm.PayloadClass {
   187  	return charm.PayloadClass{
   188  		Name: payload.Name,
   189  		Type: payload.Type,
   190  	}
   191  }
   192  
   193  func convertCharmResourceMetaMap(resources map[string]params.CharmResourceMeta) (map[string]resource.Meta, error) {
   194  	if len(resources) == 0 {
   195  		return nil, nil
   196  	}
   197  	result := make(map[string]resource.Meta)
   198  	for key, value := range resources {
   199  		converted, err := convertCharmResourceMeta(value)
   200  		if err != nil {
   201  			return nil, errors.Trace(err)
   202  		}
   203  		result[key] = converted
   204  	}
   205  	return result, nil
   206  }
   207  
   208  func convertCharmResourceMeta(meta params.CharmResourceMeta) (resource.Meta, error) {
   209  	resourceType, err := resource.ParseType(meta.Type)
   210  	if err != nil {
   211  		return resource.Meta{}, errors.Trace(err)
   212  	}
   213  	return resource.Meta{
   214  		Name:        meta.Name,
   215  		Type:        resourceType,
   216  		Path:        meta.Path,
   217  		Description: meta.Description,
   218  	}, nil
   219  }
   220  
   221  func convertCharmActions(actions *params.CharmActions) *charm.Actions {
   222  	if actions == nil {
   223  		return nil
   224  	}
   225  	return &charm.Actions{
   226  		ActionSpecs: convertCharmActionSpecMap(actions.ActionSpecs),
   227  	}
   228  }
   229  
   230  func convertCharmActionSpecMap(specs map[string]params.CharmActionSpec) map[string]charm.ActionSpec {
   231  	if len(specs) == 0 {
   232  		return nil
   233  	}
   234  	result := make(map[string]charm.ActionSpec)
   235  	for key, value := range specs {
   236  		result[key] = convertCharmActionSpec(value)
   237  	}
   238  	return result
   239  }
   240  
   241  func convertCharmActionSpec(spec params.CharmActionSpec) charm.ActionSpec {
   242  	return charm.ActionSpec{
   243  		Description: spec.Description,
   244  		Params:      spec.Params,
   245  	}
   246  }
   247  
   248  func convertCharmMetrics(metrics *params.CharmMetrics) *charm.Metrics {
   249  	if metrics == nil {
   250  		return nil
   251  	}
   252  	return &charm.Metrics{
   253  		Metrics: convertCharmMetricMap(metrics.Metrics),
   254  		Plan:    convertCharmPlan(metrics.Plan),
   255  	}
   256  }
   257  
   258  func convertCharmPlan(plan params.CharmPlan) *charm.Plan {
   259  	return &charm.Plan{Required: plan.Required}
   260  }
   261  
   262  func convertCharmMetricMap(metrics map[string]params.CharmMetric) map[string]charm.Metric {
   263  	if len(metrics) == 0 {
   264  		return nil
   265  	}
   266  	result := make(map[string]charm.Metric)
   267  	for key, value := range metrics {
   268  		result[key] = convertCharmMetric(value)
   269  	}
   270  	return result
   271  }
   272  
   273  func convertCharmMetric(metric params.CharmMetric) charm.Metric {
   274  	return charm.Metric{
   275  		Type:        charm.MetricType(metric.Type),
   276  		Description: metric.Description,
   277  	}
   278  }
   279  
   280  func convertCharmExtraBindingMap(bindings map[string]string) map[string]charm.ExtraBinding {
   281  	if len(bindings) == 0 {
   282  		return nil
   283  	}
   284  	result := make(map[string]charm.ExtraBinding)
   285  	for key, value := range bindings {
   286  		result[key] = charm.ExtraBinding{value}
   287  	}
   288  	return result
   289  }
   290  
   291  func convertCharmLXDProfile(lxdProfile *params.CharmLXDProfile) *charm.LXDProfile {
   292  	if lxdProfile == nil {
   293  		return nil
   294  	}
   295  	return &charm.LXDProfile{
   296  		Description: lxdProfile.Description,
   297  		Config:      convertCharmLXDProfileConfigMap(lxdProfile.Config),
   298  		Devices:     convertCharmLXDProfileDevicesMap(lxdProfile.Devices),
   299  	}
   300  }
   301  
   302  func convertCharmLXDProfileConfigMap(config map[string]string) map[string]string {
   303  	result := make(map[string]string, len(config))
   304  	for k, v := range config {
   305  		result[k] = v
   306  	}
   307  	return result
   308  }
   309  
   310  func convertCharmLXDProfileDevicesMap(devices map[string]map[string]string) map[string]map[string]string {
   311  	result := make(map[string]map[string]string, len(devices))
   312  	for k, v := range devices {
   313  		nested := make(map[string]string, len(v))
   314  		for nk, nv := range v {
   315  			nested[nk] = nv
   316  		}
   317  		result[k] = nested
   318  	}
   319  	return result
   320  }