Example #1
0
def do_resource_signal(hc, args):
    '''Send a signal to a resource.'''
    fields = {'stack_id': args.id, 'resource_name': args.resource}
    data = args.data
    data_file = args.data_file
    if data and data_file:
        raise exc.CommandError('Can only specify one of data and data-file')
    if data_file:
        data_url = template_utils.normalise_file_path_to_url(data_file)
        data = request.urlopen(data_url).read()
    if data:
        if isinstance(data, six.binary_type):
            data = data.decode('utf-8')
        try:
            data = jsonutils.loads(data)
        except ValueError as ex:
            raise exc.CommandError('Data should be in JSON format: %s' % ex)
        if not isinstance(data, dict):
            raise exc.CommandError('Data should be a JSON dict')
        fields['data'] = data
    try:
        hc.resources.signal(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack or resource not found: %s %s' %
                               (args.id, args.resource))
def get_template_contents(template_file=None,
                          template_url=None,
                          template_object=None,
                          object_request=None,
                          files=None,
                          existing=False,
                          fetch_child=True):

    is_object = False
    # Transform a bare file path to a file:// URL.
    if template_file:
        template_url = utils.normalise_file_path_to_url(template_file)

    if template_url:
        tpl = request.urlopen(template_url).read()

    elif template_object:
        is_object = True
        template_url = template_object
        tpl = object_request and object_request('GET', template_object)
    elif existing:
        return {}, None
    else:
        raise exc.CommandError(
            _('Need to specify exactly one of '
              '[%(arg1)s, %(arg2)s or %(arg3)s]'
              ' or %(arg4)s') % {
                  'arg1': '--template-file',
                  'arg2': '--template-url',
                  'arg3': '--template-object',
                  'arg4': '--existing'
              })

    if not tpl:
        raise exc.CommandError(
            _('Could not fetch template from %s') % template_url)

    try:
        if isinstance(tpl, six.binary_type):
            tpl = tpl.decode('utf-8')
        template = template_format.parse(tpl)
    except ValueError as e:
        raise exc.CommandError(
            _('Error parsing template %(url)s %(error)s') % {
                'url': template_url,
                'error': e
            })
    if files is None:
        files = {}

    if fetch_child:
        tmpl_base_url = utils.base_url_for_url(template_url)
        resolve_template_get_files(template, files, tmpl_base_url, is_object,
                                   object_request)
    return files, template
Example #3
0
    def _get_keystone_auth(self, session, auth_url, **kwargs):
        """
        Figure out whether to use v2 or v3 of the Keystone API, and return the auth
        object.

        This function is based, with minor changes, on the official OpenStack Heat
        client's shell implementation.  Specifically,
        python-heatclient/heatclient/shell.py.
        """
        v2_auth_url = None
        v3_auth_url = None
        try:
            ks_discover = discover.Discover(session=session, auth_url=auth_url)
            v2_auth_url = ks_discover.url_for('2.0')
            v3_auth_url = ks_discover.url_for('3.0')
        except ks_exc.ClientException:
            # If discovery is not supported, parse version out of the auth URL.
            url_parts = urlparse.urlparse(auth_url)
            (scheme, netloc, path, params, query, fragment) = url_parts
            path = path.lower()
            if path.startswith('/v3'):
                v3_auth_url = auth_url
            elif path.startswith('/v2'):
                v2_auth_url = auth_url
            else:
                raise heat_exc.CommandError(
                    'Unable to determine Keystone version.')

        auth = None
        if v3_auth_url and v2_auth_url:
            # Both v2 and v3 are supported. Use v3 only if domain information is
            # provided.
            user_domain_name = kwargs.get('user_domain_name', None)
            user_domain_id = kwargs.get('user_domain_id', None)
            project_domain_name = kwargs.get('project_domain_name', None)
            project_domain_id = kwargs.get('project_domain_id', None)

            if (user_domain_name or user_domain_id or project_domain_name
                    or project_domain_id):
                auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
            else:
                auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
        elif v3_auth_url:
            auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
        elif v2_auth_url:
            auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
        else:
            raise heat_exc.CommandError(
                'Unable to determine Keystone version.')

        return auth
Example #4
0
def do_stack_adopt(hc, args):
    '''Adopt a stack.'''
    env_files, env = template_utils.process_environment_and_files(
        env_path=args.environment_file)

    if not args.adopt_file:
        raise exc.CommandError('Need to specify --adopt-file')

    adopt_url = template_utils.normalise_file_path_to_url(args.adopt_file)
    adopt_data = request.urlopen(adopt_url).read()

    if args.create_timeout:
        logger.warning('-c/--create-timeout is deprecated, '
                       'please use -t/--timeout instead')

    fields = {
        'stack_name': args.name,
        'disable_rollback': not (args.enable_rollback),
        'adopt_stack_data': adopt_data,
        'parameters': utils.format_parameters(args.parameters),
        'files': dict(list(env_files.items())),
        'environment': env
    }

    timeout = args.timeout or args.create_timeout
    if timeout:
        fields['timeout_mins'] = timeout

    hc.stacks.create(**fields)
    do_stack_list(hc)
Example #5
0
def do_event_list(hc, args):
    '''List events for a stack.'''
    fields = {
        'stack_id': args.id,
        'resource_name': args.resource,
        'limit': args.limit,
        'marker': args.marker,
        'filters': utils.format_parameters(args.filters)
    }
    try:
        events = hc.events.list(**fields)
    except exc.HTTPNotFound as ex:
        # it could be the stack or resource that is not found
        # just use the message that the server sent us.
        raise exc.CommandError(str(ex))
    else:
        fields = [
            'id', 'resource_status_reason', 'resource_status', 'event_time'
        ]
        if len(events) >= 1:
            if hasattr(events[0], 'resource_name'):
                fields.insert(0, 'resource_name')
            else:
                fields.insert(0, 'logical_resource_id')
        utils.print_list(events, fields, sortby_index=None)
Example #6
0
def _discover_auth_versions(session, auth_url):
    # discover the API versions the server is supporting base on the
    # given URL
    v2_auth_url = None
    v3_auth_url = None
    try:
        ks_discover = discover.Discover(session=session, auth_url=auth_url)
        v2_auth_url = ks_discover.url_for('2.0')
        v3_auth_url = ks_discover.url_for('3.0')
    except ks_exc.ClientException:
        # Identity service may not support discover API version.
        # Lets trying to figure out the API version from the original URL.
        path = urlparse.urlparse(auth_url).path
        path = path.lower()
        if path.startswith('/v3'):
            v3_auth_url = auth_url
        elif path.startswith('/v2'):
            v2_auth_url = auth_url
        else:
            # not enough information to determine the auth version
            msg = ('Unable to determine the Keystone version '
                   'to authenticate with using the given '
                   'auth_url. Identity service may not support API '
                   'version discovery. Please provide a versioned '
                   'auth_url instead.')
            raise exc.CommandError(msg)

    return v2_auth_url, v3_auth_url
Example #7
0
def _get_keystone_auth(session, auth_url, **kwargs):
    # discover the supported keystone versions using the given url
    (v2_auth_url, v3_auth_url) = _discover_auth_versions(session=session,
                                                         auth_url=auth_url)

    # Determine which authentication plugin to use. First inspect the
    # auth_url to see the supported version. If both v3 and v2 are
    # supported, then use the highest version if possible.
    auth = None
    if v3_auth_url and v2_auth_url:
        user_domain_name = kwargs.get('user_domain_name', None)
        user_domain_id = kwargs.get('user_domain_id', None)
        project_domain_name = kwargs.get('project_domain_name', None)
        project_domain_id = kwargs.get('project_domain_id', None)

        # support both v2 and v3 auth. Use v3 if domain information is
        # provided.
        if (user_domain_name or user_domain_id or project_domain_name
                or project_domain_id):
            auth = _get_keystone_v3_auth(v3_auth_url, **kwargs)
        else:
            auth = _get_keystone_v2_auth(v2_auth_url, **kwargs)
    elif v3_auth_url:
        # support only v3
        auth = _get_keystone_v3_auth(v3_auth_url, **kwargs)
    elif v2_auth_url:
        # support only v2
        auth = _get_keystone_v2_auth(v2_auth_url, **kwargs)
    else:
        raise exc.CommandError('Unable to determine the Keystone version '
                               'to authenticate with using the given '
                               'auth_url.')

    return auth
Example #8
0
def format_parameters(params, parse_semicolon=True):
    '''Reformat parameters into dict of format expected by the API.'''

    if not params:
        return {}

    if parse_semicolon:
        # expect multiple invocations of --parameters but fall back
        # to ; delimited if only one --parameters is specified
        if len(params) == 1:
            params = params[0].split(';')

    parameters = {}
    for p in params:
        try:
            (n, v) = p.split(('='), 1)
        except ValueError:
            msg = _('Malformed parameter(%s). Use the key=value format.') % p
            raise exc.CommandError(msg)

        if n not in parameters:
            parameters[n] = v
        else:
            if not isinstance(parameters[n], list):
                parameters[n] = [parameters[n]]
            parameters[n].append(v)

    return parameters
Example #9
0
    def take_action(self, parsed_args):
        self.log.debug('take_action(%s)', parsed_args)

        client = self.app.client_manager.orchestration

        fields = {
            'stack_id': parsed_args.stack,
            'resource_name': parsed_args.resource,
            'event_id': parsed_args.event
        }

        try:
            client.stacks.get(parsed_args.stack)
            client.resources.get(parsed_args.stack, parsed_args.resource)
            event = client.events.get(**fields)
        except exc.HTTPNotFound as ex:
            raise exc.CommandError(str(ex))

        formatters = {
            'links': heat_utils.link_formatter,
            'resource_properties': heat_utils.json_formatter
        }

        columns = []
        for key in event.to_dict():
            columns.append(key)

        return columns, utils.get_item_properties(event, columns,
                                                  formatters=formatters)
Example #10
0
def find_resource(manager, name_or_id):
    """Helper for the _find_* methods."""
    # first try to get entity as integer id
    try:
        if isinstance(name_or_id, int) or name_or_id.isdigit():
            return manager.get(int(name_or_id))
    except exc.NotFound:
        pass

    # now try to get entity as uuid
    try:
        uuid.UUID(str(name_or_id))
        return manager.get(name_or_id)
    except (ValueError, exc.NotFound):
        pass

    # finally try to find entity by name
    try:
        return manager.find(name=name_or_id)
    except exc.NotFound:
        msg = _("No %(name)s with a name or ID of "
                "'%(name_or_id)s' exists.") % \
            {
                'name': manager.resource_class.__name__.lower(),
                'name_or_id': name_or_id
            }
        raise exc.CommandError(msg)
Example #11
0
def do_stack_cancel_update(hc, args):
    '''Cancel currently running update of the stack.'''
    fields = {'stack_id': args.id}
    try:
        hc.actions.cancel_update(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        do_stack_list(hc)
Example #12
0
def do_action_check(hc, args):
    '''Check that stack resources are in expected states.'''
    fields = {'stack_id': args.id}
    try:
        hc.actions.check(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        do_stack_list(hc)
Example #13
0
def do_action_resume(hc, args):
    '''Resume the stack.'''
    fields = {'stack_id': args.id}
    try:
        hc.actions.resume(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        do_stack_list(hc)
Example #14
0
def do_stack_abandon(hc, args):
    '''Abandon the stack.'''
    fields = {'stack_id': args.id}
    try:
        stack = hc.stacks.abandon(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        print(jsonutils.dumps(stack, indent=2))
Example #15
0
def do_resource_type_show(hc, args):
    '''Show the resource type.'''
    try:
        resource_type = hc.resource_types.get(args.resource_type)
    except exc.HTTPNotFound:
        raise exc.CommandError('Resource Type not found: %s' %
                               args.resource_type)
    else:
        print(jsonutils.dumps(resource_type, indent=2))
Example #16
0
def do_resource_metadata(hc, args):
    '''List resource metadata.'''
    fields = {'stack_id': args.id, 'resource_name': args.resource}
    try:
        metadata = hc.resources.metadata(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack or resource not found: %s %s' %
                               (args.id, args.resource))
    else:
        print(jsonutils.dumps(metadata, indent=2))
Example #17
0
 def do_help(self, args):
     """Display help about this program or one of its subcommands."""
     if getattr(args, 'command', None):
         if args.command in self.subcommands:
             self.subcommands[args.command].print_help()
         else:
             raise exc.CommandError("'%s' is not a valid subcommand" %
                                    args.command)
     else:
         self.parser.print_help()
Example #18
0
def do_output_show(hc, args):
    '''Show a specific stack output.'''
    try:
        stack = hc.stacks.get(stack_id=args.id)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        for output in stack.to_dict().get('outputs', []):
            if output['output_key'] == args.output:
                if 'output_error' in output:
                    msg = "Error: %s" % output['output_error']
                    raise exc.CommandError(msg)
                else:
                    value = output['output_value']
                break
        else:
            return

        print(jsonutils.dumps(value, indent=2, ensure_ascii=False))
Example #19
0
def _get_nested_ids(hc, stack_id):
    nested_ids = []
    try:
        resources = hc.resources.list(stack_id=stack_id)
    except exc.HTTPNotFound:
        raise exc.CommandError(_('Stack not found: %s') % stack_id)
    for r in resources:
        nested_id = utils.resource_nested_identifier(r)
        if nested_id:
            nested_ids.append(nested_id)
    return nested_ids
Example #20
0
def read_url_content(url):
    try:
        content = request.urlopen(url).read()
    except error.URLError:
        raise exc.CommandError('Could not fetch contents for %s' % url)
    if content:
        try:
            content.decode('utf-8')
        except ValueError:
            content = base64.encodestring(content)
    return content
Example #21
0
def get_hook_type_via_status(hc, stack_id):
    # Figure out if the hook should be pre-create or pre-update based
    # on the stack status, also sanity assertions that we're in-progress.
    try:
        stack = hc.stacks.get(stack_id=stack_id)
    except exc.HTTPNotFound:
        raise exc.CommandError(_('Stack not found: %s') % stack_id)
    else:
        if 'IN_PROGRESS' not in stack.stack_status:
            raise exc.CommandError(
                _('Stack status %s not IN_PROGRESS') % stack.stack_status)

    if 'CREATE' in stack.stack_status:
        hook_type = 'pre-create'
    elif 'UPDATE' in stack.stack_status:
        hook_type = 'pre-update'
    else:
        raise exc.CommandError(
            _('Unexpected stack status %s, '
              'only create/update supported') % stack.stack_status)
    return hook_type
Example #22
0
def do_resource_template(hc, args):
    '''Generate a template based on a resource.'''
    fields = {'resource_name': args.resource}
    try:
        template = hc.resources.generate_template(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Resource %s not found.' % args.resource)
    else:
        if args.format:
            print(utils.format_output(template, format=args.format))
        else:
            print(utils.format_output(template))
Example #23
0
def build_signal_id(hc, args):
    if args.signal_transport != 'TEMP_URL_SIGNAL':
        return

    if args.os_no_client_auth:
        raise exc.CommandError(
            _('Cannot use --os-no-client-auth, auth required to create '
              'a Swift TempURL.'))
    swift_client = create_swift_client(hc.http_client.auth,
                                       hc.http_client.session, args)

    return create_temp_url(swift_client, args.name, args.timeout)
Example #24
0
def do_template_show(hc, args):
    '''Get the template for the specified stack.'''
    fields = {'stack_id': args.id}
    try:
        template = hc.stacks.template(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        if 'heat_template_version' in template:
            print(yaml.safe_dump(template, indent=2))
        else:
            print(jsonutils.dumps(template, indent=2, ensure_ascii=False))
Example #25
0
def get_template_contents(template_file=None,
                          template_url=None,
                          template_object=None,
                          object_request=None,
                          files=None):

    # Transform a bare file path to a file:// URL.
    if template_file:
        template_url = normalise_file_path_to_url(template_file)

    if template_url:
        tpl = request.urlopen(template_url).read()

    elif template_object:
        template_url = template_object
        tpl = object_request and object_request('GET', template_object)
    else:
        raise exc.CommandError('Need to specify exactly one of '
                               '--template-file, --template-url '
                               'or --template-object')

    if not tpl:
        raise exc.CommandError('Could not fetch template from %s' %
                               template_url)

    try:
        if isinstance(tpl, six.binary_type):
            tpl = tpl.decode('utf-8')
        template = template_format.parse(tpl)
    except ValueError as e:
        raise exc.CommandError('Error parsing template %s %s' %
                               (template_url, e))

    tmpl_base_url = base_url_for_url(template_url)
    if files is None:
        files = {}
    resolve_template_get_files(template, files, tmpl_base_url)
    resolve_template_type(template, files, tmpl_base_url)
    return files, template
def _get_stack_events(hc, stack_id, event_args):
    event_args['stack_id'] = stack_id
    try:
        events = hc.events.list(**event_args)
    except exc.HTTPNotFound as ex:
        # it could be the stack or resource that is not found
        # just use the message that the server sent us.
        raise exc.CommandError(str(ex))
    else:
        # Show which stack the event comes from (for nested events)
        for e in events:
            e.stack_name = stack_id.split("/")[0]
        return events
Example #27
0
def do_stack_abandon(hc, args):
    '''Abandon the stack.

    This will delete the record of the stack from Heat, but will not delete
    any of the underlying resources. Prints an adoptable JSON representation
    of the stack to stdout on success.
    '''
    fields = {'stack_id': args.id}
    try:
        stack = hc.stacks.abandon(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        print(jsonutils.dumps(stack, indent=2))
Example #28
0
def _get_stack_events(h_client, stack_id, event_args):
    '''
    Get event for stack
    '''
    event_args['stack_id'] = stack_id
    event_args['resource_name'] = None
    try:
        events = h_client.events.list(**event_args)
    except exc.HTTPNotFound as ex:
        raise exc.CommandError(str(ex))
    else:
        for event in events:
            event.stack_name = stack_id.split('/')[0]
        return events
Example #29
0
def do_stack_abandon(hc, args):
    '''Abandon the stack.

    This will delete the record of the stack from Heat, but will not delete
    any of the underlying resources. Prints an adoptable JSON representation
    of the stack to stdout or a file on success.
    '''
    fields = {'stack_id': args.id}
    try:
        stack = hc.stacks.abandon(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack not found: %s' % args.id)
    else:
        result = jsonutils.dumps(stack, indent=2)
        if args.output_file is not None:
            try:
                with open(args.output_file, "w") as f:
                    f.write(result)
            except IOError as err:
                print(result)
                raise exc.CommandError(str(err))
        else:
            print(result)
Example #30
0
def do_resource_show(hc, args):
    '''Describe the resource.'''
    fields = {'stack_id': args.id, 'resource_name': args.resource}
    try:
        resource = hc.resources.get(**fields)
    except exc.HTTPNotFound:
        raise exc.CommandError('Stack or resource not found: %s %s' %
                               (args.id, args.resource))
    else:
        formatters = {
            'links': utils.link_formatter,
            'required_by': utils.newline_list_formatter
        }
        utils.print_dict(resource.to_dict(), formatters=formatters)