示例#1
0
def cli(env, is_open):
    """List tickets."""
    ticket_mgr = SoftLayer.TicketManager(env.client)

    tickets = ticket_mgr.list_tickets(open_status=not is_open,
                                      closed_status=is_open)

    table = formatting.Table(['id', 'assigned user', 'title',
                              'creation date', 'last edit date'])

    for ticket in tickets:
        user = '******'
        if ticket.get('assignedUser'):
            user = "******" % (ticket['assignedUser']['firstName'],
                              ticket['assignedUser']['lastName']),

        table.add_row([
            ticket['id'],
            user,
            click.wrap_text(ticket['title']),
            ticket['createDate'],
            ticket['lastEditDate']
        ])

    return table
def get_ticket_results(mgr, ticket_id, update_count=1):
    """Get output about a ticket.

    :param integer id: the ticket ID
    :param integer update_count: number of entries to retrieve from ticket
    :returns: a KeyValue table containing the details of the ticket

    """
    result = mgr.get_ticket(ticket_id)
    result = utils.NestedDict(result)

    table = formatting.KeyValueTable(['Name', 'Value'])
    table.align['Name'] = 'r'
    table.align['Value'] = 'l'

    table.add_row(['id', result['id']])
    table.add_row(['title', result['title']])
    if result['assignedUser']:
        table.add_row(['assignedUser',
                       "%s %s" % (result['assignedUser']['firstName'],
                                  result['assignedUser']['lastName'])])
    table.add_row(['createDate', result['createDate']])
    table.add_row(['lastEditDate', result['lastEditDate']])

    total_update_count = result['updateCount']
    count = min(total_update_count, update_count)
    for i, update in enumerate(result['updates'][:count]):
        # NOTE(kmcdonald): Windows new-line characters need to be stripped out
        wrapped_entry = click.wrap_text(update['entry'].replace('\r', ''))
        table.add_row(['Update %s' % (i + 1,), wrapped_entry])

    return table
示例#3
0
def delete(jobs_names, base_dir, confirm):
    """
    Delete jobs on the Jenkins server.
    """
    jenkins_url = conf.get(base_dir, ['server', 'location'])
    if confirm and jobs_names:
        question = click.style(click.wrap_text(
            'Are you sure you want to delete the following jobs on the '
            'Jenkins server?'
        ), fg='red', bold=True)
        jobs_list = '\n'.join('  %s' % n for n in jobs_names)
        click.confirm('%s\n\n%s\n\n' % (question, jobs_list), abort=True)

    exit_code = 0
    for name in jobs_names:
        try:
            jenkins_url = jenkins_api.handle_auth(
                base_dir,
                jenkins_api.delete_job,
                jenkins_url,
                name
            )
        except requests.HTTPError as exc:
            if exc.response.status_code == 404:
                click.secho('%s was not found' % name, fg='red')
                exit_code = 1

    sys.exit(exit_code)
示例#4
0
文件: kiss.py 项目: parente/kiss
def show(user, seq):
    '''Show kiss details.

    Prompts for which kiss to run if one is not matched by the optional sequence
    of characters.
    '''
    gists = get('users/{}/gists'.format(user)).json()
    kisses = get_kisses(gists, seq)
    kiss = get_one_kiss(kisses, 'Choose a kiss to view')

    click.echo('Showing details for "{}"\n'.format(kiss['name']))
    readme = None
    run = None
    for filename in kiss['files']:
        if filename.startswith('README'):
            readme = requests.get(kiss['files'][filename]['raw_url'])
        elif filename == 'run':
            run = requests.get(kiss['files'][filename]['raw_url'])
        if readme is not None and run is not None: break

    click.echo(click.wrap_text(readme.text, preserve_paragraphs=True))
    click.echo()
    click.echo(run.text)

    click.echo('\nIncludes: {}'.format(', '.join(kiss['files'])))
    click.echo('Created: {}'.format(kiss['created_at']))
    click.echo('Updated: {}'.format(kiss['updated_at']))
    click.echo('URL: {}'.format(kiss['html_url']))
示例#5
0
def cli(env, is_open):
    """List tickets."""
    ticket_mgr = SoftLayer.TicketManager(env.client)

    tickets = ticket_mgr.list_tickets(open_status=is_open,
                                      closed_status=not is_open)

    table = formatting.Table(['id', 'assigned_user', 'title',
                              'last_edited', 'status'])

    for ticket in tickets:
        user = formatting.blank()
        if ticket.get('assignedUser'):
            user = "******" % (ticket['assignedUser']['firstName'],
                              ticket['assignedUser']['lastName'])

        table.add_row([
            ticket['id'],
            user,
            click.wrap_text(ticket['title']),
            ticket['lastEditDate'],
            ticket['status']['name'],
        ])

    env.fout(table)
示例#6
0
    def _format_indented_message(self, message, newline=True,
                                 indent='         ', sha=''):
        """Format an indented message.

        :type message: str
        :param message: The commit comment.

        :type newline: bool
        :param newline: Determines whether to prepend a newline.

        :type indent: str
        :param indent: The indent, consisting of blank chars.
            TODO: Consider passing an int denoting # blank chars, or try to
            calculate the indent dynamically.

        :type sha: str
        :param sha: The commit hash.

        :rtype: str
        :return: The formattted commit comment.
        """
        subsequent_indent = indent
        if sha != '':
            subsequent_indent += '         '
        message = self.strip_line_breaks(message)
        formatted_message = click.wrap_text(
            text=click.style(sha, fg=self.config.clr_tertiary)+message,
            initial_indent=indent,
            subsequent_indent=subsequent_indent)
        if newline:
            formatted_message = click.style('\n' + formatted_message)
        return formatted_message
示例#7
0
    def format_trending_entry(self, view_entry):
        """Formats a trending repo entry.

        Args:
            * view_entry: A dictionary parsed to include feed URITemplates.

        Returns:
            A string representing the formatted item.
        """
        trending_entry = view_entry.item
        item_parts = trending_entry.title.split(' ')
        title = item_parts[0]
        item = self.format_index_title(view_entry.index, title)
        summary_parts = trending_entry.summary.split('\n')
        summary = summary_parts[0] if len(summary_parts) > 1 else ''
        summary = self.strip_line_breaks(summary)
        language = summary_parts[-1]
        if language == '()':
            language = '(Unknown)'
        language = re.sub(r'(\()', r'', language)
        language = re.sub(r'(\))', r'', language)
        item += click.style(
            '(' + str(pretty_date_time(trending_entry.updated_parsed)) + ')',
            fg='yellow')
        if summary:
            item += '\n'
            summary = click.wrap_text(
                text=summary,
                initial_indent='         ',
                subsequent_indent='         ')
        item += click.style(summary, fg=None)
        item += '\n'
        item += click.style('         Language: ' + language, fg='green')
        return item
示例#8
0
    def format_trending_entry(self, view_entry):
        """Formats a trending repo entry.

        :type view_entry: dict
        :param view_entry: The URITemplates feed.

        :rtype: str
        :return: The formattted trending entry.
        """
        trending_entry = view_entry.item
        item_parts = trending_entry.title.split(' ')
        title = item_parts[0]
        item = self.format_index_title(view_entry.index, title)
        summary_parts = trending_entry.summary.split('\n')
        summary = summary_parts[0] if len(summary_parts) > 1 else ''
        summary = self.strip_line_breaks(summary)
        language = summary_parts[-1]
        if language == '()':
            language = '(Unknown)'
        language = re.sub(r'(\()', r'', language)
        language = re.sub(r'(\))', r'', language)
        if summary:
            item += '\n'
            summary = click.wrap_text(
                text=summary,
                initial_indent='         ',
                subsequent_indent='         ')
        item += click.style(summary, self.config.clr_message)
        item += '\n'
        item += click.style('         ' + language,
                            fg=self.config.clr_message)
        return item
示例#9
0
 def _get_prompt_tokens(cli):
     rv = [
         (Token.PROMPT, message),
         (Token.COLON, ': '),
     ]
     if first and help:
         rv.insert(0, (Token.HELP, wrap_text(help) + '\n'))
     return rv
示例#10
0
 def __call__(self, s):
     new_s = wrap_text(
         s,
         width=self._max_width,
         initial_indent=self._indent_string.as_string,
         subsequent_indent=self._indent_string.extra_indent,
     )
     return(new_s)
示例#11
0
文件: ui.py 项目: mermoldy/reddit-cli
def echo(text='', prepend='', initial_indent='', subsequent_indent='', fg=''):
    window_width, _ = click.get_terminal_size()
    wrapped = click.wrap_text(text,
                              width=window_width - len(initial_indent),
                              initial_indent=prepend + initial_indent,
                              subsequent_indent=prepend + subsequent_indent,
                              preserve_paragraphs=False)
    click.secho(wrapped, fg=fg)
示例#12
0
 def _format_commit_or_comment(self, message, sha=''):
     indent = '         '
     subsequent_indent = indent if sha == '' else '                  '
     message = self.strip_line_breaks(message)
     formatted_message = click.wrap_text(
         text=click.style(sha, fg='cyan')+message,
         initial_indent=indent,
         subsequent_indent=subsequent_indent)
     return formatted_message
示例#13
0
 def print_results(kind, colour, results):
     click.echo(
         "{RESULT}: {num}\n{tests}".format(
             RESULT=click.style(kind, fg=colour, bold=True),
             num=len(results),
             tests=click.wrap_text(", ".join(sorted(results))),
         )
     )
     if results:
         click.echo()
示例#14
0
文件: utility.py 项目: Hamuko/cum
def print_new_normal(items):
    """Prints the new chapter information. E.g.
        joukamachi-no-dandelion
        30  31  32  33  34
        minami-ke
        153  154  155  156  157
    """
    width = click.get_terminal_size()[0]
    for series in items:
        click.secho(series[0], bold=True)
        click.echo(click.wrap_text(series[1], width=width))
示例#15
0
文件: cum.py 项目: CounterPillow/cum
def list_new():
    items = {}
    for chapter in db.Chapter.find_new():
        try:
            items[chapter.alias].append(chapter.chapter)
        except KeyError:
            items[chapter.alias] = [chapter.chapter]

    for series in sorted(items):
        if config.get().compact_new:
            name = click.style(series, bold=True)
            chapters = '  '.join([x for x in items[series]])
            line = click.wrap_text(' '.join([name, chapters]),
                                   subsequent_indent=' ' * (len(series) + 1),
                                   width=click.get_terminal_size()[0])
            click.echo(line)
        else:
            click.secho(series, bold=True)
            click.echo(click.wrap_text('  '.join([x for x in items[series]]),
                                       width=click.get_terminal_size()[0]))
示例#16
0
    def prompt(self, text, default=None, info=None):
        self.question += 1
        self.e('')
        self.e('Step %d:' % self.question, fg='yellow')
        if info is not None:
            self.e(click.wrap_text(info, self.term_width, '| ', '| '))
        text = '> ' + click.style(text, fg='green')

        if default is True or default is False:
            return click.confirm(text, default=default)
        return click.prompt(text, default=default, show_default=True)
示例#17
0
 def _get_prompt_tokens(cli):
     rv = [
         (Token.PROMPT, message),
         (Token.BRACKET, ' ['),
         (Token.DEFAULT, 'Y/n' if default else 'y/N'),
         (Token.BRACKET, ']'),
         (Token.COLON, ': '),
     ]
     if first and help:
         rv.insert(0, (Token.HELP, wrap_text(help) + '\n'))
     return rv
示例#18
0
    def prompt(key, text, default=None, info=None):
        e('')
        e('Step %d:' % (len(options) + 1), fg='yellow')
        if info is not None:
            e(click.wrap_text(info, term_width - 2, '| ', '| '))
        text = '> ' + click.style(text, fg='green')

        if default is True or default is False:
            rv = click.confirm(text, default=default)
        else:
            rv = click.prompt(text, default=default, show_default=True)
        options[key] = rv
示例#19
0
    def prompt(self, text, default=None, info=None):
        self.question += 1
        self.e("")
        self.e("Step %d:" % self.question, fg="yellow")
        if info is not None:
            self.e(click.wrap_text(info, self.term_width - 2, "| ", "| "))
        text = "> " + click.style(text, fg="green")

        if default is True or default is False:
            rv = click.confirm(text, default=default)
        else:
            rv = click.prompt(text, default=default, show_default=True)
        return rv
示例#20
0
def _confirm_mismatching_job_type_overwrite(job_name, expected_type,
                                            pushed_type):
    utils.sechowrap('')
    utils.sechowrap('Failed to push %s.' % job_name, fg='red', bold=True)
    utils.sechowrap('')
    utils.sechowrap('The job type on the server does not match the job type '
                    'being pushed:', fg='red')
    utils.sechowrap('  expected: %s' % expected_type, fg='red')
    utils.sechowrap('  pushed: %s' % pushed_type, fg='red')
    utils.sechowrap('')
    return click.confirm(click.style(click.wrap_text(
        'Do you want to delete the old job and replace it with this one? '
        'you will loose all the builds history'
    ), fg='yellow'))
示例#21
0
 def callback(ctx, param, value):
     if not value:
         return
     click.echo('Current version: %s' % __version__)
     for version in CHANGELOG:
         click.echo('Version history: %s' % version)
         for item in CHANGELOG[version].split('\n'):
             if not item:
                 continue
             click.echo(click.wrap_text(
                 item.lstrip(),
                 initial_indent='    ',
                 subsequent_indent='        '))
     ctx.exit()
示例#22
0
def get_ticket_results(mgr, ticket_id, update_count=1):
    """Get output about a ticket.

    :param integer id: the ticket ID
    :param integer update_count: number of entries to retrieve from ticket
    :returns: a KeyValue table containing the details of the ticket

    """
    ticket = mgr.get_ticket(ticket_id)

    table = formatting.KeyValueTable(['Name', 'Value'])
    table.align['Name'] = 'r'
    table.align['Value'] = 'l'

    table.add_row(['id', ticket['id']])
    table.add_row(['title', ticket['title']])
    if ticket.get('assignedUser'):
        user = ticket['assignedUser']
        table.add_row([
            'user',
            "%s %s" % (user.get('firstName'), user.get('lastName')),
        ])

    table.add_row(['status', ticket['status']['name']])
    table.add_row(['created', ticket.get('createDate')])
    table.add_row(['edited', ticket.get('lastEditDate')])

    # Only show up to the specified update count
    updates = ticket.get('updates', [])
    count = min(len(updates), update_count)
    count_offset = len(updates) - count + 1  # Display as one-indexed
    for i, update in enumerate(updates[-count:]):
        wrapped_entry = ""

        # Add user details (fields are different between employee and users)
        editor = update.get('editor')
        if editor:
            if editor.get('displayName'):
                wrapped_entry += "By %s (Employee)\n" % (editor['displayName'])
            if editor.get('firstName'):
                wrapped_entry += "By %s %s\n" % (editor.get('firstName'),
                                                 editor.get('lastName'))

        # NOTE(kmcdonald): Windows new-line characters need to be stripped out
        wrapped_entry += click.wrap_text(update['entry'].replace('\r', ''))
        table.add_row(['update %s' % (count_offset + i,), wrapped_entry])

    return table
示例#23
0
def _confirm_and_delete(base_dir, unknown_jobs, confirm, jenkins_url):
    utils.sechowrap('The following jobs are present on the server but not in '
                    'the local repository:', fg='yellow')
    click.secho('  ' + '\n  '.join(sorted(unknown_jobs)), fg='yellow')
    if confirm:
        utils.sechowrap('')
        delete = click.confirm(click.style(click.wrap_text(
            'Do you really want to delete these jobs? THIS CANNOT BE '
            'RECOVERED!'
        ), fg='red', bold=True))
    else:
        delete = True
    if delete:
        for job in unknown_jobs:
            _, jenkins_url = jenkins_api.handle_auth(base_dir,
                                                     jenkins_api.delete_job,
                                                     jenkins_url,
                                                     job)
示例#24
0
def attach():
    """
    Enter a python shell with contracts and blockchain client
    available.
    """
    project_dir = os.path.abspath(os.getcwd())
    contracts_meta = utils.load_contracts(project_dir)

    context = {
        'contracts': package_contracts(contracts_meta),
        'client': Client('127.0.0.1', '8545'),
    }

    contract_names = ', '.join(sorted(contracts_meta.keys()))

    banner = textwrap.dedent(
        """
        Python: {python_version}

        Populus: v{populus_version}

        Project Path: {project_dir}

        contracts  -> Contract classes
        client     -> Blockchain client ({client_type})

        Contracts: {contracts}
        """
    ).format(
        python_version=sys.version.partition('\n')[0],
        populus_version=populus.__version__,
        project_dir=project_dir,
        client_type="json-rpc",
        contracts=click.wrap_text(
            contract_names, initial_indent='', subsequent_indent=' ' * 4,
        ),
    ).strip()

    if is_ipython:
        shell = InteractiveConsole(user_ns=context)
    else:
        shell = InteractiveConsole(context)
    shell.interact(banner)
def write_page(data):
    path = data['path'][1:]
    if not path:
        return
    filename = os.path.join(OUT, *(path + ['contents.lr']))
    dirname = os.path.dirname(filename)
    try:
        os.makedirs(dirname)
    except OSError:
        pass

    args = [x['metavar'] for x in data['arguments']]
    body = [
        '`%s`' % ' '.join(data['path'] + args),
        '',
        data['help'] or '',
    ]

    body.append('')
    body.append('## Options')
    body.append('')
    for opt in data['options']:
        prefix = '- `%s`: ' % opt['opt_string']
        for line in click.wrap_text(
                opt['help'] or '', 74, prefix, '  ').splitlines():
            body.append(line)
    body.append('- `--help`: print this help page.')

    fields = [
        ('comment', 'This file is auto generated by dump-cli-help.py'),
        ('title', path[-1]),
        ('summary', data['summary']),
        ('type', 'cmdlet'),
        ('body', '\n'.join(body)),
    ]

    with open(filename, 'w') as f:
        f.write('\n---\n'.join('%s:%s%s' % (
            k,
            len(v.splitlines()) > 1 and '\n\n' or ' ',
            v
        ) for k, v in fields))
示例#26
0
    def format_comment(self, item, depth, header_color, header_adornment):
        """Format a given item's comment.

        :type item: :class:`haxor.Item`
        :param item: An instance of `haxor.Item`.

        :type depth: int
        :param depth: The current recursion depth, used to indent the comment.

        :type header_color: str
        :param header_color: The header color.

        :type header_adornment: str
        :param header_adornment: The header adornment.

        :rtype: tuple
        :return: * A string representing the formatted comment header.
                 * A string representing the formatted comment.
        """
        indent = self.COMMENT_INDENT * depth
        formatted_heading = click.style(
            '\n{i}{b} - {d}{h}'.format(
                i=indent,
                b=item.by,
                d=str(pretty_date_time(item.submission_time)),
                h=header_adornment),
            fg=header_color)
        unescaped_text = self.html.unescape(item.text)
        regex_paragraph = re.compile(r'<p>')
        unescaped_text = regex_paragraph.sub(click.style(
            '\n\n' + indent), unescaped_text)
        regex_url = re.compile(r'(<a href=(".*") .*</a>)')
        unescaped_text = regex_url.sub(click.style(
            r'\2', fg=self.config.clr_link), unescaped_text)
        regex_tag = re.compile(r'(<(.*)>.*?<\/\2>)')
        unescaped_text = regex_tag.sub(click.style(
            r'\1', fg=self.config.clr_tag), unescaped_text)
        formatted_comment = click.wrap_text(text=unescaped_text,
                                            initial_indent=indent,
                                            subsequent_indent=indent)
        return formatted_heading, formatted_comment
示例#27
0
def cli(env, name, public):
    """List images."""

    image_mgr = SoftLayer.ImageManager(env.client)

    images = []
    if public in [False, None]:
        for image in image_mgr.list_private_images(name=name,
                                                   mask=image_mod.MASK):
            images.append(image)

    if public in [True, None]:
        for image in image_mgr.list_public_images(name=name,
                                                  mask=image_mod.MASK):
            images.append(image)

    table = formatting.Table(['id',
                              'name',
                              'type',
                              'visibility',
                              'account'])

    images = [image for image in images if image['parentId'] == '']
    for image in images:

        visibility = (image_mod.PUBLIC_TYPE if image['publicFlag']
                      else image_mod.PRIVATE_TYPE)
        table.add_row([
            image.get('id', formatting.blank()),
            formatting.FormattedItem(image['name'],
                                     click.wrap_text(image['name'], width=50)),
            formatting.FormattedItem(
                utils.lookup(image, 'imageType', 'keyName'),
                utils.lookup(image, 'imageType', 'name')),
            visibility,
            image.get('accountId', formatting.blank()),
        ])

    env.fout(table)
示例#28
0
def generate_oci_config():
    click.echo(
        click.wrap_text(text=generate_oci_config_instructions,
                        preserve_paragraphs=True))

    config_location = os.path.abspath(
        click.prompt('Enter a location for your config',
                     default=os.path.join(default_directory, 'config'),
                     value_proc=process_config_filename))
    if os.path.exists(config_location):
        if not click.confirm(
                'File: {} already exists. Do you want to overwrite?'.format(
                    config_location)):
            click.echo(config_generation_canceled_message)
            return
    else:
        dirname = os.path.dirname(config_location)

        # if user inputs only a filename (dirname=='') it implies the current directory so no need to create a dir
        if dirname and not os.path.exists(dirname):
            create_directory(dirname)

    user_id = click.prompt(
        'Enter a user OCID',
        value_proc=lambda ocid: validate_ocid(ocid, config.PATTERNS['user']))
    tenant_id = click.prompt('Enter a tenancy OCID',
                             value_proc=lambda ocid: validate_ocid(
                                 ocid, config.PATTERNS['tenancy']))

    region = None
    while not region:
        region_list = ', '.join(sorted(REGIONS))
        region = click.prompt(
            text='Enter a region (e.g. {})'.format(region_list),
            value_proc=validate_region)

    if click.confirm(
            "Do you want to generate a new RSA key pair? (If you decline you will be asked to supply the path to an existing key.)",
            default=True):
        key_location = os.path.abspath(
            click.prompt(text='Enter a directory for your keys to be created',
                         default=default_directory))
        key_location = os.path.expanduser(key_location)
        if not os.path.exists(key_location):
            create_directory(key_location)

        private_key = cli_util.generate_key()
        public_key = private_key.public_key()

        key_name = click.prompt('Enter a name for your key', 'oci_api_key')
        if not write_public_key_to_file(
                os.path.join(key_location, key_name +
                             public_key_filename_suffix), public_key):
            click.echo(config_generation_canceled_message)
            return

        key_passphrase = click.prompt(
            text=
            'Enter a passphrase for your private key (empty for no passphrase)',
            default='',
            hide_input=True,
            show_default=False,
            confirmation_prompt=True)
        private_key_file = os.path.join(key_location,
                                        key_name + private_key_filename_suffix)
        if not write_private_key_to_file(private_key_file, private_key,
                                         key_passphrase):
            click.echo(config_generation_canceled_message)
            return

        fingerprint = public_key_to_fingerprint(public_key)
        click.echo("Fingerprint: {}".format(fingerprint))
    else:
        private_key_file, has_passphrase, private_key = click.prompt(
            text='Enter the location of your private key file',
            value_proc=validate_private_key_file)
        private_key_file = os.path.abspath(private_key_file)

        key_passphrase = None
        if has_passphrase:
            key_passphrase, private_key = click.prompt(
                text='Enter the passphrase for your private key',
                hide_input=True,
                value_proc=lambda passphrase: validate_private_key_passphrase(
                    private_key_file, passphrase))

        fingerprint = public_key_to_fingerprint(private_key.public_key())
        click.echo("Fingerprint: {}".format(fingerprint))

    if key_passphrase and not click.confirm(
            'Do you want to write your passphrase to the config file? (if not, you will need to supply it as an argument to the CLI)',
            default=False):
        key_passphrase = None

    write_config(config_location, user_id, fingerprint, private_key_file,
                 tenant_id, region, key_passphrase)

    click.echo('Config written to {}'.format(config_location))
    click.echo(
        click.wrap_text(upload_public_key_instructions,
                        preserve_paragraphs=True))
示例#29
0
def attach(active):
    """
    Enter a python shell with contracts and blockchain client
    available.
    """
    project_dir = os.path.abspath(os.getcwd())
    contracts_meta = utils.load_contracts(project_dir)
    client = Client('127.0.0.1', '8545')

    context = {
        'contracts': package_contracts(contracts_meta),
        'client': client,
    }
    data_dir = None
    if active:
        data_dir = get_active_data_dir(project_dir)
        if os.path.islink(data_dir):
            setup_known_instances(context, data_dir)
        else:
            click.echo(click.style("No Valid Active Chain Data Directory Found!", fg="red"))

    def redeploy(contracts=[], record=True):
        return(deploy_set(
            context, client, project_dir, data_dir=data_dir,
            record=record, contracts_by_name=contracts
        ))

    context["redeploy"] = redeploy

    contract_names = ', '.join(sorted(contracts_meta.keys()))

    banner = textwrap.dedent(
        """
        Python: {python_version}

        Populus: v{populus_version}

        Project Path: {project_dir}

        contracts  -> Contract classes
        client     -> Blockchain client ({client_type})
        redeploy   -> Method to re-deploy project contracts
                      Example:
                        deployed_cts = redeploy()
                        deployed_cts = redeploy(record = False)
                        deployed_cts = redeploy(contracts = ["Example"])

        Contracts: {contracts}
        Check contracts.<type>.known for deployed contracts.

        """
    ).format(
        python_version=sys.version.partition('\n')[0],
        populus_version=populus.__version__,
        project_dir=project_dir,
        client_type="json-rpc",
        contracts=click.wrap_text(
            contract_names, initial_indent='', subsequent_indent=' ' * 4,
        ),
    ).strip()

    if is_ipython:
        shell = InteractiveConsole(user_ns=context)
    else:
        shell = InteractiveConsole(context)

    # Start the active directory link observer
    event_handler = ActiveDataDirChangedEventHandler(
        project_dir=project_dir,
        context=context,
    )
    observer = get_active_dir_observer(project_dir, event_handler)

    observer.start()
    shell.interact(banner)
    observer.stop()
    observer.join()
示例#30
0
tenets = (
    "TST Tenet #1: One should strive to act with compassion and empathy towards all creatures in accordance with reason.",
    "TST Tenet #2: The struggle for justice is an ongoing and necessary pursuit that should prevail over laws and institutions.",
    "TST Tenet #3: One's body is inviolable, subject to one's own will alone.",
    "TST Tenet #4: The freedoms of others should be respected, including the freedom to offend. To willfully and unjustly encroach upon the freedoms of another is to forgo your own.",
    "TST Tenet #5: Beliefs should conform to our best scientific understanding of the world. We should take care never to distort scientific facts to fit our beliefs.",
    "TST Tenet #6: People are fallible. If we make a mistake, we should do our best to rectify it and resolve any harm that may have been caused.",
    "TST Tenet #7: Every tenet is a guiding principle designed to inspire nobility in action and thought. The spirit of compassion, wisdom, and justice should always prevail over the written or spoken word.",
)

wrapped_tenets = list()

width = click.get_terminal_size()[0]

for item in tenets:
    wrapped_tenets.append(click.wrap_text(item, width=width))

# 8200 seconds = 23 hours
# By picking a tenet based off of a non-24-hour increment, we avoid pinning one tenet to one day of the week.
# This way we will avoid the problem experienced by pinning one tenet to one day, which would never show us
# tenets for days where we don't use a computer, such as a weekend.
random_id = int(time.time() / 82400 % 7)


@click.command()
@click.option("-a", "--all/--no-all", default=False, help="Print all tenets.")
@click.option("-i", "--id", type=click.IntRange(1, 7), help="Print a specific tenet ID (1-7)")
@click.option("-r", "--random/--no-random", default=False, help="Print a random tenent.")
def main(random, all, id):
    option_count = 0
    for item in [random, all, id]:
示例#31
0
def generate_processor_help(ocrd_tool, processor_instance=None):
    """Generate a string describing the full CLI of this processor including params.
    
    Args:
         ocrd_tool (dict): this processor's ``tools`` section of the module's ``ocrd-tool.json``
         processor_instance (object, optional): the processor implementation
             (for adding any module/class/function docstrings)
    """
    parameter_help = ''
    if 'parameters' not in ocrd_tool or not ocrd_tool['parameters']:
        parameter_help = '  NONE\n'
    else:
        def wrap(s):
            return wrap_text(s, initial_indent=' '*3,
                             subsequent_indent=' '*4,
                             width=72, preserve_paragraphs=True)
        for param_name, param in ocrd_tool['parameters'].items():
            parameter_help += wrap('"%s" [%s%s]' % (
                param_name,
                param['type'],
                ' - REQUIRED' if 'required' in param and param['required'] else
                ' - %s' % json.dumps(param['default']) if 'default' in param else ''))
            parameter_help += '\n ' + wrap(param['description'])
            if 'enum' in param:
                parameter_help += '\n ' + wrap('Possible values: %s' % json.dumps(param['enum']))
            parameter_help += "\n"
    doc_help = ''
    if processor_instance:
        module = inspect.getmodule(processor_instance)
        if module and module.__doc__:
            doc_help += '\n' + inspect.cleandoc(module.__doc__)
        if processor_instance.__doc__:
            doc_help += '\n' + inspect.cleandoc(processor_instance.__doc__)
        if processor_instance.process.__doc__:
            doc_help += '\n' + inspect.cleandoc(processor_instance.process.__doc__)
        if doc_help:
            doc_help = '\n\n' + wrap_text(doc_help, width=72,
                                          initial_indent='  > ',
                                          subsequent_indent='  > ',
                                          preserve_paragraphs=True)
    return '''
Usage: %s [OPTIONS]

  %s%s

Options:
  -I, --input-file-grp USE        File group(s) used as input
  -O, --output-file-grp USE       File group(s) used as output
  -g, --page-id ID                Physical page ID(s) to process
  --overwrite                     Remove existing output pages/images
                                  (with --page-id, remove only those)
  -p, --parameter JSON-PATH       Parameters, either verbatim JSON string
                                  or JSON file path
  -P, --param-override KEY VAL    Override a single JSON object key-value pair,
                                  taking precedence over --parameter
  -m, --mets URL-PATH             URL or file path of METS to process
  -w, --working-dir PATH          Working directory of local workspace
  -l, --log-level [OFF|ERROR|WARN|INFO|DEBUG|TRACE]
                                  Log level
  -C, --show-resource RESNAME     Dump the content of processor resource RESNAME
  -L, --list-resources            List names of processor resources
  -J, --dump-json                 Dump tool description as JSON and exit
  -h, --help                      This help message
  -V, --version                   Show version

Parameters:
%s
Default Wiring:
  %s -> %s

''' % (
    ocrd_tool['executable'],
    ocrd_tool['description'],
    doc_help,
    parameter_help,
    ocrd_tool.get('input_file_grp', 'NONE'),
    ocrd_tool.get('output_file_grp', 'NONE')
)
示例#32
0
def echo_success(message):
    echo(click.style(
        click.wrap_text(message, preserve_paragraphs=True),
        fg='green')
    )
示例#33
0
文件: setup.py 项目: javfg/indico
def _error(msg):
    msg = wrap_text(msg)
    click.echo(click.style(msg, fg='red', bold=True), err=True)
示例#34
0
def check_push_line(ctx: click.Context, remote_name: str, line: str) -> None:
    # stdin format:
    # <local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF
    lref, lhash, _rref, rhash = line.strip().split(" ")
    if lref == "(delete)":
        assert lhash == NULL_HEX_SHA
        ctx.exit(0)  # allow deletes in any case

    repo = ctx.obj.repo
    lref_commit = repo.commit(lhash)
    if rhash == NULL_HEX_SHA:  # remote is empty
        refs = lhash  # all commits reachalbe from lhash
        rref_commit: Optional[git.Commit] = None
        linear = True  # empty remotes are always in line
        redate_base = ""
    else:
        # all reachable from lhash but not from rhash
        # if l and r diverge it's equivalent to lhash
        # if l is behind r it means refs is empty (all commits reachable)
        try:
            rref_commit = repo.commit(rhash)
        except ValueError:
            # rhash not found locally, i.e. is not part of local history
            linear = False
        else:
            linear = _is_parent_of(rref_commit, lref_commit)

        if not linear:
            # r diverges from l – push will fail unless forced
            # Note: We can only detect force pushes by checking the
            # arguments of the caller process (e.g., with psutil).
            # However this is a hack and requires additional dep.
            # In case of a non-force push displaying unredacted commits
            # distracts from the diverging issue and the check makes more
            # sense for the subsequent push (after merge or rebase) anyway.
            # Force pushes should by far be the rarer case.
            # Ergo: We warn the user and skip the check at the risk of
            # missing force pushes ith unredacted commits.
            click.echo(
                "Detected diverging remote. "
                "Skip pre-push check for unredacted commits.",
                err=True)
            ctx.exit(0)
        else:
            refs = f"{rhash}..{lhash}"
            redate_base = utils.get_named_ref(rref_commit)

    # check for unredated commits
    redacter = ctx.obj.get_dateredacter()
    found_dirty = False
    for commit in repo.iter_commits(rev=refs):
        is_redacted = utils.is_already_redacted(redacter, commit)
        if not is_redacted:
            if not found_dirty:
                click.echo(
                    "You tried to push commits with unredacted "
                    "timestamps:",
                    err=True,
                )
                found_dirty = True
            click.echo(commit.hexsha, err=True)

    if not found_dirty:
        # all is redacted and fine – allow push
        ctx.exit(0)

    # Allow pushing tags that appear dirty but are not
    # because lref is already on the remote.
    # Rational: The dates are already public, ergo: no additional harm.
    if lref.startswith(TAG_PREFIX):
        if list_containing_branches(repo, lhash, f"{remote_name}/*"):
            # lref is already on this remote - allow
            ctx.exit(0)

    # Alert about dirty commits and abort push
    redate_param = f" {redate_base}" if redate_base else ""
    click.echo(
        "\nTo redact and redate run:\n"
        f"\tgit-privacy redate{redate_param}",
        err=True)

    # get potential remote branches containing revs
    rbranches = list_containing_remote_branches(repo, refs)
    if rbranches:
        click.echo(click.wrap_text(
            "\nWARNING: Those commits seem to be part of the following"
            " remote branches."
            " After a redate your local history will diverge from them:\n"),
                   err=True)
        click.echo("\n".join(rbranches), err=True)
        click.echo(click.wrap_text(
            "\nNote: To push them without a redate pass the '--no-verify'"
            " option to git push."),
                   err=True)
    ctx.exit(1)
示例#35
0
def parseJSON(word, table, n):
    """ Parse the json table using library 
        https://github.com/Suyash458/WiktionaryParser
    Args:
        word: string; target word we are looking up
        table: json; returned json results on queried word from Wikitionary API.
        n: int; Maximum number of definition entries/examples shown.

    Raises:
        TypeError: If table is not a string type.
        ValueError: If returned table is empty.

    Returns:
        Returns the formated string
    """
    res = ""
    if len(table[0]["definitions"]) < 1:
        res += click.style(
            "🚨Sorry, wkdict can't find this word in the dictionary...🚨\n",
            fg='red',
            bold=True)
        res += '\n'
        res += click.style('The word you typed is {}\n'.format(word),
                           fg='bright_red',
                           bold=True)
    else:
        for e_idx, entry in enumerate(table):
            # word + prons (optional)
            pron_dict = entry.get("pronunciations", None)
            word_idx = str(e_idx + 1) + ") "
            pron = ""

            if pron_dict is not None:
                prons = pron_dict.get("text", [""])
                if len(prons) != 0:
                    pron = prons[0]

            res += click.style(word_idx + word, bold=True)
            res += click.style('\t' + pron + '\n', fg='bright_magenta')

            # defitions
            definitions = entry.get("definitions", [])
            for def_idx, def_text in enumerate(definitions):
                # part of speech
                part_of_speech = def_text.get("partOfSpeech", "")
                res += click.style('   🏷  ' + part_of_speech + '\n',
                                   fg='yellow')
                # underlined heading "definition"
                res += '\n'
                res += click.style(
                    '\t📗 ' + click.style('Definitions\n', underline=True))

                for text_id, text in enumerate(def_text.get("text", [])):
                    # definition entries
                    if text_id < n:
                        formated_def = click.wrap_text(
                            text,
                            width=65,
                            initial_indent='\t☞ ',
                            subsequent_indent='\t  ',
                            preserve_paragraphs=True)
                        res += click.style(formated_def + '\n', fg='green')

                res += '\n'
                if def_text.get("examples") != []:
                    res += click.style(
                        '\t📘 ' + click.style('Examples', underline=True) +
                        '\n')
                    for text_id, text in enumerate(def_text.get(
                            "examples", [])):
                        if text_id < n:
                            text = click.style(text, fg='blue')
                            formated_eg = click.wrap_text(
                                text,
                                width=65,
                                initial_indent='\t➡ ',
                                subsequent_indent='\t  ',
                                preserve_paragraphs=True)
                            res += formated_eg + '\n'
    return res
示例#36
0
文件: __init__.py 项目: simonbru/taxi
def echo_error(message):
    echo(
        click.style(click.wrap_text("Error: %s" % message,
                                    preserve_paragraphs=True),
                    fg='red'))
示例#37
0
文件: base.py 项目: simonbru/taxi
def create_config_file(filename):
    """
    Create main configuration file if it doesn't exist.
    """
    import textwrap
    from six.moves.urllib import parse

    if not os.path.exists(filename):
        old_default_config_file = os.path.join(os.path.dirname(filename),
                                               '.tksrc')
        if os.path.exists(old_default_config_file):
            upgrade = click.confirm("\n".join(
                textwrap.wrap(
                    "It looks like you recently updated Taxi. Some "
                    "configuration changes are required. You can either let "
                    "me upgrade your configuration file or do it "
                    "manually.")) + "\n\nProceed with automatic configuration "
                                    "file upgrade?",
                                    default=True)

            if upgrade:
                settings = Settings(old_default_config_file)
                settings.convert_to_4()
                with open(filename, 'w') as config_file:
                    settings.config.write(config_file)
                os.remove(old_default_config_file)
                return
            else:
                print("Ok then.")
                sys.exit(0)

        welcome_msg = "Welcome to Taxi!"
        click.secho(welcome_msg, fg='green', bold=True)
        click.secho('=' * len(welcome_msg) + '\n', fg='green', bold=True)

        click.echo(
            click.wrap_text(
                "It looks like this is the first time you run Taxi. You will need "
                "a configuration file ({}) in order to proceed. Please answer a "
                "few questions to create your configuration file.".format(
                    filename)) + '\n')

        config = pkg_resources.resource_string(
            'taxi', 'etc/taxirc.sample').decode('utf-8')
        context = {}
        available_backends = plugins_registry.get_available_backends()

        context['backend'] = click.prompt(
            "Backend you want to use (choices are %s)" %
            ', '.join(available_backends),
            type=click.Choice(available_backends))
        context['username'] = click.prompt("Username or token")
        context['password'] = parse.quote(click.prompt(
            "Password (leave empty if you're using"
            " a token)",
            hide_input=True,
            default=''),
                                          safe='')
        # Password can be empty in case of token auth so the ':' separator
        # is not included in the template config, so we add it if the user
        # has set a password
        if context['password']:
            context['password'] = '******' + context['password']

        context['hostname'] = click.prompt(
            "Hostname of the backend (eg. timesheets.example.com)",
            type=Hostname())

        editor = Editor().get_editor()
        context['editor'] = click.prompt(
            "Editor command to edit your timesheets", default=editor)

        templated_config = config.format(**context)

        directory = os.path.dirname(filename)
        if not os.path.exists(directory):
            os.makedirs(directory)

        with open(filename, 'w') as f:
            f.write(templated_config)
    else:
        settings = Settings(filename)
        conversions = settings.needed_conversions

        if conversions:
            for conversion in conversions:
                conversion()

            settings.write_config()
示例#38
0
文件: __init__.py 项目: simonbru/taxi
def echo_warning(message):
    echo(
        click.style(click.wrap_text(message, preserve_paragraphs=True),
                    fg='yellow'))
示例#39
0
文件: __init__.py 项目: simonbru/taxi
def echo_success(message):
    echo(
        click.style(click.wrap_text(message, preserve_paragraphs=True),
                    fg='green'))
示例#40
0
文件: cli.py 项目: rowhit/tmuxp
def scan_config(config, config_dir=None):
    """Return the real config path or raise an exception.

    :param config: config file, valid examples:
        - a file name, myconfig.yaml
        - relative path, ../config.yaml or ../project
        - a period, .
    :type config: str

    If config is directory, scan for .tmuxp.{yaml,yml,json} in directory. If
    one or more found, it will warn and pick the first.

    If config is ".", "./" or None, it will scan current directory.

    If config is has no path and only a filename, e.g. "myconfig.yaml" it will
    search config dir.

    If config has no path and only a name with no extension, e.g. "myconfig",
    it will scan for file name with yaml, yml and json. If multiple exist, it
    will warn and pick the first.

    :raises: :class:`click.exceptions.FileError`
    """
    if not config_dir:
        config_dir = get_config_dir()
    path = os.path
    exists, join, isabs = path.exists, path.join, path.isabs
    dirname, normpath, splitext = path.dirname, path.normpath, path.splitext
    cwd = os.getcwd()
    is_name = False
    file_error = None

    config = os.path.expanduser(config)
    # if purename, resolve to confg dir
    if is_pure_name(config):
        is_name = True
    elif (not isabs(config) or len(dirname(config)) > 1 or config == '.'
          or config == "" or config == "./"):  # if relative, fill in full path
        config = normpath(join(cwd, config))

    # no extension, scan
    if not splitext(config)[1]:
        if is_name:
            candidates = [
                x for x in [
                    '%s%s' % (join(config_dir, config), ext)
                    for ext in ['.yaml', '.yml', '.json']
                ] if exists(x)
            ]
            if not len(candidates):
                file_error = (
                    'config not found in config dir (yaml/yml/json) %s '
                    'for name' % (config_dir))
        else:
            candidates = [
                x for x in [
                    join(config, ext)
                    for ext in ['.tmuxp.yaml', '.tmuxp.yml', '.tmuxp.json']
                ] if exists(x)
            ]

            if len(candidates) > 1:
                click.secho('Multiple .tmuxp.{yml,yaml,json} configs in %s' %
                            dirname(config),
                            fg="red")
                click.echo(
                    click.wrap_text(
                        'This is undefined behavior, use only one. '
                        'Use file names e.g. myproject.json, coolproject.yaml. '
                        'You can load them by filename.'))
            elif not len(candidates):
                file_error = 'No tmuxp files found in directory'
        if len(candidates):
            config = candidates[0]
    elif not exists(config):
        file_error = 'file not found'

    if file_error:
        raise FileError(file_error, config)

    return config
示例#41
0
文件: cli.py 项目: jli206/guildai
def _wrap(s):
    terminal_width = click.get_terminal_size()[0]
    width = max(min(terminal_width, 78), 40)
    return click.wrap_text(s, width)
示例#42
0
    print(w)


@main.command()
def topheadlines():
    """ Please enter your choice from the listsources """


newsSource = click.prompt("Please enter your choice from listsources")

main_url = "https://newsapi.org/v2/top-headlines?apiKey=133011acc65c42569875c0252ae5310d=" + newsSource

# fetching data in json format
open_headline = requests.get(main_url).json()

headline = open_headline["articles"]

output = []

for h in headline:
    click.echo('\n')
    click.secho(click.style('TITLE: ' + h['title'], fg='red'))
    click.secho(click.wrap_text(h['description']))
    click.secho(click.style('DOMAIN: ' + h['url'], fg='blue'))

for i in output[:11]:
    print(i)

if __name__ == '__main__':
    main()
示例#43
0
def formatDetails(message: str) -> str:
    """Format text explaining details for display below a main result."""
    return wrap_text(message, initial_indent='  ', subsequent_indent='  ')
示例#44
0
 def wrap(s):
     return wrap_text(s, initial_indent=' '*3,
                      subsequent_indent=' '*4,
                      width=72, preserve_paragraphs=True)
示例#45
0
def generate_oci_config():
    click.echo(click.wrap_text(text=generate_oci_config_instructions, preserve_paragraphs=True))

    config_location, profile_name = prompt_for_config_location()
    if not config_location:
        click.echo(config_generation_canceled_message)
        sys.exit(0)

    user_id = click.prompt('Enter a user OCID', value_proc=lambda ocid: validate_ocid(ocid, config.PATTERNS['user']))
    tenant_id = click.prompt('Enter a tenancy OCID', value_proc=lambda ocid: validate_ocid(ocid, config.PATTERNS['tenancy']))

    region = prompt_for_region()

    if click.confirm("Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to an existing key.)", default=True):
        key_location = os.path.abspath(os.path.expanduser(click.prompt(text='Enter a directory for your keys to be created', default=DEFAULT_DIRECTORY)))
        if not os.path.exists(key_location):
            create_directory(key_location)

        private_key = cli_util.generate_key()
        public_key = private_key.public_key()

        key_name = click.prompt('Enter a name for your key', DEFAULT_KEY_NAME)
        if not write_public_key_to_file(os.path.join(key_location, key_name + PUBLIC_KEY_FILENAME_SUFFIX), public_key):
            click.echo(config_generation_canceled_message)
            return

        key_passphrase = click.prompt(text='Enter a passphrase for your private key (empty for no passphrase)', default='', hide_input=True, show_default=False, confirmation_prompt=True)
        private_key_file = os.path.join(key_location, key_name + PRIVATE_KEY_FILENAME_SUFFIX)
        if not write_private_key_to_file(private_key_file, private_key, key_passphrase):
            click.echo(config_generation_canceled_message)
            return

        fingerprint = public_key_to_fingerprint(public_key)
        click.echo("Fingerprint: {}".format(fingerprint))
    else:
        private_key_file, has_passphrase, private_key = click.prompt(text='Enter the location of your API Signing private key file', value_proc=validate_private_key_file)
        private_key_file = os.path.abspath(private_key_file)

        key_passphrase = None
        if has_passphrase:
            key_passphrase, private_key = click.prompt(text='Enter the passphrase for your private key', hide_input=True, value_proc=lambda passphrase: validate_private_key_passphrase(private_key_file, passphrase))

        fingerprint = public_key_to_fingerprint(private_key.public_key())
        click.echo("Fingerprint: {}".format(fingerprint))

    if key_passphrase and not click.confirm('Do you want to write your passphrase to the config file? (If not, you will need to enter it when prompted each time you run an oci command)', default=False):
        key_passphrase = None

    write_config(
        config_location,
        user_id,
        fingerprint,
        private_key_file,
        tenant_id,
        region,
        pass_phrase=key_passphrase,
        profile_name=profile_name
    )

    click.echo('Config written to {}'.format(config_location))
    click.echo(click.wrap_text(upload_public_key_instructions, preserve_paragraphs=True))
示例#46
0
文件: setup.py 项目: javfg/indico
def _warn(msg):
    msg = wrap_text(msg)
    click.echo(click.style(msg, fg='yellow'), err=True)
示例#47
0
def create_config_file(filename):
    """
    Create main configuration file if it doesn't exist.
    """
    import textwrap
    from six.moves.urllib import parse

    if not os.path.exists(filename):
        old_default_config_file = os.path.join(os.path.dirname(filename),
                                               '.tksrc')
        if os.path.exists(old_default_config_file):
            upgrade = click.confirm("\n".join(textwrap.wrap(
                "It looks like you recently updated Taxi. Some "
                "configuration changes are required. You can either let "
                "me upgrade your configuration file or do it "
                "manually.")) + "\n\nProceed with automatic configuration "
                "file upgrade?", default=True
            )

            if upgrade:
                settings = Settings(old_default_config_file)
                settings.convert_to_4()
                with open(filename, 'w') as config_file:
                    settings.config.write(config_file)
                os.remove(old_default_config_file)
                return
            else:
                print("Ok then.")
                sys.exit(0)

        welcome_msg = "Welcome to Taxi!"
        click.secho(welcome_msg, fg='green', bold=True)
        click.secho('=' * len(welcome_msg) + '\n', fg='green', bold=True)

        click.echo(click.wrap_text(
            "It looks like this is the first time you run Taxi. You will need "
            "a configuration file ({}) in order to proceed. Please answer a "
            "few questions to create your configuration file.".format(
                filename
            )
        ) + '\n')

        config = resource_string('taxi',
                                 'etc/taxirc.sample').decode('utf-8')
        context = {}
        available_backends = backends_registry._entry_points.keys()

        context['backend'] = click.prompt(
            "Backend you want to use (choices are %s)" %
            ', '.join(available_backends),
            type=click.Choice(available_backends)
        )
        context['username'] = click.prompt("Username or token")
        context['password'] = parse.quote(
            click.prompt("Password (leave empty if you're using"
                         " a token)", hide_input=True, default=''),
            safe=''
        )
        # Password can be empty in case of token auth so the ':' separator
        # is not included in the template config, so we add it if the user
        # has set a password
        if context['password']:
            context['password'] = '******' + context['password']

        context['hostname'] = click.prompt(
            "Hostname of the backend (eg. timesheets.example.com)",
            type=Hostname()
        )

        editor = Editor().get_editor()
        context['editor'] = click.prompt(
            "Editor command to edit your timesheets", default=editor
        )

        templated_config = config.format(**context)

        directory = os.path.dirname(filename)
        if not os.path.exists(directory):
            os.makedirs(directory)

        with open(filename, 'w') as f:
            f.write(templated_config)
    else:
        settings = Settings(filename)
        conversions = settings.needed_conversions

        if conversions:
            for conversion in conversions:
                conversion()

            settings.write_config()
示例#48
0
def setup_instance_principal(ctx):
    click.echo(click.wrap_text(text=instance_principal_setup_instructions, preserve_paragraphs=True))

    # get the private key passphrase (applicable for api key pair and session token auth), and if the passphrase is not None, then return it each time the passphrase is requested during this script
    passphrase = None
    if ctx.obj['auth'] == OCI_CLI_AUTH_API_KEY or ctx.obj['auth'] == OCI_CLI_AUTH_SESSION_TOKEN:
        passphrase = get_passphrase(ctx)
    if passphrase:
        def passphrase_provider():
            return passphrase
        cli_util.prompt_for_passphrase = passphrase_provider

    # build necessary client objects; these functions also handle authentication
    compute_client = cli_util.build_client('core', 'compute', ctx)
    identity_client = cli_util.build_client('identity', 'identity', ctx)

    # build the config object (applicable for auth types other than instance principal or resource principal)
    config_obj = None
    if ctx.obj['auth'] != OCI_CLI_AUTH_INSTANCE_PRINCIPAL and ctx.obj['auth'] != OCI_CLI_AUTH_RESOURCE_PRINCIPAL:
        config_obj = cli_util.build_config(ctx.obj)

    if not click.confirm('Do you have an existing compute instance for which you would like to set up instance principal authentication?', default=True):
        click.echo('Please create a compute instance and then run this command again. For information regarding how to create a compute instance, please visit https://docs.oracle.com/en-us/iaas/Content/GSG/Reference/overviewworkflow.htm')
        sys.exit(1)

    # get the instance OCID and the name of the compartment that the instance is in
    instance_ocid, result = get_resource('instance', compute_client.get_instance)
    instance_compartment_ocid = result.data.compartment_id
    result = identity_client.get_compartment(instance_compartment_ocid)
    instance_compartment_name = result.data.name

    if click.confirm('Do you want to add this instance to an existing dynamic group?', default=False):
        # get dynamic group OCID and update its matching rules
        group_ocid, result = get_resource('dynamic group', identity_client.get_dynamic_group)
        group_name = result.data.name
        click.echo('For information about dynamic group matching rule syntax, please visit https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm#Writing')
        current_rule = result.data.matching_rule
        if instance_ocid in current_rule:
            default_group_rule = current_rule
        elif '{' in current_rule:
            default_group_rule = "Any " + current_rule[current_rule.index('{'):current_rule.rindex('}')] + ", instance.id = '{}'}}".format(instance_ocid)
        else:
            default_group_rule = "Any {" + current_rule + ", instance.id = '{}'}}".format(instance_ocid)
        group_rule = click.prompt('Enter the matching rule(s) you would like to set for this dynamic group', default=default_group_rule)
        ctx.invoke(identity_cli.update_dynamic_group, wait_for_state='ACTIVE', dynamic_group_id=group_ocid, matching_rule=group_rule)

        # check if the user wants to create/update a policy for this group
        if click.confirm('Do you want to create a new policy for this group?', default=False):
            new_policy = True
        else:
            new_policy = False

        if (not new_policy) and click.confirm('Do you want to update a policy for this group?', default=False):
            policy_ocid, result = get_resource('policy', identity_client.get_policy)
            click.echo('For information about policy syntax, please visit https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/policysyntax.htm')
            default_policy_statement = json.dumps(result.data.statements)
            policy_statement = click.prompt('Enter the statement(s) you would like to set for this policy (please enter your statements in JSON format, as a bracket-enclosed list of strings)', default=default_policy_statement, value_proc=lambda statements: validate_statements(statements))
            ctx.invoke(identity_cli.update_policy, wait_for_state='ACTIVE', policy_id=policy_ocid, statements=policy_statement)
    else:
        # create dynamic group and add this instance to the group using a matching rule
        if config_obj:
            tenancy_ocid = config_obj['tenancy']
        else:
            tenancy_ocid, result = get_resource('tenancy', identity_client.get_tenancy)
        group_name = click.prompt('Enter a name for your new dynamic group', value_proc=lambda name: validate_resource_name(name))
        group_description = click.prompt('Enter a description for your new dynamic group')
        click.echo('For information about dynamic group matching rule syntax, please visit https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm#Writing')
        default_group_rule = "Any {{instance.id = '{}'}}".format(instance_ocid)
        group_rule = click.prompt('Enter the matching rule(s) you would like to set for this dynamic group', default=default_group_rule)
        ctx.invoke(identity_cli.create_dynamic_group, wait_for_state='ACTIVE', compartment_id=tenancy_ocid, name=group_name, matching_rule=group_rule, description=group_description)

        # since this is a new group that won't have an existing policy, have the user go through policy creation flow
        new_policy = True

    if new_policy:
        # create policy for the new dynamic group
        policy_name = click.prompt('Enter a name for the new policy to be used for your new dynamic group', value_proc=lambda name: validate_resource_name(name))
        policy_description = click.prompt('Enter a description for the new policy to be used for your new dynamic group')
        click.echo('WARNING: Using the default policy at the prompt below will grant all permissions for all your OCI resources to every instance in the dynamic group. Please ensure that this is the policy you want to use. If not, you can enter your custom policy statement(s) at the prompt.')
        click.echo('For information about policy syntax, please visit https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/policysyntax.htm')
        default_policy_statement = '["Allow dynamic-group {} to manage all-resources in compartment {}"]'.format(group_name, instance_compartment_name)
        policy_statement = click.prompt('Enter the statement(s) you would like to set for this policy (please enter your statements in JSON format, as a bracket-enclosed list of strings)', default=default_policy_statement, value_proc=lambda statements: validate_statements(statements))
        policy_compartment_ocid = instance_compartment_ocid
        if click.confirm('This policy is currently set to be put in compartment {}, which is the compartment that your instance is in. Do you want to create this policy in a different compartment?'.format(instance_compartment_name), default=False):
            policy_compartment_ocid, result = get_resource('compartment', identity_client.get_compartment)
        ctx.invoke(identity_cli.create_policy, wait_for_state='ACTIVE', compartment_id=policy_compartment_ocid, name=policy_name, statements=policy_statement, description=policy_description)

    click.echo('Successfully set up instance principal authentication for your instance!')
    click.echo(click.wrap_text(text=instance_principal_setup_end_message.format(compartment_id=instance_compartment_ocid, auth=OCI_CLI_AUTH_INSTANCE_PRINCIPAL), preserve_paragraphs=True))