mirror of
https://github.com/neondatabase/neon.git
synced 2026-10-27 14:06:45 +00:00
Tidy up pageserver's endpoints
This commit is contained in:
committed by
Kirill Bulatov
parent
7b5482bac0
commit
a5e10c4f64
@@ -29,30 +29,27 @@ def test_pageserver_auth(zenith_env_builder: ZenithEnvBuilder):
|
||||
tenant_id=env.initial_tenant)
|
||||
|
||||
# tenant can create branches
|
||||
tenant_http_client.timeline_create(timeline_id=uuid4(),
|
||||
tenant_id=env.initial_tenant,
|
||||
tenant_http_client.timeline_create(tenant_id=env.initial_tenant,
|
||||
ancestor_timeline_id=new_timeline_id)
|
||||
# console can create branches for tenant
|
||||
management_http_client.timeline_create(timeline_id=uuid4(),
|
||||
tenant_id=env.initial_tenant,
|
||||
management_http_client.timeline_create(tenant_id=env.initial_tenant,
|
||||
ancestor_timeline_id=new_timeline_id)
|
||||
|
||||
# fail to create branch using token with different tenant_id
|
||||
with pytest.raises(ZenithPageserverApiException,
|
||||
match='Forbidden: Tenant id mismatch. Permission denied'):
|
||||
invalid_tenant_http_client.timeline_create(timeline_id=uuid4(),
|
||||
tenant_id=env.initial_tenant,
|
||||
invalid_tenant_http_client.timeline_create(tenant_id=env.initial_tenant,
|
||||
ancestor_timeline_id=new_timeline_id)
|
||||
|
||||
# create tenant using management token
|
||||
management_http_client.tenant_create(uuid4())
|
||||
management_http_client.tenant_create()
|
||||
|
||||
# fail to create tenant using tenant token
|
||||
with pytest.raises(
|
||||
ZenithPageserverApiException,
|
||||
match='Forbidden: Attempt to access management api with tenant scope. Permission denied'
|
||||
):
|
||||
tenant_http_client.tenant_create(uuid4())
|
||||
tenant_http_client.tenant_create()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('with_wal_acceptors', [False, True])
|
||||
|
||||
@@ -15,17 +15,15 @@ def helper_compare_timeline_list(pageserver_http_client: ZenithPageserverHttpCli
|
||||
Filters out timelines created by other tests.
|
||||
"""
|
||||
|
||||
timelines_api = sorted(
|
||||
map(lambda t: cast(str, t['timeline_id']),
|
||||
pageserver_http_client.timeline_list(initial_tenant)))
|
||||
|
||||
timelines_cli = env.zenith_cli.list_timelines()
|
||||
timelines_cli = [
|
||||
b for b in timelines_cli if b.startswith('test_cli_') or b in ('empty', 'main')
|
||||
]
|
||||
assert timelines_cli == env.zenith_cli.list_timelines(initial_tenant)
|
||||
|
||||
timelines_cli_with_tenant_arg = env.zenith_cli.list_timelines(initial_tenant)
|
||||
timelines_cli_with_tenant_arg = [
|
||||
b for b in timelines_cli if b.startswith('test_cli_') or b in ('empty', 'main')
|
||||
]
|
||||
|
||||
assert timelines_cli == timelines_cli_with_tenant_arg
|
||||
cli_timeline_ids = sorted([timeline_id for (_, timeline_id) in timelines_cli])
|
||||
assert timelines_api == cli_timeline_ids
|
||||
|
||||
|
||||
def test_cli_timeline_list(zenith_simple_env: ZenithEnv):
|
||||
@@ -45,7 +43,7 @@ def test_cli_timeline_list(zenith_simple_env: ZenithEnv):
|
||||
helper_compare_timeline_list(pageserver_http_client, env, env.initial_tenant)
|
||||
|
||||
# Check that all new branches are visible via CLI
|
||||
timelines_cli = env.zenith_cli.list_timelines()
|
||||
timelines_cli = [timeline_id for (_, timeline_id) in env.zenith_cli.list_timelines()]
|
||||
|
||||
assert main_timeline_id.hex in timelines_cli
|
||||
assert nested_timeline_id.hex in timelines_cli
|
||||
|
||||
@@ -712,27 +712,29 @@ class ZenithPageserverHttpClient(requests.Session):
|
||||
|
||||
def timeline_attach(self, tenant_id: uuid.UUID, timeline_id: uuid.UUID):
|
||||
res = self.post(
|
||||
f"http://localhost:{self.port}/v1/timeline/{tenant_id.hex}/{timeline_id.hex}/attach", )
|
||||
f"http://localhost:{self.port}/v1/tenant/{tenant_id.hex}/timeline/{timeline_id.hex}/attach",
|
||||
)
|
||||
self.verbose_error(res)
|
||||
|
||||
def timeline_detach(self, tenant_id: uuid.UUID, timeline_id: uuid.UUID):
|
||||
res = self.post(
|
||||
f"http://localhost:{self.port}/v1/timeline/{tenant_id.hex}/{timeline_id.hex}/detach", )
|
||||
f"http://localhost:{self.port}/v1/tenant/{tenant_id.hex}/timeline/{timeline_id.hex}/detach",
|
||||
)
|
||||
self.verbose_error(res)
|
||||
|
||||
def timeline_create(self,
|
||||
tenant_id: uuid.UUID,
|
||||
timeline_id: uuid.UUID,
|
||||
start_lsn: Optional[str] = None,
|
||||
ancestor_timeline_id: Optional[uuid.UUID] = None) -> Dict[Any, Any]:
|
||||
res = self.post(f"http://localhost:{self.port}/v1/timeline",
|
||||
def timeline_create(
|
||||
self,
|
||||
tenant_id: uuid.UUID,
|
||||
timeline_id: Optional[uuid.UUID] = None,
|
||||
ancestor_timeline_id: Optional[uuid.UUID] = None,
|
||||
ancestor_start_lsn: Optional[str] = None,
|
||||
) -> Dict[Any, Any]:
|
||||
res = self.post(f"http://localhost:{self.port}/v1/tenant/{tenant_id.hex}/timeline",
|
||||
json={
|
||||
'tenant_id':
|
||||
tenant_id.hex,
|
||||
'timeline_id':
|
||||
timeline_id.hex,
|
||||
'start_lsn':
|
||||
start_lsn,
|
||||
'new_timeline_id':
|
||||
timeline_id.hex if timeline_id else None,
|
||||
'ancestor_start_lsn':
|
||||
ancestor_start_lsn,
|
||||
'ancestor_timeline_id':
|
||||
ancestor_timeline_id.hex if ancestor_timeline_id else None,
|
||||
})
|
||||
@@ -748,18 +750,23 @@ class ZenithPageserverHttpClient(requests.Session):
|
||||
assert isinstance(res_json, list)
|
||||
return res_json
|
||||
|
||||
def tenant_create(self, tenant_id: uuid.UUID):
|
||||
def tenant_create(self,
|
||||
tenant_id: Optional[uuid.UUID] = None,
|
||||
new_timeline_id: Optional[uuid.UUID] = None) -> Dict[Any, Any]:
|
||||
res = self.post(
|
||||
f"http://localhost:{self.port}/v1/tenant",
|
||||
json={
|
||||
'tenant_id': tenant_id.hex,
|
||||
'new_tenant_id': tenant_id.hex if tenant_id else None,
|
||||
'initial_timeline_id': new_timeline_id.hex if new_timeline_id else None,
|
||||
},
|
||||
)
|
||||
self.verbose_error(res)
|
||||
return res.json()
|
||||
res_json = res.json()
|
||||
assert isinstance(res_json, dict)
|
||||
return res_json
|
||||
|
||||
def timeline_list(self, tenant_id: uuid.UUID) -> List[Dict[Any, Any]]:
|
||||
res = self.get(f"http://localhost:{self.port}/v1/timeline/{tenant_id.hex}")
|
||||
res = self.get(f"http://localhost:{self.port}/v1/tenant/{tenant_id.hex}/timeline")
|
||||
self.verbose_error(res)
|
||||
res_json = res.json()
|
||||
assert isinstance(res_json, list)
|
||||
@@ -767,7 +774,7 @@ class ZenithPageserverHttpClient(requests.Session):
|
||||
|
||||
def timeline_detail(self, tenant_id: uuid.UUID, timeline_id: uuid.UUID) -> Dict[Any, Any]:
|
||||
res = self.get(
|
||||
f"http://localhost:{self.port}/v1/timeline/{tenant_id.hex}/{timeline_id.hex}?include-non-incremental-logical-size=1"
|
||||
f"http://localhost:{self.port}/v1/tenant/{tenant_id.hex}/timeline/{timeline_id.hex}?include-non-incremental-logical-size=1"
|
||||
)
|
||||
self.verbose_error(res)
|
||||
res_json = res.json()
|
||||
@@ -861,13 +868,21 @@ class ZenithCli:
|
||||
else:
|
||||
return uuid.UUID(created_timeline_id)
|
||||
|
||||
def list_timelines(self, tenant_id: Optional[uuid.UUID] = None) -> List[str]:
|
||||
def list_timelines(self, tenant_id: Optional[uuid.UUID] = None) -> List[Tuple[str, str]]:
|
||||
"""
|
||||
Returns a list of (branch_name, timeline_id) tuples out of parsed `zenith timeline list` CLI output.
|
||||
"""
|
||||
|
||||
# (L) main [b49f7954224a0ad25cc0013ea107b54b]
|
||||
# (L) ┣━ @0/16B5A50: test_cli_branch_list_main [20f98c79111b9015d84452258b7d5540]
|
||||
timeline_data_extractor = re.compile(
|
||||
r"\s(?P<branch_name>[^\s]+)\s\[(?P<timeline_id>[^\]]+)\]", re.MULTILINE)
|
||||
res = self.raw_cli(
|
||||
['timeline', 'list', '--tenant-id', (tenant_id or self.env.initial_tenant).hex])
|
||||
branches_cli = sorted(
|
||||
map(lambda b: b.split(') ')[-1].strip().split(':')[-1].strip(),
|
||||
res.stdout.strip().split("\n")))
|
||||
return branches_cli
|
||||
timelines_cli = sorted(
|
||||
map(lambda branch_and_id: (branch_and_id[0], branch_and_id[1]),
|
||||
timeline_data_extractor.findall(res.stdout)))
|
||||
return timelines_cli
|
||||
|
||||
def init(self,
|
||||
config_toml: str,
|
||||
|
||||
Reference in New Issue
Block a user