Added port security flag support to ports.
[snaps.git] / snaps / openstack / create_router.py
index 3e0d904..4f95c3b 100644 (file)
 import logging
 
 from neutronclient.common.exceptions import NotFound
-from snaps.openstack.create_network import PortSettings
-from snaps.openstack.utils import neutron_utils, keystone_utils
+
+from snaps.config.router import RouterConfig
+from snaps.openstack.openstack_creator import OpenStackNetworkObject
+from snaps.openstack.utils import neutron_utils
 
 __author__ = 'spisarski'
 
 logger = logging.getLogger('OpenStackNetwork')
 
 
-class OpenStackRouter:
+class OpenStackRouter(OpenStackNetworkObject):
     """
-    Class responsible for creating a router in OpenStack
+    Class responsible for managing a router in OpenStack
     """
 
     def __init__(self, os_creds, router_settings):
@@ -33,16 +35,15 @@ class OpenStackRouter:
         Constructor - all parameters are required
         :param os_creds: The credentials to connect with OpenStack
         :param router_settings: The settings used to create a router object
-                                (must be an instance of the RouterSettings
+                                (must be an instance of the RouterConfig
                                 class)
         """
-        self.__os_creds = os_creds
+        super(self.__class__, self).__init__(os_creds)
 
         if not router_settings:
             raise RouterCreationError('router_settings is required')
 
         self.router_settings = router_settings
-        self.__neutron = None
 
         # Attributes instantiated on create()
         self.__router = None
@@ -53,65 +54,88 @@ class OpenStackRouter:
         # interfaces are the value
         self.__ports = list()
 
-    def create(self, cleanup=False):
+    def initialize(self):
         """
-        Responsible for creating the router.
-        :param cleanup: When true, only perform lookups for OpenStack objects.
-        :return: the router object
+        Loads the existing router.
+        :return: the Router domain object
         """
-        self.__neutron = neutron_utils.neutron_client(self.__os_creds)
-
-        logger.debug(
-            'Creating Router with name - ' + self.router_settings.name)
-        existing = False
-        router_inst = neutron_utils.get_router_by_name(
-            self.__neutron, self.router_settings.name)
-        if router_inst:
-            self.__router = router_inst
-            existing = True
-        else:
-            if not cleanup:
-                self.__router = neutron_utils.create_router(
-                    self.__neutron, self.__os_creds, self.router_settings)
-
-        for internal_subnet_name in self.router_settings.internal_subnets:
-            internal_subnet = neutron_utils.get_subnet_by_name(
-                self.__neutron, internal_subnet_name)
-            if internal_subnet:
-                self.__internal_subnets.append(internal_subnet)
-                if internal_subnet and not cleanup and not existing:
-                    logger.debug('Adding router to subnet...')
-                    router_intf = neutron_utils.add_interface_router(
-                        self.__neutron, self.__router, subnet=internal_subnet)
-                    self.__internal_router_interface = router_intf
-            else:
-                raise RouterCreationError(
-                    'Subnet not found with name ' + internal_subnet_name)
-
-        for port_setting in self.router_settings.port_settings:
-            port = neutron_utils.get_port_by_name(self.__neutron,
-                                                  port_setting.name)
-            logger.info(
-                'Retrieved port %s for router - %s', port_setting.name,
-                self.router_settings.name)
-            if port:
-                self.__ports.append(port)
-
-            if not port and not cleanup and not existing:
-                port = neutron_utils.create_port(self.__neutron,
-                                                 self.__os_creds, port_setting)
+        super(self.__class__, self).initialize()
+
+        self.__router = neutron_utils.get_router(
+            self._neutron, router_settings=self.router_settings)
+
+        if self.__router:
+            for internal_subnet_name in self.router_settings.internal_subnets:
+                internal_subnet = neutron_utils.get_subnet(
+                    self._neutron, subnet_name=internal_subnet_name)
+                if internal_subnet:
+                    self.__internal_subnets.append(internal_subnet)
+                else:
+                    raise RouterCreationError(
+                        'Subnet not found with name ' + internal_subnet_name)
+
+            for port_setting in self.router_settings.port_settings:
+                port = neutron_utils.get_port(
+                    self._neutron, port_settings=port_setting)
                 if port:
-                    logger.info(
-                        'Created port %s for router - %s', port_setting.name,
-                        self.router_settings.name)
                     self.__ports.append(port)
-                    neutron_utils.add_interface_router(self.__neutron,
-                                                       self.__router,
-                                                       port=port)
+
+        return self.__router
+
+    def create(self):
+        """
+        Responsible for creating the router.
+        :return: the Router domain object
+        """
+        self.initialize()
+
+        if not self.__router:
+            self.__router = neutron_utils.create_router(
+                self._neutron, self._os_creds, self.router_settings)
+
+            for internal_subnet_name in self.router_settings.internal_subnets:
+                internal_subnet = neutron_utils.get_subnet(
+                    self._neutron, subnet_name=internal_subnet_name)
+                if internal_subnet:
+                    self.__internal_subnets.append(internal_subnet)
+                    if internal_subnet:
+                        logger.debug('Adding router to subnet...')
+                        router_intf = neutron_utils.add_interface_router(
+                            self._neutron, self.__router,
+                            subnet=internal_subnet)
+                        self.__internal_router_interface = router_intf
                 else:
                     raise RouterCreationError(
-                        'Error creating port with name - ' + port_setting.name)
+                        'Subnet not found with name ' + internal_subnet_name)
+
+            for port_setting in self.router_settings.port_settings:
+                port = neutron_utils.get_port(
+                    self._neutron, port_settings=port_setting)
+                logger.info(
+                    'Retrieved port %s for router - %s', port_setting.name,
+                    self.router_settings.name)
+                if port:
+                    self.__ports.append(port)
 
+                if not port:
+                    port = neutron_utils.create_port(
+                        self._neutron, self._os_creds, port_setting)
+                    if port:
+                        logger.info(
+                            'Created port %s for router - %s',
+                            port_setting.name,
+                            self.router_settings.name)
+                        self.__ports.append(port)
+                        neutron_utils.add_interface_router(self._neutron,
+                                                           self.__router,
+                                                           port=port)
+                    else:
+                        raise RouterCreationError(
+                            'Error creating port with name - '
+                            + port_setting.name)
+
+        self.__router = neutron_utils.get_router_by_id(
+            self._neutron, self.__router.id)
         return self.__router
 
     def clean(self):
@@ -123,7 +147,7 @@ class OpenStackRouter:
                 'Removing router interface from router %s and port %s',
                 self.router_settings.name, port.name)
             try:
-                neutron_utils.remove_interface_router(self.__neutron,
+                neutron_utils.remove_interface_router(self._neutron,
                                                       self.__router, port=port)
             except NotFound:
                 pass
@@ -134,7 +158,7 @@ class OpenStackRouter:
                 'Removing router interface from router %s and subnet %s',
                 self.router_settings.name, internal_subnet.name)
             try:
-                neutron_utils.remove_interface_router(self.__neutron,
+                neutron_utils.remove_interface_router(self._neutron,
                                                       self.__router,
                                                       subnet=internal_subnet)
             except NotFound:
@@ -144,7 +168,7 @@ class OpenStackRouter:
         if self.__router:
             logger.info('Removing router ' + self.router_settings.name)
             try:
-                neutron_utils.delete_router(self.__neutron, self.__router)
+                neutron_utils.delete_router(self._neutron, self.__router)
             except NotFound:
                 pass
             self.__router = None
@@ -170,101 +194,15 @@ class RouterCreationError(Exception):
     """
 
 
-class RouterSettings:
+class RouterSettings(RouterConfig):
     """
-    Class representing a router configuration
+    Class to hold the configuration settings required for creating OpenStack
+    router objects
+    deprecated
     """
 
     def __init__(self, **kwargs):
-        """
-        Constructor - all parameters are optional
-        :param name: The router name.
-        :param project_name: The name of the project who owns the network. Only
-                             administrative users can specify a project ID
-                             other than their own. You cannot change this value
-                             through authorization policies.
-        :param external_gateway: Name of the external network to which to route
-        :param admin_state_up: The administrative status of the router.
-                               True = up / False = down (default True)
-        :param external_fixed_ips: Dictionary containing the IP address
-                                   parameters.
-        :param internal_subnets: List of subnet names to which to connect this
-                                 router for Floating IP purposes
-        :param port_settings: List of PortSettings objects
-        :return:
-        """
-        self.name = kwargs.get('name')
-        self.project_name = kwargs.get('project_name')
-        self.external_gateway = kwargs.get('external_gateway')
-
-        self.admin_state_up = kwargs.get('admin_state_up')
-        self.enable_snat = kwargs.get('enable_snat')
-        self.external_fixed_ips = kwargs.get('external_fixed_ips')
-        if kwargs.get('internal_subnets'):
-            self.internal_subnets = kwargs['internal_subnets']
-        else:
-            self.internal_subnets = list()
-
-        self.port_settings = list()
-        if kwargs.get('interfaces', kwargs.get('port_settings')):
-            interfaces = kwargs.get('interfaces', kwargs.get('port_settings'))
-            for interface in interfaces:
-                if isinstance(interface, PortSettings):
-                    self.port_settings.append(interface)
-                else:
-                    self.port_settings.append(
-                        PortSettings(**interface['port']))
-
-        if not self.name:
-            raise RouterSettingsError('Name is required')
-
-    def dict_for_neutron(self, neutron, os_creds):
-        """
-        Returns a dictionary object representing this object.
-        This is meant to be converted into JSON designed for use by the Neutron
-        API
-
-        TODO - expand automated testing to exercise all parameters
-        :param neutron: The neutron client to retrieve external network
-                        information if necessary
-        :param os_creds: The OpenStack credentials
-        :return: the dictionary object
-        """
-        out = dict()
-        ext_gw = dict()
-
-        if self.name:
-            out['name'] = self.name
-        if self.project_name:
-            keystone = keystone_utils.keystone_client(os_creds)
-            project = keystone_utils.get_project(
-                keystone=keystone, project_name=self.project_name)
-            project_id = None
-            if project:
-                project_id = project.id
-            if project_id:
-                out['tenant_id'] = project_id
-            else:
-                raise RouterSettingsError(
-                    'Could not find project ID for project named - ' +
-                    self.project_name)
-        if self.admin_state_up is not None:
-            out['admin_state_up'] = self.admin_state_up
-        if self.external_gateway:
-            ext_net = neutron_utils.get_network(
-                neutron, network_name=self.external_gateway)
-            if ext_net:
-                ext_gw['network_id'] = ext_net.id
-                out['external_gateway_info'] = ext_gw
-            else:
-                raise RouterSettingsError(
-                    'Could not find the external network named - ' +
-                    self.external_gateway)
-
-        return {'router': out}
-
-
-class RouterSettingsError(Exception):
-    """
-    Exception to be thrown when router settings attributes are incorrect
-    """
+        from warnings import warn
+        warn('Use snaps.config.router.RouterConfig instead',
+             DeprecationWarning)
+        super(self.__class__, self).__init__(**kwargs)