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

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package firewaller
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"gopkg.in/juju/names.v2"
    10  
    11  	apiwatcher "github.com/juju/juju/api/watcher"
    12  	"github.com/juju/juju/apiserver/params"
    13  	"github.com/juju/juju/core/instance"
    14  	"github.com/juju/juju/core/network"
    15  	"github.com/juju/juju/core/watcher"
    16  )
    17  
    18  // Machine represents a juju machine as seen by the firewaller worker.
    19  type Machine struct {
    20  	st   *Client
    21  	tag  names.MachineTag
    22  	life params.Life
    23  }
    24  
    25  // Tag returns the machine tag.
    26  func (m *Machine) Tag() names.MachineTag {
    27  	return m.tag
    28  }
    29  
    30  // WatchUnits starts a StringsWatcher to watch all units assigned to
    31  // the machine.
    32  func (m *Machine) WatchUnits() (watcher.StringsWatcher, error) {
    33  	var results params.StringsWatchResults
    34  	args := params.Entities{
    35  		Entities: []params.Entity{{Tag: m.tag.String()}},
    36  	}
    37  	err := m.st.facade.FacadeCall("WatchUnits", args, &results)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	if len(results.Results) != 1 {
    42  		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
    43  	}
    44  	result := results.Results[0]
    45  	if result.Error != nil {
    46  		return nil, result.Error
    47  	}
    48  	w := apiwatcher.NewStringsWatcher(m.st.facade.RawAPICaller(), result)
    49  	return w, nil
    50  }
    51  
    52  // InstanceId returns the provider specific instance id for this
    53  // machine, or a CodeNotProvisioned error, if not set.
    54  func (m *Machine) InstanceId() (instance.Id, error) {
    55  	var results params.StringResults
    56  	args := params.Entities{
    57  		Entities: []params.Entity{{Tag: m.tag.String()}},
    58  	}
    59  	err := m.st.facade.FacadeCall("InstanceId", args, &results)
    60  	if err != nil {
    61  		return "", err
    62  	}
    63  	if len(results.Results) != 1 {
    64  		return "", fmt.Errorf("expected 1 result, got %d", len(results.Results))
    65  	}
    66  	result := results.Results[0]
    67  	if result.Error != nil {
    68  		return "", result.Error
    69  	}
    70  	return instance.Id(result.Result), nil
    71  }
    72  
    73  // Life returns the machine's life cycle value.
    74  func (m *Machine) Life() params.Life {
    75  	return m.life
    76  }
    77  
    78  // ActiveSubnets returns a list of subnet tags for which the machine has opened
    79  // ports.
    80  func (m *Machine) ActiveSubnets() ([]names.SubnetTag, error) {
    81  	var results params.StringsResults
    82  	args := params.Entities{
    83  		Entities: []params.Entity{{Tag: m.tag.String()}},
    84  	}
    85  	err := m.st.facade.FacadeCall("GetMachineActiveSubnets", args, &results)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	if len(results.Results) != 1 {
    90  		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
    91  	}
    92  	result := results.Results[0]
    93  	if result.Error != nil {
    94  		return nil, result.Error
    95  	}
    96  	// Convert string tags to names.SubnetTag before returning.
    97  	tags := make([]names.SubnetTag, len(result.Result))
    98  	for i, tag := range result.Result {
    99  		var subnetTag names.SubnetTag
   100  		if tag != "" {
   101  			subnetTag, err = names.ParseSubnetTag(tag)
   102  			if err != nil {
   103  				return nil, err
   104  			}
   105  		}
   106  		tags[i] = subnetTag
   107  	}
   108  	return tags, nil
   109  }
   110  
   111  // OpenedPorts returns a map of network.PortRange to unit tag for all opened
   112  // port ranges on the machine for the subnet matching given subnetTag.
   113  func (m *Machine) OpenedPorts(subnetTag names.SubnetTag) (map[network.PortRange]names.UnitTag, error) {
   114  	var results params.MachinePortsResults
   115  	var subnetTagAsString string
   116  	if subnetTag.Id() != "" {
   117  		subnetTagAsString = subnetTag.String()
   118  	}
   119  	args := params.MachinePortsParams{
   120  		Params: []params.MachinePorts{
   121  			{MachineTag: m.tag.String(), SubnetTag: subnetTagAsString},
   122  		},
   123  	}
   124  	err := m.st.facade.FacadeCall("GetMachinePorts", args, &results)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	if len(results.Results) != 1 {
   129  		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
   130  	}
   131  	result := results.Results[0]
   132  	if result.Error != nil {
   133  		return nil, result.Error
   134  	}
   135  	// Convert string tags to names.UnitTag before returning.
   136  	endResult := make(map[network.PortRange]names.UnitTag)
   137  	for _, ports := range result.Ports {
   138  		unitTag, err := names.ParseUnitTag(ports.UnitTag)
   139  		if err != nil {
   140  			return nil, err
   141  		}
   142  		endResult[ports.PortRange.NetworkPortRange()] = unitTag
   143  	}
   144  	return endResult, nil
   145  }
   146  
   147  // IsManual returns true if the machine was manually provisioned.
   148  func (m *Machine) IsManual() (bool, error) {
   149  	var results params.BoolResults
   150  	args := params.Entities{
   151  		Entities: []params.Entity{{Tag: m.tag.String()}},
   152  	}
   153  	err := m.st.facade.FacadeCall("AreManuallyProvisioned", args, &results)
   154  	if err != nil {
   155  		return false, err
   156  	}
   157  	if len(results.Results) != 1 {
   158  		return false, fmt.Errorf("expected 1 result, got %d", len(results.Results))
   159  	}
   160  	result := results.Results[0]
   161  	if result.Error != nil {
   162  		return false, result.Error
   163  	}
   164  	return result.Result, nil
   165  }