def test_url_join(): """ Some basic URL joining tests. """ url = URL("https://example.org:123/path/to/somewhere") assert url.join("/somewhere-else") == "https://example.org:123/somewhere-else" assert ( url.join("somewhere-else") == "https://example.org:123/path/to/somewhere-else" ) assert ( url.join("../somewhere-else") == "https://example.org:123/path/somewhere-else" ) assert url.join("../../somewhere-else") == "https://example.org:123/somewhere-else"
async def import_project_as_template( endpoint: URL, username: EmailStr, password: SecretStr, project_file: Path, project_name: str, share_with_gid: int, # TODO: not used!? ) -> int: try: async with AsyncClient(base_url=endpoint.join("v0")) as client: await login_user(client, username, password) project_uuid = await import_project(client, project_file) await rename_project(client, project_uuid, project_name) template_uuid = await publish_as_template(client, project_uuid) typer.secho( f"project published as template! uuid [{template_uuid}]", fg=typer.colors.BRIGHT_WHITE, ) except HTTPStatusError as exc: typer.secho(create_human_readable_message(exc), fg=typer.colors.RED, err=True) return os.EX_SOFTWARE except Exception as exc: # pylint: disable=broad-except typer.secho(f"Unexpected issue: {exc}", fg=typer.colors.RED, err=True) return os.EX_SOFTWARE return os.EX_OK
async def create_user_with_password(endpoint: URL, username: EmailStr, password: SecretStr) -> int: try: async with AsyncClient(base_url=endpoint.join("v0")) as client: typer.secho( f"registering user {username} with password {password}", fg=typer.colors.YELLOW, ) await register_user(client, username, password) typer.secho(f"user registered", fg=typer.colors.YELLOW) await logout_current_user(client) typer.secho(f"registration done", fg=typer.colors.YELLOW) except Exception as exc: # pylint: disable=broad-except typer.secho(f"Unexpected issue: {exc}", fg=typer.colors.RED, err=True) return 1 return 0
async def clean( endpoint: URL, username: EmailStr, password: SecretStr, project_id: Optional[str] ) -> int: try: async with AsyncClient( base_url=endpoint.join("v0"), timeout=DEFAULT_TIMEOUT ) as client: await login_user(client, username, password) all_projects = [] if project_id: project = await get_project_for_user(client, project_id) if not project: typer.secho( f"project {project_id} not found!", fg=typer.colors.RED, err=True, ) return 1 all_projects = [project] if not all_projects: all_projects = await get_all_projects_for_user(client) if not all_projects: typer.secho("no projects found!", fg=typer.colors.RED, err=True) return 1 total = len(all_projects) typer.secho(f"{total} projects will be deleted...", fg=typer.colors.YELLOW) with typer.progressbar( length=total, label="deleting projects" ) as progressbar: await asyncio.gather( *[ delete_project(client, prj["uuid"], progressbar) for prj in all_projects ] ) typer.secho(f"completed projects deletion", fg=typer.colors.YELLOW) except Exception as exc: # pylint: disable=broad-except typer.secho( f"Unexpected issue: {exc}, [{type(exc)}]", fg=typer.colors.RED, err=True ) return 1 return 0
def test_url_join_rfc3986(): """ URL joining tests, as-per reference examples in RFC 3986. https://tools.ietf.org/html/rfc3986#section-5.4 """ url = URL("http://example.com/b/c/d;p?q") with pytest.raises(InvalidURL): assert url.join("g:h") == "g:h" assert url.join("g") == "http://example.com/b/c/g" assert url.join("./g") == "http://example.com/b/c/g" assert url.join("g/") == "http://example.com/b/c/g/" assert url.join("/g") == "http://example.com/g" assert url.join("//g") == "http://g" assert url.join("?y") == "http://example.com/b/c/d;p?y" assert url.join("g?y") == "http://example.com/b/c/g?y" assert url.join("#s") == "http://example.com/b/c/d;p?q#s" assert url.join("g#s") == "http://example.com/b/c/g#s" assert url.join("g?y#s") == "http://example.com/b/c/g?y#s" assert url.join(";x") == "http://example.com/b/c/;x" assert url.join("g;x") == "http://example.com/b/c/g;x" assert url.join("g;x?y#s") == "http://example.com/b/c/g;x?y#s" assert url.join("") == "http://example.com/b/c/d;p?q" assert url.join(".") == "http://example.com/b/c/" assert url.join("./") == "http://example.com/b/c/" assert url.join("..") == "http://example.com/b/" assert url.join("../") == "http://example.com/b/" assert url.join("../g") == "http://example.com/b/g" assert url.join("../..") == "http://example.com/" assert url.join("../../") == "http://example.com/" assert url.join("../../g") == "http://example.com/g" assert url.join("../../../g") == "http://example.com/g" assert url.join("../../../../g") == "http://example.com/g" assert url.join("/./g") == "http://example.com/g" assert url.join("/../g") == "http://example.com/g" assert url.join("g.") == "http://example.com/b/c/g." assert url.join(".g") == "http://example.com/b/c/.g" assert url.join("g..") == "http://example.com/b/c/g.." assert url.join("..g") == "http://example.com/b/c/..g" assert url.join("./../g") == "http://example.com/b/g" assert url.join("./g/.") == "http://example.com/b/c/g/" assert url.join("g/./h") == "http://example.com/b/c/g/h" assert url.join("g/../h") == "http://example.com/b/c/h" assert url.join("g;x=1/./y") == "http://example.com/b/c/g;x=1/y" assert url.join("g;x=1/../y") == "http://example.com/b/c/y" assert url.join("g?y/./x") == "http://example.com/b/c/g?y/./x" assert url.join("g?y/../x") == "http://example.com/b/c/g?y/../x" assert url.join("g#s/./x") == "http://example.com/b/c/g#s/./x" assert url.join("g#s/../x") == "http://example.com/b/c/g#s/../x"
async def list_images_in_registry( endpoint: URL, username: str, password: str, from_date: Optional[datetime], to_date: datetime, ) -> Dict[str, List[Tuple[str, str, str, str]]]: if not from_date: from_date = datetime(year=2000, month=1, day=1) typer.secho( f"listing images from {from_date} to {to_date} from {endpoint}", fg=typer.colors.YELLOW, ) list_of_images_in_date_range = defaultdict(list) async with AsyncClient(base_url=endpoint.join("v2"), auth=(username, password), http2=True) as client: list_of_repositories = await get_repos(client) with typer.progressbar(list_of_repositories, label="Processing repositories") as progress: for repo in progress: r = await client.get(f"/{repo}/tags/list") r.raise_for_status() list_of_tags = [ tag for tag in r.json()["tags"] if tag != "latest" ] # we go in reverse order, so the first that does not go in the date range will stop the loop for tag in reversed(list_of_tags): r = await client.get(f"/{repo}/manifests/{tag}") r.raise_for_status() manifest = r.json() # manifest[history] contains all the blobs, taking the latest one corresponds to the image creation date history = manifest["history"] tag_creation_dates = deque() for blob in history: v1_comp = json.loads(blob["v1Compatibility"]) tag_creation_dates.append( datetime.strptime(v1_comp["created"][:N], "%Y-%m-%dT%H:%M:%S.%f")) tag_last_date = sorted(tag_creation_dates)[-1] # check this service is in the time range if tag_last_date < from_date or tag_last_date > to_date: break # get the image labels from the last blob (same as director does) v1_comp = json.loads(history[0]["v1Compatibility"]) container_config = v1_comp.get("container_config", v1_comp["config"]) simcore_labels = {} for label_key, label_value in container_config[ "Labels"].items(): if label_key.startswith("io.simcore"): simcore_labels.update(json.loads(label_value)) list_of_images_in_date_range[repo].append(( tag, simcore_labels["name"], simcore_labels["description"], simcore_labels["type"], )) typer.secho( f"Completed. Found {len(list_of_images_in_date_range)} created between {from_date} and {to_date}", fg=typer.colors.YELLOW, ) typer.secho(f"{pformat(list_of_images_in_date_range)}") return list_of_images_in_date_range