Skip to content

Commit

Permalink
CLOUDSTACK: ex_list_nics, ex_add_nic_to_vm, ex_remove_nic_from_vm + t…
Browse files Browse the repository at this point in the history
…ests
  • Loading branch information
boul committed Oct 3, 2014
1 parent 08b4638 commit 2d6de86
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 36 deletions.
190 changes: 154 additions & 36 deletions libcloud/compute/drivers/cloudstack.py
Expand Up @@ -5,7 +5,7 @@
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -181,6 +181,10 @@
'project_id': {
'key_name': 'projectid',
'transform_func': str
},
'nics:': {
'key_name': 'nic',
'transform_func': list
}
},
'volume': {
Expand Down Expand Up @@ -302,6 +306,12 @@
'vpcavailable': {'key_name': 'vpcavailable', 'transform_func': int},
'vpclimit': {'key_name': 'vpclimit', 'transform_func': int},
'vpctotal': {'key_name': 'vpctotal', 'transform_func': int}
},
'nic': {
'secondary_ip': {
'key_name': 'secondaryip',
'transform_func': list
}
}
}

Expand Down Expand Up @@ -413,7 +423,6 @@ class CloudStackFirewallRule(object):
def __init__(self, id, address, cidr_list, protocol,
icmp_code=None, icmp_type=None,
start_port=None, end_port=None):

"""
A Firewall rule.
Expand Down Expand Up @@ -468,7 +477,6 @@ class CloudStackEgressFirewallRule(object):
def __init__(self, id, network_id, cidr_list, protocol,
icmp_code=None, icmp_type=None,
start_port=None, end_port=None):

"""
A egress firewall rule.
Expand Down Expand Up @@ -654,6 +662,35 @@ def __repr__(self):
self.driver.name))


class CloudStackNic(object):
"""
Class representing a CloudStack Network Interface.
"""

def __init__(self, id, network_id, net_mask, gateway, ip_address,
is_default, mac_address, driver, extra=None):
self.id = id
self.network_id = network_id
self.net_mask = net_mask
self.gateway = gateway
self.ip_address = ip_address
self.is_default = is_default
self.mac_address = mac_address
self.driver = driver
self.extra = extra or {}

def __repr__(self):
return (('<CloudStackNic: id=%s, network_id=%s, '
'net_mask=%s, gateway=%s, ip_address=%s, '
'is_default=%s, mac_address=%s, driver%s>')
% (self.id, self.network_id, self.net_mask,
self.gateway, self.ip_address, self.is_default,
self.mac_address, self.driver.name))

def __eq__(self, other):
return self.__class__ is other.__class__ and self.id == other.id


class CloudStackVPC(object):
"""
Class representing a CloudStack VPC.
Expand Down Expand Up @@ -1123,13 +1160,13 @@ def ex_list_networks(self):
extra['tags'] = self._get_resource_tags(net['tags'])

networks.append(CloudStackNetwork(
net['displaytext'],
net['name'],
net['networkofferingid'],
net['id'],
net['zoneid'],
self,
extra=extra))
net['displaytext'],
net['name'],
net['networkofferingid'],
net['id'],
net['zoneid'],
self,
extra=extra))

return networks

Expand All @@ -1147,13 +1184,13 @@ def ex_list_network_offerings(self):

for netoffer in netoffers:
networkofferings.append(CloudStackNetworkOffering(
netoffer['name'],
netoffer['displaytext'],
netoffer['guestiptype'],
netoffer['id'],
netoffer['serviceofferingid'],
netoffer['forvpc'],
self))
netoffer['name'],
netoffer['displaytext'],
netoffer['guestiptype'],
netoffer['id'],
netoffer['serviceofferingid'],
netoffer['forvpc'],
self))

return networkofferings

Expand All @@ -1170,10 +1207,10 @@ def ex_create_network(self, display_text, name, network_offering,
:param name: the name of the network
:type name: ``str``
:param network_offering: the network offering id
:param network_offering: NetworkOffering object
:type network_offering: :class:'CloudStackNetworkOffering`
:param location: Zone
:param location: Zone object
:type location: :class:`NodeLocation`
:param gateway: Optional, the Gateway of this network
Expand Down Expand Up @@ -1281,10 +1318,10 @@ def ex_list_vpc_offerings(self):

for vpcoffer in vpcoffers:
vpcofferings.append(CloudStackVPCOffering(
vpcoffer['name'],
vpcoffer['displaytext'],
vpcoffer['id'],
self))
vpcoffer['name'],
vpcoffer['displaytext'],
vpcoffer['id'],
self))

return vpcofferings

Expand All @@ -1301,15 +1338,14 @@ def ex_list_vpcs(self):

networks = []
for vpc in vpcs:

networks.append(CloudStackVPC(
vpc['displaytext'],
vpc['name'],
vpc['vpcofferingid'],
vpc['id'],
vpc['zoneid'],
vpc['cidr'],
self))
vpc['displaytext'],
vpc['name'],
vpc['vpcofferingid'],
vpc['id'],
vpc['zoneid'],
vpc['cidr'],
self))

return networks

Expand Down Expand Up @@ -1406,11 +1442,11 @@ def ex_list_projects(self):
extra['tags'] = self._get_resource_tags(proj['tags'])

projects.append(CloudStackProject(
id=proj['id'],
name=proj['name'],
display_text=proj['displaytext'],
driver=self,
extra=extra))
id=proj['id'],
name=proj['name'],
display_text=proj['displaytext'],
driver=self,
extra=extra))

return projects

Expand Down Expand Up @@ -2695,6 +2731,88 @@ def ex_list_os_types(self):
ostypes = self._sync_request('listOsTypes')
return ostypes['ostype']

def ex_list_nics(self, node):
"""
List the available networks
:param vm: Node Object
:type vm: :class:`CloudStackNode
:rtype ``list`` of :class:`CloudStackNic`
"""

res = self._sync_request(command='listNics',
params={'virtualmachineid': node.id},
method='GET')
items = res.get('nic', [])

nics = []
extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['nic']
for item in items:
extra = self._get_extra_dict(item, extra_map)

nics.append(CloudStackNic(
id=item['id'],
network_id=item['networkid'],
net_mask=item['netmask'],
gateway=item['gateway'],
ip_address=item['ipaddress'],
is_default=item['isdefault'],
mac_address=item['macaddress'],
driver=self,
extra=extra))

return nics

def ex_add_nic_to_node(self, node, network, ip_address=None):
"""
Add an extra Nic to a VM
:param network: NetworkOffering object
:type network: :class:'CloudStackNetwork`
:param node: Node Object
:type node: :class:'CloudStackNode`
:param ip_address: Optional, specific IP for this Nic
:type ip_address: ``str``
:rtype: ``bool``
"""

args = {
'virtualmachineid': node.id,
'networkid': network.id
}

if ip_address is not None:
args['ipaddress'] = ip_address

self._async_request(command='addNicToVirtualMachine',
params=args)
return True

def ex_remove_nic_from_node(self, nic, node):

"""
Remove Nic from a VM
:param nic: Nic object
:type nic: :class:'CloudStackNetwork`
:param node: Node Object
:type node: :class:'CloudStackNode`
:rtype: ``bool``
"""

self._async_request(command='removeNicFromVirtualMachine',
params={'nicid': nic.id,
'virtualmachineid': node.id})

return True

def _to_snapshot(self, data):
"""
Create snapshot object from data
Expand Down
@@ -0,0 +1 @@
{ "addnictovirtualmachineresponse" : {"jobid":"addnictovm"} }
@@ -0,0 +1 @@
{ "listnicsresponse" : { "count":1 ,"nic" : [ {"id":"15418e74-25e8-42d3-9bd7-eb55e57825fe","networkid":"de45b0ed-b5ae-4374-ac7c-aff3fb2aefa2","netmask":"255.255.255.0","gateway":"10.1.1.1","ipaddress":"10.1.1.136","isdefault":true,"macaddress":"02:00:00:b9:01:1a"} ] } }
@@ -0,0 +1,37 @@
{
"queryasyncjobresultresponse" : {
"accountid" : "02c9bf08-6f36-44b1-a57f-df0708f90de4", "userid" : "6ef2b921-4ecf-4651-8188-f9868db73e73", "cmd" : "org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd", "jobstatus" : 1, "jobprocstatus" : 0, "jobresultcode" : 0, "jobresulttype" : "object", "jobresult" : {
"virtualmachine" : {
"id" : "903897b7-9241-4f93-bd08-3453c36a3c99", "name" : "test", "account" : "rkuipers_admin", "domainid" : "4b6e626c-9d50-4480-bf77-daae632c7ffd", "domain" : "rkuipers", "created" : "2014-10-03T17:24:37+0200", "state" : "Stopped", "haenable" : false, "zoneid" : "2", "zonename" : "BETA-SBP-DC-1", "guestosid" : "278699da-edfc-11e2-a249-005056ba4c5e", "securitygroup" : [], "nic" : [{
"id": "15418e74-25e8-42d3-9bd7-eb55e57825fe",
"networkid": "de45b0ed-b5ae-4374-ac7c-aff3fb2aefa2",
"networkname": "rkuipers-default",
"netmask": "255.255.255.0",
"gateway": "10.1.1.1",
"ipaddress": "10.1.1.136",
"isolationuri": "lswitch:d3eaa05c-4392-4918-93ab-c4a979a7988a",
"broadcasturi": "lswitch:d3eaa05c-4392-4918-93ab-c4a979a7988a",
"traffictype": "Guest",
"type": "Isolated",
"isdefault": true,
"macaddress": "02:00:00:b9:01:1a"
}, {
"id": "f71e48da-fe40-458d-9033-ea27a3a92de1",
"networkid": "f59ee08a-66b5-40c6-baa7-392394c6cea9",
"networkname": "node_cellar_network",
"netmask": "255.255.255.0",
"gateway": "10.1.1.1",
"ipaddress": "10.1.1.253",
"isolationuri": "lswitch:bad1ca9f-b039-4ad1-b5fc-1f3147fad7fa",
"broadcasturi": "lswitch:bad1ca9f-b039-4ad1-b5fc-1f3147fad7fa",
"traffictype": "Guest",
"type": "Isolated",
"isdefault": false,
"macaddress": "02:00:4f:84:00:1d"
}
], "hypervisor" : "XenServer", "tags" : [], "affinitygroup" : [], "displayvm" : true, "isdynamicallyscalable" : false
}
}, "created" : "2014-10-03T18:30:59+0200", "jobid" : "e521e748-1271-4587-8433-2d094704bfe9"
}
}

@@ -0,0 +1,37 @@
{
"queryasyncjobresultresponse" : {
"accountid" : "02c9bf08-6f36-44b1-a57f-df0708f90de4", "userid" : "6ef2b921-4ecf-4651-8188-f9868db73e73", "cmd" : "org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd", "jobstatus" : 1, "jobprocstatus" : 0, "jobresultcode" : 0, "jobresulttype" : "object", "jobresult" : {
"virtualmachine" : {
"id" : "903897b7-9241-4f93-bd08-3453c36a3c99", "name" : "test", "account" : "rkuipers_admin", "domainid" : "4b6e626c-9d50-4480-bf77-daae632c7ffd", "domain" : "rkuipers", "created" : "2014-10-03T17:24:37+0200", "state" : "Stopped", "haenable" : false, "zoneid" : "2", "zonename" : "BETA-SBP-DC-1", "guestosid" : "278699da-edfc-11e2-a249-005056ba4c5e", "securitygroup" : [], "nic" : [{
"id": "15418e74-25e8-42d3-9bd7-eb55e57825fe",
"networkid": "de45b0ed-b5ae-4374-ac7c-aff3fb2aefa2",
"networkname": "rkuipers-default",
"netmask": "255.255.255.0",
"gateway": "10.1.1.1",
"ipaddress": "10.1.1.136",
"isolationuri": "lswitch:d3eaa05c-4392-4918-93ab-c4a979a7988a",
"broadcasturi": "lswitch:d3eaa05c-4392-4918-93ab-c4a979a7988a",
"traffictype": "Guest",
"type": "Isolated",
"isdefault": true,
"macaddress": "02:00:00:b9:01:1a"
}, {
"id": "f71e48da-fe40-458d-9033-ea27a3a92de1",
"networkid": "f59ee08a-66b5-40c6-baa7-392394c6cea9",
"networkname": "node_cellar_network",
"netmask": "255.255.255.0",
"gateway": "10.1.1.1",
"ipaddress": "10.1.1.253",
"isolationuri": "lswitch:bad1ca9f-b039-4ad1-b5fc-1f3147fad7fa",
"broadcasturi": "lswitch:bad1ca9f-b039-4ad1-b5fc-1f3147fad7fa",
"traffictype": "Guest",
"type": "Isolated",
"isdefault": false,
"macaddress": "02:00:4f:84:00:1d"
}
], "hypervisor" : "XenServer", "tags" : [], "affinitygroup" : [], "displayvm" : true, "isdynamicallyscalable" : false
}
}, "created" : "2014-10-03T18:40:30+0200", "jobid" : "23fc6bfc-e354-41c8-bf8b-c0db8227feb4"
}
}

@@ -0,0 +1 @@
{ "removenicfromvirtualmachineresponse" : {"jobid":"removenic"} }

0 comments on commit 2d6de86

Please sign in to comment.