def update_platform(workspace_id: int, platform_id: int, platform_data) -> dict: """ Update the platform entry :param workspace_id: :param platform_id: :return: The updated platform definition """ platform_name = shlex.quote(platform_data['name']) platform_url = shlex.quote(platform_data['url']) session = db_session() workspace = session.query(Workspace).filter(Workspace.id == workspace_id).first() if workspace is None: raise NotFound("workspace with id {} could not be found".format(workspace_id)) platform = session.query(Platform). \ filter(Platform.workspace == workspace). \ filter(Platform.id == platform_id). \ first() if platform is None: raise NotFound("Platform with id {} could not be found".format(platform_id)) if platform_name != platform.name: existing_platforms = session.query(Platform). \ filter(Platform.workspace == workspace). \ filter(Platform.name == platform_data['name']). \ all() if len(existing_platforms) > 0: raise NameConflict("Platform with name {} already exists".format(platform_data['name'])) platform.name = platform_name platform.url = platform_url update_workspace_descriptor(platform.workspace) session.commit() return platform.as_dict()
def update_catalogue(workspace_id, catalogue_id, catalogue_data): """ Updates a specific catalogue by its id. The catalogue applies the given name and url, that are in the json parameter. :param workspace_id: The Workspace ID :param catalogue_id: The Catalogue ID :return: The updated Catalogue descriptor """ catalogue_name = shlex.quote(catalogue_data['name']) catalogue_url = shlex.quote(catalogue_data['url']) session = db_session() workspace = session.query(Workspace).filter(Workspace.id == workspace_id).first() if workspace is None: raise NotFound("workspace with id {} could not be found".format(workspace_id)) catalogue = session.query(Catalogue). \ filter(Catalogue.workspace == workspace). \ filter(Catalogue.id == catalogue_id). \ first() if catalogue is None: raise NotFound("catalogue with id {} could not be found".format(catalogue_id)) if catalogue_name != catalogue.name: existing_catalogues = session.query(catalogue). \ filter(catalogue.workspace == workspace). \ filter(catalogue.name == catalogue_data['name']). \ all() if len(existing_catalogues) > 0: raise NameConflict("catalogue with name {} already exists".format(catalogue_data['name'])) catalogue.name = catalogue_name catalogue.url = catalogue_url session.commit() update_workspace_descriptor(catalogue.workspace) return catalogue.as_dict()
def delete(workspace_id: int, platform_id: int) -> dict: """ Deletes the platform from the workspace :param workspace_id: :param platform_id: :return: the deleted platform description """ session = db_session() workspace = session.query(Workspace).filter( Workspace.id == workspace_id).first() if workspace is None: raise NotFound( "workspace with id {} could not be found".format(workspace_id)) platform = session.query(Platform). \ filter(Platform.workspace == workspace). \ filter(Platform.id == platform_id). \ first() if platform is None: raise NotFound( "Platform with id {} could not be found".format(platform_id)) session.delete(platform) update_workspace_descriptor(platform.workspace) session.commit() return platform.as_dict()
def create_catalogue(workspace_id: int, catalogue_data): """ Creates a catalgoue in the given workspace. A catalogue is defined by its name and url. These are given as json data :param workspace_id: Workspace ID of the target workspace, where the catalogue should get created. :return: Catalogue descriptor """ catalogue_name = shlex.quote(catalogue_data['name']) catalogue_url = shlex.quote(catalogue_data['url']) session = db_session() workspace = session.query(Workspace).filter(Workspace.id == workspace_id).first() if workspace is None: raise NotFound("workspace with id {} could not be found".format(workspace_id)) existing_catalogues = session.query(Catalogue). \ filter(Catalogue.workspace == workspace). \ filter(Catalogue.name == catalogue_data['name']). \ all() if len(existing_catalogues) > 0: raise NameConflict("catalogue with name {} already exists".format(catalogue_data['name'])) catalogue = Catalogue(name=catalogue_name, url=catalogue_url, workspace=workspace) session.add(catalogue) session.commit() update_workspace_descriptor(catalogue.workspace) return catalogue.as_dict()
def create_platform(workspace_id: int, platform_data) -> dict: """ Create a new platform entry :param workspace_id: :param platform_data: :return: """ platform_name = shlex.quote(platform_data['name']) platform_url = shlex.quote(platform_data['url']) session = db_session() workspace = session.query(Workspace).filter( Workspace.id == workspace_id).first() if workspace is None: raise NotFound( "workspace with id {} could not be found".format(workspace_id)) existing_platforms = session.query(Platform). \ filter(Platform.workspace == workspace). \ filter(Platform.name == platform_data['name']). \ all() if len(existing_platforms) > 0: raise NameConflict("Platform with name {} already exists".format( platform_data['name'])) platform = Platform(name=platform_name, url=platform_url, workspace=workspace) session.add(platform) update_workspace_descriptor(platform.workspace) session.commit() return platform.as_dict()
def create_platform(workspace_id: int, platform_data) -> dict: """ Create a new platform entry :param workspace_id: The workspace ID :param platform_data: The platform info :return: The newly created platform descriptor """ platform_name = shlex.quote(platform_data['name']) platform_url = shlex.quote(platform_data['url']) session = db_session() workspace = session.query(Workspace).filter(Workspace.id == workspace_id).first() if workspace is None: raise NotFound("workspace with id {} could not be found".format(workspace_id)) existing_platforms = session.query(Platform). \ filter(Platform.workspace == workspace). \ filter(Platform.name == platform_data['name']). \ all() if len(existing_platforms) > 0: raise NameConflict("Platform with name {} already exists".format(platform_data['name'])) platform = Platform(name=platform_name, url=platform_url, workspace=workspace) session.add(platform) update_workspace_descriptor(platform.workspace) session.commit() return platform.as_dict()
def create_workspace(login: str, workspace_data: dict) -> dict: """ Creates a workspace (on disk and in the database) from the given workspace data :param workspace_data: The workspace configuration data :return: The created workspace """ wsName = shlex.quote(workspace_data["name"]) session = db_session() # test if ws Name exists in database user = get_user(login) existingWorkspaces = list(session.query(Workspace) .filter(Workspace.owner == user) .filter(Workspace.name == wsName)) if len(existingWorkspaces) > 0: raise NameConflict("Workspace with name " + wsName + " already exists") wsPath = path.join(WORKSPACES_DIR, user.name, wsName) # prepare db insert try: ws = Workspace(name=wsName, path=wsPath, owner=user) session.add(ws) if 'platforms' in workspace_data: for platform in workspace_data['platforms']: ptf = Platform(platform['name'], platform['url'], True, ws) if 'token' in platform: ptf.token_path = create_token_file(platform['token']) session.add(ptf) test_url(platform['name'], platform['url'] + "/api/v2/packages") if 'catalogues' in workspace_data: for catalogue in workspace_data['catalogues']: session.add(Catalogue(catalogue['name'], catalogue['url'], True, ws)) test_url(catalogue['name'], catalogue['url']) except Exception as e: logger.exception(e) session.rollback() raise # create workspace on disk proc = Popen(['son-workspace', '--init', '--workspace', wsPath], stdout=PIPE, stderr=PIPE) out, err = proc.communicate() exitcode = proc.returncode if out.decode().find('existing') >= 0: workspace_exists = True else: workspace_exists = False if exitcode == 0 and not workspace_exists: update_workspace_descriptor(ws) session.commit() return ws.as_dict() else: session.rollback() if workspace_exists: raise NameConflict(out.decode()) raise Exception(err, out)
def test_push_project(self): package_path = self.test_package_location session = db_session() ws = session.query(Workspace).filter(Workspace.id == self.wsid).first() result = publishutil.push_to_platform(package_path=package_path, ws=ws) self.assertTrue('service_uuid' in result) caught = False try: ws.platforms[0].url = get_config()['test']['platform-instance-wrong'] update_workspace_descriptor(ws) result = publishutil.push_to_platform(package_path=package_path, ws=ws) # wrong port except ExtNotReachable: caught = True self.assertTrue(caught) session.rollback()
def test_push_project(self): package_path = self.test_package_location session = db_session() ws = session.query(Workspace).filter(Workspace.id == self.wsid).first() result = publishutil.push_to_platform(package_path=package_path, ws=ws) self.assertTrue('service_uuid' in result) caught = False try: ws.platforms[0].url = get_config( )['test']['platform-instance-wrong'] update_workspace_descriptor(ws) result = publishutil.push_to_platform(package_path=package_path, ws=ws) # wrong port except ExtNotReachable: caught = True self.assertTrue(caught) session.rollback()
def delete(workspace_id, catalogue_id): """ Deletes a catalogue by its id :param workspace_id: :param catalogue_id: :return: """ session = db_session() workspace = session.query(Workspace).filter(Workspace.id == workspace_id).first() if workspace is None: raise NotFound("workspace with id {} could not be found".format(workspace_id)) catalogue = session.query(Catalogue). \ filter(Catalogue.workspace == workspace). \ filter(Catalogue.id == catalogue_id). \ first() if catalogue is None: raise NotFound("catalogue with id {} could not be found".format(catalogue_id)) session.delete(catalogue) session.commit() update_workspace_descriptor(catalogue.workspace) return catalogue.as_dict()
def delete(workspace_id: int, platform_id: int) -> dict: """ Deletes the platform from the workspace :param workspace_id: :param platform_id: :return: the deleted platform description """ session = db_session() workspace = session.query(Workspace).filter(Workspace.id == workspace_id).first() if workspace is None: raise NotFound("workspace with id {} could not be found".format(workspace_id)) platform = session.query(Platform). \ filter(Platform.workspace == workspace). \ filter(Platform.id == platform_id). \ first() if platform is None: raise NotFound("Platform with id {} could not be found".format(platform_id)) session.delete(platform) update_workspace_descriptor(platform.workspace) session.commit() return platform.as_dict()
def update_workspace(workspace_data, wsid): """ Updates the workspace with the given workspace data :param workspace_data: The new workspace configuration :param wsid: the workspace ID :return: The updated workspace """ session = db_session() workspace = session.query(Workspace).filter(Workspace.id == int(wsid)).first() # type: Workspace if workspace is None: raise NotFound("Workspace with id {} could not be found".format(wsid)) # Update name if 'name' in workspace_data: if path.exists(workspace.path): new_name = workspace_data['name'] old_path = workspace.path # only update if name has changed if new_name != workspace.name: new_path = rreplace(workspace.path, workspace.name, new_name, 1) if path.exists(new_path): raise NameConflict("Invalid name parameter, workspace '{}' already exists".format(new_name)) # Do not allow move directories outside of the workspaces_dir if not new_path.startswith(WORKSPACES_DIR): raise Exception( "Invalid path parameter, you are not allowed to break out of {}".format(WORKSPACES_DIR)) else: # Move the directory shutil.move(old_path, new_path) workspace.name = new_name workspace.path = new_path for platform in workspace.platforms: deleted = True if 'platforms' in workspace_data: for updated_platform in workspace_data['platforms']: if 'id' in updated_platform and platform.id == updated_platform['id']: deleted = False break if deleted: session.delete(platform) if 'platforms' in workspace_data: for updated_platform in workspace_data['platforms']: platform = None if 'id' in updated_platform: platform = session.query(Platform). \ filter(Platform.id == updated_platform['id']). \ filter(Platform.workspace == workspace). \ first() if platform: # update existing test_url(updated_platform['name'], updated_platform['url'] + "/api/v2/packages") platform.name = updated_platform['name'] platform.url = updated_platform['url'] if 'token' in updated_platform: platform.token_path = create_token_file(updated_platform['token']) else: # create new test_url(updated_platform['name'], updated_platform['url'] + "/api/v2/packages") # TODO test this! new_platform = Platform(updated_platform['name'], updated_platform['url'], True, workspace) session.add(new_platform) for catalogue in workspace.catalogues: deleted = True if 'catalogues' in workspace_data: for updated_catalogue in workspace_data['catalogues']: if 'id' in updated_catalogue and catalogue.id == updated_catalogue['id']: deleted = False break if deleted: # check if catalogue is still referenced for project in workspace.projects: if catalogue.name in project.publish_to: raise InvalidArgument( "Cannot delete catalogue '{}' because it is still used in project '{}'!".format(catalogue.name, project.name)) session.delete(catalogue) if 'catalogues' in workspace_data: for updated_catalogue in workspace_data['catalogues']: catalogue = None if 'id' in updated_catalogue: catalogue = session.query(Catalogue). \ filter(Catalogue.id == updated_catalogue['id']). \ filter(Catalogue.workspace == workspace). \ first() if catalogue: # update existing test_url(updated_catalogue['name'], updated_catalogue['url']) catalogue.name = updated_catalogue['name'] catalogue.url = updated_catalogue['url'] else: # create new test_url(updated_catalogue['name'], updated_catalogue['url']) new_catalogue = Catalogue(updated_catalogue['name'], updated_catalogue['url'], True, workspace) session.add(new_catalogue) update_workspace_descriptor(workspace) db_session.commit() return workspace.as_dict()
def create_workspace(login: str, workspace_data: dict) -> dict: """ Creates a workspace (on disk and in the database) from the given workspace data :param workspace_data: The workspace configuration data :return: The created workspace """ wsName = shlex.quote(workspace_data["name"]) session = db_session() # test if ws Name exists in database user = get_user(login) existingWorkspaces = list( session.query(Workspace).filter(Workspace.owner == user).filter( Workspace.name == wsName)) if len(existingWorkspaces) > 0: raise NameConflict("Workspace with name " + wsName + " already exists") wsPath = path.join(WORKSPACES_DIR, user.name, wsName) # prepare db insert try: ws = Workspace(name=wsName, path=wsPath, owner=user) session.add(ws) if 'platforms' in workspace_data: for platform in workspace_data['platforms']: ptf = Platform(platform['name'], platform['url'], True, ws) if 'token' in platform: ptf.token_path = create_token_file(platform['token']) session.add(ptf) test_url(platform['name'], platform['url'] + "/api/v2/packages") if 'catalogues' in workspace_data: for catalogue in workspace_data['catalogues']: session.add( Catalogue(catalogue['name'], catalogue['url'], True, ws)) test_url(catalogue['name'], catalogue['url']) except Exception as e: logger.exception(e) session.rollback() raise # create workspace on disk proc = Popen(['son-workspace', '--init', '--workspace', wsPath], stdout=PIPE, stderr=PIPE) out, err = proc.communicate() exitcode = proc.returncode if out.decode().find('existing') >= 0: workspace_exists = True else: workspace_exists = False if exitcode == 0 and not workspace_exists: update_workspace_descriptor(ws) session.commit() return ws.as_dict() else: session.rollback() if workspace_exists: raise NameConflict(out.decode()) raise Exception(err, out)
def update_workspace(workspace_data, wsid): """ Updates the workspace with the given workspace data :param workspace_data: The new workspace configuration :param wsid: the workspace ID :return: The updated workspace """ session = db_session() workspace = session.query(Workspace).filter( Workspace.id == int(wsid)).first() # type: Workspace if workspace is None: raise NotFound("Workspace with id {} could not be found".format(wsid)) # Update name if 'name' in workspace_data: if path.exists(workspace.path): new_name = workspace_data['name'] old_path = workspace.path # only update if name has changed if new_name != workspace.name: new_path = rreplace(workspace.path, workspace.name, new_name, 1) if path.exists(new_path): raise NameConflict( "Invalid name parameter, workspace '{}' already exists" .format(new_name)) # Do not allow move directories outside of the workspaces_dir if not new_path.startswith(WORKSPACES_DIR): raise Exception( "Invalid path parameter, you are not allowed to break out of {}" .format(WORKSPACES_DIR)) else: # Move the directory shutil.move(old_path, new_path) workspace.name = new_name workspace.path = new_path for platform in workspace.platforms: deleted = True if 'platforms' in workspace_data: for updated_platform in workspace_data['platforms']: if 'id' in updated_platform and platform.id == updated_platform[ 'id']: deleted = False break if deleted: session.delete(platform) if 'platforms' in workspace_data: for updated_platform in workspace_data['platforms']: platform = None if 'id' in updated_platform: platform = session.query(Platform). \ filter(Platform.id == updated_platform['id']). \ filter(Platform.workspace == workspace). \ first() if platform: # update existing test_url(updated_platform['name'], updated_platform['url'] + "/api/v2/packages") platform.name = updated_platform['name'] platform.url = updated_platform['url'] if 'token' in updated_platform: platform.token_path = create_token_file( updated_platform['token']) else: # create new test_url(updated_platform['name'], updated_platform['url'] + "/api/v2/packages") # TODO test this! new_platform = Platform(updated_platform['name'], updated_platform['url'], True, workspace) session.add(new_platform) for catalogue in workspace.catalogues: deleted = True if 'catalogues' in workspace_data: for updated_catalogue in workspace_data['catalogues']: if 'id' in updated_catalogue and catalogue.id == updated_catalogue[ 'id']: deleted = False break if deleted: # check if catalogue is still referenced for project in workspace.projects: if catalogue.name in project.publish_to: raise InvalidArgument( "Cannot delete catalogue '{}' because it is still used in project '{}'!" .format(catalogue.name, project.name)) session.delete(catalogue) if 'catalogues' in workspace_data: for updated_catalogue in workspace_data['catalogues']: catalogue = None if 'id' in updated_catalogue: catalogue = session.query(Catalogue). \ filter(Catalogue.id == updated_catalogue['id']). \ filter(Catalogue.workspace == workspace). \ first() if catalogue: # update existing test_url(updated_catalogue['name'], updated_catalogue['url']) catalogue.name = updated_catalogue['name'] catalogue.url = updated_catalogue['url'] else: # create new test_url(updated_catalogue['name'], updated_catalogue['url']) new_catalogue = Catalogue(updated_catalogue['name'], updated_catalogue['url'], True, workspace) session.add(new_catalogue) update_workspace_descriptor(workspace) db_session.commit() return workspace.as_dict()