Several pricing related changes, mostly tracking enough information on a
node so you can look up what size (and price) a node is.
diff --git a/libcloud/drivers/gogrid.py b/libcloud/drivers/gogrid.py
index 317ec0c..dc08fc2 100644
--- a/libcloud/drivers/gogrid.py
+++ b/libcloud/drivers/gogrid.py
@@ -141,7 +141,7 @@ class GoGridNodeDriver(NodeDriver):
return NodeState.UNKNOWN
def _get_ip(self, element):
- return element['ip']['ip']
+ return element.get('ip').get('ip')
def _get_id(self, element):
return element.get('id')
@@ -155,6 +155,7 @@ class GoGridNodeDriver(NodeDriver):
state=state,
public_ip=[ip],
private_ip=[],
+ extra={'ram':element.get('ram').get('name')},
driver=self.connection.driver)
return n
diff --git a/libcloud/drivers/linode.py b/libcloud/drivers/linode.py
index 6d7bd08..312544c 100644
--- a/libcloud/drivers/linode.py
+++ b/libcloud/drivers/linode.py
@@ -52,6 +52,19 @@ LINODE_API = "api.linode.com"
# For beta accounts, change this to "/api/".
LINODE_ROOT = "/"
+# Map of TOTALRAM to PLANID, allows us to figure out what plan
+# a particular node is on
+LINODE_PLAN_IDS = {360:'1',
+ 540:'2',
+ 720:'3',
+ 1080:'4',
+ 1440:'5',
+ 2880:'6',
+ 5760:'7',
+ 8640:'8',
+ 11520:'9',
+ 14400:'10'}
+
class LinodeResponse(Response):
# Wraps a Linode API HTTP response.
@@ -144,6 +157,7 @@ class LinodeNodeDriver(NodeDriver):
type = Provider.LINODE
name = "Linode"
connectionCls = LinodeConnection
+ _linode_plan_ids = LINODE_PLAN_IDS
def __init__(self, key):
self.datacenter = None
@@ -455,6 +469,7 @@ class LinodeNodeDriver(NodeDriver):
state=self.LINODE_STATES[obj["STATUS"]], public_ip=public_ip,
private_ip=private_ip, driver=self.connection.driver)
n.extra = copy(obj)
+ n.extra = {"PLANID":self._linode_plan_ids.get(obj.get("TOTALRAM"))}
return n
features = {"create_node": ["ssh_key", "password"]}
diff --git a/libcloud/drivers/rackspace.py b/libcloud/drivers/rackspace.py
index 49865dc..d1f85a2 100644
--- a/libcloud/drivers/rackspace.py
+++ b/libcloud/drivers/rackspace.py
@@ -28,6 +28,21 @@ from xml.parsers.expat import ExpatError
NAMESPACE = 'http://docs.rackspacecloud.com/servers/api/v1.0'
+#
+# Prices need to be hardcoded as Rackspace doesn't expose them through
+# the API. Prices are associated with flavors, of which there are 7.
+# See - http://www.rackspacecloud.com/cloud_hosting_products/servers/pricing
+#
+RACKSPACE_PRICES = {
+ '1':'.015',
+ '2':'.030',
+ '3':'.060',
+ '4':'.120',
+ '5':'.240',
+ '6':'.480',
+ '7':'.960',
+}
+
class RackspaceResponse(Response):
def success(self):
@@ -147,6 +162,8 @@ class RackspaceNodeDriver(NodeDriver):
type = Provider.RACKSPACE
name = 'Rackspace'
+ _rackspace_prices = RACKSPACE_PRICES
+
features = {"create_node": ["generates_password"]}
NODE_STATE_MAP = { 'BUILD': NodeState.PENDING,
@@ -307,7 +324,7 @@ class RackspaceNodeDriver(NodeDriver):
ram=int(el.get('ram')),
disk=int(el.get('disk')),
bandwidth=None, # XXX: needs hardcode
- price=None, # XXX: needs hardcode,
+ price=self._rackspace_prices.get(el.get('id')), # Hardcoded,
driver=self.connection.driver)
return s
diff --git a/libcloud/drivers/rimuhosting.py b/libcloud/drivers/rimuhosting.py
index 0ea5737..4566c96 100644
--- a/libcloud/drivers/rimuhosting.py
+++ b/libcloud/drivers/rimuhosting.py
@@ -141,7 +141,8 @@ class RimuHostingNodeDriver(NodeDriver):
),
private_ip=[],
driver=self.connection.driver,
- extra={'order_oid': order['order_oid']})
+ extra={'order_oid': order['order_oid'],
+ 'monthly_recurring_fee': order['billing_info']['monthly_recurring_fee']})
return n
def _to_size(self,plan):
diff --git a/libcloud/drivers/vpsnet.py b/libcloud/drivers/vpsnet.py
index e9073e5..1e962f7 100644
--- a/libcloud/drivers/vpsnet.py
+++ b/libcloud/drivers/vpsnet.py
@@ -101,6 +101,7 @@ class VPSNetNodeDriver(NodeDriver):
state=state,
public_ip=[vm.get('primary_ip_address', None)],
private_ip=[],
+ extra={'slices_count':vm['slices_count']}, # Number of nodes consumed by VM
driver=self.connection.driver)
return n
@@ -166,8 +167,8 @@ class VPSNetNodeDriver(NodeDriver):
def list_sizes(self, location=None):
res = self.connection.request('/nodes.%s' % (API_VERSION,))
available_nodes = len([size for size in res.object
- if not size['slice']["virtual_machine_id"]])
- sizes = [self._to_size(i) for i in range(1,available_nodes + 1)]
+ if size['slice']['virtual_machine_id']])
+ sizes = [self._to_size(i) for i in range(1, available_nodes + 1)]
return sizes
def destroy_node(self, node):