예제 #1
0
def release_resources(username, experiment_id):
    experiments_to_delete = find_by_element_value(entities.Experiment,
                                                  entities.Experiment.id,
                                                  experiment_id)
    if len(experiments_to_delete) == 0:
        logger.error("No experiment to be deleted....")
        raise ExperimentNotFound("No experiment to be deleted....")
    experiment_to_delete = experiments_to_delete[0]
    _release_all_experiment_resources(experiment_to_delete, username)
    logger.info("deleting %s" % experiment_to_delete.name)
    delete(experiment_to_delete)
예제 #2
0
def refresh_resources(username, manager_name=None):
    managers = []
    if manager_name is None:
        for man in find(ManagerEndpoint):
            managers.append(man.name)
    else:
        managers.append(manager_name)

    user_info = get_user_info(username)
    result = []
    if user_info:
        for manager in managers:
            stub = get_stub_from_manager_name(manager)
            request_message = user_info
            try:
                response = stub.refresh_resources(request_message)
            except _Rendezvous:
                traceback.print_exc()
                logger.error(
                    "Exception while calling gRPC, maybe %s Manager is down?" %
                    manager)
                raise RpcFailedCall(
                    "Exception while calling gRPC, maybe %s Manager is down?" %
                    manager)
            if response.result != 0:
                logger.error("list resources returned %d: %s" %
                             (response.result, response.error_message))
                raise RpcFailedCall("list resources returned %d: %s" %
                                    (response.result, response.error_message))
            result.extend(response.list_resource.resources)

    logger.debug("Saving %d resources" % len(result))

    for rm in find(entities.ResourceMetadata):
        if rm.node_type in REFRESH_RES_NODE_TYPES:
            delete(rm)

    for rm in result:
        resource_metadata = ResourceMetadata()
        if rm.resource_id and (not hasattr(rm, 'user') or rm.user == username):
            resource_metadata.id = rm.resource_id
            resource_metadata.description = rm.description
            resource_metadata.cardinality = rm.cardinality
            resource_metadata.node_type = rm.node_type
            if hasattr(rm, 'user') and rm.user:
                resource_metadata.user = rm.user
            else:
                resource_metadata.user = ''
            resource_metadata.testbed = list(TESTBED_MAPPING.keys())[list(
                TESTBED_MAPPING.values()).index(rm.testbed)]
            save(resource_metadata, ResourceMetadata)

    return result
예제 #3
0
def _terminate_expired_resource(res: entities.UsedResource):
    resource_to_delete = find(entities.UsedResource, _id=res.id)
    exp_id = resource_to_delete.parent_id
    if resource_to_delete and res == resource_to_delete:
        _release_used_resource(res)
        delete(resource_to_delete)
    else:
        logger.debug("The initial experiment was removed")
        return
    exp = find(entities.Experiment, _id=exp_id)
    if not len(exp.resources):
        delete(exp)
def unregister_endpoint(manager_endpoint_name: str) -> bool:
    deleted = False
    for manager_endpoint in find(ManagerEndpoint):
        if manager_endpoint.name == manager_endpoint_name:
            for resource_type in get_mapping_managers().get(
                    manager_endpoint.name):
                for rm in [
                        rm for rm in find(ResourceMetadata)
                        if rm.node_type.lower() == resource_type.lower()
                ]:
                    delete(rm)
            delete(manager_endpoint)
            deleted = True
    return deleted
예제 #5
0
    def reserve(self):
        used_resources = []
        for node in self.topology_template.nodetemplates:
            used_resource = _get_used_resource_from_node(node, self.username)
            used_resources.append(used_resource)
            CalendarManager.check_availability_for_node(used_resource)
        try:
            CalendarManager.check_overlapping_resources(used_resources)
        except ExperimentValidationError as e:
            delete(self.experiment)
            raise e
        # all node have been granted

        for us in self.experiment.resources:
            us.status = ResourceStatus.RESERVED.value

        save(self.experiment)
 def register(self, request, context):
     logger.info("registering %s" % request.name)
     old_managers = find_by_element_value(ManagerEndpoint,
                                          ManagerEndpoint.name,
                                          request.name)
     for old_man in old_managers:
         delete(old_man)
         logger.debug("Removed old manager endpoint: %s:%s" %
                      (old_man.name, old_man.endpoint))
     manager_endpoint = ManagerEndpoint()
     manager_endpoint.name = request.name
     manager_endpoint.endpoint = request.endpoint
     save(manager_endpoint, ManagerEndpoint)
     list_resources()
     response_message = messages_pb2.ResponseMessage()
     response_message.result = 0
     return response_message
예제 #7
0
def list_resources(username='', manager_name=None):
    managers = []
    if manager_name is None:
        for man in find(ManagerEndpoint):
            managers.append(man.name)
    else:
        managers.append(manager_name)

    result = []
    # List resources can be done in parallel
    max_workers = len(managers)
    tpe = ThreadPoolExecutor(max_workers=max_workers)
    threads = []
    for manager in managers:
        threads.append(tpe.submit(_execute_rpc_list_res, manager))
    for t in threads:
        result.extend(t.result())

    logger.debug("Saving %d resources" % len(result))

    for rm in find(entities.ResourceMetadata):
        for rm_to_del in result:
            if rm.id == rm_to_del.resource_id:
                delete(rm)

    for rm in result:
        if username == '' or rm.user == username:
            resource_metadata = ResourceMetadata()
            if not username is None:
                resource_metadata.user = username
            resource_metadata.id = rm.resource_id
            resource_metadata.description = rm.description
            resource_metadata.cardinality = rm.cardinality
            resource_metadata.node_type = rm.node_type
            resource_metadata.testbed = _get_testbed_string(rm.testbed)
            save(resource_metadata, ResourceMetadata)

    return result
예제 #8
0
def delete_user(username):
    for experimenter in find(Experimenter):
        if experimenter.username == username:
            for experiment in find(entities.Experiment):
                if experiment.username == username:
                    try:
                        release_resources(username, experiment.id)
                    except ExperimentNotFound as e:
                        pass
                    except Exception as e:
                        logger.error(
                            'Exception while trying to delete experiment {} of user {}: {}'
                            .format(experiment.id, username, str(e)))
                        traceback.print_exc()
                        logger.warning(
                            'Removing the resources and experiment {} of user {} from the database so they might actually not be removed!'
                            .format(experiment.id, username))
                        try:
                            for ur in find(UsedResource):
                                if ur.parent_id == experiment.id:
                                    logger.debug(
                                        'Removing used resource {} ({}) from the database.'
                                        .format(ur.id, ur.name))
                                    try:
                                        delete(ur)
                                    except Exception as e:
                                        logger.error(
                                            'Exception while removing used resource {} ({}) from the database: {}'
                                            .format(ur.id, ur.name, e))
                                        traceback.print_exc()
                            logger.debug(
                                'Removing experiment {} from the database.'.
                                format(experiment.id))
                            try:
                                delete(experiment)
                            except Exception as e:
                                logger.error(
                                    'Exception while removing experiment {} from the database: {}'
                                    .format(experiment.id, e))
                                traceback.print_exc()
                        except Exception as e:
                            logger.error(
                                'Exception while removing the resources and experiment {} of user {} from the database.'
                                .format(experiment.id, username))
            user_info = _create_user_info_from_experimenter(experimenter)
            for man in MANAGERS_CREATE_USER:
                try:
                    get_stub_from_manager_name(man).delete_user(user_info)
                    logger.info("Manager {} delete user {} finished".format(
                        man, experimenter.username))
                except ManagerNotFound:
                    traceback.print_exc()
                    logger.error(
                        "Manager {} is not register and needs to delete user {}"
                        .format(man, experimenter.username))
            delete(experimenter)
예제 #9
0
    def __init__(self, file_path, username):
        self.username = username
        self.file_path = file_path
        zf = zipfile.ZipFile(self.file_path)
        for info in zf.infolist():
            filename = info.filename
            logger.debug("Filename: %s" % filename)
            if filename.endswith(".yaml") and filename.startswith(
                    "Definitions/"):
                logger.debug("parsing %s..." % filename)
                try:
                    tpl = ToscaTemplate(
                        yaml_dict_tpl=yaml.load(zf.read(filename)))
                except Exception as e:
                    if hasattr(e, 'message'):
                        raise ExperimentValidationError(e.message)
                    elif isinstance(e.args, list):
                        raise ExperimentValidationError(e.args[0])
                    elif isinstance(e.args, str):
                        raise ExperimentValidationError(e.args)
                    else:
                        raise ExperimentValidationError(
                            "no message available", e)

                for node in tpl.nodetemplates:
                    logger.debug(
                        "Found node: %s of type %s with properties: %s" %
                        (node.name, node.type,
                         list(node.get_properties().keys())))
                self.topology_template = tpl
            if filename == 'TOSCA-Metadata/Metadata.yaml':
                metadata = yaml.load(zf.read(filename))
                self.name = metadata.get('name')
                if find(entities.Experiment,
                        '{}_{}'.format(self.username, self.name)) is not None:
                    raise ExperimentValidationError(
                        'There is already an experiment with this name, please choose a different one.'
                    )
                # 12/12/12 10:55
                self.start_date = self.get_start_date(metadata)
                # 12/12/12 11:55
                self.end_date = self.get_end_date(metadata)
                today = datetime.today().date()
                logger.info("End date: date: %s" % self.end_date.date())
                if self.end_date.date() < today:
                    logger.error(
                        'For the experiment {} the end date({}) is in the past.'
                        .format(self.name, self.end_date.date()))
                    raise ExperimentValidationError(
                        'For the experiment {} the end date({}) is in the past.'
                        .format(self.name, self.end_date.date()))
                self.duration = self.end_date - self.start_date
                logger.debug("Experiment duration %s" % self.duration)
            if filename.startswith("Files/") and filename.endswith('.csar'):

                experiment_nsd_csar_location = get_config(
                    'system', 'temp-csar-location',
                    '/etc/softfire/experiment-nsd-csar')

                experiment_nsd_csar_location = '{}/{}'.format(
                    experiment_nsd_csar_location.rstrip('/'), username)
                if not os.path.exists(experiment_nsd_csar_location):
                    os.makedirs(experiment_nsd_csar_location)
                data = zf.read(filename)

                nsd_file_location = "%s/%s" % (experiment_nsd_csar_location,
                                               filename.split('/')[-1])
                with open(nsd_file_location, 'wb+') as f:
                    f.write(data)
        temp_ids = []
        for node in self.topology_template.nodetemplates:
            if node.type == 'NfvResource':
                file_name = node.get_properties().get('file_name')
                if file_name:
                    file_name = file_name.value
                if file_name and file_name.startswith(
                        "Files/") and file_name.endswith(".csar"):
                    real_file_name = file_name[6:]
                    tmp_file_location = '{}/{}/{}'.format(
                        get_config(
                            'system', 'temp-csar-location',
                            '/etc/softfire/experiment-nsd-csar').rstrip('/'),
                        username, real_file_name)
                    # get the description
                    try:
                        zf = zipfile.ZipFile(tmp_file_location)
                    except FileNotFoundError:
                        logger.error(
                            "Please check that the file_name property is correctly set to the file name passed."
                        )
                        raise ExperimentValidationError(
                            "Please check that the file_name property is correctly set to the file name passed."
                        )
                    try:
                        filenames = [
                            zipinfo.filename for zipinfo in zf.filelist
                        ]
                        if 'TOSCA-Metadata/Metadata.yaml' in filenames:
                            logger.debug(
                                "Found 'TOSCA-Metadata/Metadata.yaml'")
                            yaml_file = zf.read('TOSCA-Metadata/Metadata.yaml')
                        elif 'tosca-metadata/Metadata.yaml' in filenames:
                            # just for legacy support
                            # the correct file name following the specification is 'TOSCA-Metadata'
                            # to support experiments that were created before this fix we still check for 'tosca-metadata' though
                            logger.warning(
                                "'TOSCA-Metadata/Metadata.yaml' not found. Will try 'tosca-metadata/Metadata.yaml' to support older experiments."
                            )
                            yaml_file = zf.read('tosca-metadata/Metadata.yaml')
                        else:
                            raise ExperimentValidationError(
                                'The TOSCA-Metadata/Metadata.yaml file is missing in {}.'
                                .format(file_name))
                    except KeyError as e:
                        traceback.print_exc()
                        if hasattr(e, 'message'):
                            raise ExperimentValidationError(e.message)
                        else:
                            raise ExperimentValidationError(e.args)
                    if yaml_file:
                        yaml_content = yaml.load(yaml_file)
                        description = yaml_content.get('description')
                    else:
                        description = 'No description available'
                    testbeds = node.get_properties().get('testbeds').value
                    temp_ids.append(
                        add_resource(
                            username,
                            node.get_properties().get('resource_id').value,
                            "NfvResource", -1, description,
                            list(testbeds.keys())[0], real_file_name))
        try:
            self._validate()
        except Exception as e:
            for id in temp_ids:
                delete(find(ResourceMetadata, _id=id))
            raise ExperimentValidationError(e.args)

        exp = entities.Experiment()
        exp.id = '{}_{}'.format(self.username, self.name)
        exp.username = self.username
        exp.name = self.name
        exp.start_date = self.start_date
        exp.end_date = self.end_date
        exp.resources = []

        for node in self.topology_template.nodetemplates:
            exp.resources.append(self._get_used_resource_by_node(node))

        element_value = find_by_element_value(entities.Experiment,
                                              entities.Experiment.username,
                                              self.username)
        max_no_experiment = get_config("System", "max-number-experiments", 3)
        if len(element_value) >= max_no_experiment:
            raise ExperimentValidationError(
                "You cannot have more than %s experiments at the same time!" %
                max_no_experiment)

        logger.info("Saving experiment %s" % exp.name)
        save(exp)
        self.experiment = exp
        for res in exp.resources:
            _start_termination_thread_for_res(res)