github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/provider/maas/instance.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"fmt"
     8  	"sync"
     9  
    10  	"launchpad.net/gomaasapi"
    11  
    12  	"github.com/juju/juju/instance"
    13  )
    14  
    15  type maasInstance struct {
    16  	environ *maasEnviron
    17  
    18  	mu         sync.Mutex
    19  	maasObject *gomaasapi.MAASObject
    20  }
    21  
    22  var _ instance.Instance = (*maasInstance)(nil)
    23  
    24  func (mi *maasInstance) String() string {
    25  	hostname, err := mi.hostname()
    26  	if err != nil {
    27  		// This is meant to be impossible, but be paranoid.
    28  		hostname = fmt.Sprintf("<DNSName failed: %q>", err)
    29  	}
    30  	return fmt.Sprintf("%s:%s", hostname, mi.Id())
    31  }
    32  
    33  func (mi *maasInstance) Id() instance.Id {
    34  	return maasObjectId(mi.getMaasObject())
    35  }
    36  
    37  func maasObjectId(maasObject *gomaasapi.MAASObject) instance.Id {
    38  	// Use the node's 'resource_uri' value.
    39  	return instance.Id(maasObject.URI().String())
    40  }
    41  
    42  func (mi *maasInstance) Status() string {
    43  	// MAAS does not track node status once they're allocated.
    44  	// Since any instance that juju knows about will be an
    45  	// allocated one, it doesn't make sense to report any
    46  	// state unless we obtain it through some means other than
    47  	// through the MAAS API.
    48  	return ""
    49  }
    50  
    51  // Refresh refreshes the instance with the most up-to-date information
    52  // from the MAAS server.
    53  func (mi *maasInstance) Refresh() error {
    54  	mi.mu.Lock()
    55  	defer mi.mu.Unlock()
    56  	insts, err := mi.environ.Instances([]instance.Id{maasObjectId(mi.maasObject)})
    57  	if err != nil {
    58  		return err
    59  	}
    60  	mi.maasObject = insts[0].(*maasInstance).maasObject
    61  	return nil
    62  }
    63  
    64  func (mi *maasInstance) getMaasObject() *gomaasapi.MAASObject {
    65  	mi.mu.Lock()
    66  	defer mi.mu.Unlock()
    67  	return mi.maasObject
    68  }
    69  
    70  func (mi *maasInstance) Addresses() ([]instance.Address, error) {
    71  	name, err := mi.hostname()
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	host := instance.Address{name, instance.HostName, "", instance.NetworkPublic}
    76  	addrs := []instance.Address{host}
    77  
    78  	ips, err := mi.ipAddresses()
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	for _, ip := range ips {
    84  		a := instance.NewAddress(ip, instance.NetworkUnknown)
    85  		addrs = append(addrs, a)
    86  	}
    87  
    88  	return addrs, nil
    89  }
    90  
    91  func (mi *maasInstance) ipAddresses() ([]string, error) {
    92  	// we have to do this the hard way, since maasObject doesn't have this built-in yet
    93  	addressArray := mi.getMaasObject().GetMap()["ip_addresses"]
    94  	if addressArray.IsNil() {
    95  		// Older MAAS versions do not return ip_addresses.
    96  		return nil, nil
    97  	}
    98  	objs, err := addressArray.GetArray()
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	ips := make([]string, len(objs))
   103  	for i, obj := range objs {
   104  		s, err := obj.GetString()
   105  		if err != nil {
   106  			return nil, err
   107  		}
   108  		ips[i] = s
   109  	}
   110  	return ips, nil
   111  }
   112  
   113  func (mi *maasInstance) hostname() (string, error) {
   114  	// A MAAS instance has its DNS name immediately.
   115  	return mi.getMaasObject().GetField("hostname")
   116  }
   117  
   118  // MAAS does not do firewalling so these port methods do nothing.
   119  func (mi *maasInstance) OpenPorts(machineId string, ports []instance.Port) error {
   120  	logger.Debugf("unimplemented OpenPorts() called")
   121  	return nil
   122  }
   123  
   124  func (mi *maasInstance) ClosePorts(machineId string, ports []instance.Port) error {
   125  	logger.Debugf("unimplemented ClosePorts() called")
   126  	return nil
   127  }
   128  
   129  func (mi *maasInstance) Ports(machineId string) ([]instance.Port, error) {
   130  	logger.Debugf("unimplemented Ports() called")
   131  	return []instance.Port{}, nil
   132  }