コード例 #1
0
ファイル: cli.py プロジェクト: mythmon/morgoth-cli
def init(ctx):
    """Initialize Morgoth."""
    url = click.prompt('Balrog URL',
                       settings.get('balrog_url', DEFAULT_BALROG_URL))
    username = click.prompt('Username', default=settings.get('username', ''))

    if username == '':
        username = None

    # Prompt for a password if a username is provided
    password = None
    if username:
        password = click.prompt('Password', hide_input=True)

    output('Attempting to validate Balrog credentials...', Fore.BLUE)
    get_validated_environment(url=url, username=username, password=password)

    gpg_homedir = None
    gpg_fingerprint = None
    if password:
        gpg_homedir = click.prompt(
            'GPG homedir', settings.get('gpg.homedir', GPG_HOMEDIR_DEFAULT))
        gpg_fingerprint = click.prompt('Public key fingerprint',
                                       settings.get('gpg.fingerprint'))

    # Create a settings file
    settings.path = CONFIG_PATH

    ctx.invoke(config, key='balrog_url', value=url)

    if username:
        ctx.invoke(config, key='username', value=username)
        ctx.invoke(config, key='gpg.homedir', value=gpg_homedir)
        ctx.invoke(config, key='gpg.fingerprint', value=gpg_fingerprint)
        ctx.invoke(config, key='password', value=password)
コード例 #2
0
ファイル: cli.py プロジェクト: mythmon/morgoth-cli
def config(key, value, delete, list):
    """Get or set a configuration value."""
    if list:
        for section in settings.config:
            for option in settings.config[section]:
                key = '{}.{}'.format(section, option)
                output('{} = {}'.format(key, settings.get(key)))
    elif delete:
        try:
            settings.delete(key)
        except KeyError:
            output('Setting does not exist.')
            exit(1)
    elif value == '':
        if settings.get(key):
            output(settings.get(key))
            exit(0)
    elif key:
        try:
            settings.set(key, value)
        except GPGImproperlyConfigured:
            output('GPG settings improperly configured.', Fore.RED)
            exit(1)

    settings.save()
コード例 #3
0
ファイル: cli.py プロジェクト: mythmon/morgoth-cli
def get_validated_environment(**kwargs):
    environment = Environment(kwargs.get('url', settings.get('balrog_url')),
                              username=kwargs.get('username',
                                                  settings.get('username')),
                              password=kwargs.get(
                                  'password',
                                  settings.get('password', decrypt=True)))

    try:
        environment.validate()
    except Timeout:
        output('Timeout while attempting to connect. Check VPN.', Fore.RED)
        exit(1)
    except HTTPError as err:
        if err.response.status_code == 401:
            output('Invalid Balrog credentials.', Fore.RED)
            if kwargs.get('verbose'):
                output('Error from server:')
                output(json.dumps(err.response.json(), indent=2))
            exit(1)
        raise

    return environment
コード例 #4
0
ファイル: cli.py プロジェクト: mythmon/morgoth-cli
def auth(ctx, username, verbose):
    """Update authentication settings."""
    if not username:
        username = click.prompt('Username', settings.get('username'))

    password = None
    while not password:
        password = click.prompt('Password', hide_input=True)

    output('Attempting to validate Balrog credentials...', Fore.BLUE)
    get_validated_environment(username=username,
                              password=password,
                              verbose=verbose)

    ctx.invoke(config, key='username', value=username)
    ctx.invoke(config, key='password', value=password)
コード例 #5
0
ファイル: cli.py プロジェクト: mythmon/morgoth-cli
def make_release(xpi_file, profile, verbose):
    """Make a new release from an XPI file."""
    prefix = settings.get('aws.prefix', DEFAULT_AWS_PREFIX)

    try:
        xpi = XPI(xpi_file)
    except XPI.DoesNotExist:
        output('File does not exist.', Fore.RED)
        exit(1)
    except XPI.BadZipfile:
        output('XPI cannot be unzipped.', Fore.RED)
        exit(1)
    except XPI.BadXPIfile:
        output('XPI is not properly configured.', Fore.RED)
        exit(1)
    else:
        output('Found: {}'.format(xpi.release_name), Fore.CYAN)

        if not click.confirm('Is this correct?'):
            output('Release could not be auto-generated.', Fore.RED)
            exit(1)

        session = boto3.Session(profile_name=profile)
        s3 = session.resource('s3')
        bucket = s3.Bucket(
            settings.get('aws.bucket_name', DEFAULT_AWS_BUCKET_NAME))

        exists = False
        for obj in bucket.objects.filter(Prefix=prefix):
            if obj.key == xpi.get_ftp_path(prefix):
                exists = True

        uploaded = False
        if exists:
            tmpdir = tempfile.mkdtemp()
            download_path = os.path.join(tmpdir, xpi.file_name)
            bucket.download_file(xpi.get_ftp_path(prefix), download_path)
            uploaded_xpi = XPI(download_path)

            if uploaded_xpi.sha512sum == xpi.sha512sum:
                output('XPI already uploaded.', Fore.GREEN)
                uploaded = True
            else:
                output('XPI with matching filename already uploaded.',
                       Fore.YELLOW)

        if not uploaded:
            if exists and not click.confirm('Would you like to replace it?'):
                output('Aborting.', Fore.RED)
                exit(1)
            with open(xpi.path, 'rb') as data:
                bucket.put_object(Key=xpi.get_ftp_path(prefix), Body=data)
                output('XPI uploaded successfully.', Fore.GREEN)

        release_data = xpi.generate_release_data(
            settings.get('aws.base_url', DEFAULT_AWS_BASE_URL), prefix)

        if click.confirm('Upload release to Balrog?'):
            environment = get_validated_environment(verbose=verbose)

            environment.request('releases',
                                data={
                                    'blob': json.dumps(release_data),
                                    'name': xpi.release_name,
                                    'product': 'SystemAddons',
                                    'csrf_token': environment.csrf(),
                                })

            output('Uploaded: {}{}'.format(Style.BRIGHT, xpi.release_name))
        elif click.confirm('Save release to file?'):
            json_path = 'releases/{}.json'.format(xpi.release_name)

            if os.path.exists(json_path):
                output('Release JSON file already exists.', Fore.YELLOW)
                if not click.confirm('Replace existing release JSON file?'):
                    output('Aborting.', Fore.RED)
                    exit(1)

            output('Saving to: {}{}'.format(Style.BRIGHT, json_path))

            os.makedirs('releases', exist_ok=True)
            with open(json_path, 'w') as f:
                f.write(json.dumps(release_data, indent=2, sort_keys=True))
        else:
            output(json.dumps(release_data, indent=2, sort_keys=True))

    output('')
コード例 #6
0
ファイル: cli.py プロジェクト: mythmon/morgoth-cli
@cli.command()
@click.option('--verbose', '-v', is_flag=True)
def status(verbose):
    """Show the current status."""
    if verbose:
        output(STATUS_5H17)


@cli.group()
def make():
    """Make a new object."""
    pass


@make.command('release')
@click.option('--profile', default=settings.get('aws.profile'))
@click.option('--verbose', '-v', is_flag=True)
@click.argument('xpi_file')
def make_release(xpi_file, profile, verbose):
    """Make a new release from an XPI file."""
    prefix = settings.get('aws.prefix', DEFAULT_AWS_PREFIX)

    try:
        xpi = XPI(xpi_file)
    except XPI.DoesNotExist:
        output('File does not exist.', Fore.RED)
        exit(1)
    except XPI.BadZipfile:
        output('XPI cannot be unzipped.', Fore.RED)
        exit(1)
    except XPI.BadXPIfile: