From 38bcfd656e3affc1f16e100607a3e294b758dec8 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Tue, 25 Oct 2016 00:37:25 +0530 Subject: [PATCH 01/11] #15 Basic implementation of Connectivity PoC. Very basic, not tested yet --- .../drivermetadata.xml | 2 +- drivers/openstack_shell/src/driver.py | 3 + .../openstack_shell/src/drivermetadata.xml | 2 +- .../operations/connectivity_operation.py | 192 ++++++++++++++++++ .../neutron/neutron_network_service.py | 64 ++++++ .../services/nova/nova_instance_service.py | 25 +++ .../connectivity_action_result_model.py | 10 + .../openstack/models/driver_response_model.py | 8 + .../cp/openstack/openstack_shell.py | 16 ++ package/requirements.txt | 1 + 10 files changed, 321 insertions(+), 2 deletions(-) create mode 100644 package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py create mode 100644 package/cloudshell/cp/openstack/models/connectivity_action_result_model.py create mode 100644 package/cloudshell/cp/openstack/models/driver_response_model.py diff --git a/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml b/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml index 8293fd1..d2dd8af 100644 --- a/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml +++ b/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/drivers/openstack_shell/src/driver.py b/drivers/openstack_shell/src/driver.py index 91c7aa8..f451d4f 100644 --- a/drivers/openstack_shell/src/driver.py +++ b/drivers/openstack_shell/src/driver.py @@ -29,6 +29,9 @@ def deploy_from_image(self, context, request): # "cloud_provider_resource_name" : "openstack"}, # unpicklable=False)) + def ApplyConnectivityChanges(self, context, request): + return self.os_shell.apply_connectivity(context, request) + def PowerOn(self, context, ports): return self.os_shell.power_on(context) diff --git a/drivers/openstack_shell/src/drivermetadata.xml b/drivers/openstack_shell/src/drivermetadata.xml index bb10e8c..68db4b8 100644 --- a/drivers/openstack_shell/src/drivermetadata.xml +++ b/drivers/openstack_shell/src/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py index 7eebb09..aa3e6ba 100644 --- a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py +++ b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py @@ -1,12 +1,21 @@ from cloudshell.cp.openstack.domain.services.nova.nova_instance_service import NovaInstanceService +from cloudshell.cp.openstack.domain.services.neutron.neutron_network_service import NeutronNetworkService from cloudshell.cp.openstack.domain.services.waiters.instance import InstanceWaiter +from cloudshell.cp.openstack.common.deploy_data_holder import DeployDataHolder + +from cloudshell.cp.openstack.models.connectivity_action_result_model import ConnectivityActionResultModel +from cloudshell.cp.openstack.models.driver_response_model import DriverResponse, DriverResponseRoot + +import jsonpickle + class ConnectivityOperation(object): public_ip = "Public IP" def __init__(self): self.instance_waiter = InstanceWaiter() self.instance_service = NovaInstanceService(self.instance_waiter) + self.network_service = NeutronNetworkService() def refresh_ip(self, openstack_session, cloudshell_session, deployed_app_resource, private_ip, resource_fullname, @@ -38,3 +47,186 @@ def refresh_ip(self, openstack_session, cloudshell_session, # FIXME : hardcoded public IP right now. Get it from floating IP later. cloudshell_session.SetAttributeValue(resource_fullname, ConnectivityOperation.public_ip, "192.168.1.1") + + def apply_connectivity(self, openstack_session, resource_model, conn_request, logger): + """ + Implements Apply connectivity - parses the conn_requests and creates + :param openstack_session: + :param resource_model: + :param conn_request: + :return: + """ + + conn_req_deploy_data = DeployDataHolder(jsonpickle.decode(conn_request)) + + # Now collect following dict + # Key: (vlanID) + # value: List of (Resource_Name, VM_UUID, connectionID) + # For each item, create network, and assign a nic on that network + + actions = conn_req_deploy_data.driverRequest.actions + + set_vlan_actions_dict = {} + remove_vlan_actions_dict = {} + # TODO : implement remove actions dict + for action in actions: + if action.type == 'setVlan': + curr_dict = set_vlan_actions_dict + else: + curr_dict = remove_vlan_actions_dict + + action_vlanid = action.connectionParams.vlanId + actionid = action.actionId + + deployed_app_res_name = action.actionTarget.fullName + + for cust_attr in action.customAttributes : + if cust_attr.attributeName == 'VM_UUID': + vm_uuid = cust_attr.attributeValue + resource_info = (deployed_app_res_name, vm_uuid, actionid) + if action_vlanid in curr_dict.keys(): + curr_dict[action_vlanid].append(resource_info) + else: + curr_dict[action_vlanid] = [resource_info] + + results = [] + if set_vlan_actions_dict : + result = self._do_set_vlan_actions(openstack_session=openstack_session, + resource_model=resource_model, + vlan_actions=set_vlan_actions_dict, + logger=logger) + + results += result + + if remove_vlan_actions_dict: + result = self._do_remove_vlan_actions(openstack_session=openstack_session, + resource_model=resource_model, + vlan_actions=set_vlan_actions_dict, + logger=logger) + results += result + + # We have apply Connectivity results - We should send out the JSON and encode it + driver_response = DriverResponse() + driver_response.actionResults = results + driver_response_root = DriverResponseRoot() + driver_response_root.driverResponse = driver_response + + return driver_response_root + + def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, logger): + """ + + :param openstack_session: + :param resource_model: + :param vlan_actions: + :return: + """ + + # For each VLAN ID (create VLAN network) + results = [] + + for k, values in vlan_actions.iteritems(): + + net = self.network_service.create_network_with_vlanid(openstack_session=openstack_session, + vlanid=int(k), + logger=logger) + if not net: + # FIXME : create error for the action + results = self._set_fail_results(values=values, + action_type='setVlan', + failure_text="Failed to Create Network with VLAN ID {0}".format(k)) + else: + net_id = net['id'] + # Create subnet : We just use hard coded CIDR for now. They wil be all isolated + # thanks to VLANs + subnet = self.network_service.attach_subnet_to_net(openstack_session=openstack_session, + net_id=net_id, + logger=logger) + if not subnet: + # FIXME: create error for action + results = self._set_fail_results(values=values, + action_type='setVlan', + failure_text="Failed to attach Subnet to Network {0}".format(net_id)) + else: + attach_results = [] + for val in values: + + instance_id = val[1] + # returns MAC Address of the attached port - which is reflected in updated Port + result = self.instance_service.attach_nic_to_net(openstack_session, instance_id, net_id, logger) + if not result: + action_result = ConnectivityActionResultModel() + action_result.success = False + action_result.actionId = val[2] + action_result.errorMessage = \ + "Failed to Attach NIC on Network {0} to Instance {1}".format(net_id, val[0]) + action_result.infoMessage = None + action_result.updatedInterface = None + # + #result = {"success": "False", + # "actionId": val[2], + # "infoMessage" : "", + # "errorMessage": , + # "type": "setVlan", + # "updatedInterface" : "" + # } + + else: + action_result = ConnectivityActionResultModel() + action_result.success = True + action_result.actionId = val[2] + action_result.errorMessage = \ + "Successfully Attached NIC on Network {0} to Instance {1}".format(net_id, val[0]) + action_result.infoMessage = None + action_result.updatedInterface = result + + #result = {"success": "Success", + # "actionId": val[2], + # "infoMessage" : "Successfully Attached NIC on Network {0} to Instance {1}".format(net_id, val[0]), + # "errorMessage": "", + # "type": "setVlan", + # "updatedInterface": result + # } + attach_results.append(action_result) + results = attach_results + return results + + def _do_remove_vlan_actions(self, openstack_session, resource_model, vlan_actions, logger): + """ + Function implementing Remove VLANs in apply_connectivity + :param openstack_session: + :param resource_model: + :param vlan_actions: + :param logger: + :return: + """ + logger.info("_do_remove_vlan_actions called.") + return [] + + def _set_fail_results(self, values, failure_text, action_type, logger=None): + """ + For all connections (obtained from values, set the failed results text, useful in generating output + :param values: + :param failure_text: + :param logger: + :return: + """ + results = [] + for value in values: + action_result = ConnectivityActionResultModel() + action_result.success = False + action_result.actionId = value[2] + action_result.infoMessage = None + action_result.errorMessage = failure_text + action_result.type = action_type + action_result.updatedInterface = None + + #result = {"success": "Success", + # "actionId": value[2], + # "infoMessage" : "", + # "errorMessage": failure_text, + # "type": action_type, + # "updatedInterface": "" + # } + results.append(action_result) + return results \ No newline at end of file diff --git a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py new file mode 100644 index 0000000..2f97dc0 --- /dev/null +++ b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py @@ -0,0 +1,64 @@ +from neutronclient.v2_0 import client as neutron_client + +class NeutronNetworkService(object): + """ + A wrapper class around Neutron API + """ + + def __init__(self): + pass + self.cidr_octet3 = 0 + self.cidr_str = '10.1.{0}.0/24' + + def create_network_with_vlanid(self, openstack_session, vlanid, logger): + """ + + :param openstack_session: + :param vlanid: + :return: + """ + + client = neutron_client.Client(session=openstack_session) + + nw_name = "net_vlanid_{0}".format(vlanid) + create_nw_json = {'provider:physical_network': 'public', + 'provider:network_type': 'vlan', + 'provider:segmentation_id': vlanid, + 'name': nw_name, + 'admin_state_up': True} + + # FIXME : If an exception is raised - we just raise it all the way back? For now yes + try: + new_net = client.create_network({'network': create_nw_json}) + new_net = new_net['network'] + except Exception as e: + logger.error("Exception {0} Occurred while creating network".format(e)) + return None + + return new_net + + def attach_subnet_to_net(self, openstack_session, net_id, logger): + """ + + :param net_id: + :return: + """ + + client = neutron_client.Client(session=openstack_session) + + # FIXME: would work for 255 networks only for now + cidr = self.cidr_str.format(self.cidr_octet3) + self.cidr_octet3 += 1 + + create_subnet_json = {'cidr': cidr, + 'network_id': net_id, + 'ip_version': 4} + + try: + new_subnet = client.create_subnet({'subnet':create_subnet_json}) + new_subnet = new_subnet['subnet'] + except Exception as e: + logger.error("Exception {0} Occurred while creating network".format(e)) + return None + + return new_subnet diff --git a/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py b/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py index 8a336e6..c014790 100644 --- a/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py +++ b/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py @@ -180,3 +180,28 @@ def get_instance_from_instance_id(self, openstack_session, instance_id, logger, return None except Exception: raise + + def attach_nic_to_net(self, openstack_session, instance_id, net_id, logger): + """ + + :param openstack_session: + :param instance_id: + :param net_id: + :param logger: + :return: + """ + + instance = self.get_instance_from_instance_id(openstack_session=openstack_session, + instance_id=instance_id, + logger=logger) + if instance is None : + return None + + try: + res = instance.interface_attach(net_id=net_id, port_id=None, fixed_ip=None) + iface_mac = res.to_dict.get('mac_addr') + return iface_mac + except Exception as e: + logger.info("Exception: {0} during interface attach".format(e)) + + return None \ No newline at end of file diff --git a/package/cloudshell/cp/openstack/models/connectivity_action_result_model.py b/package/cloudshell/cp/openstack/models/connectivity_action_result_model.py new file mode 100644 index 0000000..e65977f --- /dev/null +++ b/package/cloudshell/cp/openstack/models/connectivity_action_result_model.py @@ -0,0 +1,10 @@ + + +class ConnectivityActionResultModel(object): + def __init__(self): + self.actionId = None + self.success = None + self.infoMessage = None + self.errorMessage = None + self.type = None + self.updatedInterface = None \ No newline at end of file diff --git a/package/cloudshell/cp/openstack/models/driver_response_model.py b/package/cloudshell/cp/openstack/models/driver_response_model.py new file mode 100644 index 0000000..9c0134b --- /dev/null +++ b/package/cloudshell/cp/openstack/models/driver_response_model.py @@ -0,0 +1,8 @@ + +class DriverResponse(object): + def __init__(self): + self.actionResults = [] + +class DriverResponseRoot(object): + def __init__(self): + self.driverResponse = None diff --git a/package/cloudshell/cp/openstack/openstack_shell.py b/package/cloudshell/cp/openstack/openstack_shell.py index 6a6eb86..b143758 100644 --- a/package/cloudshell/cp/openstack/openstack_shell.py +++ b/package/cloudshell/cp/openstack/openstack_shell.py @@ -82,6 +82,7 @@ def power_off(self, command_context): :param cloudshell.shell.core.context.ResourceRemoteCommandContext command_context: :rtype None: """ + with LoggingSessionContext(command_context) as logger: with ErrorHandlingContext(logger): with CloudShellSessionContext(command_context) as cs_session: @@ -213,4 +214,19 @@ def refresh_ip(self, command_context): resource_fullname=deployed_app_fullname, logger=logger) + def apply_connectivity(self, command_context, connectivity_request): + with LoggingSessionContext(command_context) as logger: + with ErrorHandlingContext(logger): + with CloudShellSessionContext(command_context) as cs_session: + resource_model = self.model_parser.get_resource_model_from_context(command_context.resource) + + logger.debug(resource_model) + os_session = self.os_session_provider.get_openstack_session(cs_session, resource_model, logger) + connectivity_result = self.connectivity_operation.apply_connectivity(openstack_session=os_session, + resource_model=resource_model, + conn_request=connectivity_request, + logger=logger) + + return self.command_result_parser.set_command_result(connectivity_result) + # Connectivity Operations End diff --git a/package/requirements.txt b/package/requirements.txt index 04c85a5..39832c7 100644 --- a/package/requirements.txt +++ b/package/requirements.txt @@ -2,4 +2,5 @@ cloudshell-automation-api>=7.0.0.0,<7.1.0.0 cloudshell-core>=2.1.0,<2.2.0 cloudshell-shell-core>=2.2.0,<2.3.0 python-novaclient>=4.0.8,<5.1.0 +python-neutronclient>=5.0.0,<=6.0.0 jsonpickle==0.9.3 From 14d531713c0f2bfdef87b4709ebbb5371f70038d Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Tue, 25 Oct 2016 01:23:13 +0530 Subject: [PATCH 02/11] #15 Updating the version to test from pypi. So that new dependencies are all downloaded --- .../openstack_nova_image_instance/drivermetadata.xml | 2 +- .../openstack_nova_image_instance/requirements.txt | 2 +- drivers/deployment_drivers/version.txt | 2 +- drivers/openstack_shell/src/drivermetadata.xml | 2 +- drivers/openstack_shell/src/requirements.txt | 2 +- drivers/openstack_shell/version.txt | 2 +- drivers/version.txt | 2 +- package/version.txt | 2 +- version.txt | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml b/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml index d2dd8af..ab3722e 100644 --- a/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml +++ b/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/drivers/deployment_drivers/openstack_nova_image_instance/requirements.txt b/drivers/deployment_drivers/openstack_nova_image_instance/requirements.txt index a306927..d76f53a 100644 --- a/drivers/deployment_drivers/openstack_nova_image_instance/requirements.txt +++ b/drivers/deployment_drivers/openstack_nova_image_instance/requirements.txt @@ -1,3 +1,3 @@ cloudshell-shell-core>=2.2.0,<2.3.0 -cloudshell-cp-openstack<1.0.0 +cloudshell-cp-openstack<0.1.0 jsonpickle diff --git a/drivers/deployment_drivers/version.txt b/drivers/deployment_drivers/version.txt index 43b2961..9789c4c 100644 --- a/drivers/deployment_drivers/version.txt +++ b/drivers/deployment_drivers/version.txt @@ -1 +1 @@ -0.0.13 +0.0.14 diff --git a/drivers/openstack_shell/src/drivermetadata.xml b/drivers/openstack_shell/src/drivermetadata.xml index 68db4b8..44208a8 100644 --- a/drivers/openstack_shell/src/drivermetadata.xml +++ b/drivers/openstack_shell/src/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/drivers/openstack_shell/src/requirements.txt b/drivers/openstack_shell/src/requirements.txt index a306927..d76f53a 100644 --- a/drivers/openstack_shell/src/requirements.txt +++ b/drivers/openstack_shell/src/requirements.txt @@ -1,3 +1,3 @@ cloudshell-shell-core>=2.2.0,<2.3.0 -cloudshell-cp-openstack<1.0.0 +cloudshell-cp-openstack<0.1.0 jsonpickle diff --git a/drivers/openstack_shell/version.txt b/drivers/openstack_shell/version.txt index 43b2961..1111c9c 100644 --- a/drivers/openstack_shell/version.txt +++ b/drivers/openstack_shell/version.txt @@ -1 +1 @@ -0.0.13 +0.0.14 \ No newline at end of file diff --git a/drivers/version.txt b/drivers/version.txt index 43b2961..9789c4c 100644 --- a/drivers/version.txt +++ b/drivers/version.txt @@ -1 +1 @@ -0.0.13 +0.0.14 diff --git a/package/version.txt b/package/version.txt index 43b2961..9789c4c 100644 --- a/package/version.txt +++ b/package/version.txt @@ -1 +1 @@ -0.0.13 +0.0.14 diff --git a/version.txt b/version.txt index 43b2961..9789c4c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.0.13 +0.0.14 From 0a5272a3444baeb11e8f12dc185a3ad25b53c7e6 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Tue, 25 Oct 2016 02:28:31 +0530 Subject: [PATCH 03/11] #15 Basic connectivity working - now. Apps can connect using VLAN service. --- .../command/operations/connectivity_operation.py | 9 +++++---- .../domain/services/nova/nova_instance_service.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py index aa3e6ba..43b8671 100644 --- a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py +++ b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py @@ -80,7 +80,7 @@ def apply_connectivity(self, openstack_session, resource_model, conn_request, lo deployed_app_res_name = action.actionTarget.fullName - for cust_attr in action.customAttributes : + for cust_attr in action.customActionAttributes : if cust_attr.attributeName == 'VM_UUID': vm_uuid = cust_attr.attributeValue resource_info = (deployed_app_res_name, vm_uuid, actionid) @@ -173,12 +173,13 @@ def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, else: action_result = ConnectivityActionResultModel() - action_result.success = True + action_result.success = "True" action_result.actionId = val[2] - action_result.errorMessage = \ + action_result.errorMessage = "" + action_result.infoMessage = \ "Successfully Attached NIC on Network {0} to Instance {1}".format(net_id, val[0]) - action_result.infoMessage = None action_result.updatedInterface = result + action_result.type = 'setVlan' #result = {"success": "Success", # "actionId": val[2], diff --git a/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py b/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py index c014790..2566a59 100644 --- a/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py +++ b/package/cloudshell/cp/openstack/domain/services/nova/nova_instance_service.py @@ -199,7 +199,7 @@ def attach_nic_to_net(self, openstack_session, instance_id, net_id, logger): try: res = instance.interface_attach(net_id=net_id, port_id=None, fixed_ip=None) - iface_mac = res.to_dict.get('mac_addr') + iface_mac = res.to_dict().get('mac_addr') return iface_mac except Exception as e: logger.info("Exception: {0} during interface attach".format(e)) From d248c52c3b642287d755ce7718810be739806548 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Mon, 31 Oct 2016 21:54:30 +0530 Subject: [PATCH 04/11] #15 Subnets are not hard-coded anymore - they are taken from an exclusion list of "reserverd networks". Fixed issues where if a network already existed to use it --- .../DataModel/datamodel.xml | 11 ++++ .../operations/connectivity_operation.py | 57 ++++++----------- .../neutron/neutron_network_service.py | 62 ++++++++++++++++--- .../cp/openstack/models/model_parser.py | 1 + .../models/openstack_resource_model.py | 1 + .../cp/openstack/openstack_shell.py | 8 +-- 6 files changed, 87 insertions(+), 53 deletions(-) diff --git a/drivers/openstack_shellPackage/DataModel/datamodel.xml b/drivers/openstack_shellPackage/DataModel/datamodel.xml index c08075f..f84bb39 100644 --- a/drivers/openstack_shellPackage/DataModel/datamodel.xml +++ b/drivers/openstack_shellPackage/DataModel/datamodel.xml @@ -85,6 +85,14 @@ + + + + + + + + @@ -196,6 +204,9 @@ + + + diff --git a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py index 43b8671..dc48f3f 100644 --- a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py +++ b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py @@ -48,11 +48,11 @@ def refresh_ip(self, openstack_session, cloudshell_session, # FIXME : hardcoded public IP right now. Get it from floating IP later. cloudshell_session.SetAttributeValue(resource_fullname, ConnectivityOperation.public_ip, "192.168.1.1") - def apply_connectivity(self, openstack_session, resource_model, conn_request, logger): + def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, logger): """ Implements Apply connectivity - parses the conn_requests and creates :param openstack_session: - :param resource_model: + :param cp_resource_model: :param conn_request: :return: """ @@ -68,6 +68,7 @@ def apply_connectivity(self, openstack_session, resource_model, conn_request, lo set_vlan_actions_dict = {} remove_vlan_actions_dict = {} + # TODO : implement remove actions dict for action in actions: if action.type == 'setVlan': @@ -92,7 +93,7 @@ def apply_connectivity(self, openstack_session, resource_model, conn_request, lo results = [] if set_vlan_actions_dict : result = self._do_set_vlan_actions(openstack_session=openstack_session, - resource_model=resource_model, + cp_resource_model=cp_resource_model, vlan_actions=set_vlan_actions_dict, logger=logger) @@ -100,7 +101,7 @@ def apply_connectivity(self, openstack_session, resource_model, conn_request, lo if remove_vlan_actions_dict: result = self._do_remove_vlan_actions(openstack_session=openstack_session, - resource_model=resource_model, + cp_resource_model=cp_resource_model, vlan_actions=set_vlan_actions_dict, logger=logger) results += result @@ -113,11 +114,11 @@ def apply_connectivity(self, openstack_session, resource_model, conn_request, lo return driver_response_root - def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, logger): + def _do_set_vlan_actions(self, openstack_session, cp_resource_model, vlan_actions, logger): """ :param openstack_session: - :param resource_model: + :param cp_resource_model: :param vlan_actions: :return: """ @@ -126,7 +127,6 @@ def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, results = [] for k, values in vlan_actions.iteritems(): - net = self.network_service.create_network_with_vlanid(openstack_session=openstack_session, vlanid=int(k), logger=logger) @@ -137,11 +137,15 @@ def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, failure_text="Failed to Create Network with VLAN ID {0}".format(k)) else: net_id = net['id'] - # Create subnet : We just use hard coded CIDR for now. They wil be all isolated - # thanks to VLANs - subnet = self.network_service.attach_subnet_to_net(openstack_session=openstack_session, - net_id=net_id, - logger=logger) + + subnet = net['subnets'] + if not subnet: + subnet = self.network_service.attach_subnet_to_net(openstack_session=openstack_session, + cp_resource_model=cp_resource_model, + net_id=net_id, + logger=logger) + else: + subnet = subnet[0] if not subnet: # FIXME: create error for action results = self._set_fail_results(values=values, @@ -162,15 +166,6 @@ def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, "Failed to Attach NIC on Network {0} to Instance {1}".format(net_id, val[0]) action_result.infoMessage = None action_result.updatedInterface = None - # - #result = {"success": "False", - # "actionId": val[2], - # "infoMessage" : "", - # "errorMessage": , - # "type": "setVlan", - # "updatedInterface" : "" - # } - else: action_result = ConnectivityActionResultModel() action_result.success = "True" @@ -180,23 +175,15 @@ def _do_set_vlan_actions(self, openstack_session, resource_model, vlan_actions, "Successfully Attached NIC on Network {0} to Instance {1}".format(net_id, val[0]) action_result.updatedInterface = result action_result.type = 'setVlan' - - #result = {"success": "Success", - # "actionId": val[2], - # "infoMessage" : "Successfully Attached NIC on Network {0} to Instance {1}".format(net_id, val[0]), - # "errorMessage": "", - # "type": "setVlan", - # "updatedInterface": result - # } attach_results.append(action_result) results = attach_results return results - def _do_remove_vlan_actions(self, openstack_session, resource_model, vlan_actions, logger): + def _do_remove_vlan_actions(self, openstack_session, cp_resource_model, vlan_actions, logger): """ Function implementing Remove VLANs in apply_connectivity :param openstack_session: - :param resource_model: + :param cp_resource_model: :param vlan_actions: :param logger: :return: @@ -221,13 +208,5 @@ def _set_fail_results(self, values, failure_text, action_type, logger=None): action_result.errorMessage = failure_text action_result.type = action_type action_result.updatedInterface = None - - #result = {"success": "Success", - # "actionId": value[2], - # "infoMessage" : "", - # "errorMessage": failure_text, - # "type": action_type, - # "updatedInterface": "" - # } results.append(action_result) return results \ No newline at end of file diff --git a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py index 2f97dc0..2ee7fa8 100644 --- a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py +++ b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py @@ -1,4 +1,5 @@ from neutronclient.v2_0 import client as neutron_client +from neutronclient.common.exceptions import Conflict as NetCreateConflict class NeutronNetworkService(object): """ @@ -7,8 +8,9 @@ class NeutronNetworkService(object): def __init__(self): pass - self.cidr_octet3 = 0 - self.cidr_str = '10.1.{0}.0/24' + self.cidr_base = None + self.cidr_subnet_num = 0 + self.allocated_subnets = [] def create_network_with_vlanid(self, openstack_session, vlanid, logger): """ @@ -22,33 +24,39 @@ def create_network_with_vlanid(self, openstack_session, vlanid, logger): nw_name = "net_vlanid_{0}".format(vlanid) create_nw_json = {'provider:physical_network': 'public', - 'provider:network_type': 'vlan', - 'provider:segmentation_id': vlanid, - 'name': nw_name, - 'admin_state_up': True} + 'provider:network_type': 'vlan', + 'provider:segmentation_id': vlanid, + 'name': nw_name, + 'admin_state_up': True} # FIXME : If an exception is raised - we just raise it all the way back? For now yes try: new_net = client.create_network({'network': create_nw_json}) new_net = new_net['network'] + except NetCreateConflict: + new_net = client.list_networks(**{'provider:segmentation_id':vlanid}) + new_net = new_net['networks'][0] except Exception as e: logger.error("Exception {0} Occurred while creating network".format(e)) return None return new_net - def attach_subnet_to_net(self, openstack_session, net_id, logger): + def attach_subnet_to_net(self, openstack_session, cp_resource_model, net_id, logger): """ + :param openstack_session: + :param cp_resource_model: :param net_id: :return: """ client = neutron_client.Client(session=openstack_session) - # FIXME: would work for 255 networks only for now - cidr = self.cidr_str.format(self.cidr_octet3) - self.cidr_octet3 += 1 + cidr = self._get_unused_cidr(cp_resource_model.reserved_networks) + if cidr is None: + logger.error("Cannot allocate new subnet. All subnets exhausted") + return None create_subnet_json = {'cidr': cidr, 'network_id': net_id, @@ -62,3 +70,37 @@ def attach_subnet_to_net(self, openstack_session, net_id, logger): return None return new_subnet + + def _get_unused_cidr(self, cp_resvd_cidrs): + """ + + :param cp_resvd_cidrs: + :return: + """ + + # Algorithm below is a very simplistic one where we choose one of the three prefixes and then use + # /24 networks starting with that prefix. This algorithm will break if all three 10.X, 192.168.X and 172.X + # networks are used in a given On Prem Network. + if self.cidr_base is not None: + cidr = ".".join([self.cidr_base, str(self.cidr_subnet_num), "0/24"]) + if self.cidr_subnet_num not in self.allocated_subnets: + self.allocated_subnets.append(self.cidr_subnet_num) + self.cidr_subnet_num += 1 + if self.cidr_subnet_num == 255: + self.cidr_subnet_num = 0 + return cidr + else: + candidate_prefixes = {'10': '10.0', '192.168': '192.168', '172': '172.0'} + + possible_prefixes = filter(lambda x: any(map(lambda y: y.startswith(x), cp_resvd_cidrs)), + candidate_prefixes.keys()) + if not possible_prefixes: + return None + else: + prefix = possible_prefixes[0] + self.cidr_base = candidate_prefixes[prefix] + cidr = ".".join([self.cidr_base, str(self.cidr_subnet_num), "0/24"]) + self.allocated_subnets.append(self.cidr_subnet_num) + self.cidr_subnet_num += 1 + return cidr + return None \ No newline at end of file diff --git a/package/cloudshell/cp/openstack/models/model_parser.py b/package/cloudshell/cp/openstack/models/model_parser.py index fe9947a..a78e6f3 100644 --- a/package/cloudshell/cp/openstack/models/model_parser.py +++ b/package/cloudshell/cp/openstack/models/model_parser.py @@ -28,6 +28,7 @@ def get_resource_model_from_context(resource): os_res_model.os_mgmt_subnet_cidr = attrs['OpenStack Management Subnet CIDR'] os_res_model.qs_mgmt_subnet_cidr = attrs['Quali Management Subnet CIDR'] os_res_model.os_floating_ip_pool = attrs['Floating IP Pool'] + os_res_model.reserved_networks = attrs['Reserved Networks'] return os_res_model @staticmethod diff --git a/package/cloudshell/cp/openstack/models/openstack_resource_model.py b/package/cloudshell/cp/openstack/models/openstack_resource_model.py index a5d26df..919673f 100644 --- a/package/cloudshell/cp/openstack/models/openstack_resource_model.py +++ b/package/cloudshell/cp/openstack/models/openstack_resource_model.py @@ -14,6 +14,7 @@ def __init__(self): self.os_mgmt_subnet_cidr = '' self.qs_mgmt_subnet_cidr = '' self.os_floating_ip_pool = '' + self.reserved_networks = '' def __str__(self): desc = "OpenStack Resource: controller_url: {0}, domain: {1}, project_name : {2}, os_user_name : {3}".format( diff --git a/package/cloudshell/cp/openstack/openstack_shell.py b/package/cloudshell/cp/openstack/openstack_shell.py index b143758..52edc64 100644 --- a/package/cloudshell/cp/openstack/openstack_shell.py +++ b/package/cloudshell/cp/openstack/openstack_shell.py @@ -218,14 +218,14 @@ def apply_connectivity(self, command_context, connectivity_request): with LoggingSessionContext(command_context) as logger: with ErrorHandlingContext(logger): with CloudShellSessionContext(command_context) as cs_session: - resource_model = self.model_parser.get_resource_model_from_context(command_context.resource) + cp_resource_model = self.model_parser.get_resource_model_from_context(command_context.resource) logger.debug(resource_model) os_session = self.os_session_provider.get_openstack_session(cs_session, resource_model, logger) connectivity_result = self.connectivity_operation.apply_connectivity(openstack_session=os_session, - resource_model=resource_model, - conn_request=connectivity_request, - logger=logger) + cp_resource_model=cp_resource_model, + conn_request=connectivity_request, + logger=logger) return self.command_result_parser.set_command_result(connectivity_result) From 293042f0d1fba99ca45a8beb2709dc6c7e3adf3f Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Mon, 31 Oct 2016 21:58:41 +0530 Subject: [PATCH 05/11] #15 Upped the version to 0.0.15 --- drivers/openstack_shell/src/drivermetadata.xml | 2 +- drivers/openstack_shell/version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/openstack_shell/src/drivermetadata.xml b/drivers/openstack_shell/src/drivermetadata.xml index 44208a8..c9a17a2 100644 --- a/drivers/openstack_shell/src/drivermetadata.xml +++ b/drivers/openstack_shell/src/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/drivers/openstack_shell/version.txt b/drivers/openstack_shell/version.txt index 1111c9c..9beca35 100644 --- a/drivers/openstack_shell/version.txt +++ b/drivers/openstack_shell/version.txt @@ -1 +1 @@ -0.0.14 \ No newline at end of file +0.0.15 \ No newline at end of file From 9c1fb0d72c90a84ffc38be1080421a2e5888c156 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Mon, 31 Oct 2016 22:01:32 +0530 Subject: [PATCH 06/11] #15 Upped the version to 0.0.15 --- .../openstack_nova_image_instance/drivermetadata.xml | 2 +- drivers/deployment_drivers/version.txt | 2 +- drivers/version.txt | 2 +- package/version.txt | 2 +- version.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml b/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml index ab3722e..09026e4 100644 --- a/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml +++ b/drivers/deployment_drivers/openstack_nova_image_instance/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/drivers/deployment_drivers/version.txt b/drivers/deployment_drivers/version.txt index 9789c4c..ceddfb2 100644 --- a/drivers/deployment_drivers/version.txt +++ b/drivers/deployment_drivers/version.txt @@ -1 +1 @@ -0.0.14 +0.0.15 diff --git a/drivers/version.txt b/drivers/version.txt index 9789c4c..ceddfb2 100644 --- a/drivers/version.txt +++ b/drivers/version.txt @@ -1 +1 @@ -0.0.14 +0.0.15 diff --git a/package/version.txt b/package/version.txt index 9789c4c..9beca35 100644 --- a/package/version.txt +++ b/package/version.txt @@ -1 +1 @@ -0.0.14 +0.0.15 \ No newline at end of file diff --git a/version.txt b/version.txt index 9789c4c..ceddfb2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.0.14 +0.0.15 From 13c3cadfd0ad6690412464519792e74551bc6998 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Tue, 1 Nov 2016 00:46:44 +0530 Subject: [PATCH 07/11] #15 Upped the version to 0.0.15 --- drivers/openstack_shell/src/drivermetadata.xml | 1 + .../Configuration/shellconfig.xml | 1 + .../services/neutron/neutron_network_service.py | 11 +++++++---- package/cloudshell/cp/openstack/openstack_shell.py | 5 +++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/openstack_shell/src/drivermetadata.xml b/drivers/openstack_shell/src/drivermetadata.xml index c9a17a2..6ebd344 100644 --- a/drivers/openstack_shell/src/drivermetadata.xml +++ b/drivers/openstack_shell/src/drivermetadata.xml @@ -5,6 +5,7 @@ + diff --git a/drivers/openstack_shellPackage/Configuration/shellconfig.xml b/drivers/openstack_shellPackage/Configuration/shellconfig.xml index 2039f36..0dffb6c 100644 --- a/drivers/openstack_shellPackage/Configuration/shellconfig.xml +++ b/drivers/openstack_shellPackage/Configuration/shellconfig.xml @@ -17,6 +17,7 @@ + diff --git a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py index 2ee7fa8..bed646c 100644 --- a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py +++ b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py @@ -53,7 +53,7 @@ def attach_subnet_to_net(self, openstack_session, cp_resource_model, net_id, log client = neutron_client.Client(session=openstack_session) - cidr = self._get_unused_cidr(cp_resource_model.reserved_networks) + cidr = self._get_unused_cidr(cp_resvd_cidrs=cp_resource_model.reserved_networks, logger=logger) if cidr is None: logger.error("Cannot allocate new subnet. All subnets exhausted") return None @@ -71,7 +71,7 @@ def attach_subnet_to_net(self, openstack_session, cp_resource_model, net_id, log return new_subnet - def _get_unused_cidr(self, cp_resvd_cidrs): + def _get_unused_cidr(self, cp_resvd_cidrs, logger): """ :param cp_resvd_cidrs: @@ -91,9 +91,12 @@ def _get_unused_cidr(self, cp_resvd_cidrs): return cidr else: candidate_prefixes = {'10': '10.0', '192.168': '192.168', '172': '172.0'} - - possible_prefixes = filter(lambda x: any(map(lambda y: y.startswith(x), cp_resvd_cidrs)), + cp_resvd_cidrs = cp_resvd_cidrs.split(",") + logger.error(cp_resvd_cidrs) + possible_prefixes = filter(lambda x: any(map(lambda y: not y.strip().startswith(x), cp_resvd_cidrs)), candidate_prefixes.keys()) + + logger.info(possible_prefixes) if not possible_prefixes: return None else: diff --git a/package/cloudshell/cp/openstack/openstack_shell.py b/package/cloudshell/cp/openstack/openstack_shell.py index 52edc64..4a8f958 100644 --- a/package/cloudshell/cp/openstack/openstack_shell.py +++ b/package/cloudshell/cp/openstack/openstack_shell.py @@ -218,10 +218,11 @@ def apply_connectivity(self, command_context, connectivity_request): with LoggingSessionContext(command_context) as logger: with ErrorHandlingContext(logger): with CloudShellSessionContext(command_context) as cs_session: + logger.info(connectivity_request) cp_resource_model = self.model_parser.get_resource_model_from_context(command_context.resource) - logger.debug(resource_model) - os_session = self.os_session_provider.get_openstack_session(cs_session, resource_model, logger) + logger.debug(cp_resource_model) + os_session = self.os_session_provider.get_openstack_session(cs_session, cp_resource_model, logger) connectivity_result = self.connectivity_operation.apply_connectivity(openstack_session=os_session, cp_resource_model=cp_resource_model, conn_request=connectivity_request, From 007b093cfc95a0aea9b668b96446c92d05816c3c Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Tue, 1 Nov 2016 13:59:56 +0530 Subject: [PATCH 08/11] #15 Fixed Docstrings. --- .../operations/connectivity_operation.py | 34 ++++++++++--------- .../neutron/neutron_network_service.py | 23 +++++++------ .../cp/openstack/openstack_shell.py | 6 ++++ 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py index dc48f3f..a7d80b5 100644 --- a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py +++ b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py @@ -51,10 +51,10 @@ def refresh_ip(self, openstack_session, cloudshell_session, def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, logger): """ Implements Apply connectivity - parses the conn_requests and creates - :param openstack_session: - :param cp_resource_model: - :param conn_request: - :return: + :param keystoneauth1.session.Session openstack_session: + :param OpenStackResourceModel cp_resource_model: + :param str conn_request: Connectivty Request JSON + :return DriverResponseRoot: """ conn_req_deploy_data = DeployDataHolder(jsonpickle.decode(conn_request)) @@ -117,10 +117,11 @@ def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, def _do_set_vlan_actions(self, openstack_session, cp_resource_model, vlan_actions, logger): """ - :param openstack_session: - :param cp_resource_model: - :param vlan_actions: - :return: + :param keystoneauth1.session.Session openstack_session: + :param OpenStackResourceModel cp_resource_model: + :param dict vlan_actions: + :param LoggingSessionContext logger: + :return ConnectivityActionResult List : """ # For each VLAN ID (create VLAN network) @@ -182,10 +183,10 @@ def _do_set_vlan_actions(self, openstack_session, cp_resource_model, vlan_action def _do_remove_vlan_actions(self, openstack_session, cp_resource_model, vlan_actions, logger): """ Function implementing Remove VLANs in apply_connectivity - :param openstack_session: - :param cp_resource_model: - :param vlan_actions: - :param logger: + :param keystoneauth1.session.Session openstack_session: + :param OpenStckResourceModel cp_resource_model: + :param dict vlan_actions: + :param LoggingSessionContext logger: :return: """ logger.info("_do_remove_vlan_actions called.") @@ -193,11 +194,12 @@ def _do_remove_vlan_actions(self, openstack_session, cp_resource_model, vlan_act def _set_fail_results(self, values, failure_text, action_type, logger=None): """ - For all connections (obtained from values, set the failed results text, useful in generating output - :param values: - :param failure_text: + For all connections (obtained from values), set the failed results text, useful in generating output + :param tuple values: + :param str failure_text: + :param str action_type :param logger: - :return: + :return ConnectivityActionResultModel List: """ results = [] for value in values: diff --git a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py index bed646c..c73aea0 100644 --- a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py +++ b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py @@ -7,7 +7,6 @@ class NeutronNetworkService(object): """ def __init__(self): - pass self.cidr_base = None self.cidr_subnet_num = 0 self.allocated_subnets = [] @@ -15,9 +14,10 @@ def __init__(self): def create_network_with_vlanid(self, openstack_session, vlanid, logger): """ - :param openstack_session: - :param vlanid: - :return: + :param keystoneauth1.session.Session openstack_session: + :param int vlanid: + :param LoggingSessionContext logger: + :return dict : """ client = neutron_client.Client(session=openstack_session) @@ -44,11 +44,12 @@ def create_network_with_vlanid(self, openstack_session, vlanid, logger): def attach_subnet_to_net(self, openstack_session, cp_resource_model, net_id, logger): """ + Atttach a subnet to the network with given net_id. - :param openstack_session: - :param cp_resource_model: - :param net_id: - :return: + :param keystoneauth1.session.Session openstack_session: + :param OpenStackResourceModel cp_resource_model: + :param str net_id: UUID string + :return dict: """ client = neutron_client.Client(session=openstack_session) @@ -73,9 +74,9 @@ def attach_subnet_to_net(self, openstack_session, cp_resource_model, net_id, log def _get_unused_cidr(self, cp_resvd_cidrs, logger): """ - - :param cp_resvd_cidrs: - :return: + Gets unused CIDR that excludes the reserved CIDRs + :param str cp_resvd_cidrs: + :return str: """ # Algorithm below is a very simplistic one where we choose one of the three prefixes and then use diff --git a/package/cloudshell/cp/openstack/openstack_shell.py b/package/cloudshell/cp/openstack/openstack_shell.py index 4a8f958..bcf899b 100644 --- a/package/cloudshell/cp/openstack/openstack_shell.py +++ b/package/cloudshell/cp/openstack/openstack_shell.py @@ -215,6 +215,12 @@ def refresh_ip(self, command_context): logger=logger) def apply_connectivity(self, command_context, connectivity_request): + """ + + :param cloudshell.shell.core.context.ResourceRemoteCommandContext command_context: + :param str connectivity_request: Connectivity Request JSON string + :return: + """ with LoggingSessionContext(command_context) as logger: with ErrorHandlingContext(logger): with CloudShellSessionContext(command_context) as cs_session: From 8a16b46280373e555a6055484cf088afd119964f Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Thu, 3 Nov 2016 11:39:26 +0530 Subject: [PATCH 09/11] Added FIXME based on reviews --- .../command/operations/connectivity_operation.py | 12 ++++++++++-- .../services/neutron/neutron_network_service.py | 1 + package/cloudshell/cp/openstack/openstack_shell.py | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py index a7d80b5..62b51fc 100644 --- a/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py +++ b/package/cloudshell/cp/openstack/command/operations/connectivity_operation.py @@ -61,7 +61,7 @@ def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, # Now collect following dict # Key: (vlanID) - # value: List of (Resource_Name, VM_UUID, connectionID) + # value: List of (Resource_Name, VM_UUID, actionID) # For each item, create network, and assign a nic on that network actions = conn_req_deploy_data.driverRequest.actions @@ -69,10 +69,13 @@ def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, set_vlan_actions_dict = {} remove_vlan_actions_dict = {} + # Add more description # TODO : implement remove actions dict for action in actions: + # FIXME: Move this "ifs into a separate function if action.type == 'setVlan': curr_dict = set_vlan_actions_dict + # FIXME: Check whether this is 'removeVlan' else: curr_dict = remove_vlan_actions_dict @@ -84,6 +87,7 @@ def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, for cust_attr in action.customActionAttributes : if cust_attr.attributeName == 'VM_UUID': vm_uuid = cust_attr.attributeValue + # FIXME : changed this to object for later readability resource_info = (deployed_app_res_name, vm_uuid, actionid) if action_vlanid in curr_dict.keys(): curr_dict[action_vlanid].append(resource_info) @@ -91,7 +95,7 @@ def apply_connectivity(self, openstack_session, cp_resource_model, conn_request, curr_dict[action_vlanid] = [resource_info] results = [] - if set_vlan_actions_dict : + if set_vlan_actions_dict: result = self._do_set_vlan_actions(openstack_session=openstack_session, cp_resource_model=cp_resource_model, vlan_actions=set_vlan_actions_dict, @@ -128,6 +132,8 @@ def _do_set_vlan_actions(self, openstack_session, cp_resource_model, vlan_action results = [] for k, values in vlan_actions.iteritems(): + # FIXME: results getting overwritten + # FIXME: update the nethod name net = self.network_service.create_network_with_vlanid(openstack_session=openstack_session, vlanid=int(k), logger=logger) @@ -141,6 +147,7 @@ def _do_set_vlan_actions(self, openstack_session, cp_resource_model, vlan_action subnet = net['subnets'] if not subnet: + # FIXME: Rename this function to create_and_attach subnet = self.network_service.attach_subnet_to_net(openstack_session=openstack_session, cp_resource_model=cp_resource_model, net_id=net_id, @@ -154,6 +161,7 @@ def _do_set_vlan_actions(self, openstack_session, cp_resource_model, vlan_action failure_text="Failed to attach Subnet to Network {0}".format(net_id)) else: attach_results = [] + # FIXME: let's move this for val in values: instance_id = val[1] diff --git a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py index c73aea0..9ed7fdd 100644 --- a/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py +++ b/package/cloudshell/cp/openstack/domain/services/neutron/neutron_network_service.py @@ -82,6 +82,7 @@ def _get_unused_cidr(self, cp_resvd_cidrs, logger): # Algorithm below is a very simplistic one where we choose one of the three prefixes and then use # /24 networks starting with that prefix. This algorithm will break if all three 10.X, 192.168.X and 172.X # networks are used in a given On Prem Network. + # FIXME: Get subnets from openstack and not simply. if self.cidr_base is not None: cidr = ".".join([self.cidr_base, str(self.cidr_subnet_num), "0/24"]) if self.cidr_subnet_num not in self.allocated_subnets: diff --git a/package/cloudshell/cp/openstack/openstack_shell.py b/package/cloudshell/cp/openstack/openstack_shell.py index bcf899b..4d222e8 100644 --- a/package/cloudshell/cp/openstack/openstack_shell.py +++ b/package/cloudshell/cp/openstack/openstack_shell.py @@ -224,6 +224,7 @@ def apply_connectivity(self, command_context, connectivity_request): with LoggingSessionContext(command_context) as logger: with ErrorHandlingContext(logger): with CloudShellSessionContext(command_context) as cs_session: + # FIXME: When implementing a context manager create all clients inside the contextManager. logger.info(connectivity_request) cp_resource_model = self.model_parser.get_resource_model_from_context(command_context.resource) From ea93b47b9866539ec4aa14f3408d6f9a700a80e6 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Thu, 3 Nov 2016 18:17:36 +0530 Subject: [PATCH 10/11] #15 model_parser unit test failure fixed --- .../test_cp/test_openstack/test_models/test_model_parser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/tests/test_cp/test_openstack/test_models/test_model_parser.py b/package/tests/test_cp/test_openstack/test_models/test_model_parser.py index 6755217..bbd3cc6 100644 --- a/package/tests/test_cp/test_openstack/test_models/test_model_parser.py +++ b/package/tests/test_cp/test_openstack/test_models/test_model_parser.py @@ -21,6 +21,7 @@ def test_get_resource_model_from_context(self): test_resource.attributes['OpenStack User Password'] = 'test_pass' test_resource.attributes['Quali Management Network UUID'] = '1234-56-78' test_resource.attributes['Floating IP Pool'] = '10.0.0.100-10.0.0.101' + test_resource.attriubtes['Reserved Networks'] = '172.22.0.0/16' result = self.tested_class.get_resource_model_from_context(test_resource) @@ -32,6 +33,7 @@ def test_get_resource_model_from_context(self): self.assertEqual(result.os_user_password, 'test_pass') self.assertEqual(result.qs_mgmt_os_net_uuid, '1234-56-78') self.assertEqual(result.os_floating_ip_pool, '10.0.0.100-10.0.0.101') + self.assertEqual(result.reserved_networks, '172.22.0.0/16') @mock.patch("cloudshell.cp.openstack.models.model_parser.jsonpickle") @mock.patch("cloudshell.cp.openstack.models.model_parser.DeployOSNovaImageInstanceResourceModel") From ea7e45943589e6798a995253eb80256fe4aae018 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Thu, 3 Nov 2016 18:17:36 +0530 Subject: [PATCH 11/11] #15 model_parser unit test failure fixed --- .../test_cp/test_openstack/test_models/test_model_parser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/tests/test_cp/test_openstack/test_models/test_model_parser.py b/package/tests/test_cp/test_openstack/test_models/test_model_parser.py index 6755217..80d69a5 100644 --- a/package/tests/test_cp/test_openstack/test_models/test_model_parser.py +++ b/package/tests/test_cp/test_openstack/test_models/test_model_parser.py @@ -21,6 +21,7 @@ def test_get_resource_model_from_context(self): test_resource.attributes['OpenStack User Password'] = 'test_pass' test_resource.attributes['Quali Management Network UUID'] = '1234-56-78' test_resource.attributes['Floating IP Pool'] = '10.0.0.100-10.0.0.101' + test_resource.attributes['Reserved Networks'] = '172.22.0.0/16' result = self.tested_class.get_resource_model_from_context(test_resource) @@ -32,6 +33,7 @@ def test_get_resource_model_from_context(self): self.assertEqual(result.os_user_password, 'test_pass') self.assertEqual(result.qs_mgmt_os_net_uuid, '1234-56-78') self.assertEqual(result.os_floating_ip_pool, '10.0.0.100-10.0.0.101') + self.assertEqual(result.reserved_networks, '172.22.0.0/16') @mock.patch("cloudshell.cp.openstack.models.model_parser.jsonpickle") @mock.patch("cloudshell.cp.openstack.models.model_parser.DeployOSNovaImageInstanceResourceModel")