Beispiel #1
0
 def configuration_complete(self, *, action: str, token: ConfigToken,
                            out_properties: dict):
     super().configuration_complete(action=action,
                                    token=token,
                                    out_properties=out_properties)
     rc = self.get_control_by_type(rtype=token.get_resource_type())
     if rc is not None:
         rc.configuration_complete(action=action,
                                   token=token,
                                   out_properties=out_properties)
     else:
         raise AuthorityException(
             Constants.UNSUPPORTED_RESOURCE_TYPE.format(
                 token.get_resource_type()))
 def handler_complete(self, properties: dict, unit: ConfigToken,
                      old_unit: ConfigToken):
     try:
         self.lock.acquire()
         self.logger.debug(f"Properties: {properties} Unit: {unit}")
         # Copy the sliver from the Unit to
         old_unit.update_sliver(sliver=unit.get_sliver())
         self.plugin.configuration_complete(token=old_unit,
                                            properties=properties)
     except Exception as e:
         self.logger.error(f"Exception occurred {e}")
         self.logger.error(traceback.format_exc())
     finally:
         self.lock.release()
    def invoke_handler(self, unit: ConfigToken, operation: str):
        try:
            handler = self.config_mappings.get(str(unit.get_resource_type()),
                                               None)
            if handler is None:
                raise AuthorityException(
                    f"No handler found for resource type {unit.get_resource_type()}"
                )

            future = self.executor.submit(self.process_pool_main, operation,
                                          handler.get_class_name(),
                                          handler.get_module_name(),
                                          handler.get_properties(), unit,
                                          self.process_pool_lock)

            self.queue_future(future=future, unit=unit)
            self.logger.debug(
                f"Handler operation {operation} scheduled for Resource Type: {unit.get_resource_type()} "
                f"Unit: {unit.get_id()} Reservation: {unit.get_reservation_id()}"
            )

        except Exception as e:
            self.logger.error(f"Exception occurred {e}")
            self.logger.error(traceback.format_exc())
            result = {
                Constants.PROPERTY_TARGET_NAME: operation,
                Constants.PROPERTY_TARGET_RESULT_CODE:
                Constants.RESULT_CODE_EXCEPTION,
                Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0
            }

            self.handler_complete(unit=unit, properties=result, old_unit=unit)
        finally:
            self.logger.info(f"Executing {operation} completed")
    def delete(self, unit: ConfigToken) -> Tuple[dict, ConfigToken]:
        result = {Constants.PROPERTY_TARGET_NAME: Constants.TARGET_DELETE,
                  Constants.PROPERTY_TARGET_RESULT_CODE: Constants.RESULT_CODE_OK,
                  Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0}
        try:
            self.get_logger().info(f"Delete invoked for unit: {unit}")
            sliver = unit.get_sliver()
            if sliver is None:
                raise NetHandlerException(f"Unit # {unit} has no assigned slivers")

            unit_id = str(unit.get_reservation_id())
            self.__cleanup(sliver=sliver, raise_exception=True, unit_id=unit_id)
        except Exception as e:
            result = {Constants.PROPERTY_TARGET_NAME: Constants.TARGET_DELETE,
                      Constants.PROPERTY_TARGET_RESULT_CODE: Constants.RESULT_CODE_EXCEPTION,
                      Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0,
                      Constants.PROPERTY_EXCEPTION_MESSAGE: e}
            self.get_logger().error(e)
            self.get_logger().error(traceback.format_exc())
        finally:
            self.get_logger().info(f"Delete completed")
        return result, unit
    def process_modify_complete(self, *, unit: ConfigToken, properties: dict):
        self.logger.debug("Modify")
        self.logger.debug(properties)

        if self.actor.is_stopped():
            raise PluginException(Constants.INVALID_ACTOR_STATE)

        sequence = HandlerProcessor.get_action_sequence_number(
            properties=properties)
        notice = None
        # TODO synchronized on token
        if sequence != unit.get_sequence():
            self.logger.warning(
                "(modify complete) sequences mismatch: incoming ({}) local: ({}). "
                "Ignoring event.".format(sequence, unit.get_sequence()))
            return
        else:
            self.logger.debug(
                "(modify complete) incoming ({}) local: ({})".format(
                    sequence, unit.get_sequence()))

        # TODO properties

        result = HandlerProcessor.get_result_code(properties=properties)
        msg = HandlerProcessor.get_exception_message(properties=properties)
        if msg is None:
            msg = HandlerProcessor.get_result_code_message(
                properties=properties)

        if result == 0:
            self.logger.debug("modify code 0 (success)")
            self.merge_unit_properties(unit=unit, properties=properties)
            unit.complete_modify()

        elif result == -1:
            self.logger.debug("modify code -1 with message: {}".format(msg))
            notice = "Exception during modify for unit: {} {}".format(
                unit.get_id(), msg)
            self.fail_modify_no_update(unit=unit, message=notice)

        else:
            self.logger.debug("modify code {} with message: {}".format(
                result, msg))
            notice = "Error code= {} during modify for unit: {} with message: {}".format(
                result, unit.get_id(), msg)
            self.fail_modify_no_update(unit=unit, message=notice)

        try:
            self.get_substrate_database().update_unit(u=unit)
        except Exception as e:
            self.logger.error(e)
        finally:
            self.logger.debug("process modify complete")
Beispiel #6
0
    def modify(self, unit: ConfigToken) -> Tuple[dict, ConfigToken]:
        """
        Modify a provisioned Unit
        :param unit: unit representing VM
        :param properties: properties
        :return: tuple of result status and the unit
        """
        result = {
            Constants.PROPERTY_TARGET_NAME: Constants.TARGET_MODIFY,
            Constants.PROPERTY_TARGET_RESULT_CODE: Constants.RESULT_CODE_OK,
            Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0
        }
        try:
            self.get_logger().info(f"Modify invoked for unit: {unit}")
            sliver = unit.get_modified()
            if sliver.attached_components_info is not None:
                for component in sliver.attached_components_info.devices.values(
                ):
                    if component.get_type() not in [
                            ComponentType.SharedNIC, ComponentType.SmartNIC
                    ]:
                        continue
                    user = self.__get_default_user(
                        image=sliver.get_image_ref())
                    self.configure_nic(component=component,
                                       mgmt_ip=sliver.management_ip,
                                       user=user)
        except Exception as e:
            self.get_logger().error(e)
            self.get_logger().error(traceback.format_exc())
            # TODO
            result = {
                Constants.PROPERTY_TARGET_NAME: Constants.TARGET_MODIFY,
                Constants.PROPERTY_TARGET_RESULT_CODE:
                Constants.RESULT_CODE_EXCEPTION,
                Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0,
                Constants.PROPERTY_EXCEPTION_MESSAGE: e
            }
        finally:

            self.get_logger().info(f"Modify completed")
        return result, unit
    def create(self, unit: ConfigToken) -> Tuple[dict, ConfigToken]:
        """
        Create a Network Service
        :param unit: unit representing an NSO Network Service
        :return: tuple of result status and the unit
        """
        result = {Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
                  Constants.PROPERTY_TARGET_RESULT_CODE: Constants.RESULT_CODE_OK,
                  Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0}
        sliver = None

        try:
            self.get_logger().info(f"Create invoked for unit: {unit}")
            sliver = unit.get_sliver()
            unit_id = str(unit.get_reservation_id())
            if sliver is None:
                raise NetHandlerException(f"Unit # {unit} has no assigned slivers")

            unit_properties = unit.get_properties()  # use: TBD

            resource_type = str(sliver.get_type())

            playbook_path = self.get_config()[AmConstants.PLAYBOOK_SECTION][AmConstants.PB_LOCATION]
            inventory_path = self.get_config()[AmConstants.PLAYBOOK_SECTION][AmConstants.PB_INVENTORY]

            playbook = self.get_config()[AmConstants.PLAYBOOK_SECTION][resource_type]
            if playbook is None or inventory_path is None or playbook_path is None:
                raise NetHandlerException(f"Missing config parameters playbook: {playbook} "
                                          f"playbook_path: {playbook_path} inventory_path: {inventory_path}")
            playbook_path_full = f"{playbook_path}/{playbook}"

            if sliver.get_labels() is None or sliver.get_labels().local_name is None:
                # truncate service_name length to no greater than 53 (36+1+16)
                sliver_name = sliver.get_name()[:16] if len(sliver.get_name()) > 16 else sliver.get_name()
                service_name = f'{sliver_name}-{unit_id}'
            else:
                service_name = sliver.get_labels().local_name
            service_type = resource_type.lower()
            if service_type == 'l2bridge':
                service_data = self.__l2bridge_create_data(sliver, service_name)
            elif service_type == 'l2ptp':
                service_data = self.__l2ptp_create_data(sliver, service_name)
            elif service_type == 'l2sts':
                service_data = self.__l2sts_create_data(sliver, service_name)
            elif service_type == 'fabnetv4':
                service_data = self.__fabnetv4_create_data(sliver, service_name)
                service_type = 'l3rt'
            elif service_type == 'fabnetv6':
                service_data = self.__fabnetv6_create_data(sliver, service_name)
                service_type = 'l3rt'
            elif service_type == 'portmirror':
                service_data = self.__portmirror_create_data(sliver, service_name)
                service_type = 'port-mirror'
            else:
                raise NetHandlerException(f'unrecognized network service type "{service_type}"')
            data = {
                "tailf-ncs:services": {
                    f'{service_type}:{service_type}': [service_data]
                }
            }
            extra_vars = {
                "service_name": service_name,
                "service_type": service_type,
                "service_action": "create",
                "data": data
            }
            print(json.dumps(extra_vars))
            ansible_helper = AnsibleHelper(inventory_path=inventory_path, logger=self.get_logger())
            ansible_helper.set_extra_vars(extra_vars=extra_vars)
            self.get_logger().debug(f"Executing playbook {playbook_path_full} to create Network Service")
            ansible_helper.run_playbook(playbook_path=playbook_path_full)
            ansible_callback = ansible_helper.get_result_callback()
            unreachable = ansible_callback.get_json_result_unreachable()
            if unreachable:
                raise NetHandlerException(f'network service {service_name} was not committed due to connection error')
            failed = ansible_callback.get_json_result_failed()
            if failed:
                ansible_callback.dump_all_failed(logger=self.get_logger())
                raise NetHandlerException(f'network service {service_name} was not committed due to config error')
            ok = ansible_callback.get_json_result_ok()
            if ok:
                if not ok['changed']:
                    self.get_logger().info(f'network service {service_name} was committed ok but without change')

        except Exception as e:
            # Delete VM in case of failure
            if sliver is not None and unit_id is not None:
                self.__cleanup(sliver=sliver, unit_id=unit_id)
            result = {Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
                      Constants.PROPERTY_TARGET_RESULT_CODE: Constants.RESULT_CODE_EXCEPTION,
                      Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0,
                      Constants.PROPERTY_EXCEPTION_MESSAGE: e}
            self.get_logger().error(e)
            self.get_logger().error(traceback.format_exc())
        finally:
            self.get_logger().info(f"Create completed")
        return result, unit
Beispiel #8
0
    def create(self, unit: ConfigToken) -> Tuple[dict, ConfigToken]:
        result = None
        try:
            self.get_logger().info(f"Create invoked for unit: {unit}")
            sliver = unit.get_sliver()

            if isinstance(sliver, NodeSliver):
                assert (sliver.label_allocations is not None)
                assert (sliver.label_allocations.instance_parent is not None)
                assert (sliver.get_capacity_hints() is not None)
                assert (sliver.get_capacity_hints().instance_type is not None)
                assert (sliver.get_image_ref() is not None)
                assert (sliver.get_name() is not None)
                assert (sliver.get_type() is not None)
                if sliver.attached_components_info is not None:
                    for component in sliver.attached_components_info.devices.values(
                    ):
                        assert (component.label_allocations is not None)
                        assert (component.label_allocations.bdf is not None)
                sliver.label_allocations.instance = 'instance_001'
                sliver.management_ip = '1.2.3.4'

                self.get_logger().debug(f"s: {sliver}")
                nic_types = [ComponentType.SharedNIC, ComponentType.SmartNIC]
                if sliver.attached_components_info is not None:
                    for c in sliver.attached_components_info.devices.values():
                        if c.get_type() not in nic_types:
                            continue
                        self.get_logger().debug(f"c: {c}")
                        if c.network_service_info is not None and c.network_service_info.network_services is not None:
                            for ns in c.network_service_info.network_services.values(
                            ):
                                self.get_logger().debug(f"ns: {ns}")
                                if ns.interface_info is not None and ns.interface_info.interfaces is not None:
                                    for i in ns.interface_info.interfaces.values(
                                    ):
                                        self.get_logger().debug(f"ifs: {i}")
                result = {
                    Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
                    Constants.PROPERTY_TARGET_RESULT_CODE:
                    Constants.RESULT_CODE_OK,
                    Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0
                }

            elif isinstance(sliver, NetworkServiceSliver):
                assert (sliver.get_type() is not None)
                assert (sliver.interface_info is not None)
                for interface in sliver.interface_info.interfaces.values():
                    assert (interface.labels is not None)
                    assert (interface.labels.device_name is not None)
                    assert (interface.labels.local_name is not None)
                    assert (interface.capacities is not None)

                    if sliver.get_type() == ServiceType.L2PTP:
                        assert (interface.labels.vlan is not None)

                    if sliver.get_type() == ServiceType.FABNetv4:
                        assert (sliver.get_gateway() is not None)
                        assert (sliver.get_gateway().lab.ipv4_subnet
                                is not None)
                        assert (sliver.get_gateway().lab.ipv4 is not None)
                        assert (interface.labels.vlan is not None)

                    if sliver.get_type() == ServiceType.FABNetv6:
                        assert (sliver.get_gateway() is not None)
                        assert (sliver.get_gateway().lab.ipv6_subnet
                                is not None)
                        assert (sliver.get_gateway().lab.ipv6 is not None)
                        assert (interface.labels.vlan is not None)

                result = {
                    Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
                    Constants.PROPERTY_TARGET_RESULT_CODE:
                    Constants.RESULT_CODE_OK,
                    Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0
                }
        except Exception as e:
            result = {
                Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
                Constants.PROPERTY_TARGET_RESULT_CODE:
                Constants.RESULT_CODE_EXCEPTION,
                Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0
            }
            self.get_logger().error(e)
            self.get_logger().error(traceback.format_exc())
        finally:

            self.get_logger().info(f"Create completed")
        return result, unit
Beispiel #9
0
    def create(self, unit: ConfigToken) -> Tuple[dict, ConfigToken]:
        """
        Create a VM
        :param unit: unit representing VM
        :return: tuple of result status and the unit
        """
        result = {
            Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
            Constants.PROPERTY_TARGET_RESULT_CODE: Constants.RESULT_CODE_OK,
            Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0
        }

        unit_id = None
        sliver = None
        try:
            self.get_logger().info(f"Create invoked for unit: {unit}")
            sliver = unit.get_sliver()
            unit_id = str(unit.get_reservation_id())
            if sliver is None:
                raise VmHandlerException(
                    f"Unit # {unit} has no assigned slivers")

            unit_properties = unit.get_properties()
            ssh_key = unit_properties.get(Constants.USER_SSH_KEY, None)

            worker_node = sliver.label_allocations.instance_parent
            flavor = sliver.get_capacity_hints().instance_type
            vmname = sliver.get_name()
            image = sliver.get_image_ref()
            init_script = sliver.get_boot_script()

            if worker_node is None or flavor is None or vmname is None or image is None:
                raise VmHandlerException(
                    f"Missing required parameters workernode: {worker_node} "
                    f"flavor: {flavor}: vmname: {vmname} image: {image}")

            resource_type = str(sliver.get_type())
            playbook_path = self.get_config()[AmConstants.PLAYBOOK_SECTION][
                AmConstants.PB_LOCATION]
            inventory_path = self.get_config()[AmConstants.PLAYBOOK_SECTION][
                AmConstants.PB_INVENTORY]

            playbook = self.get_config()[
                AmConstants.PLAYBOOK_SECTION][resource_type]
            if playbook is None or inventory_path is None or playbook_path is None:
                raise VmHandlerException(
                    f"Missing config parameters playbook: {playbook} "
                    f"playbook_path: {playbook_path} inventory_path: {inventory_path}"
                )

            # create VM
            playbook_path_full = f"{playbook_path}/{playbook}"
            instance_props = self.__create_vm(playbook_path=playbook_path_full,
                                              inventory_path=inventory_path,
                                              vm_name=vmname,
                                              image=image,
                                              flavor=flavor,
                                              worker_node=worker_node,
                                              unit_id=unit_id,
                                              ssh_key=ssh_key,
                                              init_script=init_script)

            disable_fip = self.get_config()[AmConstants.RUNTIME_SECTION][
                AmConstants.RT_DISABLE_FIP]

            user = self.__get_default_user(image=image)

            if disable_fip:
                self.get_logger().info(
                    "Floating IP is disabled, using IPV6 Global Unicast Address"
                )
                fip = instance_props.get(AmConstants.SERVER_ACCESS_IPV6, None)
            else:
                # Attach FIP
                fip = self.__attach_fip(playbook_path=playbook_path_full,
                                        inventory_path=inventory_path,
                                        vm_name=vmname,
                                        unit_id=unit_id)

                self.__verify_ssh(mgmt_ip=fip, user=user)
                self.__post_boot_config(mgmt_ip=fip, user=user)

            sliver.label_allocations.instance = instance_props.get(
                AmConstants.SERVER_INSTANCE_NAME, None)

            # Attach any attached PCI Devices
            if sliver.attached_components_info is not None:
                for component in sliver.attached_components_info.devices.values(
                ):
                    resource_type = str(component.get_type())
                    playbook = self.get_config()[
                        AmConstants.PLAYBOOK_SECTION][resource_type]
                    if playbook is None:
                        raise VmHandlerException(
                            f"Missing parameters playbook: {playbook} "
                            f"resource_type: {resource_type} component: {component} "
                            f"sliver: {sliver}")

                    playbook_path_full = f"{playbook_path}/{playbook}"
                    self.get_logger().debug(
                        f"Attaching Devices {playbook_path_full}")
                    self.__attach_detach_pci(
                        playbook_path=playbook_path_full,
                        inventory_path=inventory_path,
                        host=worker_node,
                        instance_name=sliver.label_allocations.instance,
                        device_name=str(unit.get_id()),
                        component=component,
                        user=user,
                        mgmt_ip=fip)

            sliver.management_ip = fip

        except Exception as e:
            self.get_logger().error(e)
            self.get_logger().error(traceback.format_exc())
            # Delete VM in case of failure
            if sliver is not None and unit_id is not None:
                self.__cleanup(sliver=sliver, unit_id=unit_id)
                unit.sliver.label_allocations.instance = None

            result = {
                Constants.PROPERTY_TARGET_NAME: Constants.TARGET_CREATE,
                Constants.PROPERTY_TARGET_RESULT_CODE:
                Constants.RESULT_CODE_EXCEPTION,
                Constants.PROPERTY_ACTION_SEQUENCE_NUMBER: 0,
                Constants.PROPERTY_EXCEPTION_MESSAGE: e
            }
        finally:

            self.get_logger().info(f"Create completed")
        return result, unit