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

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package firewaller
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/names.v2"
     9  
    10  	"github.com/juju/juju/api"
    11  	"github.com/juju/juju/api/base"
    12  	"github.com/juju/juju/api/common"
    13  	"github.com/juju/juju/api/common/cloudspec"
    14  	apiwatcher "github.com/juju/juju/api/watcher"
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/core/relation"
    17  	"github.com/juju/juju/core/watcher"
    18  	"gopkg.in/macaroon.v2-unstable"
    19  )
    20  
    21  const firewallerFacade = "Firewaller"
    22  
    23  // Client provides access to the Firewaller API facade.
    24  type Client struct {
    25  	facade base.FacadeCaller
    26  	*common.ModelWatcher
    27  	*cloudspec.CloudSpecAPI
    28  }
    29  
    30  // NewClient creates a new client-side Firewaller API facade.
    31  func NewClient(caller base.APICaller) (*Client, error) {
    32  	modelTag, isModel := caller.ModelTag()
    33  	if !isModel {
    34  		return nil, errors.New("expected model specific API connection")
    35  	}
    36  	facadeCaller := base.NewFacadeCaller(caller, firewallerFacade)
    37  	return &Client{
    38  		facade:       facadeCaller,
    39  		ModelWatcher: common.NewModelWatcher(facadeCaller),
    40  		CloudSpecAPI: cloudspec.NewCloudSpecAPI(facadeCaller, modelTag),
    41  	}, nil
    42  }
    43  
    44  // BestAPIVersion returns the API version that we were able to
    45  // determine is supported by both the client and the API Server.
    46  func (c *Client) BestAPIVersion() int {
    47  	return c.facade.BestAPIVersion()
    48  }
    49  
    50  // ModelTag returns the current model's tag.
    51  func (c *Client) ModelTag() (names.ModelTag, bool) {
    52  	return c.facade.RawAPICaller().ModelTag()
    53  }
    54  
    55  // life requests the life cycle of the given entity from the server.
    56  func (c *Client) life(tag names.Tag) (params.Life, error) {
    57  	return common.OneLife(c.facade, tag)
    58  }
    59  
    60  // Unit provides access to methods of a state.Unit through the facade.
    61  func (c *Client) Unit(tag names.UnitTag) (*Unit, error) {
    62  	life, err := c.life(tag)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	return &Unit{
    67  		tag:  tag,
    68  		life: life,
    69  		st:   c,
    70  	}, nil
    71  }
    72  
    73  // Machine provides access to methods of a state.Machine through the
    74  // facade.
    75  func (c *Client) Machine(tag names.MachineTag) (*Machine, error) {
    76  	life, err := c.life(tag)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	return &Machine{
    81  		tag:  tag,
    82  		life: life,
    83  		st:   c,
    84  	}, nil
    85  }
    86  
    87  // WatchModelMachines returns a StringsWatcher that notifies of
    88  // changes to the life cycles of the top level machines in the current
    89  // model.
    90  func (c *Client) WatchModelMachines() (watcher.StringsWatcher, error) {
    91  	var result params.StringsWatchResult
    92  	err := c.facade.FacadeCall("WatchModelMachines", nil, &result)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	if err := result.Error; err != nil {
    97  		return nil, result.Error
    98  	}
    99  	w := apiwatcher.NewStringsWatcher(c.facade.RawAPICaller(), result)
   100  	return w, nil
   101  }
   102  
   103  // WatchOpenedPorts returns a StringsWatcher that notifies of
   104  // changes to the opened ports for the current model.
   105  func (c *Client) WatchOpenedPorts() (watcher.StringsWatcher, error) {
   106  	modelTag, ok := c.ModelTag()
   107  	if !ok {
   108  		return nil, errors.New("API connection is controller-only (should never happen)")
   109  	}
   110  	var results params.StringsWatchResults
   111  	args := params.Entities{
   112  		Entities: []params.Entity{{Tag: modelTag.String()}},
   113  	}
   114  	if err := c.facade.FacadeCall("WatchOpenedPorts", args, &results); err != nil {
   115  		return nil, err
   116  	}
   117  	if len(results.Results) != 1 {
   118  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
   119  	}
   120  	result := results.Results[0]
   121  	if err := result.Error; err != nil {
   122  		return nil, result.Error
   123  	}
   124  	w := apiwatcher.NewStringsWatcher(c.facade.RawAPICaller(), result)
   125  	return w, nil
   126  }
   127  
   128  // Relation provides access to methods of a state.Relation through the
   129  // facade.
   130  func (c *Client) Relation(tag names.RelationTag) (*Relation, error) {
   131  	life, err := c.life(tag)
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  	return &Relation{
   136  		tag:  tag,
   137  		life: life,
   138  	}, nil
   139  }
   140  
   141  // WatchEgressAddressesForRelation returns a watcher that notifies when addresses,
   142  // from which connections will originate to the provider side of the relation, change.
   143  // Each event contains the entire set of addresses which the provider side is required
   144  // to allow for access from the other side of the relation.
   145  func (c *Client) WatchEgressAddressesForRelation(relationTag names.RelationTag) (watcher.StringsWatcher, error) {
   146  	args := params.Entities{[]params.Entity{{Tag: relationTag.String()}}}
   147  	var results params.StringsWatchResults
   148  	err := c.facade.FacadeCall("WatchEgressAddressesForRelations", args, &results)
   149  	if err != nil {
   150  		return nil, errors.Trace(err)
   151  	}
   152  	if len(results.Results) != 1 {
   153  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
   154  	}
   155  	result := results.Results[0]
   156  	if result.Error != nil {
   157  		return nil, result.Error
   158  	}
   159  	w := apiwatcher.NewStringsWatcher(c.facade.RawAPICaller(), result)
   160  	return w, nil
   161  }
   162  
   163  // WatchIngressAddressesForRelation returns a watcher that notifies when addresses,
   164  // from which connections will originate for the relation, change.
   165  // Each event contains the entire set of addresses which are required
   166  // for ingress into this model from the other requirer side of the relation.
   167  func (c *Client) WatchIngressAddressesForRelation(relationTag names.RelationTag) (watcher.StringsWatcher, error) {
   168  	args := params.Entities{[]params.Entity{{Tag: relationTag.String()}}}
   169  	var results params.StringsWatchResults
   170  	err := c.facade.FacadeCall("WatchIngressAddressesForRelations", args, &results)
   171  	if err != nil {
   172  		return nil, errors.Trace(err)
   173  	}
   174  	if len(results.Results) != 1 {
   175  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
   176  	}
   177  	result := results.Results[0]
   178  	if result.Error != nil {
   179  		return nil, result.Error
   180  	}
   181  	w := apiwatcher.NewStringsWatcher(c.facade.RawAPICaller(), result)
   182  	return w, nil
   183  }
   184  
   185  // ControllerAPIInfoForModels returns the controller api connection details for the specified model.
   186  func (c *Client) ControllerAPIInfoForModel(modelUUID string) (*api.Info, error) {
   187  	modelTag := names.NewModelTag(modelUUID)
   188  	args := params.Entities{[]params.Entity{{Tag: modelTag.String()}}}
   189  	var results params.ControllerAPIInfoResults
   190  	err := c.facade.FacadeCall("ControllerAPIInfoForModels", args, &results)
   191  	if err != nil {
   192  		return nil, errors.Trace(err)
   193  	}
   194  	if len(results.Results) != 1 {
   195  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
   196  	}
   197  	result := results.Results[0]
   198  	if result.Error != nil {
   199  		return nil, result.Error
   200  	}
   201  	return &api.Info{
   202  		Addrs:    result.Addresses,
   203  		CACert:   result.CACert,
   204  		ModelTag: modelTag,
   205  	}, nil
   206  }
   207  
   208  // MacaroonForRelation returns the macaroon to use when publishing changes for the relation.
   209  func (c *Client) MacaroonForRelation(relationKey string) (*macaroon.Macaroon, error) {
   210  	relationTag := names.NewRelationTag(relationKey)
   211  	args := params.Entities{[]params.Entity{{Tag: relationTag.String()}}}
   212  	var results params.MacaroonResults
   213  	err := c.facade.FacadeCall("MacaroonForRelations", args, &results)
   214  	if err != nil {
   215  		return nil, errors.Trace(err)
   216  	}
   217  	if len(results.Results) != 1 {
   218  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
   219  	}
   220  	result := results.Results[0]
   221  	if result.Error != nil {
   222  		return nil, result.Error
   223  	}
   224  	return result.Result, nil
   225  }
   226  
   227  // SetRelationStatus sets the status for a given relation.
   228  func (c *Client) SetRelationStatus(relationKey string, status relation.Status, message string) error {
   229  	relationTag := names.NewRelationTag(relationKey)
   230  	args := params.SetStatus{Entities: []params.EntityStatusArgs{
   231  		{Tag: relationTag.String(), Status: status.String(), Info: message},
   232  	}}
   233  
   234  	var results params.ErrorResults
   235  	err := c.facade.FacadeCall("SetRelationsStatus", args, &results)
   236  	if err != nil {
   237  		return errors.Trace(err)
   238  	}
   239  	return results.OneError()
   240  }
   241  
   242  // FirewallRules returns the firewall rules for the specified known service names.
   243  func (c *Client) FirewallRules(knownServices ...string) ([]params.FirewallRule, error) {
   244  	args := params.KnownServiceArgs{
   245  		KnownServices: make([]params.KnownServiceValue, len(knownServices)),
   246  	}
   247  	for i, s := range knownServices {
   248  		args.KnownServices[i] = params.KnownServiceValue(s)
   249  	}
   250  
   251  	var results params.ListFirewallRulesResults
   252  	err := c.facade.FacadeCall("FirewallRules", args, &results)
   253  	if err != nil {
   254  		return nil, errors.Trace(err)
   255  	}
   256  	return results.Rules, nil
   257  }