Tidy up pageserver's endpoints

This commit is contained in:
Kirill Bulatov
2022-03-10 19:38:58 +02:00
committed by Kirill Bulatov
parent 7b5482bac0
commit a5e10c4f64
12 changed files with 246 additions and 172 deletions
+5 -8
View File
@@ -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])
+8 -10
View File
@@ -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
+39 -24
View File
@@ -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,