github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/provider/ec2/instance.go (about)

     1  // Copyright 2011-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package ec2
     5  
     6  import (
     7  	"fmt"
     8  	"sync"
     9  
    10  	"gopkg.in/amz.v3/ec2"
    11  
    12  	"github.com/juju/juju/environs/config"
    13  	"github.com/juju/juju/instance"
    14  	"github.com/juju/juju/network"
    15  )
    16  
    17  type ec2Instance struct {
    18  	e *environ
    19  
    20  	mu sync.Mutex
    21  	*ec2.Instance
    22  }
    23  
    24  func (inst *ec2Instance) String() string {
    25  	return string(inst.Id())
    26  }
    27  
    28  var _ instance.Instance = (*ec2Instance)(nil)
    29  
    30  func (inst *ec2Instance) getInstance() *ec2.Instance {
    31  	inst.mu.Lock()
    32  	defer inst.mu.Unlock()
    33  	return inst.Instance
    34  }
    35  
    36  func (inst *ec2Instance) Id() instance.Id {
    37  	return instance.Id(inst.getInstance().InstanceId)
    38  }
    39  
    40  func (inst *ec2Instance) Status() string {
    41  	return inst.getInstance().State.Name
    42  }
    43  
    44  // Refresh implements instance.Refresh(), requerying the
    45  // Instance details over the ec2 api
    46  func (inst *ec2Instance) Refresh() error {
    47  	_, err := inst.refresh()
    48  	return err
    49  }
    50  
    51  // refresh requeries Instance details over the ec2 api.
    52  func (inst *ec2Instance) refresh() (*ec2.Instance, error) {
    53  	id := inst.Id()
    54  	insts, err := inst.e.Instances([]instance.Id{id})
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	inst.mu.Lock()
    59  	defer inst.mu.Unlock()
    60  	inst.Instance = insts[0].(*ec2Instance).Instance
    61  	return inst.Instance, nil
    62  }
    63  
    64  // Addresses implements network.Addresses() returning generic address
    65  // details for the instance, and requerying the ec2 api if required.
    66  func (inst *ec2Instance) Addresses() ([]network.Address, error) {
    67  	// TODO(gz): Stop relying on this requerying logic, maybe remove error
    68  	instInstance := inst.getInstance()
    69  	var addresses []network.Address
    70  	possibleAddresses := []network.Address{
    71  		{
    72  			Value: instInstance.IPAddress,
    73  			Type:  network.IPv4Address,
    74  			Scope: network.ScopePublic,
    75  		},
    76  		{
    77  			Value: instInstance.PrivateIPAddress,
    78  			Type:  network.IPv4Address,
    79  			Scope: network.ScopeCloudLocal,
    80  		},
    81  	}
    82  	for _, address := range possibleAddresses {
    83  		if address.Value != "" {
    84  			addresses = append(addresses, address)
    85  		}
    86  	}
    87  	return addresses, nil
    88  }
    89  
    90  func (inst *ec2Instance) OpenPorts(machineId string, ports []network.PortRange) error {
    91  	if inst.e.Config().FirewallMode() != config.FwInstance {
    92  		return fmt.Errorf("invalid firewall mode %q for opening ports on instance",
    93  			inst.e.Config().FirewallMode())
    94  	}
    95  	name := inst.e.machineGroupName(machineId)
    96  	if err := inst.e.openPortsInGroup(name, ports); err != nil {
    97  		return err
    98  	}
    99  	logger.Infof("opened ports in security group %s: %v", name, ports)
   100  	return nil
   101  }
   102  
   103  func (inst *ec2Instance) ClosePorts(machineId string, ports []network.PortRange) error {
   104  	if inst.e.Config().FirewallMode() != config.FwInstance {
   105  		return fmt.Errorf("invalid firewall mode %q for closing ports on instance",
   106  			inst.e.Config().FirewallMode())
   107  	}
   108  	name := inst.e.machineGroupName(machineId)
   109  	if err := inst.e.closePortsInGroup(name, ports); err != nil {
   110  		return err
   111  	}
   112  	logger.Infof("closed ports in security group %s: %v", name, ports)
   113  	return nil
   114  }
   115  
   116  func (inst *ec2Instance) Ports(machineId string) ([]network.PortRange, error) {
   117  	if inst.e.Config().FirewallMode() != config.FwInstance {
   118  		return nil, fmt.Errorf("invalid firewall mode %q for retrieving ports from instance",
   119  			inst.e.Config().FirewallMode())
   120  	}
   121  	name := inst.e.machineGroupName(machineId)
   122  	ranges, err := inst.e.portsInGroup(name)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	return ranges, nil
   127  }