# limitations under the License.
import logging
-from neutronclient.common.exceptions import NotFound
+import enum
+from neutronclient.common.exceptions import NetworkNotFoundClient
from snaps.openstack.openstack_creator import OpenStackNetworkObject
from snaps.openstack.utils import keystone_utils, neutron_utils
# Attributes instantiated on create()
self.__network = None
- self.__subnets = list()
def initialize(self):
"""
self._neutron, network_settings=self.network_settings,
project_id=self.network_settings.get_project_id(self._os_creds))
- if self.__network:
- for subnet_setting in self.network_settings.subnet_settings:
- sub_inst = neutron_utils.get_subnet(
- self._neutron, subnet_settings=subnet_setting)
- if sub_inst:
- self.__subnets.append(sub_inst)
- logger.debug(
- "Subnet '%s' created successfully" % sub_inst.id)
-
return self.__network
def create(self):
self.__network = neutron_utils.create_network(
self._neutron, self._os_creds, self.network_settings)
logger.debug(
- "Network '%s' created successfully" % self.__network.id)
-
- for subnet_setting in self.network_settings.subnet_settings:
- sub_inst = neutron_utils.get_subnet(
- self._neutron, subnet_settings=subnet_setting)
- if not sub_inst:
- sub_inst = neutron_utils.create_subnet(
- self._neutron, subnet_setting, self._os_creds,
- self.__network)
- if sub_inst:
- self.__subnets.append(sub_inst)
- logger.debug(
- "Subnet '%s' created successfully" % sub_inst.id)
+ 'Network [%s] created successfully' % self.__network.id)
return self.__network
"""
Removes and deletes all items created in reverse order.
"""
- for subnet in self.__subnets:
- try:
- logger.info(
- 'Deleting subnet with name ' + subnet.name)
- neutron_utils.delete_subnet(self._neutron, subnet)
- except NotFound as e:
- logger.warning(
- 'Error deleting subnet with message - ' + str(e))
- pass
- self.__subnets = list()
-
if self.__network:
try:
neutron_utils.delete_network(self._neutron, self.__network)
- except NotFound:
+ except NetworkNotFoundClient:
pass
-
self.__network = None
def get_network(self):
"""
return self.__network
- def get_subnets(self):
- """
- Returns the OpenStack subnet objects
- :return:
- """
- return self.__subnets
-
class NetworkSettings:
"""
self.subnet_settings = list()
subnet_settings = kwargs.get('subnets')
if not subnet_settings:
- subnet_settings = kwargs.get('subnet_settings')
+ subnet_settings = kwargs.get('subnet_settings', list())
if subnet_settings:
for subnet_config in subnet_settings:
if isinstance(subnet_config, SubnetSettings):
"""
+class IPv6Mode(enum.Enum):
+ """
+ A rule's direction
+ """
+ slaac = 'slaac'
+ stateful = 'dhcpv6-stateful'
+ stateless = 'dhcpv6-stateless'
+
+
class SubnetSettings:
"""
Class representing a subnet configuration
]
:param destination: The destination for static route (optional)
:param nexthop: The next hop for the destination (optional)
- :param ipv6_ra_mode: A valid value is dhcpv6-stateful,
- dhcpv6-stateless, or slaac (optional)
- :param ipv6_address_mode: A valid value is dhcpv6-stateful,
- dhcpv6-stateless, or slaac (optional)
+ :param ipv6_ra_mode: an instance of the IPv6Mode enum
+ (optional when enable_dhcp is True)
+ :param ipv6_address_mode: an instance of the IPv6Mode enum
+ (optional when enable_dhcp is True)
:raise: SubnetSettingsError when config does not have or cidr values
are None
"""
self.gateway_ip = kwargs.get('gateway_ip')
self.enable_dhcp = kwargs.get('enable_dhcp')
- if kwargs.get('dns_nameservers'):
+ if 'dns_nameservers' in kwargs:
self.dns_nameservers = kwargs.get('dns_nameservers')
else:
- self.dns_nameservers = ['8.8.8.8']
+ if self.ip_version == 4:
+ self.dns_nameservers = ['8.8.8.8']
+ else:
+ self.dns_nameservers = list()
self.host_routes = kwargs.get('host_routes')
self.destination = kwargs.get('destination')
self.nexthop = kwargs.get('nexthop')
- self.ipv6_ra_mode = kwargs.get('ipv6_ra_mode')
- self.ipv6_address_mode = kwargs.get('ipv6_address_mode')
+ self.ipv6_ra_mode = map_mode(kwargs.get('ipv6_ra_mode'))
+ self.ipv6_address_mode = map_mode(kwargs.get('ipv6_address_mode'))
if not self.name or not self.cidr:
raise SubnetSettingsError('Name and cidr required for subnets')
if self.nexthop:
out['nexthop'] = self.nexthop
if self.ipv6_ra_mode:
- out['ipv6_ra_mode'] = self.ipv6_ra_mode
+ out['ipv6_ra_mode'] = self.ipv6_ra_mode.value
if self.ipv6_address_mode:
- out['ipv6_address_mode'] = self.ipv6_address_mode
+ out['ipv6_address_mode'] = self.ipv6_address_mode.value
return out
+def map_mode(mode):
+ """
+ Takes a the direction value maps it to the Direction enum. When None return
+ None
+ :param mode: the mode value
+ :return: the IPv6Mode enum object
+ :raise: SubnetSettingsError if value is invalid
+ """
+ if not mode:
+ return None
+ if isinstance(mode, IPv6Mode):
+ return mode
+ else:
+ mode_str = str(mode)
+ if mode_str == 'slaac':
+ return IPv6Mode.slaac
+ elif mode_str == 'dhcpv6-stateful':
+ return IPv6Mode.stateful
+ elif mode_str == 'stateful':
+ return IPv6Mode.stateful
+ elif mode_str == 'dhcpv6-stateless':
+ return IPv6Mode.stateless
+ elif mode_str == 'stateless':
+ return IPv6Mode.stateless
+ else:
+ raise SubnetSettingsError('Invalid mode - ' + mode_str)
+
+
class SubnetSettingsError(Exception):
"""
Exception to be thrown when subnet settings attributes are incorrect
'subnet_name' and 'ip' values which will get mapped to
self.fixed_ips. These values will be directly
translated into the fixed_ips dict (optional)
- :param fixed_ips: A dict where the key is the subnet IDs and value is
- the IP address to assign to the port (optional and
- recommended to configure via ip_addrs instead)
:param security_groups: One or more security group IDs.
:param allowed_address_pairs: A dictionary containing a set of zero or
more allowed address pairs. An address
if 'port' in kwargs:
kwargs = kwargs['port']
- self.network = None
-
self.name = kwargs.get('name')
self.network_name = kwargs.get('network_name')
self.project_name = kwargs.get('project_name')
self.mac_address = kwargs.get('mac_address')
self.ip_addrs = kwargs.get('ip_addrs')
- self.fixed_ips = kwargs.get('fixed_ips')
self.security_groups = kwargs.get('security_groups')
self.allowed_address_pairs = kwargs.get('allowed_address_pairs')
self.opt_value = kwargs.get('opt_value')
raise PortSettingsError(
'The attribute network_name is required')
- def __set_fixed_ips(self, neutron):
+ def __get_fixed_ips(self, neutron):
"""
Sets the self.fixed_ips value
:param neutron: the Neutron client
:return: None
"""
- if not self.fixed_ips and self.ip_addrs:
- self.fixed_ips = list()
+
+ fixed_ips = list()
+ if self.ip_addrs:
for ip_addr_dict in self.ip_addrs:
subnet = neutron_utils.get_subnet(
neutron, subnet_name=ip_addr_dict['subnet_name'])
if subnet and 'ip' in ip_addr_dict:
- self.fixed_ips.append({'ip_address': ip_addr_dict['ip'],
- 'subnet_id': subnet.id})
+ fixed_ips.append({'ip_address': ip_addr_dict['ip'],
+ 'subnet_id': subnet.id})
else:
raise PortSettingsError(
'Invalid port configuration, subnet does not exist '
'with name - ' + ip_addr_dict['subnet_name'])
+ return fixed_ips
+
def dict_for_neutron(self, neutron, os_creds):
"""
Returns a dictionary object representing this object.
:param os_creds: the OpenStack credentials
:return: the dictionary object
"""
- self.__set_fixed_ips(neutron)
out = dict()
if project:
project_id = project.id
- if not self.network:
- self.network = neutron_utils.get_network(
- neutron, network_name=self.network_name, project_id=project_id)
- if not self.network:
+ network = neutron_utils.get_network(
+ neutron, network_name=self.network_name, project_id=project_id)
+ if not network:
raise PortSettingsError(
'Cannot locate network with name - ' + self.network_name)
- out['network_id'] = self.network.id
+ out['network_id'] = network.id
if self.admin_state_up is not None:
out['admin_state_up'] = self.admin_state_up
self.project_name)
if self.mac_address:
out['mac_address'] = self.mac_address
- if self.fixed_ips and len(self.fixed_ips) > 0:
- out['fixed_ips'] = self.fixed_ips
+
+ fixed_ips = self.__get_fixed_ips(neutron)
+ if fixed_ips and len(fixed_ips) > 0:
+ out['fixed_ips'] = fixed_ips
+
if self.security_groups:
out['security_groups'] = self.security_groups
if self.allowed_address_pairs and len(self.allowed_address_pairs) > 0:
self.project_name == other.project_name and
self.mac_address == other.mac_address and
self.ip_addrs == other.ip_addrs and
- self.fixed_ips == other.fixed_ips and
+ # self.fixed_ips == other.fixed_ips and
self.security_groups == other.security_groups and
self.allowed_address_pairs == other.allowed_address_pairs and
self.opt_value == other.opt_value and