def _scan_for_services(services_dir, pj):
    from son_editor.models.descriptor import Service
    session = db_session()
    try:
        for service_file in os.listdir(services_dir):
            if service_file.endswith(".yml"):
                service = Service()
                file_path = os.path.join(services_dir, service_file)
                load_ns_vnf_from_disk(file_path, service)
                db_service = session.query(Service). \
                    filter(Service.project == pj). \
                    filter(Service.name == service.name). \
                    filter(Service.vendor == service.vendor). \
                    filter(Service.version == service.version). \
                    first()
                if not db_service:
                    logger.info("Found service in project {}: {}".format(pj.name, service.uid))
                    service.project = pj
                    session.add(service)
                    session.commit()
                else:
                    session.rollback()
                if get_file_path("nsd", service) != file_path:
                    shutil.move(file_path, get_file_path("nsd", service))  # rename to expected name format
            elif os.path.isdir(os.path.join(services_dir, service_file)):
                _scan_for_services(os.path.join(services_dir, service_file), pj)
    except:
        session.rollback()
def _scan_for_services(services_dir, pj):
    from son_editor.models.descriptor import Service
    session = db_session()
    try:
        for service_file in os.listdir(services_dir):
            if service_file.endswith(".yml"):
                service = Service()
                file_path = os.path.join(services_dir, service_file)
                load_ns_vnf_from_disk(file_path, service)
                db_service = session.query(Service). \
                    filter(Service.project == pj). \
                    filter(Service.name == service.name). \
                    filter(Service.vendor == service.vendor). \
                    filter(Service.version == service.version). \
                    first()
                if not db_service:
                    logger.info("Found service in project {}: {}".format(
                        pj.name, service.uid))
                    service.project = pj
                    session.add(service)
                    session.commit()
                else:
                    session.rollback()
                if get_file_path("nsd", service) != file_path:
                    shutil.move(file_path, get_file_path(
                        "nsd", service))  # rename to expected name format
            elif os.path.isdir(os.path.join(services_dir, service_file)):
                _scan_for_services(os.path.join(services_dir, service_file),
                                   pj)
    except:
        session.rollback()
Example #3
0
def _scan_for_functions(function_dir, pj):
    """
    Scan project for functions
    
    Scans the given directory for functions and adds them to the project.
    
    :param function_dir: The functions directory in the project
    :param pj: The project model from the database
    """
    session = db_session()
    from son_editor.models.descriptor import Function
    try:
        for function_folder in os.listdir(function_dir):
            folder_path = os.path.join(function_dir, function_folder)
            if os.path.isdir(folder_path):
                yaml_files = [
                    file for file in os.listdir(folder_path)
                    if file.endswith(".yml")
                ]
                if len(yaml_files) == 1:
                    function = Function()
                    file_path = os.path.join(folder_path, yaml_files[0])
                    load_ns_vnf_from_disk(file_path, function)
                    db_function = session.query(Function). \
                        filter(Function.project == pj). \
                        filter(Function.name == function.name). \
                        filter(Function.vendor == function.vendor). \
                        filter(Function.version == function.version). \
                        first()
                    if not db_function:
                        logger.info("Found function in project {}: {}".format(
                            pj.name, function.uid))
                        function.project = pj
                        session.add(function)
                        session.commit()
                    else:
                        function = db_function
                    # rename folder if necessary
                    target_folder = os.path.normpath(
                        get_file_path("vnf", function).replace(
                            get_file_name(function), ''))
                    if os.path.normpath(folder_path) != target_folder:
                        shutil.move(folder_path, target_folder)
                        file_path = file_path.replace(folder_path,
                                                      target_folder)
                    # rename file if necessary
                    if not os.path.exists(get_file_path("vnf", function)):
                        shutil.move(file_path, get_file_path("vnf", function))
                else:
                    logger.info(
                        "Multiple or no yaml files in folder {}. Ignoring".
                        format(folder_path))

    except:
        logger.exception("Could not load function descriptor:")
    finally:
        session.rollback()
def update_function(ws_id: int, prj_id: int, func_id: int, func_data: dict) -> dict:
    """
    Update the function descriptor
    :param ws_id:
    :param prj_id:
    :param func_id:
    :param func_data:
    :return: The updated function descriptor
    """
    session = db_session()

    ws = session.query(Workspace).filter(Workspace.id == ws_id).first()
    validate_vnf(ws.vnf_schema_index, func_data)

    # test if ws Name exists in database
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == prj_id). \
        filter(Function.id == func_id).first()
    if function is None:
        session.rollback()
        raise NotFound("Function with id {} does not exist".format(func_id))
    function.descriptor = json.dumps(func_data)

    old_file_name = get_file_path("vnf", function)
    old_folder_path = old_file_name.replace(get_file_name(function), "")
    try:
        function.name = shlex.quote(func_data["name"])
        function.vendor = shlex.quote(func_data["vendor"])
        function.version = shlex.quote(func_data["version"])
    except KeyError as ke:
        session.rollback()
        raise InvalidArgument("Missing key {} in function data".format(str(ke)))

    try:
        new_file_name = get_file_path("vnf", function)
        new_folder_path = new_file_name.replace(get_file_name(function), "")
        if old_folder_path != new_folder_path:
            # move old files to new location
            os.makedirs(new_folder_path)
            for file in os.listdir(old_folder_path):
                if not old_file_name == os.path.join(old_folder_path, file):  # don't move descriptor yet
                    shutil.move(os.path.join(old_folder_path, file), os.path.join(new_folder_path, file))
        if not new_file_name == old_file_name:
            shutil.move(old_file_name, new_file_name)
        if old_folder_path != new_folder_path:
            # cleanup old folder
            shutil.rmtree(old_folder_path)
        write_ns_vnf_to_disk("vnf", function)
    except:
        session.rollback()
        logger.exception("Could not update descriptor file:")
        raise
    session.commit()
    return function.as_dict()
def update_service(ws_id, project_id, service_id, service_data):
    """
    Update the service using the service data from the request
    :param ws_id:
    :param project_id:
    :param service_id:
    :param service_data:
    :return:
    """
    session = db_session()
    service = session.query(Service). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Service.id == service_id).first()
    if service:
        old_file_name = get_file_path("nsd", service)
        # Parse parameters and update record
        if 'descriptor' in service_data:
            # validate service descriptor
            workspace = session.query(Workspace).filter(
                Workspace.id == ws_id).first()
            validate_service_descriptor(workspace.ns_schema_index,
                                        service_data["descriptor"])
            service.descriptor = json.dumps(service_data["descriptor"])
            try:
                service.name = shlex.quote(service_data["descriptor"]["name"])
                service.vendor = shlex.quote(
                    service_data["descriptor"]["vendor"])
                service.version = shlex.quote(
                    service_data["descriptor"]["version"])
            except KeyError as ke:
                raise InvalidArgument("Missing key {} in function data".format(
                    str(ke)))

        if 'meta' in service_data:
            service.meta = json.dumps(service_data["meta"])

        new_file_name = get_file_path("nsd", service)
        try:
            if not old_file_name == new_file_name:
                shutil.move(old_file_name, new_file_name)
            write_ns_vnf_to_disk("nsd", service)
        except:
            logger.exception("Could not update descriptor file:")
            raise
        session.commit()
        return service.as_dict()
    else:
        raise NotFound(
            "Could not update service '{}', because no record was found".
            format(service_id))
def _scan_for_functions(function_dir, pj):
    """
    Scan project for functions
    
    Scans the given directory for functions and adds them to the project.
    
    :param function_dir: The functions directory in the project
    :param pj: The project model from the database
    """
    session = db_session()
    from son_editor.models.descriptor import Function
    try:
        for function_folder in os.listdir(function_dir):
            folder_path = os.path.join(function_dir, function_folder)
            if os.path.isdir(folder_path):
                yaml_files = [file for file in os.listdir(folder_path) if file.endswith(".yml")]
                if len(yaml_files) == 1:
                    function = Function()
                    file_path = os.path.join(folder_path, yaml_files[0])
                    load_ns_vnf_from_disk(file_path, function)
                    db_function = session.query(Function). \
                        filter(Function.project == pj). \
                        filter(Function.name == function.name). \
                        filter(Function.vendor == function.vendor). \
                        filter(Function.version == function.version). \
                        first()
                    if not db_function:
                        logger.info("Found function in project {}: {}".format(pj.name, function.uid))
                        function.project = pj
                        session.add(function)
                        session.commit()
                    else:
                        function = db_function
                    # rename folder if necessary
                    target_folder = os.path.normpath(
                        get_file_path("vnf", function).replace(get_file_name(function), ''))
                    if os.path.normpath(folder_path) != target_folder:
                        shutil.move(folder_path, target_folder)
                        file_path = file_path.replace(folder_path, target_folder)
                    # rename file if necessary
                    if not os.path.exists(get_file_path("vnf", function)):
                        shutil.move(file_path, get_file_path("vnf", function))
                else:
                    logger.info("Multiple or no yaml files in folder {}. Ignoring".format(folder_path))

    except:
        logger.exception("Could not load function descriptor:")
    finally:
        session.rollback()
Example #7
0
def save_image_file(ws_id, project_id, function_id, file):
    """
    Saves the vnf image file into the vnfs folder
    
    :param ws_id: The workspace ID 
    :param project_id: The project ID 
    :param function_id: The function ID
    :param file: The image file
    :return: A success message
    """
    if file.filename == '':
        raise InvalidArgument("No file attached!")
    if file:
        filename = secure_filename(file.filename)
        session = db_session()
        function = session.query(Function). \
            join(Project). \
            join(Workspace). \
            filter(Workspace.id == ws_id). \
            filter(Project.id == project_id). \
            filter(Function.id == function_id).first()
        if function is not None:
            file_path = get_file_path("vnf", function)
            file_path = file_path.replace(get_file_name(function), filename)
            file.save(file_path)
            return "File {} successfully uploaded!".format(filename)
        else:
            raise NotFound("Function with id " + function_id +
                           " does not exist")
Example #8
0
def delete_image_file(ws_id, project_id, vnf_id, filename):
    """
    Deletes the image file with the given name
    
    :param ws_id:  The workspace ID
    :param project_id: The project ID
    :param vnf_id: The VNF ID
    :param filename: The name of the file to delete
    :return: A success message
    :raises NotFound: if the image file could not be located
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == vnf_id).first()
    if function:
        save_name = secure_filename(filename)
        if not save_name == get_file_name(function):
            file_path = get_file_path("vnf", function).replace(
                get_file_name(function), save_name)
            if os.path.exists(file_path):
                os.remove(file_path)
                return "File {} was deleted".format(save_name)
            else:
                raise NotFound("File {} not found!".format(save_name))
    else:
        raise NotFound("Function with id " + vnf_id + " does not exist")
def delete_service(project_id: int, service_id: int) -> dict:
    """
    Deletes the service from the Database and from the disk
    :param project_id: The Projects ID
    :param service_id: The Services ID
    :return: The descriptor of the deleted service
    """
    session = db_session()
    project = session.query(Project).filter(Project.id == project_id).first()

    if project is None:
        raise NotFound("Could not delete service: project with id {} not found".format(service_id))

    service = session.query(Service). \
        filter(Service.id == service_id). \
        filter(Service.project == project). \
        first()
    if service is None:
        raise NotFound("Could not delete service: service with id {} not found".format(service_id))

    session.delete(service)
    try:
        os.remove(get_file_path("nsd", service))
    except:
        session.rollback()
        logger.exception("Could not delete service:")
        raise
    session.commit()
    return service.as_dict()
def delete_service(project_id: int, service_id: int) -> dict:
    """
    Deletes the service from the Database and from the disk

    :param project_id: The Projects ID
    :param service_id: The Services ID
    :return: The descriptor of the deleted service
    """
    session = db_session()
    project = session.query(Project).filter(Project.id == project_id).first()

    if project is None:
        raise NotFound("Could not delete service: project with id {} not found".format(service_id))

    service = session.query(Service). \
        filter(Service.id == service_id). \
        filter(Service.project == project). \
        first()
    if service is None:
        raise NotFound("Could not delete service: service with id {} not found".format(service_id))

    refs = get_references(service, session)
    if refs:
        session.rollback()
        ref_str = ",\n".join(ref.uid for ref in refs)
        raise StillReferenced("Could not delete service because it is still referenced by \n" + ref_str)
    session.delete(service)
    try:
        os.remove(get_file_path("nsd", service))
    except:
        session.rollback()
        logger.exception("Could not delete service:")
        raise
    session.commit()
    return service.as_dict()
def delete_image_file(ws_id, project_id, vnf_id, filename):
    """
    Deletes the image file with the given name
    
    :param ws_id:  The workspace ID
    :param project_id: The project ID
    :param vnf_id: The VNF ID
    :param filename: The name of the file to delete
    :return: A success message
    :raises NotFound: if the image file could not be located
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == vnf_id).first()
    if function:
        save_name = secure_filename(filename)
        if not save_name == get_file_name(function):
            file_path = get_file_path("vnf", function).replace(get_file_name(function), save_name)
            if os.path.exists(file_path):
                os.remove(file_path)
                return "File {} was deleted".format(save_name)
            else:
                raise NotFound("File {} not found!".format(save_name))
    else:
        raise NotFound("Function with id " + vnf_id + " does not exist")
def get_image_files(ws_id, project_id, function_id):
    """
    Returns a list of image file names located in the vnf folder
    
    :param ws_id: The Workspace ID
    :param project_id: The project ID
    :param function_id: The function ID
    :return: A List of image file names for this VNF 
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function:
        folder_path = get_file_path("vnf", function).replace(get_file_name(function), "")
        image_files = []

        for filename in os.listdir(folder_path):
            if not Path(os.path.join(folder_path, filename)).is_dir():
                if not filename == get_file_name(function):
                    image_files.append(filename)
        return image_files
    else:
        raise NotFound("Function with id " + function_id + " does not exist")
def save_image_file(ws_id, project_id, function_id, file):
    """
    Saves the vnf image file into the vnfs folder
    
    :param ws_id: The workspace ID 
    :param project_id: The project ID 
    :param function_id: The function ID
    :param file: The image file
    :return: A success message
    """
    if file.filename == '':
        raise InvalidArgument("No file attached!")
    if file:
        filename = secure_filename(file.filename)
        session = db_session()
        function = session.query(Function). \
            join(Project). \
            join(Workspace). \
            filter(Workspace.id == ws_id). \
            filter(Project.id == project_id). \
            filter(Function.id == function_id).first()
        if function is not None:
            file_path = get_file_path("vnf", function)
            file_path = file_path.replace(get_file_name(function), filename)
            file.save(file_path)
            return "File {} successfully uploaded!".format(filename)
        else:
            raise NotFound("Function with id " + function_id + " does not exist")
def delete_function(ws_id: int, project_id: int, function_id: int) -> dict:
    """
    Deletes the function
    :param ws_id:
    :param project_id:
    :param function_id:
    :return: the deleted function
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function is not None:
        session.delete(function)
    else:
        session.rollback()
        raise NotFound("Function with id " + function_id + " does not exist")
    try:
        os.remove(get_file_path("vnf", function))
    except:
        session.rollback()
        logger.exception("Could not delete function:")
        raise
    session.commit()
    return function.as_dict()
Example #15
0
def get_image_files(ws_id, project_id, function_id):
    """
    Returns a list of image file names located in the vnf folder
    
    :param ws_id: The Workspace ID
    :param project_id: The project ID
    :param function_id: The function ID
    :return: A List of image file names for this VNF 
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function:
        folder_path = get_file_path("vnf",
                                    function).replace(get_file_name(function),
                                                      "")
        image_files = []

        for filename in os.listdir(folder_path):
            if not Path(os.path.join(folder_path, filename)).is_dir():
                if not filename == get_file_name(function):
                    image_files.append(filename)
        return image_files
    else:
        raise NotFound("Function with id " + function_id + " does not exist")
def update_service(ws_id, project_id, service_id, service_data):
    """
    Update the service using the service data from the request
    :param ws_id:
    :param project_id:
    :param service_id:
    :param service_data:
    :return:
    """
    session = db_session()
    service = session.query(Service). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Service.id == service_id).first()
    if service:
        old_file_name = get_file_path("nsd", service)
        # Parse parameters and update record
        if 'descriptor' in service_data:
            # validate service descriptor
            workspace = session.query(Workspace).filter(Workspace.id == ws_id).first()
            validate_service_descriptor(workspace.ns_schema_index, service_data["descriptor"])
            service.descriptor = json.dumps(service_data["descriptor"])
            try:
                service.name = shlex.quote(service_data["descriptor"]["name"])
                service.vendor = shlex.quote(service_data["descriptor"]["vendor"])
                service.version = shlex.quote(service_data["descriptor"]["version"])
            except KeyError as ke:
                raise InvalidArgument("Missing key {} in function data".format(str(ke)))

        if 'meta' in service_data:
            service.meta = json.dumps(service_data["meta"])

        new_file_name = get_file_path("nsd", service)
        try:
            if not old_file_name == new_file_name:
                shutil.move(old_file_name, new_file_name)
            write_ns_vnf_to_disk("nsd", service)
        except:
            logger.exception("Could not update descriptor file:")
            raise
        session.commit()
        return service.as_dict()
    else:
        raise NotFound("Could not update service '{}', because no record was found".format(service_id))
Example #17
0
def delete_function(ws_id: int, project_id: int, function_id: int) -> dict:
    """
    Deletes the function

    :param ws_id: The workspace ID
    :param project_id: The project ID
    :param function_id: The function ID
    :return: the deleted function
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function is not None:
        refs = get_references(function, session)
        if refs:
            session.rollback()
            ref_str = ", ".join(ref.uid for ref in refs)
            raise StillReferenced(
                "Could not delete function because it is still referenced by "
                + ref_str)
        session.delete(function)
    else:
        session.rollback()
        raise NotFound("Function with id " + function_id + " does not exist")
    try:
        file_path = get_file_path("vnf", function)
        os.remove(file_path)
        # check if other descriptor files present, if not clean the vnf folder
        folder_path = file_path.replace(get_file_name(function), "")
        found_descriptor = False
        for file in os.listdir(folder_path):
            if file.endswith(".yml"):
                found_descriptor = True
                break
        if not found_descriptor:
            shutil.rmtree(folder_path)
    except:
        session.rollback()
        logger.exception("Could not delete function:")
        raise
    session.commit()
    return function.as_dict()
def delete_function(ws_id: int, project_id: int, function_id: int) -> dict:
    """
    Deletes the function

    :param ws_id:
    :param project_id:
    :param function_id:
    :return: the deleted function
    """
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function is not None:
        refs = get_references(function, session)
        if refs:
            session.rollback()
            ref_str = ", ".join(ref.uid for ref in refs)
            raise StillReferenced("Could not delete function because it is still referenced by " + ref_str)
        session.delete(function)
    else:
        session.rollback()
        raise NotFound("Function with id " + function_id + " does not exist")
    try:
        file_path = get_file_path("vnf", function)
        os.remove(file_path)
        # check if other descriptor files present, if not clean the vnf folder
        folder_path = file_path.replace(get_file_name(function), "")
        found_descriptor = False
        for file in os.listdir(folder_path):
            if file.endswith(".yml"):
                found_descriptor = True
                break
        if not found_descriptor:
            shutil.rmtree(folder_path)
    except:
        session.rollback()
        logger.exception("Could not delete function:")
        raise
    session.commit()
    return function.as_dict()
def get_image_files(ws_id, project_id, function_id):
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function:
        folder_path = get_file_path("vnf", function).replace(get_file_name(function), "")
        image_files = []

        for filename in os.listdir(folder_path):
            if not Path(os.path.join(folder_path, filename)).is_dir():
                if not filename == get_file_name(function):
                    image_files.append(filename)
        return image_files
    else:
        raise NotFound("Function with id " + function_id + " does not exist")
def delete_image_file(ws_id, project_id, vnf_id, filename):
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == vnf_id).first()
    if function:
        save_name = secure_filename(filename)
        if not save_name == get_file_name(function):
            file_path = get_file_path("vnf", function).replace(get_file_name(function), save_name)
            if os.path.exists(file_path):
                os.remove(file_path)
                return "File {} was deleted".format(save_name)
            else:
                raise NotFound("File {} not found!".format(save_name))
    else:
        raise NotFound("Function with id " + vnf_id + " does not exist")
def delete_image_file(ws_id, project_id, vnf_id, filename):
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == vnf_id).first()
    if function:
        save_name = secure_filename(filename)
        if not save_name == get_file_name(function):
            file_path = get_file_path("vnf", function).replace(get_file_name(function), save_name)
            if os.path.exists(file_path):
                os.remove(file_path)
                return "File {} was deleted".format(save_name)
            else:
                raise NotFound("File {} not found!".format(save_name))
    else:
        raise NotFound("Function with id " + vnf_id + " does not exist")
def get_image_files(ws_id, project_id, function_id):
    session = db_session()
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == project_id). \
        filter(Function.id == function_id).first()
    if function:
        folder_path = get_file_path("vnf", function).replace(get_file_name(function), "")
        image_files = []

        for filename in os.listdir(folder_path):
            if not Path(os.path.join(folder_path, filename)).is_dir():
                if not filename == get_file_name(function):
                    image_files.append(filename)
        return image_files
    else:
        raise NotFound("Function with id " + function_id + " does not exist")
def update_function(ws_id: int, prj_id: int, func_id: int, func_data: dict) -> dict:
    """
    Update the function descriptor

    :param ws_id:
    :param prj_id:
    :param func_id:
    :param func_data:
    :return: The updated function descriptor
    """
    session = db_session()

    ws = session.query(Workspace).filter(Workspace.id == ws_id).first()
    validate_vnf(ws.vnf_schema_index, func_data['descriptor'])
    edit_mode = func_data['edit_mode']

    # test if function exists in database
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == prj_id). \
        filter(Function.id == func_id).first()
    if function is None:
        session.rollback()
        raise NotFound("Function with id {} does not exist".format(func_id))

    old_file_name = get_file_path("vnf", function)
    old_folder_path = old_file_name.replace(get_file_name(function), "")
    old_uid = get_uid(function.vendor, function.name, function.version)
    try:
        new_name = shlex.quote(func_data['descriptor']["name"])
        new_vendor = shlex.quote(func_data['descriptor']["vendor"])
        new_version = shlex.quote(func_data['descriptor']["version"])
    except KeyError as ke:
        session.rollback()
        raise InvalidArgument("Missing key {} in function data".format(str(ke)))

    # check if new name already exists
    function_dup = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == prj_id). \
        filter(Function.name == new_name). \
        filter(Function.vendor == new_vendor). \
        filter(Function.version == new_version). \
        filter(Function.id != func_id).first()
    if function_dup:
        session.rollback()
        raise NameConflict("A function with that name, vendor and version already exists")

    new_uid = get_uid(new_vendor, new_name, new_version)
    refs = get_references(function, session)
    if old_uid != new_uid:
        if refs:
            if edit_mode == "create_new":
                function = Function(project=function.project)
                session.add(function)
            else:
                replace_function_refs(refs,
                                      function.vendor, function.name, function.version,
                                      new_vendor, new_name, new_version)
        function.vendor = new_vendor
        function.name = new_name
        function.version = new_version
        function.uid = new_uid
    function.descriptor = json.dumps(func_data['descriptor'])

    try:
        if old_uid != new_uid:
            new_file_name = get_file_path("vnf", function)
            new_folder_path = new_file_name.replace(get_file_name(function), "")

            if old_folder_path != new_folder_path:
                # move old files to new location
                os.makedirs(new_folder_path)
                for file in os.listdir(old_folder_path):
                    if not file.endswith(".yml"):  # don't move descriptor yet
                        if refs and edit_mode == "create_new":
                            if os.path.isdir(os.path.join(old_folder_path, file)):
                                shutil.copytree(os.path.join(old_folder_path, file),
                                                os.path.join(new_folder_path, file))
                            else:
                                shutil.copy(os.path.join(old_folder_path, file), os.path.join(new_folder_path, file))
                        else:
                            shutil.move(os.path.join(old_folder_path, file), os.path.join(new_folder_path, file))
                if refs and edit_mode == "create_new":
                    shutil.copy(old_file_name, new_file_name)
                else:
                    shutil.move(old_file_name, new_file_name)
            if old_folder_path != new_folder_path and not (refs and edit_mode == "create_new"):
                # cleanup old folder if no other descriptor exists
                if not os.listdir(old_folder_path):
                    shutil.rmtree(old_folder_path)
        write_ns_vnf_to_disk("vnf", function)
        if refs and old_uid != new_uid and edit_mode == 'replace_refs':
            for service in refs:
                write_ns_vnf_to_disk("ns", service)
    except:
        session.rollback()
        logger.exception("Could not update descriptor file:")
        raise
    session.commit()
    return function.as_dict()
def update_service(ws_id, project_id, service_id, service_data):
    """
    Update the service using the service data from the request
    
    Will also check for references by other services and create a copy if so

    :param ws_id: The Workspace ID
    :param project_id: The project ID
    :param service_id: The service ID
    :param service_data: The service data containing the "descriptor" and optionally some "meta" data
    :return: The updated service data
    """
    session = db_session()
    project = session.query(Project). \
        filter(Project.id == project_id).first()
    service = session.query(Service). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Service.project == project). \
        filter(Service.id == service_id).first()
    if service:
        refs = get_references(service, session)
        old_file_name = get_file_path("nsd", service)
        old_uid = get_uid(service.vendor, service.name, service.version)
        # Parse parameters and update record
        if 'descriptor' in service_data:
            # validate service descriptor
            workspace = session.query(Workspace).filter(Workspace.id == ws_id).first()
            validate_service_descriptor(workspace.schema_index, service_data["descriptor"])
            try:
                newName = shlex.quote(service_data["descriptor"]["name"])
                newVendor = shlex.quote(service_data["descriptor"]["vendor"])
                newVersion = shlex.quote(service_data["descriptor"]["version"])
            except KeyError as ke:
                raise InvalidArgument("Missing key {} in function data".format(str(ke)))
            new_uid = get_uid(newVendor, newName, newVersion)
            if old_uid != new_uid:
                if refs:
                    # keep old version and create new version in db
                    service = Service(newName, newVersion, newVendor, project=project)
                    session.add(service)
                else:
                    service.name = newName
                    service.vendor = newVendor
                    service.version = newVersion
            service.descriptor = json.dumps(service_data["descriptor"])

        if 'meta' in service_data:
            service.meta = json.dumps(service_data["meta"])

        if old_uid != new_uid:
            new_file_name = get_file_path("nsd", service)
            try:
                if not old_file_name == new_file_name:
                    if refs:
                        shutil.copy(old_file_name, new_file_name)
                    else:
                        shutil.move(old_file_name, new_file_name)
            except:
                logger.exception("Could not update descriptor file:")
                raise

        write_ns_vnf_to_disk("nsd", service)
        session.commit()
        return service.as_dict()
    else:
        raise NotFound("Could not update service '{}', because no record was found".format(service_id))
Example #25
0
def update_function(ws_id: int, prj_id: int, func_id: int,
                    func_data: dict) -> dict:
    """
    Update the function descriptor

    :param ws_id: The Workspace ID
    :param prj_id: The Project ID
    :param func_id: The function ID
    :param func_data: The funtion Data for updating
    :return: The updated function descriptor
    """
    session = db_session()

    ws = session.query(Workspace).filter(Workspace.id == ws_id).first()
    validate_vnf(ws.schema_index, func_data['descriptor'])
    edit_mode = func_data['edit_mode']

    # test if function exists in database
    function = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == prj_id). \
        filter(Function.id == func_id).first()
    if function is None:
        session.rollback()
        raise NotFound("Function with id {} does not exist".format(func_id))

    old_file_name = get_file_path("vnf", function)
    old_folder_path = old_file_name.replace(get_file_name(function), "")
    old_uid = get_uid(function.vendor, function.name, function.version)
    try:
        new_name = shlex.quote(func_data['descriptor']["name"])
        new_vendor = shlex.quote(func_data['descriptor']["vendor"])
        new_version = shlex.quote(func_data['descriptor']["version"])
    except KeyError as ke:
        session.rollback()
        raise InvalidArgument("Missing key {} in function data".format(
            str(ke)))

    # check if new name already exists
    function_dup = session.query(Function). \
        join(Project). \
        join(Workspace). \
        filter(Workspace.id == ws_id). \
        filter(Project.id == prj_id). \
        filter(Function.name == new_name). \
        filter(Function.vendor == new_vendor). \
        filter(Function.version == new_version). \
        filter(Function.id != func_id).first()
    if function_dup:
        session.rollback()
        raise NameConflict(
            "A function with that name, vendor and version already exists")

    new_uid = get_uid(new_vendor, new_name, new_version)
    refs = get_references(function, session)
    if old_uid != new_uid:
        if refs:
            if edit_mode == "create_new":
                function = Function(project=function.project)
                session.add(function)
            else:
                replace_function_refs(refs, function.vendor, function.name,
                                      function.version, new_vendor, new_name,
                                      new_version)
        function.vendor = new_vendor
        function.name = new_name
        function.version = new_version
        function.uid = new_uid
    function.descriptor = json.dumps(func_data['descriptor'])

    try:
        if old_uid != new_uid:
            new_file_name = get_file_path("vnf", function)
            new_folder_path = new_file_name.replace(get_file_name(function),
                                                    "")

            if old_folder_path != new_folder_path:
                # move old files to new location
                os.makedirs(new_folder_path)
                for file in os.listdir(old_folder_path):
                    if not file.endswith(".yml"):  # don't move descriptor yet
                        if refs and edit_mode == "create_new":
                            if os.path.isdir(
                                    os.path.join(old_folder_path, file)):
                                shutil.copytree(
                                    os.path.join(old_folder_path, file),
                                    os.path.join(new_folder_path, file))
                            else:
                                shutil.copy(
                                    os.path.join(old_folder_path, file),
                                    os.path.join(new_folder_path, file))
                        else:
                            shutil.move(os.path.join(old_folder_path, file),
                                        os.path.join(new_folder_path, file))
                if refs and edit_mode == "create_new":
                    shutil.copy(old_file_name, new_file_name)
                else:
                    shutil.move(old_file_name, new_file_name)
            if old_folder_path != new_folder_path and not (refs and edit_mode
                                                           == "create_new"):
                # cleanup old folder if no other descriptor exists
                if not os.listdir(old_folder_path):
                    shutil.rmtree(old_folder_path)
        write_ns_vnf_to_disk("vnf", function)
        if refs and old_uid != new_uid and edit_mode == 'replace_refs':
            for service in refs:
                write_ns_vnf_to_disk("ns", service)
    except:
        session.rollback()
        logger.exception("Could not update descriptor file:")
        raise
    session.commit()
    return function.as_dict()