async def create_cluster( pg_engine: Engine, faker: Faker ) -> AsyncIterable[Callable[..., Awaitable[int]]]: cluster_ids = [] async def creator(**overrides) -> int: insert_values = { "name": "default cluster name", "type": ClusterType.ON_PREMISE, "description": None, "endpoint": faker.domain_name(), "authentication": faker.pydict(value_types=str), } insert_values.update(overrides) async with pg_engine.acquire() as conn: cluster_id = await conn.scalar( clusters.insert().values(**insert_values).returning(clusters.c.id) ) cluster_ids.append(cluster_id) assert cluster_id return cluster_id yield creator # cleanup async with pg_engine.acquire() as conn: await conn.execute(clusters.delete().where(clusters.c.id.in_(cluster_ids)))
def cluster( postgres_db: sa.engine.Engine, ) -> Iterator[Callable[..., Cluster]]: created_cluster_ids: List[str] = [] def creator(user: Dict[str, Any], **cluster_kwargs) -> Cluster: cluster_config = Cluster.Config.schema_extra["examples"][0] cluster_config["owner"] = user["primary_gid"] cluster_config.update(**cluster_kwargs) new_cluster = Cluster.parse_obj(cluster_config) assert new_cluster with postgres_db.connect() as conn: # insert basic cluster created_cluster = conn.execute( sa.insert(clusters).values( new_cluster.to_clusters_db(only_update=False)).returning( sa.literal_column("*"))).one() created_cluster_ids.append(created_cluster.id) if "access_rights" in cluster_kwargs: for gid, rights in cluster_kwargs["access_rights"].items(): conn.execute( pg_insert(cluster_to_groups).values( cluster_id=created_cluster.id, gid=gid, **rights.dict()).on_conflict_do_update( index_elements=["gid", "cluster_id"], set_=rights.dict())) access_rights_in_db = {} for row in conn.execute( sa.select([ cluster_to_groups.c.gid, cluster_to_groups.c.read, cluster_to_groups.c.write, cluster_to_groups.c.delete, ]).select_from(clusters.join(cluster_to_groups)).where( clusters.c.id == created_cluster.id)): access_rights_in_db[row.gid] = { "read": row[cluster_to_groups.c.read], "write": row[cluster_to_groups.c.write], "delete": row[cluster_to_groups.c.delete], } return Cluster.construct( id=created_cluster.id, name=created_cluster.name, description=created_cluster.description, type=created_cluster.type, owner=created_cluster.owner, endpoint=created_cluster.endpoint, authentication=created_cluster.authentication, access_rights=access_rights_in_db, ) yield creator # cleanup with postgres_db.connect() as conn: conn.execute( # pylint: disable=no-value-for-parameter clusters.delete().where(clusters.c.id.in_(created_cluster_ids)))
def cluster( user_db: Dict, postgres_db: sa.engine.Engine, ) -> Iterable[Callable[..., Cluster]]: created_cluster_ids: List[str] = [] def creator(**overrides) -> Cluster: cluster_config = Cluster.Config.schema_extra["examples"][0] cluster_config["owner"] = user_db["primary_gid"] cluster_config.update(**overrides) new_cluster = Cluster.parse_obj(cluster_config) assert new_cluster with postgres_db.connect() as conn: created_cluser_id = conn.scalar( # pylint: disable=no-value-for-parameter clusters.insert().values( new_cluster.to_clusters_db(only_update=False) ).returning(clusters.c.id)) created_cluster_ids.append(created_cluser_id) result = conn.execute( sa.select([ clusters, cluster_to_groups.c.gid, cluster_to_groups.c.read, cluster_to_groups.c.write, cluster_to_groups.c.delete, ]).select_from( clusters.join( cluster_to_groups, clusters.c.id == cluster_to_groups.c.cluster_id, )).where(clusters.c.id == created_cluser_id)) row = result.fetchone() assert row return Cluster.construct( id=row[clusters.c.id], name=row[clusters.c.name], description=row[clusters.c.description], type=row[clusters.c.type], owner=row[clusters.c.owner], endpoint=row[clusters.c.endpoint], authentication=row[clusters.c.authentication], access_rights={ row[clusters.c.owner]: { "read": row[cluster_to_groups.c.read], "write": row[cluster_to_groups.c.write], "delete": row[cluster_to_groups.c.delete], } }, ) yield creator # cleanup with postgres_db.connect() as conn: conn.execute( # pylint: disable=no-value-for-parameter clusters.delete().where(clusters.c.id.in_(created_cluster_ids)))
async def test_create_cluster( enable_dev_features: None, client: TestClient, postgres_db: sa.engine.Engine, logged_user: Dict[str, Any], faker: Faker, user_role: UserRole, cluster_authentication: Callable[[], Dict[str, Any]], expected: ExpectedResponse, ): # check we can create a cluster assert client.app url = client.app.router["create_cluster_handler"].url_for() cluster_data = json.loads( ClusterCreate( endpoint=faker.uri(), authentication=cluster_authentication(), name=faker.name(), type=random.choice(list(ClusterType)), ).json(by_alias=True, exclude_unset=True) ) rsp = await client.post(f"{url}", json=cluster_data) data, error = await assert_status( rsp, expected.forbidden if user_role == UserRole.USER else expected.created, # only accessible for TESTER ) if error: # we are done here return created_cluster = Cluster.parse_obj(data) assert created_cluster # check database entry was correctly created result: ResultProxy = postgres_db.execute( sa.select([clusters]).where(clusters.c.name == cluster_data["name"]) ) assert result, "could not find cluster in database" row = result.fetchone() assert row, "could not find cluster in database" assert row[clusters.c.name] == cluster_data["name"] assert row[clusters.c.owner] == logged_user["primary_gid"] assert ( Cluster( id=row[clusters.c.id], name=cluster_data["name"], type=row[clusters.c.type], endpoint=row[clusters.c.endpoint], authentication=row[clusters.c.authentication], owner=logged_user["primary_gid"], access_rights={logged_user["primary_gid"]: CLUSTER_ADMIN_RIGHTS}, ) == created_cluster ) # cleanup postgres_db.execute(clusters.delete().where(clusters.c.id == row[clusters.c.id]))
def cluster( postgres_db: sa.engine.Engine, faker: Faker ) -> Iterable[Callable[[GroupID, Dict[GroupID, ClusterAccessRights]], Coroutine[Any, Any, Cluster]]]: list_of_created_cluster_ids = [] async def creator( gid: GroupID, cluster_access_rights: Dict[GroupID, ClusterAccessRights] = None ) -> Cluster: new_cluster = ClusterCreate( **{ "name": faker.name(), "type": random.choice(list(ClusterType)), "owner": gid, "access_rights": cluster_access_rights or {}, }) result = postgres_db.execute(clusters.insert().values( new_cluster.dict(by_alias=True, exclude={"id", "access_rights" })).returning(literal_column("*"))) cluster_in_db = result.first() assert cluster_in_db is not None new_cluster_id = cluster_in_db[clusters.c.id] list_of_created_cluster_ids.append(new_cluster_id) # when a cluster is created, the DB automatically creates the owner access rights for group_id, access_rights in new_cluster.access_rights.items(): result = postgres_db.execute( insert(cluster_to_groups).values( **{ "cluster_id": new_cluster_id, "gid": group_id, "read": access_rights.read, "write": access_rights.write, "delete": access_rights.delete, }).on_conflict_do_nothing()) return Cluster(id=new_cluster_id, **new_cluster.dict(by_alias=True, exclude={"id"})) yield creator # clean up postgres_db.execute(clusters.delete().where( clusters.c.id.in_(list_of_created_cluster_ids)))
async def test_cannot_remove_owner_that_owns_cluster( pg_engine: Engine, user_id: int, user_group_id: int, create_cluster: Callable[..., Awaitable[int]], ): cluster_id = await create_cluster(owner=user_group_id) # now try removing the user async with pg_engine.acquire() as conn: with pytest.raises(ForeignKeyViolation): await conn.execute(users.delete().where(users.c.id == user_id)) # now remove the cluster async with pg_engine.acquire() as conn: await conn.execute(clusters.delete().where(clusters.c.id == cluster_id)) # removing the user should work now async with pg_engine.acquire() as conn: await conn.execute(users.delete().where(users.c.id == user_id))
async def create_cluster(pg_engine: Engine) -> Callable[..., Awaitable[int]]: cluster_ids = [] async def creator(**overrides) -> Awaitable[int]: insert_values = { "name": "default cluster name", "type": ClusterType.ON_PREMISE, "description": None, } insert_values.update(overrides) async with pg_engine.acquire() as conn: cluster_id = await conn.scalar(clusters.insert().values( **insert_values).returning(clusters.c.id)) cluster_ids.append(cluster_id) return cluster_id yield creator # cleanup async with pg_engine.acquire() as conn: await conn.execute(clusters.delete().where( clusters.c.id.in_(cluster_ids)))