Example #1
0
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"
Example #2
0
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
Example #3
0
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
Example #5
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