Merge "NetApp cDOT multi-SVM driver can't handle duplicate addresses"
This commit is contained in:
commit
ecd6c5227a
@ -81,7 +81,7 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
|
||||
@na_utils.trace
|
||||
def create_vserver(self, vserver_name, root_volume_aggregate_name,
|
||||
root_volume_name, aggregate_names):
|
||||
root_volume_name, aggregate_names, ipspace_name):
|
||||
"""Creates new vserver and assigns aggregates."""
|
||||
create_args = {
|
||||
'vserver-name': vserver_name,
|
||||
@ -92,6 +92,14 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
'nsswitch': 'file',
|
||||
},
|
||||
}
|
||||
|
||||
if ipspace_name:
|
||||
if not self.features.IPSPACES:
|
||||
msg = 'IPSpaces are not supported on this backend.'
|
||||
raise exception.NetAppException(msg)
|
||||
else:
|
||||
create_args['ipspace'] = ipspace_name
|
||||
|
||||
self.send_request('vserver-create', create_args)
|
||||
|
||||
aggr_list = [{'aggr-name': aggr_name} for aggr_name in aggregate_names]
|
||||
@ -148,6 +156,57 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
raise exception.NetAppException(msg)
|
||||
return root_volume_name
|
||||
|
||||
@na_utils.trace
|
||||
def get_vserver_ipspace(self, vserver_name):
|
||||
"""Get the IPspace of the vserver, or None if not supported."""
|
||||
if not self.features.IPSPACES:
|
||||
return None
|
||||
|
||||
api_args = {
|
||||
'query': {
|
||||
'vserver-info': {
|
||||
'vserver-name': vserver_name,
|
||||
},
|
||||
},
|
||||
'desired-attributes': {
|
||||
'vserver-info': {
|
||||
'ipspace': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
vserver_info = self.send_request('vserver-get-iter', api_args)
|
||||
|
||||
try:
|
||||
ipspace = vserver_info.get_child_by_name(
|
||||
'attributes-list').get_child_by_name(
|
||||
'vserver-info').get_child_content('ipspace')
|
||||
except AttributeError:
|
||||
msg = _('Could not determine IPspace for Vserver %s.')
|
||||
raise exception.NetAppException(msg % vserver_name)
|
||||
return ipspace
|
||||
|
||||
@na_utils.trace
|
||||
def ipspace_has_data_vservers(self, ipspace_name):
|
||||
"""Check whether an IPspace has any data Vservers assigned to it."""
|
||||
if not self.features.IPSPACES:
|
||||
return False
|
||||
|
||||
api_args = {
|
||||
'query': {
|
||||
'vserver-info': {
|
||||
'ipspace': ipspace_name,
|
||||
'vserver-type': 'data'
|
||||
},
|
||||
},
|
||||
'desired-attributes': {
|
||||
'vserver-info': {
|
||||
'vserver-name': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
result = self.send_request('vserver-get-iter', api_args)
|
||||
return self._has_records(result)
|
||||
|
||||
@na_utils.trace
|
||||
def list_vservers(self, vserver_type='data'):
|
||||
"""Get the names of vservers present, optionally filtered by type."""
|
||||
@ -358,7 +417,7 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
@na_utils.trace
|
||||
def create_network_interface(self, ip, netmask, vlan, node, port,
|
||||
vserver_name, allocation_id,
|
||||
lif_name_template):
|
||||
lif_name_template, ipspace_name):
|
||||
"""Creates LIF on VLAN port."""
|
||||
|
||||
home_port_name = port
|
||||
@ -367,7 +426,8 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
home_port_name = '%(port)s-%(tag)s' % {'port': port, 'tag': vlan}
|
||||
|
||||
if self.features.BROADCAST_DOMAINS:
|
||||
self._ensure_broadcast_domain_for_port(node, home_port_name)
|
||||
self._ensure_broadcast_domain_for_port(node, home_port_name,
|
||||
ipspace=ipspace_name)
|
||||
|
||||
interface_name = (lif_name_template %
|
||||
{'node': node, 'net_allocation_id': allocation_id})
|
||||
@ -416,14 +476,34 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
def _ensure_broadcast_domain_for_port(self, node, port,
|
||||
domain=DEFAULT_BROADCAST_DOMAIN,
|
||||
ipspace=DEFAULT_IPSPACE):
|
||||
"""Ensure a port is in a broadcast domain. Create one if necessary."""
|
||||
"""Ensure a port is in a broadcast domain. Create one if necessary.
|
||||
|
||||
if self._get_broadcast_domain_for_port(node, port):
|
||||
If the IPspace:domain pair match for the given port, which commonly
|
||||
happens in multi-node clusters, then there isn't anything to do.
|
||||
Otherwise, we can assume the IPspace is correct and extant by this
|
||||
point, so the remaining task is to remove the port from any domain it
|
||||
is already in, create the desired domain if it doesn't exist, and add
|
||||
the port to the desired domain.
|
||||
"""
|
||||
|
||||
port_info = self._get_broadcast_domain_for_port(node, port)
|
||||
|
||||
# Port already in desired ipspace and broadcast domain.
|
||||
if (port_info['ipspace'] == ipspace
|
||||
and port_info['broadcast-domain'] == domain):
|
||||
return
|
||||
|
||||
# If in another broadcast domain, remove port from it.
|
||||
if port_info['broadcast-domain']:
|
||||
self._remove_port_from_broadcast_domain(
|
||||
node, port, port_info['broadcast-domain'],
|
||||
port_info['ipspace'])
|
||||
|
||||
# If desired broadcast domain doesn't exist, create it.
|
||||
if not self._broadcast_domain_exists(domain, ipspace):
|
||||
self._create_broadcast_domain(domain, ipspace)
|
||||
|
||||
# Move the port into the broadcast domain where it is needed.
|
||||
self._add_port_to_broadcast_domain(node, port, domain, ipspace)
|
||||
|
||||
@na_utils.trace
|
||||
@ -439,6 +519,7 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
'desired-attributes': {
|
||||
'net-port-info': {
|
||||
'broadcast-domain': None,
|
||||
'ipspace': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -452,7 +533,12 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
msg_args = {'port': port, 'node': node}
|
||||
raise exception.NetAppException(msg % msg_args)
|
||||
|
||||
return port_info[0].get_child_content('broadcast-domain')
|
||||
port = {
|
||||
'broadcast-domain':
|
||||
port_info[0].get_child_content('broadcast-domain'),
|
||||
'ipspace': port_info[0].get_child_content('ipspace')
|
||||
}
|
||||
return port
|
||||
|
||||
@na_utils.trace
|
||||
def _broadcast_domain_exists(self, domain, ipspace):
|
||||
@ -482,6 +568,25 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
}
|
||||
self.send_request('net-port-broadcast-domain-create', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def _delete_broadcast_domain(self, domain, ipspace):
|
||||
"""Delete a broadcast domain."""
|
||||
api_args = {
|
||||
'ipspace': ipspace,
|
||||
'broadcast-domain': domain,
|
||||
}
|
||||
self.send_request('net-port-broadcast-domain-destroy', api_args)
|
||||
|
||||
def _delete_broadcast_domains_for_ipspace(self, ipspace_name):
|
||||
"""Deletes all broadcast domains in an IPspace."""
|
||||
ipspaces = self.get_ipspaces(ipspace_name=ipspace_name)
|
||||
if not ipspaces:
|
||||
return
|
||||
|
||||
ipspace = ipspaces[0]
|
||||
for broadcast_domain_name in ipspace['broadcast-domains']:
|
||||
self._delete_broadcast_domain(broadcast_domain_name, ipspace_name)
|
||||
|
||||
@na_utils.trace
|
||||
def _add_port_to_broadcast_domain(self, node, port, domain, ipspace):
|
||||
|
||||
@ -510,6 +615,19 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
}
|
||||
raise exception.NetAppException(msg % msg_args)
|
||||
|
||||
@na_utils.trace
|
||||
def _remove_port_from_broadcast_domain(self, node, port, domain, ipspace):
|
||||
|
||||
qualified_port_name = ':'.join([node, port])
|
||||
api_args = {
|
||||
'ipspace': ipspace,
|
||||
'broadcast-domain': domain,
|
||||
'ports': {
|
||||
'net-qualified-port-name': qualified_port_name,
|
||||
}
|
||||
}
|
||||
self.send_request('net-port-broadcast-domain-remove-ports', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def network_interface_exists(self, vserver_name, node, port, ip, netmask,
|
||||
vlan):
|
||||
@ -594,6 +712,103 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
api_args = {'vserver': None, 'interface-name': interface_name}
|
||||
self.send_request('net-interface-delete', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def get_ipspaces(self, ipspace_name=None, max_records=1000):
|
||||
"""Gets one or more IPSpaces."""
|
||||
|
||||
if not self.features.IPSPACES:
|
||||
return []
|
||||
|
||||
api_args = {'max-records': max_records}
|
||||
if ipspace_name:
|
||||
api_args['query'] = {
|
||||
'net-ipspaces-info': {
|
||||
'ipspace': ipspace_name,
|
||||
}
|
||||
}
|
||||
|
||||
result = self.send_request('net-ipspaces-get-iter', api_args)
|
||||
if not self._has_records(result):
|
||||
return []
|
||||
|
||||
ipspaces = []
|
||||
|
||||
for net_ipspaces_info in result.get_child_by_name(
|
||||
'attributes-list').get_children():
|
||||
|
||||
ipspace = {
|
||||
'ports': [],
|
||||
'vservers': [],
|
||||
'broadcast-domains': [],
|
||||
}
|
||||
|
||||
ports = net_ipspaces_info.get_child_by_name(
|
||||
'ports') or netapp_api.NaElement('none')
|
||||
for port in ports.get_children():
|
||||
ipspace['ports'].append(port.get_content())
|
||||
|
||||
vservers = net_ipspaces_info.get_child_by_name(
|
||||
'vservers') or netapp_api.NaElement('none')
|
||||
for vserver in vservers.get_children():
|
||||
ipspace['vservers'].append(vserver.get_content())
|
||||
|
||||
broadcast_domains = net_ipspaces_info.get_child_by_name(
|
||||
'broadcast-domains') or netapp_api.NaElement('none')
|
||||
for broadcast_domain in broadcast_domains.get_children():
|
||||
ipspace['broadcast-domains'].append(
|
||||
broadcast_domain.get_content())
|
||||
|
||||
ipspace['ipspace'] = net_ipspaces_info.get_child_content('ipspace')
|
||||
ipspace['id'] = net_ipspaces_info.get_child_content('id')
|
||||
ipspace['uuid'] = net_ipspaces_info.get_child_content('uuid')
|
||||
|
||||
ipspaces.append(ipspace)
|
||||
|
||||
return ipspaces
|
||||
|
||||
@na_utils.trace
|
||||
def ipspace_exists(self, ipspace_name):
|
||||
"""Checks if IPspace exists."""
|
||||
|
||||
if not self.features.IPSPACES:
|
||||
return False
|
||||
|
||||
api_args = {
|
||||
'query': {
|
||||
'net-ipspaces-info': {
|
||||
'ipspace': ipspace_name,
|
||||
},
|
||||
},
|
||||
'desired-attributes': {
|
||||
'net-ipspaces-info': {
|
||||
'ipspace': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
result = self.send_request('net-ipspaces-get-iter', api_args)
|
||||
return self._has_records(result)
|
||||
|
||||
@na_utils.trace
|
||||
def create_ipspace(self, ipspace_name):
|
||||
"""Creates an IPspace."""
|
||||
api_args = {'ipspace': ipspace_name}
|
||||
self.send_request('net-ipspaces-create', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def delete_ipspace(self, ipspace_name):
|
||||
"""Deletes an IPspace."""
|
||||
|
||||
self._delete_broadcast_domains_for_ipspace(ipspace_name)
|
||||
|
||||
api_args = {'ipspace': ipspace_name}
|
||||
self.send_request('net-ipspaces-destroy', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def add_vserver_to_ipspace(self, ipspace_name, vserver_name):
|
||||
"""Assigns a vserver to an IPspace."""
|
||||
api_args = {'ipspace': ipspace_name, 'vserver': vserver_name}
|
||||
self.send_request('net-ipspaces-assign-vserver', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def get_node_for_aggregate(self, aggregate_name):
|
||||
"""Get home node for the specified aggregate.
|
||||
|
@ -27,6 +27,7 @@ from oslo_utils import excutils
|
||||
|
||||
from manila import exception
|
||||
from manila.i18n import _, _LE, _LW
|
||||
from manila.share.drivers.netapp.dataontap.client import client_cmode
|
||||
from manila.share.drivers.netapp.dataontap.cluster_mode import lib_base
|
||||
from manila.share.drivers.netapp import utils as na_utils
|
||||
from manila import utils
|
||||
@ -34,6 +35,7 @@ from manila import utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
SUPPORTED_NETWORK_TYPES = (None, 'flat', 'vlan')
|
||||
SEGMENTED_NETWORK_TYPES = ('vlan',)
|
||||
|
||||
|
||||
class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
@ -111,7 +113,7 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
server_details = {'vserver_name': vserver_name}
|
||||
|
||||
try:
|
||||
self._create_vserver_if_nonexistent(vserver_name, network_info)
|
||||
self._create_vserver(vserver_name, network_info)
|
||||
except Exception as e:
|
||||
e.detail_data = {'server_details': server_details}
|
||||
raise
|
||||
@ -132,41 +134,74 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
return self.configuration.netapp_vserver_name_template % server_id
|
||||
|
||||
@na_utils.trace
|
||||
def _create_vserver_if_nonexistent(self, vserver_name, network_info):
|
||||
def _create_vserver(self, vserver_name, network_info):
|
||||
"""Creates Vserver with given parameters if it doesn't exist."""
|
||||
|
||||
if self._client.vserver_exists(vserver_name):
|
||||
msg = _('Vserver %s already exists.')
|
||||
raise exception.NetAppException(msg % vserver_name)
|
||||
|
||||
ipspace_name = self._create_ipspace(network_info)
|
||||
|
||||
LOG.debug('Vserver %s does not exist, creating.', vserver_name)
|
||||
self._client.create_vserver(
|
||||
vserver_name,
|
||||
self.configuration.netapp_root_volume_aggregate,
|
||||
self.configuration.netapp_root_volume,
|
||||
self._find_matching_aggregates())
|
||||
self._find_matching_aggregates(),
|
||||
ipspace_name)
|
||||
|
||||
vserver_client = self._get_api_client(vserver=vserver_name)
|
||||
security_services = None
|
||||
try:
|
||||
self._create_vserver_lifs(vserver_name,
|
||||
vserver_client,
|
||||
network_info)
|
||||
network_info,
|
||||
ipspace_name)
|
||||
|
||||
vserver_client.enable_nfs()
|
||||
|
||||
security_services = network_info.get('security_services')
|
||||
if security_services:
|
||||
self._client.setup_security_services(security_services,
|
||||
vserver_client,
|
||||
vserver_name)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE("Failed to create network interface(s)."))
|
||||
self._client.delete_vserver(vserver_name, vserver_client)
|
||||
LOG.error(_LE("Failed to configure Vserver."))
|
||||
self._delete_vserver(vserver_name,
|
||||
security_services=security_services)
|
||||
|
||||
vserver_client.enable_nfs()
|
||||
def _get_valid_ipspace_name(self, network_id):
|
||||
"""Get IPspace name according to network id."""
|
||||
return 'ipspace_' + network_id.replace('-', '_')
|
||||
|
||||
security_services = network_info.get('security_services')
|
||||
if security_services:
|
||||
self._client.setup_security_services(security_services,
|
||||
vserver_client,
|
||||
vserver_name)
|
||||
@na_utils.trace
|
||||
def _create_ipspace(self, network_info):
|
||||
"""If supported, create an IPspace for a new Vserver."""
|
||||
|
||||
if not self._client.features.IPSPACES:
|
||||
return None
|
||||
|
||||
if network_info['network_type'] not in SEGMENTED_NETWORK_TYPES:
|
||||
return client_cmode.DEFAULT_IPSPACE
|
||||
|
||||
# NOTE(cknight): Neutron needs cDOT IP spaces because it can provide
|
||||
# overlapping IP address ranges for different subnets. That is not
|
||||
# believed to be an issue for any of Manila's other network plugins.
|
||||
ipspace_id = network_info.get('neutron_subnet_id')
|
||||
if not ipspace_id:
|
||||
return client_cmode.DEFAULT_IPSPACE
|
||||
|
||||
ipspace_name = self._get_valid_ipspace_name(ipspace_id)
|
||||
if not self._client.ipspace_exists(ipspace_name):
|
||||
self._client.create_ipspace(ipspace_name)
|
||||
|
||||
return ipspace_name
|
||||
|
||||
@na_utils.trace
|
||||
def _create_vserver_lifs(self, vserver_name, vserver_client,
|
||||
network_info):
|
||||
network_info, ipspace_name):
|
||||
|
||||
nodes = self._client.list_cluster_nodes()
|
||||
node_network_info = zip(nodes, network_info['network_allocations'])
|
||||
@ -183,6 +218,7 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
port,
|
||||
ip,
|
||||
netmask,
|
||||
ipspace_name,
|
||||
vserver_client)
|
||||
|
||||
@na_utils.trace
|
||||
@ -199,14 +235,15 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
|
||||
@na_utils.trace
|
||||
def _create_lif_if_nonexistent(self, vserver_name, allocation_id, vlan,
|
||||
node, port, ip, netmask, vserver_client):
|
||||
node, port, ip, netmask, ipspace_name,
|
||||
vserver_client):
|
||||
"""Creates LIF for Vserver."""
|
||||
if not vserver_client.network_interface_exists(vserver_name, node,
|
||||
port, ip, netmask,
|
||||
vlan):
|
||||
self._client.create_network_interface(
|
||||
ip, netmask, vlan, node, port, vserver_name, allocation_id,
|
||||
self.configuration.netapp_lif_name_template)
|
||||
self.configuration.netapp_lif_name_template, ipspace_name)
|
||||
|
||||
@na_utils.trace
|
||||
def get_network_allocations_number(self):
|
||||
@ -231,7 +268,19 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
"record will proceed anyway."), vserver)
|
||||
return
|
||||
|
||||
self._delete_vserver(vserver, security_services=security_services)
|
||||
|
||||
@na_utils.trace
|
||||
def _delete_vserver(self, vserver, security_services=None):
|
||||
"""Delete a Vserver plus IPspace and security services as needed."""
|
||||
|
||||
ipspace_name = self._client.get_vserver_ipspace(vserver)
|
||||
|
||||
vserver_client = self._get_api_client(vserver=vserver)
|
||||
self._client.delete_vserver(vserver,
|
||||
vserver_client,
|
||||
security_services=security_services)
|
||||
|
||||
if ipspace_name and not self._client.ipspace_has_data_vservers(
|
||||
ipspace_name):
|
||||
self._client.delete_ipspace(ipspace_name)
|
||||
|
@ -65,10 +65,22 @@ NETMASK = '255.255.255.0'
|
||||
NET_ALLOCATION_ID = 'fake_allocation_id'
|
||||
LIF_NAME_TEMPLATE = 'os_%(net_allocation_id)s'
|
||||
LIF_NAME = LIF_NAME_TEMPLATE % {'net_allocation_id': NET_ALLOCATION_ID}
|
||||
IPSPACE = 'fake_ipspace'
|
||||
IPSPACE_NAME = 'fake_ipspace'
|
||||
BROADCAST_DOMAIN = 'fake_domain'
|
||||
MTU = 9000
|
||||
|
||||
IPSPACES = [{
|
||||
'uuid': 'fake_uuid',
|
||||
'ipspace': IPSPACE_NAME,
|
||||
'id': 'fake_id',
|
||||
'broadcast-domains': ['OpenStack'],
|
||||
'ports': [NODE_NAME + ':' + VLAN_PORT],
|
||||
'vservers': [
|
||||
IPSPACE_NAME,
|
||||
VSERVER_NAME,
|
||||
]
|
||||
}]
|
||||
|
||||
EMS_MESSAGE = {
|
||||
'computer-name': 'fake_host',
|
||||
'event-id': '0',
|
||||
@ -113,6 +125,18 @@ VSERVER_GET_ROOT_VOLUME_NAME_RESPONSE = etree.XML("""
|
||||
</results>
|
||||
""" % {'root_volume': ROOT_VOLUME_NAME, 'fake_vserver': VSERVER_NAME})
|
||||
|
||||
VSERVER_GET_IPSPACE_NAME_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
<attributes-list>
|
||||
<vserver-info>
|
||||
<ipspace>%(ipspace)s</ipspace>
|
||||
<vserver-name>%(fake_vserver)s</vserver-name>
|
||||
</vserver-info>
|
||||
</attributes-list>
|
||||
<num-records>1</num-records>
|
||||
</results>
|
||||
""" % {'ipspace': IPSPACE_NAME, 'fake_vserver': VSERVER_NAME})
|
||||
|
||||
VSERVER_GET_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
<attributes>
|
||||
@ -447,6 +471,7 @@ NET_PORT_GET_ITER_BROADCAST_DOMAIN_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
<attributes-list>
|
||||
<net-port-info>
|
||||
<ipspace>%(ipspace)s</ipspace>
|
||||
<broadcast-domain>%(domain)s</broadcast-domain>
|
||||
<node>%(node)s</node>
|
||||
<port>%(port)s</port>
|
||||
@ -454,19 +479,25 @@ NET_PORT_GET_ITER_BROADCAST_DOMAIN_RESPONSE = etree.XML("""
|
||||
</attributes-list>
|
||||
<num-records>1</num-records>
|
||||
</results>
|
||||
""" % {'domain': BROADCAST_DOMAIN, 'node': NODE_NAME, 'port': PORT})
|
||||
""" % {
|
||||
'domain': BROADCAST_DOMAIN,
|
||||
'node': NODE_NAME,
|
||||
'port': PORT,
|
||||
'ipspace': IPSPACE_NAME,
|
||||
})
|
||||
|
||||
NET_PORT_GET_ITER_BROADCAST_DOMAIN_MISSING_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
<attributes-list>
|
||||
<net-port-info>
|
||||
<ipspace>%(ipspace)s</ipspace>
|
||||
<node>%(node)s</node>
|
||||
<port>%(port)s</port>
|
||||
</net-port-info>
|
||||
</attributes-list>
|
||||
<num-records>1</num-records>
|
||||
</results>
|
||||
""" % {'node': NODE_NAME, 'port': PORT})
|
||||
""" % {'node': NODE_NAME, 'port': PORT, 'ipspace': IPSPACE_NAME})
|
||||
|
||||
NET_PORT_BROADCAST_DOMAIN_GET_ITER_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
@ -478,7 +509,35 @@ NET_PORT_BROADCAST_DOMAIN_GET_ITER_RESPONSE = etree.XML("""
|
||||
</attributes-list>
|
||||
<num-records>1</num-records>
|
||||
</results>
|
||||
""" % {'domain': BROADCAST_DOMAIN, 'ipspace': IPSPACE})
|
||||
""" % {'domain': BROADCAST_DOMAIN, 'ipspace': IPSPACE_NAME})
|
||||
|
||||
NET_IPSPACES_GET_ITER_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
<attributes-list>
|
||||
<net-ipspaces-info>
|
||||
<broadcast-domains>
|
||||
<broadcast-domain-name>OpenStack</broadcast-domain-name>
|
||||
</broadcast-domains>
|
||||
<id>fake_id</id>
|
||||
<ipspace>%(ipspace)s</ipspace>
|
||||
<ports>
|
||||
<net-qualified-port-name>%(node)s:%(port)s</net-qualified-port-name>
|
||||
</ports>
|
||||
<uuid>fake_uuid</uuid>
|
||||
<vservers>
|
||||
<vserver-name>%(ipspace)s</vserver-name>
|
||||
<vserver-name>%(vserver)s</vserver-name>
|
||||
</vservers>
|
||||
</net-ipspaces-info>
|
||||
</attributes-list>
|
||||
<num-records>1</num-records>
|
||||
</results>
|
||||
""" % {
|
||||
'ipspace': IPSPACE_NAME,
|
||||
'node': NODE_NAME,
|
||||
'port': VLAN_PORT,
|
||||
'vserver': VSERVER_NAME
|
||||
})
|
||||
|
||||
NET_INTERFACE_GET_ITER_RESPONSE = etree.XML("""
|
||||
<results status="passed">
|
||||
|
@ -140,7 +140,7 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_create_vserver(self):
|
||||
def test_create_vserver_no_ipspace(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
@ -160,12 +160,52 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
self.client.create_vserver(fake.VSERVER_NAME,
|
||||
fake.ROOT_VOLUME_AGGREGATE_NAME,
|
||||
fake.ROOT_VOLUME_NAME,
|
||||
fake.SHARE_AGGREGATE_NAMES)
|
||||
fake.SHARE_AGGREGATE_NAMES,
|
||||
None)
|
||||
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('vserver-create', vserver_create_args),
|
||||
mock.call('vserver-modify', vserver_modify_args)])
|
||||
|
||||
def test_create_vserver_with_ipspace(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
vserver_create_args = {
|
||||
'vserver-name': fake.VSERVER_NAME,
|
||||
'root-volume-security-style': 'unix',
|
||||
'root-volume-aggregate': fake.ROOT_VOLUME_AGGREGATE_NAME,
|
||||
'root-volume': fake.ROOT_VOLUME_NAME,
|
||||
'name-server-switch': {'nsswitch': 'file'},
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
}
|
||||
vserver_modify_args = {
|
||||
'aggr-list': [{'aggr-name': aggr_name} for aggr_name
|
||||
in fake.SHARE_AGGREGATE_NAMES],
|
||||
'vserver-name': fake.VSERVER_NAME
|
||||
}
|
||||
|
||||
self.client.create_vserver(fake.VSERVER_NAME,
|
||||
fake.ROOT_VOLUME_AGGREGATE_NAME,
|
||||
fake.ROOT_VOLUME_NAME,
|
||||
fake.SHARE_AGGREGATE_NAMES,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('vserver-create', vserver_create_args),
|
||||
mock.call('vserver-modify', vserver_modify_args)])
|
||||
|
||||
def test_create_vserver_ipspaces_not_supported(self):
|
||||
|
||||
self.assertRaises(exception.NetAppException,
|
||||
self.client.create_vserver,
|
||||
fake.VSERVER_NAME,
|
||||
fake.ROOT_VOLUME_AGGREGATE_NAME,
|
||||
fake.ROOT_VOLUME_NAME,
|
||||
fake.SHARE_AGGREGATE_NAMES,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
def test_get_vserver_root_volume_name(self):
|
||||
|
||||
api_response = netapp_api.NaElement(
|
||||
@ -187,8 +227,7 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
|
||||
def test_get_vserver_root_volume_name_not_found(self):
|
||||
|
||||
api_response = netapp_api.NaElement(
|
||||
fake.NO_RECORDS_RESPONSE)
|
||||
api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
@ -197,6 +236,96 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
self.client.get_vserver_root_volume_name,
|
||||
fake.VSERVER_NAME)
|
||||
|
||||
def test_get_vserver_ipspace(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(
|
||||
fake.VSERVER_GET_IPSPACE_NAME_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client.get_vserver_ipspace(fake.VSERVER_NAME)
|
||||
|
||||
vserver_get_iter_args = {
|
||||
'query': {
|
||||
'vserver-info': {
|
||||
'vserver-name': fake.VSERVER_NAME,
|
||||
},
|
||||
},
|
||||
'desired-attributes': {
|
||||
'vserver-info': {
|
||||
'ipspace': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('vserver-get-iter', vserver_get_iter_args)])
|
||||
self.assertEqual(fake.IPSPACE_NAME, result)
|
||||
|
||||
def test_get_vserver_ipspace_not_supported(self):
|
||||
|
||||
result = self.client.get_vserver_ipspace(fake.IPSPACE_NAME)
|
||||
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_get_vserver_ipspace_not_found(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
self.assertRaises(exception.NetAppException,
|
||||
self.client.get_vserver_ipspace,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
def test_ipspace_has_data_vservers(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(fake.VSERVER_GET_ITER_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client.ipspace_has_data_vservers(fake.IPSPACE_NAME)
|
||||
|
||||
vserver_get_iter_args = {
|
||||
'query': {
|
||||
'vserver-info': {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'vserver-type': 'data'
|
||||
},
|
||||
},
|
||||
'desired-attributes': {
|
||||
'vserver-info': {
|
||||
'vserver-name': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('vserver-get-iter', vserver_get_iter_args)])
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_ipspace_has_data_vservers_not_supported(self):
|
||||
|
||||
result = self.client.ipspace_has_data_vservers(fake.IPSPACE_NAME)
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_ipspace_has_data_vservers_not_found(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client.ipspace_has_data_vservers(fake.IPSPACE_NAME)
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_list_vservers(self):
|
||||
|
||||
api_response = netapp_api.NaElement(
|
||||
@ -615,7 +744,8 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
fake.NODE_NAME, fake.PORT,
|
||||
fake.VSERVER_NAME,
|
||||
fake.NET_ALLOCATION_ID,
|
||||
fake.LIF_NAME_TEMPLATE)
|
||||
fake.LIF_NAME_TEMPLATE,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
if use_vlans:
|
||||
self.client._create_vlan.assert_called_with(
|
||||
@ -625,7 +755,8 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
|
||||
if broadcast_domains_supported:
|
||||
self.client._ensure_broadcast_domain_for_port.assert_called_with(
|
||||
fake.NODE_NAME, fake.VLAN_PORT if use_vlans else fake.PORT)
|
||||
fake.NODE_NAME, fake.VLAN_PORT if use_vlans else fake.PORT,
|
||||
ipspace=fake.IPSPACE_NAME)
|
||||
else:
|
||||
self.assertFalse(
|
||||
self.client._ensure_broadcast_domain_for_port.called)
|
||||
@ -678,54 +809,15 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
fake.PORT,
|
||||
fake.VLAN)
|
||||
|
||||
def test_ensure_broadcast_domain_for_port_has_domain(self):
|
||||
def test_ensure_broadcast_domain_for_port_domain_match(self):
|
||||
|
||||
port_info = {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
}
|
||||
self.mock_object(self.client,
|
||||
'_get_broadcast_domain_for_port',
|
||||
mock.Mock(return_value=fake.BROADCAST_DOMAIN))
|
||||
self.mock_object(self.client, '_broadcast_domain_exists')
|
||||
self.mock_object(self.client, '_create_broadcast_domain')
|
||||
self.mock_object(self.client, '_add_port_to_broadcast_domain')
|
||||
|
||||
self.client._ensure_broadcast_domain_for_port(fake.NODE_NAME,
|
||||
fake.PORT)
|
||||
|
||||
self.client._get_broadcast_domain_for_port.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT)])
|
||||
self.assertFalse(self.client._broadcast_domain_exists.called)
|
||||
self.assertFalse(self.client._create_broadcast_domain.called)
|
||||
self.assertFalse(self.client._add_port_to_broadcast_domain.called)
|
||||
|
||||
def test_ensure_broadcast_domain_for_port_domain_not_found(self):
|
||||
|
||||
self.mock_object(self.client,
|
||||
'_get_broadcast_domain_for_port',
|
||||
mock.Mock(return_value=None))
|
||||
self.mock_object(self.client,
|
||||
'_broadcast_domain_exists',
|
||||
mock.Mock(return_value=False))
|
||||
self.mock_object(self.client, '_create_broadcast_domain')
|
||||
self.mock_object(self.client, '_add_port_to_broadcast_domain')
|
||||
|
||||
self.client._ensure_broadcast_domain_for_port(
|
||||
fake.NODE_NAME, fake.PORT, domain=fake.BROADCAST_DOMAIN,
|
||||
ipspace=fake.IPSPACE)
|
||||
|
||||
self.client._get_broadcast_domain_for_port.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT)])
|
||||
self.client._broadcast_domain_exists.assert_has_calls([
|
||||
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE)])
|
||||
self.client._create_broadcast_domain.assert_has_calls([
|
||||
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE)])
|
||||
self.client._add_port_to_broadcast_domain.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)])
|
||||
|
||||
def test_ensure_broadcast_domain_for_port_domain_found(self):
|
||||
|
||||
self.mock_object(self.client,
|
||||
'_get_broadcast_domain_for_port',
|
||||
mock.Mock(return_value=None))
|
||||
mock.Mock(return_value=port_info))
|
||||
self.mock_object(self.client,
|
||||
'_broadcast_domain_exists',
|
||||
mock.Mock(return_value=True))
|
||||
@ -734,16 +826,76 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
|
||||
self.client._ensure_broadcast_domain_for_port(
|
||||
fake.NODE_NAME, fake.PORT, domain=fake.BROADCAST_DOMAIN,
|
||||
ipspace=fake.IPSPACE)
|
||||
ipspace=fake.IPSPACE_NAME)
|
||||
|
||||
self.client._get_broadcast_domain_for_port.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT)])
|
||||
self.assertFalse(self.client._broadcast_domain_exists.called)
|
||||
self.assertFalse(self.client._create_broadcast_domain.called)
|
||||
self.assertFalse(self.client._add_port_to_broadcast_domain.called)
|
||||
|
||||
def test_ensure_broadcast_domain_for_port_other_domain(self):
|
||||
|
||||
port_info = {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': 'other_domain',
|
||||
}
|
||||
self.mock_object(self.client,
|
||||
'_get_broadcast_domain_for_port',
|
||||
mock.Mock(return_value=port_info))
|
||||
self.mock_object(self.client,
|
||||
'_broadcast_domain_exists',
|
||||
mock.Mock(return_value=True))
|
||||
self.mock_object(self.client, '_create_broadcast_domain')
|
||||
self.mock_object(self.client, '_remove_port_from_broadcast_domain')
|
||||
self.mock_object(self.client, '_add_port_to_broadcast_domain')
|
||||
|
||||
self.client._ensure_broadcast_domain_for_port(
|
||||
fake.NODE_NAME, fake.PORT, domain=fake.BROADCAST_DOMAIN,
|
||||
ipspace=fake.IPSPACE_NAME)
|
||||
|
||||
self.client._get_broadcast_domain_for_port.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT)])
|
||||
self.client._remove_port_from_broadcast_domain.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT, 'other_domain',
|
||||
fake.IPSPACE_NAME)])
|
||||
self.client._broadcast_domain_exists.assert_has_calls([
|
||||
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE)])
|
||||
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME)])
|
||||
self.assertFalse(self.client._create_broadcast_domain.called)
|
||||
self.client._add_port_to_broadcast_domain.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)])
|
||||
fake.IPSPACE_NAME)])
|
||||
|
||||
def test_ensure_broadcast_domain_for_port_no_domain(self):
|
||||
|
||||
port_info = {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': None,
|
||||
}
|
||||
self.mock_object(self.client,
|
||||
'_get_broadcast_domain_for_port',
|
||||
mock.Mock(return_value=port_info))
|
||||
self.mock_object(self.client,
|
||||
'_broadcast_domain_exists',
|
||||
mock.Mock(return_value=False))
|
||||
self.mock_object(self.client, '_create_broadcast_domain')
|
||||
self.mock_object(self.client, '_remove_port_from_broadcast_domain')
|
||||
self.mock_object(self.client, '_add_port_to_broadcast_domain')
|
||||
|
||||
self.client._ensure_broadcast_domain_for_port(
|
||||
fake.NODE_NAME, fake.PORT, domain=fake.BROADCAST_DOMAIN,
|
||||
ipspace=fake.IPSPACE_NAME)
|
||||
|
||||
self.client._get_broadcast_domain_for_port.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT)])
|
||||
self.assertFalse(self.client._remove_port_from_broadcast_domain.called)
|
||||
self.client._broadcast_domain_exists.assert_has_calls([
|
||||
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME)])
|
||||
self.client._create_broadcast_domain.assert_has_calls([
|
||||
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME)])
|
||||
self.client._add_port_to_broadcast_domain.assert_has_calls([
|
||||
mock.call(fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE_NAME)])
|
||||
|
||||
def test_get_broadcast_domain_for_port(self):
|
||||
|
||||
@ -763,15 +915,20 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
'desired-attributes': {
|
||||
'net-port-info': {
|
||||
'broadcast-domain': None,
|
||||
'ipspace': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
result = self.client._get_broadcast_domain_for_port(fake.NODE_NAME,
|
||||
fake.PORT)
|
||||
|
||||
expected = {
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-port-get-iter', net_port_get_iter_args)])
|
||||
self.assertEqual(fake.BROADCAST_DOMAIN, result)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_broadcast_domain_for_port_port_not_found(self):
|
||||
|
||||
@ -797,7 +954,11 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
result = self.client._get_broadcast_domain_for_port(fake.NODE_NAME,
|
||||
fake.PORT)
|
||||
|
||||
self.assertIsNone(result)
|
||||
expected = {
|
||||
'broadcast-domain': None,
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_broadcast_domain_exists(self):
|
||||
|
||||
@ -808,12 +969,12 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client._broadcast_domain_exists(fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
net_port_broadcast_domain_get_iter_args = {
|
||||
'query': {
|
||||
'net-port-broadcast-domain-info': {
|
||||
'ipspace': fake.IPSPACE,
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
},
|
||||
},
|
||||
@ -835,7 +996,7 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client._broadcast_domain_exists(fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
@ -844,11 +1005,11 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
result = self.client._create_broadcast_domain(fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE,
|
||||
fake.IPSPACE_NAME,
|
||||
mtu=fake.MTU)
|
||||
|
||||
net_port_broadcast_domain_create_args = {
|
||||
'ipspace': fake.IPSPACE,
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
'mtu': fake.MTU,
|
||||
}
|
||||
@ -857,12 +1018,55 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
mock.call('net-port-broadcast-domain-create',
|
||||
net_port_broadcast_domain_create_args)])
|
||||
|
||||
def test_delete_broadcast_domain(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
result = self.client._delete_broadcast_domain(fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
net_port_broadcast_domain_delete_args = {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
}
|
||||
self.assertIsNone(result)
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-port-broadcast-domain-destroy',
|
||||
net_port_broadcast_domain_delete_args)])
|
||||
|
||||
def test_delete_broadcast_domains_for_ipspace_not_found(self):
|
||||
|
||||
self.mock_object(self.client,
|
||||
'get_ipspaces',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(self.client, '_delete_broadcast_domain')
|
||||
|
||||
self.client._delete_broadcast_domains_for_ipspace(fake.IPSPACE_NAME)
|
||||
|
||||
self.client.get_ipspaces.assert_called_once_with(
|
||||
ipspace_name=fake.IPSPACE_NAME)
|
||||
self.assertFalse(self.client._delete_broadcast_domain.called)
|
||||
|
||||
def test_delete_broadcast_domains_for_ipspace(self):
|
||||
|
||||
self.mock_object(self.client,
|
||||
'get_ipspaces',
|
||||
mock.Mock(return_value=fake.IPSPACES))
|
||||
self.mock_object(self.client, '_delete_broadcast_domain')
|
||||
|
||||
self.client._delete_broadcast_domains_for_ipspace(fake.IPSPACE_NAME)
|
||||
|
||||
self.client.get_ipspaces.assert_called_once_with(
|
||||
ipspace_name=fake.IPSPACE_NAME)
|
||||
self.client._delete_broadcast_domain.assert_called_once_with(
|
||||
fake.IPSPACES[0]['broadcast-domains'][0], fake.IPSPACE_NAME)
|
||||
|
||||
def test_add_port_to_broadcast_domain(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
add_port_to_broadcast_domain_args = {
|
||||
'ipspace': fake.IPSPACE,
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
'ports': {
|
||||
'net-qualified-port-name': ':'.join([fake.NODE_NAME,
|
||||
@ -871,7 +1075,7 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
}
|
||||
result = self.client._add_port_to_broadcast_domain(
|
||||
fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
self.assertIsNone(result)
|
||||
self.client.send_request.assert_has_calls([
|
||||
@ -886,7 +1090,7 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
|
||||
result = self.client._add_port_to_broadcast_domain(
|
||||
fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ -899,7 +1103,28 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
fake.NODE_NAME,
|
||||
fake.VLAN_PORT,
|
||||
fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE)
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
def test_remove_port_from_broadcast_domain(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
result = self.client._remove_port_from_broadcast_domain(
|
||||
fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
net_port_broadcast_domain_remove_ports_args = {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'broadcast-domain': fake.BROADCAST_DOMAIN,
|
||||
'ports': {
|
||||
'net-qualified-port-name': ':'.join([fake.NODE_NAME,
|
||||
fake.VLAN_PORT])
|
||||
}
|
||||
}
|
||||
self.assertIsNone(result)
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-port-broadcast-domain-remove-ports',
|
||||
net_port_broadcast_domain_remove_ports_args)])
|
||||
|
||||
def test_network_interface_exists(self):
|
||||
|
||||
@ -1059,6 +1284,128 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-interface-delete', net_interface_delete_args)])
|
||||
|
||||
def test_get_ipspaces(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(
|
||||
fake.NET_IPSPACES_GET_ITER_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client.get_ipspaces(ipspace_name=fake.IPSPACE_NAME,
|
||||
max_records=500)
|
||||
|
||||
net_ipspaces_get_iter_args = {
|
||||
'max-records': 500,
|
||||
'query': {
|
||||
'net-ipspaces-info': {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
},
|
||||
},
|
||||
}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-ipspaces-get-iter', net_ipspaces_get_iter_args)])
|
||||
self.assertEqual(fake.IPSPACES, result)
|
||||
|
||||
def test_get_ipspaces_not_found(self):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client.get_ipspaces()
|
||||
|
||||
net_ipspaces_get_iter_args = {'max-records': 1000}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-ipspaces-get-iter', net_ipspaces_get_iter_args)])
|
||||
self.assertEqual([], result)
|
||||
|
||||
def test_get_ipspaces_not_supported(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
result = self.client.get_ipspaces()
|
||||
|
||||
self.assertFalse(self.client.send_request.called)
|
||||
self.assertEqual([], result)
|
||||
|
||||
@ddt.data((fake.NET_IPSPACES_GET_ITER_RESPONSE, True),
|
||||
(fake.NO_RECORDS_RESPONSE, False))
|
||||
@ddt.unpack
|
||||
def test_ipspace_exists(self, api_response, expected):
|
||||
|
||||
self.client.features.add_feature('IPSPACES')
|
||||
api_response = netapp_api.NaElement(api_response)
|
||||
self.mock_object(self.client,
|
||||
'send_request',
|
||||
mock.Mock(return_value=api_response))
|
||||
|
||||
result = self.client.ipspace_exists(fake.IPSPACE_NAME)
|
||||
|
||||
net_ipspaces_get_iter_args = {
|
||||
'query': {
|
||||
'net-ipspaces-info': {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
},
|
||||
},
|
||||
'desired-attributes': {
|
||||
'net-ipspaces-info': {
|
||||
'ipspace': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-ipspaces-get-iter', net_ipspaces_get_iter_args)])
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_ipspace_exists_not_supported(self):
|
||||
|
||||
result = self.client.ipspace_exists(fake.IPSPACE_NAME)
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_create_ipspace(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
self.client.create_ipspace(fake.IPSPACE_NAME)
|
||||
|
||||
net_ipspaces_create_args = {'ipspace': fake.IPSPACE_NAME}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-ipspaces-create', net_ipspaces_create_args)])
|
||||
|
||||
def test_delete_ipspace(self):
|
||||
|
||||
mock_delete_broadcast_domains_for_ipspace = self.mock_object(
|
||||
self.client, '_delete_broadcast_domains_for_ipspace')
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
self.client.delete_ipspace(fake.IPSPACE_NAME)
|
||||
|
||||
net_ipspaces_destroy_args = {'ipspace': fake.IPSPACE_NAME}
|
||||
mock_delete_broadcast_domains_for_ipspace.assert_called_once_with(
|
||||
fake.IPSPACE_NAME)
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-ipspaces-destroy', net_ipspaces_destroy_args)])
|
||||
|
||||
def test_add_vserver_to_ipspace(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
self.client.add_vserver_to_ipspace(fake.IPSPACE_NAME,
|
||||
fake.VSERVER_NAME)
|
||||
|
||||
net_ipspaces_assign_vserver_args = {
|
||||
'ipspace': fake.IPSPACE_NAME,
|
||||
'vserver': fake.VSERVER_NAME
|
||||
}
|
||||
self.client.send_request.assert_has_calls([
|
||||
mock.call('net-ipspaces-assign-vserver',
|
||||
net_ipspaces_assign_vserver_args)])
|
||||
|
||||
def test_get_node_for_aggregate(self):
|
||||
|
||||
api_response = netapp_api.NaElement(
|
||||
|
@ -199,9 +199,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
'_get_vserver_name',
|
||||
mock.Mock(return_value=fake.VSERVER1))
|
||||
|
||||
mock_create_vserver = self.mock_object(
|
||||
self.library,
|
||||
'_create_vserver_if_nonexistent')
|
||||
mock_create_vserver = self.mock_object(self.library, '_create_vserver')
|
||||
|
||||
mock_validate_network_type = self.mock_object(
|
||||
self.library,
|
||||
@ -224,7 +222,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
fake_exception = exception.ManilaException("fake")
|
||||
mock_create_vserver = self.mock_object(
|
||||
self.library,
|
||||
'_create_vserver_if_nonexistent',
|
||||
'_create_vserver',
|
||||
mock.Mock(side_effect=fake_exception))
|
||||
|
||||
mock_validate_network_type = self.mock_object(
|
||||
@ -270,7 +268,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
self.assertEqual(vserver_name, actual_result)
|
||||
|
||||
def test_create_vserver_if_nonexistent(self):
|
||||
def test_create_vserver(self):
|
||||
|
||||
vserver_id = fake.NETWORK_INFO['server_id']
|
||||
vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id
|
||||
@ -288,27 +286,26 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
self.mock_object(self.library,
|
||||
'_find_matching_aggregates',
|
||||
mock.Mock(return_value=fake.AGGREGATES))
|
||||
self.mock_object(self.library,
|
||||
'_create_ipspace',
|
||||
mock.Mock(return_value=fake.IPSPACE))
|
||||
self.mock_object(self.library, '_create_vserver_lifs')
|
||||
|
||||
self.library._create_vserver_if_nonexistent(vserver_name,
|
||||
fake.NETWORK_INFO)
|
||||
self.library._get_api_client.assert_called_with(vserver=vserver_name)
|
||||
self.library._create_vserver(vserver_name, fake.NETWORK_INFO)
|
||||
|
||||
self.library._create_ipspace.assert_called_with(fake.NETWORK_INFO)
|
||||
self.library._client.create_vserver.assert_called_with(
|
||||
vserver_name,
|
||||
fake.ROOT_VOLUME_AGGREGATE,
|
||||
fake.ROOT_VOLUME,
|
||||
fake.AGGREGATES)
|
||||
vserver_name, fake.ROOT_VOLUME_AGGREGATE, fake.ROOT_VOLUME,
|
||||
fake.AGGREGATES, fake.IPSPACE)
|
||||
self.library._get_api_client.assert_called_with(vserver=vserver_name)
|
||||
self.library._create_vserver_lifs.assert_called_with(
|
||||
vserver_name,
|
||||
vserver_client,
|
||||
fake.NETWORK_INFO)
|
||||
vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE)
|
||||
self.assertTrue(vserver_client.enable_nfs.called)
|
||||
self.library._client.setup_security_services.assert_called_with(
|
||||
fake.NETWORK_INFO['security_services'],
|
||||
vserver_client,
|
||||
fake.NETWORK_INFO['security_services'], vserver_client,
|
||||
vserver_name)
|
||||
|
||||
def test_create_vserver_if_nonexistent_already_present(self):
|
||||
def test_create_vserver_already_present(self):
|
||||
|
||||
vserver_id = fake.NETWORK_INFO['server_id']
|
||||
vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id
|
||||
@ -321,13 +318,12 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
mock.Mock(return_value=True))
|
||||
|
||||
self.assertRaises(exception.NetAppException,
|
||||
self.library._create_vserver_if_nonexistent,
|
||||
self.library._create_vserver,
|
||||
vserver_name,
|
||||
fake.NETWORK_INFO)
|
||||
|
||||
@ddt.data(netapp_api.NaApiError, exception.NetAppException)
|
||||
def test_create_vserver_if_nonexistent_lif_creation_failure(self,
|
||||
lif_exception):
|
||||
def test_create_vserver_lif_creation_failure(self, lif_exception):
|
||||
|
||||
vserver_id = fake.NETWORK_INFO['server_id']
|
||||
vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id
|
||||
@ -345,12 +341,16 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
self.mock_object(self.library,
|
||||
'_find_matching_aggregates',
|
||||
mock.Mock(return_value=fake.AGGREGATES))
|
||||
self.mock_object(self.library,
|
||||
'_create_ipspace',
|
||||
mock.Mock(return_value=fake.IPSPACE))
|
||||
self.mock_object(self.library,
|
||||
'_create_vserver_lifs',
|
||||
mock.Mock(side_effect=lif_exception))
|
||||
self.mock_object(self.library, '_delete_vserver')
|
||||
|
||||
self.assertRaises(lif_exception,
|
||||
self.library._create_vserver_if_nonexistent,
|
||||
self.library._create_vserver,
|
||||
vserver_name,
|
||||
fake.NETWORK_INFO)
|
||||
|
||||
@ -359,13 +359,85 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
self.library._create_vserver_lifs.assert_called_with(
|
||||
vserver_name,
|
||||
vserver_client,
|
||||
fake.NETWORK_INFO)
|
||||
self.library._client.delete_vserver.assert_called_once_with(
|
||||
fake.NETWORK_INFO,
|
||||
fake.IPSPACE)
|
||||
self.library._delete_vserver.assert_called_once_with(
|
||||
vserver_name,
|
||||
vserver_client)
|
||||
security_services=None)
|
||||
self.assertFalse(vserver_client.enable_nfs.called)
|
||||
self.assertEqual(1, lib_multi_svm.LOG.error.call_count)
|
||||
|
||||
def test_get_valid_ipspace_name(self):
|
||||
|
||||
result = self.library._get_valid_ipspace_name(fake.IPSPACE_ID)
|
||||
|
||||
expected = 'ipspace_' + fake.IPSPACE_ID.replace('-', '_')
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_create_ipspace_not_supported(self):
|
||||
|
||||
self.library._client.features.IPSPACES = False
|
||||
|
||||
result = self.library._create_ipspace(fake.NETWORK_INFO)
|
||||
|
||||
self.assertIsNone(result)
|
||||
|
||||
@ddt.data(None, 'flat')
|
||||
def test_create_ipspace_not_vlan(self, network_type):
|
||||
|
||||
self.library._client.features.IPSPACES = True
|
||||
network_info = copy.deepcopy(fake.NETWORK_INFO)
|
||||
network_info['segmentation_id'] = None
|
||||
network_info['network_type'] = network_type
|
||||
|
||||
result = self.library._create_ipspace(network_info)
|
||||
|
||||
self.assertEqual('Default', result)
|
||||
|
||||
def test_create_ipspace_not_neutron(self):
|
||||
|
||||
self.library._client.features.IPSPACES = True
|
||||
network_info = copy.deepcopy(fake.NETWORK_INFO)
|
||||
network_info['neutron_subnet_id'] = None
|
||||
network_info['nova_net_id'] = 'fake_nova_net_id'
|
||||
|
||||
result = self.library._create_ipspace(network_info)
|
||||
|
||||
self.assertEqual('Default', result)
|
||||
|
||||
def test_create_ipspace_already_present(self):
|
||||
|
||||
self.library._client.features.IPSPACES = True
|
||||
self.mock_object(self.library._client,
|
||||
'ipspace_exists',
|
||||
mock.Mock(return_value=True))
|
||||
|
||||
result = self.library._create_ipspace(fake.NETWORK_INFO)
|
||||
|
||||
expected = self.library._get_valid_ipspace_name(
|
||||
fake.NETWORK_INFO['neutron_subnet_id'])
|
||||
self.assertEqual(expected, result)
|
||||
self.library._client.ipspace_exists.assert_has_calls([
|
||||
mock.call(expected)])
|
||||
self.assertFalse(self.library._client.create_ipspace.called)
|
||||
|
||||
def test_create_ipspace(self):
|
||||
|
||||
self.library._client.features.IPSPACES = True
|
||||
self.mock_object(self.library._client,
|
||||
'ipspace_exists',
|
||||
mock.Mock(return_value=False))
|
||||
|
||||
result = self.library._create_ipspace(fake.NETWORK_INFO)
|
||||
|
||||
expected = self.library._get_valid_ipspace_name(
|
||||
fake.NETWORK_INFO['neutron_subnet_id'])
|
||||
self.assertEqual(expected, result)
|
||||
self.library._client.ipspace_exists.assert_has_calls([
|
||||
mock.call(expected)])
|
||||
self.library._client.create_ipspace.assert_has_calls([
|
||||
mock.call(expected)])
|
||||
|
||||
def test_create_vserver_lifs(self):
|
||||
|
||||
self.mock_object(self.library._client,
|
||||
@ -378,7 +450,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
self.library._create_vserver_lifs(fake.VSERVER1,
|
||||
'fake_vserver_client',
|
||||
fake.NETWORK_INFO)
|
||||
fake.NETWORK_INFO,
|
||||
fake.IPSPACE)
|
||||
|
||||
self.library._create_lif_if_nonexistent.assert_has_calls([
|
||||
mock.call(
|
||||
@ -389,6 +462,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
fake.NODE_DATA_PORT,
|
||||
fake.NETWORK_INFO['network_allocations'][0]['ip_address'],
|
||||
fake.NETWORK_INFO_NETMASK,
|
||||
fake.IPSPACE,
|
||||
'fake_vserver_client'),
|
||||
mock.call(
|
||||
fake.VSERVER1,
|
||||
@ -398,6 +472,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
fake.NODE_DATA_PORT,
|
||||
fake.NETWORK_INFO['network_allocations'][1]['ip_address'],
|
||||
fake.NETWORK_INFO_NETMASK,
|
||||
fake.IPSPACE,
|
||||
'fake_vserver_client')])
|
||||
|
||||
def test_get_node_data_port(self):
|
||||
@ -437,6 +512,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
'fake_port',
|
||||
'fake_ip',
|
||||
'fake_netmask',
|
||||
fake.IPSPACE,
|
||||
vserver_client)
|
||||
|
||||
self.library._client.create_network_interface.assert_has_calls([
|
||||
@ -448,7 +524,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
'fake_port',
|
||||
'fake_vserver',
|
||||
'fake_allocation_id',
|
||||
fake.LIF_NAME_TEMPLATE)])
|
||||
fake.LIF_NAME_TEMPLATE,
|
||||
fake.IPSPACE)])
|
||||
|
||||
def test_create_lif_if_nonexistent_already_present(self):
|
||||
|
||||
@ -463,6 +540,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
'fake_port',
|
||||
'fake_ip',
|
||||
'fake_netmask',
|
||||
fake.IPSPACE,
|
||||
vserver_client)
|
||||
|
||||
self.assertFalse(self.library._client.create_network_interface.called)
|
||||
@ -478,11 +556,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
def test_teardown_server(self):
|
||||
|
||||
vserver_client = mock.Mock()
|
||||
self.mock_object(self.library,
|
||||
'_get_api_client',
|
||||
mock.Mock(return_value=vserver_client))
|
||||
self.library._client.vserver_exists.return_value = True
|
||||
mock_delete_vserver = self.mock_object(self.library,
|
||||
'_delete_vserver')
|
||||
|
||||
self.library.teardown_server(
|
||||
fake.SHARE_SERVER['backend_details'],
|
||||
@ -490,22 +566,26 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
self.library._client.vserver_exists.assert_called_once_with(
|
||||
fake.VSERVER1)
|
||||
self.library._client.delete_vserver.assert_called_once_with(
|
||||
mock_delete_vserver.assert_called_once_with(
|
||||
fake.VSERVER1,
|
||||
vserver_client,
|
||||
security_services=fake.NETWORK_INFO['security_services'])
|
||||
|
||||
@ddt.data(None, {}, {'vserver_name': None})
|
||||
def test_teardown_server_no_share_server(self, server_details):
|
||||
|
||||
mock_delete_vserver = self.mock_object(self.library,
|
||||
'_delete_vserver')
|
||||
|
||||
self.library.teardown_server(server_details)
|
||||
|
||||
self.assertFalse(self.library._client.delete_vserver.called)
|
||||
self.assertFalse(mock_delete_vserver.called)
|
||||
self.assertTrue(lib_multi_svm.LOG.warning.called)
|
||||
|
||||
def test_teardown_server_no_vserver(self):
|
||||
|
||||
self.library._client.vserver_exists.return_value = False
|
||||
mock_delete_vserver = self.mock_object(self.library,
|
||||
'_delete_vserver')
|
||||
|
||||
self.library.teardown_server(
|
||||
fake.SHARE_SERVER['backend_details'],
|
||||
@ -513,5 +593,72 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
self.library._client.vserver_exists.assert_called_once_with(
|
||||
fake.VSERVER1)
|
||||
self.assertFalse(self.library._client.delete_vserver.called)
|
||||
self.assertFalse(mock_delete_vserver.called)
|
||||
self.assertTrue(lib_multi_svm.LOG.warning.called)
|
||||
|
||||
def test_delete_vserver_no_ipspace(self):
|
||||
|
||||
self.mock_object(self.library._client,
|
||||
'get_vserver_ipspace',
|
||||
mock.Mock(return_value=None))
|
||||
vserver_client = mock.Mock()
|
||||
self.mock_object(self.library,
|
||||
'_get_api_client',
|
||||
mock.Mock(return_value=vserver_client))
|
||||
security_services = fake.NETWORK_INFO['security_services']
|
||||
|
||||
self.library._delete_vserver(fake.VSERVER1,
|
||||
security_services=security_services)
|
||||
|
||||
self.library._client.get_vserver_ipspace.assert_called_once_with(
|
||||
fake.VSERVER1)
|
||||
self.library._client.delete_vserver.assert_called_once_with(
|
||||
fake.VSERVER1, vserver_client, security_services=security_services)
|
||||
self.assertFalse(self.library._client.delete_ipspace.called)
|
||||
|
||||
def test_delete_vserver_ipspace_has_data_vservers(self):
|
||||
|
||||
self.mock_object(self.library._client,
|
||||
'get_vserver_ipspace',
|
||||
mock.Mock(return_value=fake.IPSPACE))
|
||||
vserver_client = mock.Mock()
|
||||
self.mock_object(self.library,
|
||||
'_get_api_client',
|
||||
mock.Mock(return_value=vserver_client))
|
||||
self.mock_object(self.library._client,
|
||||
'ipspace_has_data_vservers',
|
||||
mock.Mock(return_value=True))
|
||||
security_services = fake.NETWORK_INFO['security_services']
|
||||
|
||||
self.library._delete_vserver(fake.VSERVER1,
|
||||
security_services=security_services)
|
||||
|
||||
self.library._client.get_vserver_ipspace.assert_called_once_with(
|
||||
fake.VSERVER1)
|
||||
self.library._client.delete_vserver.assert_called_once_with(
|
||||
fake.VSERVER1, vserver_client, security_services=security_services)
|
||||
self.assertFalse(self.library._client.delete_ipspace.called)
|
||||
|
||||
def test_delete_vserver_with_ipspace(self):
|
||||
|
||||
self.mock_object(self.library._client,
|
||||
'get_vserver_ipspace',
|
||||
mock.Mock(return_value=fake.IPSPACE))
|
||||
vserver_client = mock.Mock()
|
||||
self.mock_object(self.library,
|
||||
'_get_api_client',
|
||||
mock.Mock(return_value=vserver_client))
|
||||
self.mock_object(self.library._client,
|
||||
'ipspace_has_data_vservers',
|
||||
mock.Mock(return_value=False))
|
||||
security_services = fake.NETWORK_INFO['security_services']
|
||||
|
||||
self.library._delete_vserver(fake.VSERVER1,
|
||||
security_services=security_services)
|
||||
|
||||
self.library._client.get_vserver_ipspace.assert_called_once_with(
|
||||
fake.VSERVER1)
|
||||
self.library._client.delete_vserver.assert_called_once_with(
|
||||
fake.VSERVER1, vserver_client, security_services=security_services)
|
||||
self.library._client.delete_ipspace.assert_called_once_with(
|
||||
fake.IPSPACE)
|
||||
|
@ -62,6 +62,8 @@ NODE_DATA_PORTS = ('e0c', 'e0d')
|
||||
LIF_NAME_TEMPLATE = 'os_%(net_allocation_id)s'
|
||||
SHARE_TYPE_ID = '26e89a5b-960b-46bb-a8cf-0778e653098f'
|
||||
SHARE_TYPE_NAME = 'fake_share_type'
|
||||
IPSPACE = 'fake_ipspace'
|
||||
IPSPACE_ID = '27d38c27-3e8b-4d7d-9d91-fcf295e3ac8f'
|
||||
|
||||
CLIENT_KWARGS = {
|
||||
'username': 'admin',
|
||||
@ -203,7 +205,8 @@ NETWORK_INFO = {
|
||||
'ip_address': '10.10.10.10'},
|
||||
{'id': '7eabdeed-bad2-46ea-bd0f-a33884c869e0',
|
||||
'ip_address': '10.10.10.20'}
|
||||
]
|
||||
],
|
||||
'neutron_subnet_id': '62bf1c2c-18eb-421b-8983-48a6d39aafe0',
|
||||
}
|
||||
NETWORK_INFO_NETMASK = '255.255.255.0'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user