示例#1
0
def get_template_contents(template_file=None,
                          template_url=None,
                          template_object=None,
                          object_request=None,
                          files=None,
                          existing=False):

    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') % {
                  'arg1': '--template-file',
                  'arg2': '--template-url',
                  'arg3': '--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 %(url)s %(error)s') % {
                'url': template_url,
                'error': e
            })

    tmpl_base_url = utils.base_url_for_url(template_url)
    if files is None:
        files = {}
    resolve_template_get_files(template, files, tmpl_base_url, is_object,
                               object_request)
    return files, template
示例#2
0
    def _discover_auth_versions(self, 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.
            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:
                # 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)
示例#3
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)
示例#4
0
文件: utils.py 项目: nttcom/eclcli
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)
示例#5
0
文件: utils.py 项目: nttcom/eclcli
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
示例#6
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()
示例#7
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
示例#8
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
示例#9
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)
示例#10
0
文件: utils.py 项目: nttcom/eclcli
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
示例#11
0
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
示例#12
0
    def take_action(self, parsed_args):
        self.log.debug('take_action(%s)', parsed_args)

        client = self.app.client_manager.orchestration

        version = parsed_args.template_version
        try:
            functions = client.template_versions.get(version)
        except exc.HTTPNotFound:
            msg = _('Template version not found: %s') % version
            raise exc.CommandError(msg)

        fields = ['functions', 'description']
        return (fields, (utils.get_item_properties(s, fields)
                         for s in functions))
示例#13
0
def get_hook_events(hc,
                    stack_id,
                    event_args,
                    nested_depth=0,
                    hook_type='pre-create'):
    if hook_type == 'pre-create':
        stack_action_reason = 'Stack CREATE started'
        hook_event_reason = 'CREATE paused until Hook pre-create is cleared'
        hook_clear_event_reason = 'Hook pre-create is cleared'
    elif hook_type == 'pre-update':
        stack_action_reason = 'Stack UPDATE started'
        hook_event_reason = 'UPDATE paused until Hook pre-update is cleared'
        hook_clear_event_reason = 'Hook pre-update is cleared'
    else:
        raise exc.CommandError(_('Unexpected hook type %s') % hook_type)

    events = get_events(hc,
                        stack_id=stack_id,
                        event_args=event_args,
                        nested_depth=nested_depth)

    # Get the most recent event associated with this action, which gives us the
    # event when we moved into IN_PROGRESS for the hooks we're interested in.
    stack_name = stack_id.split("/")[0]
    action_start_event = [
        e for e in enumerate(events)
        if e[1].resource_status_reason == stack_action_reason
        and e[1].stack_name == stack_name
    ][-1]
    # Slice the events with the index from the enumerate
    action_start_index = action_start_event[0]
    events = events[action_start_index:]

    # Get hook events still pending by some list filtering/comparison
    # We build a map hook events per-resource, and remove any event
    # for which there is a corresponding hook-clear event.
    resource_event_map = {}
    for e in events:
        stack_resource = (e.stack_name, e.resource_name)
        if e.resource_status_reason == hook_event_reason:
            resource_event_map[(e.stack_name, e.resource_name)] = e
        elif e.resource_status_reason == hook_clear_event_reason:
            if resource_event_map.get(stack_resource):
                del (resource_event_map[(e.stack_name, e.resource_name)])
    return list(resource_event_map.values())
示例#14
0
    def _get_keystone_auth(self, session, auth_url, **kwargs):
        # FIXME(dhu): this code should come from keystoneclient

        # discover the supported keystone versions using the given url
        (v2_auth_url,
         v3_auth_url) = self._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 = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
            else:
                auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
        elif v3_auth_url:
            # support only v3
            auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
        elif v2_auth_url:
            # support only v2
            auth = self._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
示例#15
0
    def take_action(self, parsed_args):
        self.log.debug('take_action(%s)', parsed_args)

        client = self.app.client_manager.orchestration

        columns = [
            'id', 'resource_status', 'resource_status_reason', 'event_time',
            'physical_resource_id'
        ]

        kwargs = {
            'resource_name': parsed_args.resource,
            'limit': parsed_args.limit,
            'marker': parsed_args.marker,
            # 'filters': heat_utils.format_parameters(parsed_args.filter),
            'sort_dir': 'asc'
        }

        # if parsed_args.resource and parsed_args.nested_depth:
        #     msg = _('--nested-depth cannot be specified with --resource')
        #     raise exc.CommandError(msg)

        # if parsed_args.nested_depth:
        #     # Until the API supports recursive event listing we'll have to do
        #     # the marker/limit filtering client-side
        #     del kwargs['marker']
        #     del kwargs['limit']
        #     columns.append('stack_name')
        #     # nested_depth = parsed_args.nested_depth
        # else:
        #     nested_depth = 0

        if parsed_args.follow:
            if parsed_args.formatter != 'value':
                msg = _('--follow can only be specified with --format value')
                raise exc.CommandError(msg)

            marker = parsed_args.marker
            try:
                while True:
                    kwargs['marker'] = marker
                    events = event_utils.get_events(
                        client,
                        stack_id=parsed_args.stack,
                        event_args=kwargs,
                        # nested_depth=nested_depth,
                        nested_depth=0,
                        marker=marker)
                    if events:
                        marker = getattr(events[-1], 'id', None)
                        events_log = heat_utils.event_log_formatter(events)
                        self.app.stdout.write(events_log)
                        self.app.stdout.write('\n')
                    time.sleep(5)
                    # this loop never exits
            except (KeyboardInterrupt, EOFError):  # ctrl-c, ctrl-d
                return [], []

        events = event_utils.get_events(
            client,
            stack_id=parsed_args.stack,
            event_args=kwargs,
            # nested_depth=nested_depth,
            nested_depth=0,
            marker=parsed_args.marker,
            limit=parsed_args.limit)

        if parsed_args.sort:
            events = utils.sort_items(events, ','.join(parsed_args.sort))

        if parsed_args.formatter == 'value':
            events = heat_utils.event_log_formatter(events).split('\n')
            return [], [e.split(' ') for e in events]

        if len(events):
            if hasattr(events[0], 'resource_name'):
                columns.insert(0, 'resource_name')
                columns.append('logical_resource_id')
            else:
                columns.insert(0, 'logical_resource_id')

        return (columns, (utils.get_item_properties(s, columns)
                          for s in events))
示例#16
0
    def main(self, argv):
        # Parse args once to find version
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)
        self._setup_logging(options.debug)
        self._setup_verbose(options.verbose)

        # build available subcommands based on version
        api_version = options.heat_api_version
        subcommand_parser = self.get_subcommand_parser(api_version)
        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if not args and options.help or not argv:
            self.do_help(options)
            return 0

        # Parse args again and call whatever callback was selected
        args = subcommand_parser.parse_args(argv)

        # Short-circuit and deal with help command right away.
        if args.func == self.do_help:
            self.do_help(args)
            return 0
        elif args.func == self.do_bash_completion:
            self.do_bash_completion(args)
            return 0

        if not args.os_username and not args.os_auth_token:
            raise exc.CommandError(_("You must provide a username via either "
                                     "--os-username or env[OS_USERNAME] "
                                     "or a token via --os-auth-token or "
                                     "env[OS_AUTH_TOKEN]"))

        if not args.os_password and not args.os_auth_token:
            raise exc.CommandError(_("You must provide a password via either "
                                     "--os-password or env[OS_PASSWORD] "
                                     "or a token via --os-auth-token or "
                                     "env[OS_AUTH_TOKEN]"))

        if args.os_no_client_auth:
            if not args.heat_url:
                raise exc.CommandError(_("If you specify --os-no-client-auth "
                                         "you must also specify a Heat API "
                                         "URL via either --heat-url or "
                                         "env[HEAT_URL]"))
        else:
            # Tenant/project name or ID is needed to make keystoneclient
            # retrieve a service catalog, it's not required if
            # os_no_client_auth is specified, neither is the auth URL

            if not (args.os_tenant_id or args.os_tenant_name or
                    args.os_project_id or args.os_project_name):
                raise exc.CommandError(
                    _("You must provide a tenant id via either "
                      "--os-tenant-id or env[OS_TENANT_ID] or a tenant name "
                      "via either --os-tenant-name or env[OS_TENANT_NAME] "
                      "or a project id via either --os-project-id or "
                      "env[OS_PROJECT_ID] or a project name via "
                      "either --os-project-name or env[OS_PROJECT_NAME]"))

            if not args.os_auth_url:
                raise exc.CommandError(_("You must provide an auth url via "
                                         "either --os-auth-url or via "
                                         "env[OS_AUTH_URL]"))

        kwargs = {
            'insecure': args.insecure,
            'cacert': args.os_cacert,
            'cert': args.os_cert,
            'key': args.os_key,
            'timeout': args.api_timeout
        }

        endpoint = args.heat_url
        service_type = args.os_service_type or 'orchestration'
        if args.os_no_client_auth:
            # Do not use session since no_client_auth means using heat to
            # to authenticate
            kwargs = {
                'username': args.os_username,
                'password': args.os_password,
                'auth_url': args.os_auth_url,
                'token': args.os_auth_token,
                'include_pass': args.include_password,
                'insecure': args.insecure,
                'timeout': args.api_timeout
            }
        else:
            keystone_session = self._get_keystone_session(**kwargs)
            project_id = args.os_project_id or args.os_tenant_id
            project_name = args.os_project_name or args.os_tenant_name
            endpoint_type = args.os_endpoint_type or 'publicURL'
            kwargs = {
                'username': args.os_username,
                'user_id': args.os_user_id,
                'user_domain_id': args.os_user_domain_id,
                'user_domain_name': args.os_user_domain_name,
                'password': args.os_password,
                'auth_token': args.os_auth_token,
                'project_id': project_id,
                'project_name': project_name,
                'project_domain_id': args.os_project_domain_id,
                'project_domain_name': args.os_project_domain_name,
            }
            keystone_auth = self._get_keystone_auth(keystone_session,
                                                    args.os_auth_url,
                                                    **kwargs)
            if not endpoint:
                svc_type = service_type
                region_name = args.os_region_name
                endpoint = keystone_auth.get_endpoint(keystone_session,
                                                      service_type=svc_type,
                                                      interface=endpoint_type,
                                                      region_name=region_name)
            kwargs = {
                'auth_url': args.os_auth_url,
                'session': keystone_session,
                'auth': keystone_auth,
                'service_type': service_type,
                'endpoint_type': endpoint_type,
                'region_name': args.os_region_name,
                'username': args.os_username,
                'password': args.os_password,
                'include_pass': args.include_password
            }

        client = heat_client.Client(api_version, endpoint, **kwargs)

        profile = osprofiler_profiler and options.profile
        if profile:
            osprofiler_profiler.init(options.profile)

        args.func(client, args)

        if profile:
            trace_id = osprofiler_profiler.get().get_base_id()
            print(_("Trace ID: %s") % trace_id)
            print(_("To display trace use next command:\n"
                  "osprofiler trace show --html %s ") % trace_id)
示例#17
0
def build_derived_config_params(action,
                                source,
                                name,
                                input_values,
                                server_id,
                                signal_transport,
                                signal_id=None):

    if isinstance(source, SoftwareConfig):
        source = source.to_dict()
    input_values = input_values or {}
    inputs = copy.deepcopy(source.get('inputs')) or []

    for inp in inputs:
        input_key = inp['name']
        inp['value'] = input_values.pop(input_key, inp.get('default'))

    # for any input values that do not have a declared input, add
    # a derived declared input so that they can be used as config
    # inputs
    for inpk, inpv in input_values.items():
        inputs.append({'name': inpk, 'type': 'String', 'value': inpv})

    inputs.extend([{
        'name': 'deploy_server_id',
        'description': _('ID of the server being deployed to'),
        'type': 'String',
        'value': server_id
    }, {
        'name':
        'deploy_action',
        'description':
        _('Name of the current action being deployed'),
        'type':
        'String',
        'value':
        action
    }, {
        'name':
        'deploy_signal_transport',
        'description':
        _('How the server should signal to heat with '
          'the deployment output values.'),
        'type':
        'String',
        'value':
        signal_transport
    }])

    if signal_transport == 'TEMP_URL_SIGNAL':
        inputs.append({
            'name':
            'deploy_signal_id',
            'description':
            _('ID of signal to use for signaling '
              'output values'),
            'type':
            'String',
            'value':
            signal_id
        })
        inputs.append({
            'name':
            'deploy_signal_verb',
            'description':
            _('HTTP verb to use for signaling '
              'output values'),
            'type':
            'String',
            'value':
            'PUT'
        })
    elif signal_transport != 'NO_SIGNAL':
        raise exc.CommandError(
            _('Unsupported signal transport %s') % signal_transport)

    return {
        'group': source.get('group') or 'Heat::Ungrouped',
        'config': source.get('config') or '',
        'options': source.get('options') or {},
        'inputs': inputs,
        'outputs': source.get('outputs') or [],
        'name': name
    }