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)
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()
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
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)
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('')
@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: