Exemplo n.º 1
0
    print_warning,
)
from r2c.cli.util import (
    check_docker_is_running,
    get_default_org,
    get_default_token,
    get_version,
    save_config_creds,
)
from r2c.lib.constants import PLATFORM_ANALYZER_PREFIX, PLATFORM_BASE_URL
from r2c.lib.registry import RegistryData

BAD_AUTH_CODES = {401, 422}
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 10  # sec
logger = get_logger()


def handle_request_with_error_message(r: Response) -> dict:
    """Handles the requests.response object. If the response
    code is anything other than success, CliError will be thrown.
    """
    try:
        r.raise_for_status()
    except HTTPError:
        json_response = r.json()
        api_error_code = json_response["error_type"]
        api_error_msg = f"{json_response['message']}. {json_response['next_steps']}"

        raise get_cli_error_for_api_error(api_error_code, api_error_msg)
    return r.json()
Exemplo n.º 2
0
def push(ctx, analyzer_directory, force, squash, env_args_string):
    """
    Push the analyzer in the current directory to the R2C platform.

    You must log in to push analyzers.

    This command will validate your analyzer and privately publish your analyzer
    to your org with the name specified in analyzer.json.

    Your analyzer name must follow {org}/{name}.
    """
    env_args_dict = parse_remaining(env_args_string)

    manifest, analyzer_directory = find_and_open_analyzer_manifest(
        analyzer_directory, ctx
    )
    readme = find_and_open_analyzer_readme(analyzer_directory, ctx)
    analyzer_org = get_org_from_analyzer_name(manifest.analyzer_name)

    overwriting_message = (
        " and forcing overwrite if the analyzer version exists and is pending upload."
    )
    # TODO(ulzii): let's decide which source of truth we're using for analyzer_name above and/or check consistency.
    # can't have both dir name and what's in analyzer.json
    print_msg(
        f"📌 Pushing analyzer in {analyzer_directory}{overwriting_message if force else ''}..."
    )

    default_org = get_default_org()
    if default_org is None:
        print_error_exit(
            f"You are not logged in. Please run `r2c login` to be able to push your analyzer"
        )

    if default_org != analyzer_org:
        if analyzer_org != PLATFORM_ANALYZER_PREFIX:
            print_error_exit(
                f"You're logged in to the common r2c platform. The org specified as the prefix of your analyzer name in `analyzer.json` must be `{PLATFORM_ANALYZER_PREFIX}`. "
                + f"Replace `{analyzer_org}` with `{PLATFORM_ANALYZER_PREFIX}` and try again."
                + "Please ask for help from r2c support"
            )
    try:
        # upload analyzer.json
        artifact_link = _upload_analyzer_manifest(manifest, force, readme)
    except Exception as e:
        print_exception_exit("There was an error uploading your analyzer", e)
    if artifact_link is None:
        print_error_exit(
            "There was an error uploading your analyzer. Please ask for help from R2C support"
        )
    get_logger().info(f"using artifact link: {artifact_link}")
    # get docker login creds
    creds = get_docker_creds(artifact_link)
    if creds is None:
        print_error_exit(
            "There was an error getting Docker credentials. Please ask for help from R2C support"
        )
    else:
        print_success_step("Successfully fetched credentials.")

    # docker login
    successful_login = docker_login(creds)
    if not successful_login:
        print_error_exit(
            "There was an error logging into Docker. Please ask for help from R2C support"
        )
    else:
        print_success_step("Successfully logged in to docker.")

    print_msg("🔨 Building docker container")
    # docker build and tag
    abort_on_build_failure(
        build_docker(
            manifest.analyzer_name,
            manifest.version,
            os.path.relpath(analyzer_directory, os.getcwd()),
            env_args_dict=env_args_dict,
            squash=squash,
        )
    )
    # docker push
    image_id = VersionedAnalyzer(manifest.analyzer_name, manifest.version).image_id
    print_msg(f"Pushing docker container to `{analyzer_org}`")
    successful_push = _docker_push(image_id)
    if not successful_push:
        print_error_exit(
            "There was an error pushing the Docker image. Please ask for help from R2C support"
        )
    else:
        print_success_step("Successfully pushed to R2C.")
    # mark uploaded with API
    # TODO figure out how to determine org from analyzer.json
    try:
        uploaded_url = f"{get_base_url()}/api/v1/analyzers/{manifest.analyzer_name}/{manifest.version}/uploaded"
        r = auth_put(uploaded_url)
        data = handle_request_with_error_message(r)
        if data.get("status") == "uploaded":
            web_url = data["links"]["web_url"]
            # display status to user and give link to view in web UI
            print_success(
                f"Upload finished successfully for analyzer! Visit: {web_url}"
            )
        else:
            print_error_exit("Error confirming analyzer was successfully uploaded.")
    except Exception as e:
        print_exception_exit("Error confirming analyzer was successfully uploaded", e)