예제 #1
0
def _stack_action(stack, parsed_args, heat_client, action, action_name=None):
    if parsed_args.wait:
        # find the last event to use as the marker
        events = event_utils.get_events(heat_client,
                                        stack_id=stack,
                                        event_args={'sort_dir': 'desc',
                                                    'limit': 1})
        marker = events[0].id if events else None

    try:
        action(stack)
    except heat_exc.HTTPNotFound:
        msg = _('Stack not found: %s') % stack
        raise exc.CommandError(msg)

    if parsed_args.wait:
        s = heat_client.stacks.get(stack)
        stack_status, msg = event_utils.poll_for_events(
            heat_client, s.stack_name, action=action_name, marker=marker)
        if action_name:
            if stack_status == '%s_FAILED' % action_name:
                raise exc.CommandError(msg)
        else:
            if stack_status.endswith('_FAILED'):
                raise exc.CommandError(msg)

    return heat_client.stacks.get(stack)
예제 #2
0
def update(clients, **workflow_input):
    workflow_client = clients.workflow_engine
    tripleoclients = clients.tripleoclient
    plan_name = workflow_input['container']

    with tripleoclients.messaging_websocket() as ws:
        execution = base.start_workflow(
            workflow_client,
            'tripleo.package_update.v1.package_update_plan',
            workflow_input=workflow_input)

        for payload in base.wait_for_messages(workflow_client, ws, execution):
            assert payload['status'] == "SUCCESS", pprint.pformat(payload)

    orchestration_client = clients.orchestration

    events = event_utils.get_events(orchestration_client,
                                    stack_id=plan_name,
                                    event_args={
                                        'sort_dir': 'desc',
                                        'limit': 1
                                    })
    marker = events[0].id if events else None

    time.sleep(10)
    create_result = utils.wait_for_stack_ready(orchestration_client, plan_name,
                                               marker, 'UPDATE', 1)
    if not create_result:
        shell.OpenStackShell().run(["stack", "failures", "list", plan_name])
        raise exceptions.DeploymentError("Heat Stack update failed.")
예제 #3
0
def deploy_and_wait(log,
                    clients,
                    stack,
                    plan_name,
                    verbose_level,
                    timeout=None,
                    run_validations=False,
                    skip_deploy_identifier=False,
                    deployment_options={}):
    """Start the deploy and wait for it to finish"""

    orchestration_client = clients.orchestration

    if stack is None:
        log.info("Performing Heat stack create")
        action = 'CREATE'
        marker = None
    else:
        log.info("Performing Heat stack update")
        # Make sure existing parameters for stack are reused
        # Find the last top-level event to use for the first marker
        events = event_utils.get_events(orchestration_client,
                                        stack_id=plan_name,
                                        event_args={
                                            'sort_dir': 'desc',
                                            'limit': 1
                                        })
        marker = events[0].id if events else None
        action = 'UPDATE'

    set_deployment_status(clients=clients, plan=plan_name, status='DEPLOYING')

    try:
        deploy(container=plan_name,
               run_validations=run_validations,
               skip_deploy_identifier=skip_deploy_identifier,
               timeout=timeout,
               verbosity=verbose_level)
    except Exception:
        set_deployment_status(clients=clients,
                              plan=plan_name,
                              status='DEPLOY_FAILED')
        raise

    # we always want the heat stack output while it's going.
    verbose_events = True

    # TODO(rabi) Simplify call to get events as we don't need to wait
    # for stack to be ready anymore i.e just get the events.
    create_result = utils.wait_for_stack_ready(orchestration_client, plan_name,
                                               marker, action, verbose_events)
    if not create_result:
        shell.OpenStackShell().run(["stack", "failures", "list", plan_name])
        set_deployment_status(clients=clients,
                              plan=plan_name,
                              status='DEPLOY_FAILED')
        if stack is None:
            raise exceptions.DeploymentError("Heat Stack create failed.")
        else:
            raise exceptions.DeploymentError("Heat Stack update failed.")
예제 #4
0
def _stack_action(stack, parsed_args, heat_client, action, action_name=None):
    if parsed_args.wait:
        # find the last event to use as the marker
        events = event_utils.get_events(heat_client,
                                        stack_id=stack,
                                        event_args={'sort_dir': 'desc'},
                                        limit=1)
        marker = events[0].id if events else None

    try:
        action(stack)
    except heat_exc.HTTPNotFound:
        msg = _('Stack not found: %s') % stack
        raise exc.CommandError(msg)

    if parsed_args.wait:
        s = heat_client.stacks.get(stack)
        stack_status, msg = event_utils.poll_for_events(heat_client,
                                                        s.stack_name,
                                                        action=action_name,
                                                        marker=marker)
        if action_name:
            if stack_status == '%s_FAILED' % action_name:
                raise exc.CommandError(msg)
        else:
            if stack_status.endswith('_FAILED'):
                raise exc.CommandError(msg)

    return heat_client.stacks.get(stack)
예제 #5
0
    def _wait_for_heat_complete(self, orchestration_client, stack_id, timeout):

        # Wait for the stack to go to COMPLETE.
        timeout_t = time.time() + 60 * timeout
        marker = None
        event_log_context = heat_utils.EventLogContext()
        kwargs = {
            'sort_dir': 'asc',
            'nested_depth': '6'
        }
        while True:
            time.sleep(2)
            events = event_utils.get_events(
                orchestration_client,
                stack_id=stack_id,
                event_args=kwargs,
                marker=marker)
            if events:
                marker = getattr(events[-1], 'id', None)
                events_log = heat_utils.event_log_formatter(
                    events, event_log_context)
                print(events_log)

            status = orchestration_client.stacks.get(stack_id).status
            if status == 'FAILED':
                raise Exception('Stack create failed')
            if status == 'COMPLETE':
                break
            if time.time() > timeout_t:
                msg = 'Stack creation timeout: %d minutes elapsed' % (timeout)
                raise Exception(msg)
예제 #6
0
def wait_for_stack_ready(orchestration_client,
                         stack_name,
                         marker=None,
                         action='CREATE',
                         verbose=False):
    """Check the status of an orchestration stack

    Get the status of an orchestration stack and check whether it is complete
    or failed.

    :param orchestration_client: Instance of Orchestration client
    :type  orchestration_client: heatclient.v1.client.Client

    :param stack_name: Name or UUID of stack to retrieve
    :type  stack_name: string

    :param marker: UUID of the last stack event before the current action
    :type  marker: string

    :param action: Current action to check the stack for COMPLETE
    :type action: string

    :param verbose: Whether to print events
    :type verbose: boolean
    """
    stack = get_stack(orchestration_client, stack_name)
    if not stack:
        return False
    stack_name = stack.stack_name

    while True:

        events = event_utils.get_events(orchestration_client,
                                        stack_id=stack_name,
                                        nested_depth=2,
                                        event_args={
                                            'sort_dir': 'asc',
                                            'marker': marker
                                        })

        if len(events) >= 1:
            # set marker to last event that was received.
            marker = getattr(events[-1], 'id', None)

            if verbose:
                events_log = event_log_formatter(events)
                print(events_log)

        stack = get_stack(orchestration_client, stack_name)
        stack_status = stack.stack_status
        if stack_status == '%s_COMPLETE' % action:
            print("Stack %(name)s %(status)s" %
                  dict(name=stack_name, status=stack_status))
            return True
        elif stack_status == '%s_FAILED' % action:
            print("Stack %(name)s %(status)s" %
                  dict(name=stack_name, status=stack_status))
            return False

        time.sleep(5)
예제 #7
0
    def _stack_event_summary(self, stack):

        try:
            events = event_utils.get_events(self.clients.heat,
                                            stack_id=stack.stack_name,
                                            nested_depth=1,
                                            event_args={'sort_dir': 'asc'})
        except exc.CommandError:
            return []

        return util.heat_event_log_formatter(reversed(events))
예제 #8
0
def wait_for_stack_ready(orchestration_client, stack_name, marker=None,
                         action='CREATE', verbose=False):
    """Check the status of an orchestration stack

    Get the status of an orchestration stack and check whether it is complete
    or failed.

    :param orchestration_client: Instance of Orchestration client
    :type  orchestration_client: heatclient.v1.client.Client

    :param stack_name: Name or UUID of stack to retrieve
    :type  stack_name: string

    :param marker: UUID of the last stack event before the current action
    :type  marker: string

    :param action: Current action to check the stack for COMPLETE
    :type action: string

    :param verbose: Whether to print events
    :type verbose: boolean
    """
    stack = get_stack(orchestration_client, stack_name)
    if not stack:
        return False
    stack_name = stack.stack_name

    while True:

        events = event_utils.get_events(orchestration_client,
                                        stack_id=stack_name, nested_depth=2,
                                        event_args={'sort_dir': 'asc',
                                                    'marker': marker})

        if len(events) >= 1:
            # set marker to last event that was received.
            marker = getattr(events[-1], 'id', None)

            if verbose:
                events_log = event_log_formatter(events)
                print(events_log)

        stack = get_stack(orchestration_client, stack_name)
        stack_status = stack.stack_status
        if stack_status == '%s_COMPLETE' % action:
            print("Stack %(name)s %(status)s" % dict(
                name=stack_name, status=stack_status))
            return True
        elif stack_status == '%s_FAILED' % action:
            print("Stack %(name)s %(status)s" % dict(
                name=stack_name, status=stack_status))
            return False

        time.sleep(5)
예제 #9
0
def deploy_and_wait(log,
                    clients,
                    stack,
                    plan_name,
                    verbose_level,
                    timeout=None,
                    run_validations=False,
                    skip_deploy_identifier=False,
                    deployment_options={}):
    """Start the deploy and wait for it to finish"""

    workflow_input = {
        "container": plan_name,
        "run_validations": run_validations,
        "skip_deploy_identifier": skip_deploy_identifier,
        "deployment_options": deployment_options,
    }

    if timeout is not None:
        workflow_input['timeout'] = timeout

    deploy(log, clients, **workflow_input)

    orchestration_client = clients.orchestration

    if stack is None:
        log.info("Performing Heat stack create")
        action = 'CREATE'
        marker = None
    else:
        log.info("Performing Heat stack update")
        # Make sure existing parameters for stack are reused
        # Find the last top-level event to use for the first marker
        events = event_utils.get_events(orchestration_client,
                                        stack_id=plan_name,
                                        event_args={
                                            'sort_dir': 'desc',
                                            'limit': 1
                                        })
        marker = events[0].id if events else None
        action = 'UPDATE'

    time.sleep(10)
    verbose_events = verbose_level >= 1
    create_result = utils.wait_for_stack_ready(orchestration_client, plan_name,
                                               marker, action, verbose_events)
    if not create_result:
        shell.OpenStackShell().run(["stack", "failures", "list", plan_name])
        set_deployment_status(clients, 'failed', plan=plan_name)
        if stack is None:
            raise exceptions.DeploymentError("Heat Stack create failed.")
        else:
            raise exceptions.DeploymentError("Heat Stack update failed.")
예제 #10
0
def deploy_and_wait(log,
                    clients,
                    stack,
                    plan_name,
                    verbose_level,
                    timeout=None):
    """Start the deploy and wait for it to finish"""

    workflow_input = {
        "container": plan_name,
        "queue_name": str(uuid.uuid4()),
    }

    if timeout is not None:
        workflow_input['timeout'] = timeout

    deploy(clients, **workflow_input)

    orchestration_client = clients.orchestration

    if stack is None:
        log.info("Performing Heat stack create")
        action = 'CREATE'
        marker = None
    else:
        log.info("Performing Heat stack update")
        # Make sure existing parameters for stack are reused
        # Find the last top-level event to use for the first marker
        events = event_utils.get_events(orchestration_client,
                                        stack_id=plan_name,
                                        event_args={
                                            'sort_dir': 'desc',
                                            'limit': 1
                                        })
        marker = events[0].id if events else None
        action = 'UPDATE'

    time.sleep(10)
    verbose_events = verbose_level > 0
    create_result = utils.wait_for_stack_ready(orchestration_client, plan_name,
                                               marker, action, verbose_events)
    if not create_result:
        if stack is None:
            raise exceptions.DeploymentError("Heat Stack create failed.")
        else:
            raise exceptions.DeploymentError("Heat Stack update failed.")
def update(clients, container):
    """Update the heat stack outputs for purposes of update/upgrade.

    This workflow assumes that previously the
    plan_management.update_deployment_plan workflow has already been
    run to process the templates and environments (the same way as
    'deploy' command processes them).

    :param clients: Application client object.
    :type clients: Object

    :param container: Container name to pull from.
    :type container: String.
    """

    tripleoclients = clients.tripleoclient

    orchestration_client = clients.orchestration
    object_client = tripleoclients.object_store
    plan.update_plan_environment_with_image_parameters(
       object_client, container)
    stack.stack_update(object_client, orchestration_client,
                       _STACK_TIMEOUT, container)

    events = event_utils.get_events(orchestration_client,
                                    stack_id=container,
                                    event_args={'sort_dir': 'desc',
                                                'limit': 1})
    marker = events[0].id if events else None
    time.sleep(10)
    create_result = utils.wait_for_stack_ready(
        clients.orchestration,
        container,
        marker,
        'UPDATE',
        verbose=True
    )
    if not create_result:
        raise exceptions.DeploymentError(
            'Heat Stack update failed, run the following command'
            ' `openstack --os-cloud undercloud stack failures list {}`'
            ' to investigate these failures further.'.format(container)
        )
예제 #12
0
def deploy_and_wait(log, clients, stack, plan_name, verbose_level,
                    timeout=None):
    """Start the deploy and wait for it to finish"""

    workflow_input = {
        "container": plan_name,
        "queue_name": str(uuid.uuid4()),
    }

    if timeout is not None:
        workflow_input['timeout'] = timeout

    deploy(clients, **workflow_input)

    orchestration_client = clients.orchestration

    if stack is None:
        log.info("Performing Heat stack create")
        action = 'CREATE'
        marker = None
    else:
        log.info("Performing Heat stack update")
        # Make sure existing parameters for stack are reused
        # Find the last top-level event to use for the first marker
        events = event_utils.get_events(orchestration_client,
                                        stack_id=plan_name,
                                        event_args={'sort_dir': 'desc',
                                                    'limit': 1})
        marker = events[0].id if events else None
        action = 'UPDATE'

    time.sleep(10)
    verbose_events = verbose_level > 0
    create_result = utils.wait_for_stack_ready(
        orchestration_client, plan_name, marker, action, verbose_events)
    if not create_result:
        if stack is None:
            raise exceptions.DeploymentError("Heat Stack create failed.")
        else:
            raise exceptions.DeploymentError("Heat Stack update failed.")
예제 #13
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,
            '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:
            columns.append('stack_name')
            nested_depth = parsed_args.nested_depth
        else:
            nested_depth = 0

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

            marker = parsed_args.marker
            try:
                event_log_context = heat_utils.EventLogContext()
                while True:
                    events = event_utils.get_events(
                        client,
                        stack_id=parsed_args.stack,
                        event_args=kwargs,
                        nested_depth=nested_depth,
                        marker=marker)
                    if events:
                        marker = getattr(events[-1], 'id', None)
                        events_log = heat_utils.event_log_formatter(
                            events, event_log_context)
                        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, marker=parsed_args.marker,
            limit=parsed_args.limit)

        if parsed_args.sort:
            sorts = []
            for sort in parsed_args.sort:
                if sort.startswith(":"):
                    sorts.append(":".join(["event_time", sort.lstrip(":")]))
                else:
                    sorts.append(sort)
            events = utils.sort_items(events, ','.join(sorts))

        if parsed_args.formatter == 'log':
            return [], 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)
        )
예제 #14
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        heat_client = self.app.client_manager.orchestration

        try:
            if not parsed_args.yes and sys.stdin.isatty():
                prompt_response = input(
                    _("Are you sure you want to delete this stack(s) [y/N]? ")
                ).lower()
                if not prompt_response.startswith('y'):
                    self.log.info('User did not confirm stack delete so '
                                  'taking no action.')
                    return
        except KeyboardInterrupt:  # ctrl-c
            self.log.info('User did not confirm stack delete '
                          '(ctrl-c) so taking no action.')
            return
        except EOFError:  # ctrl-d
            self.log.info('User did not confirm stack delete '
                          '(ctrl-d) so taking no action.')
            return

        failure_count = 0
        stacks_waiting = []
        for sid in parsed_args.stack:
            marker = None
            if parsed_args.wait:
                try:
                    # find the last event to use as the marker
                    events = event_utils.get_events(
                        heat_client,
                        stack_id=sid,
                        event_args={'sort_dir': 'desc'},
                        limit=1)
                    if events:
                        marker = events[0].id
                except heat_exc.CommandError as ex:
                    failure_count += 1
                    print(ex)
                    continue

            try:
                heat_client.stacks.delete(sid)
                stacks_waiting.append((sid, marker))
            except heat_exc.HTTPNotFound:
                failure_count += 1
                print(_('Stack not found: %s') % sid)
            except heat_exc.Forbidden:
                failure_count += 1
                print(_('Forbidden: %s') % sid)

        if parsed_args.wait:
            for sid, marker in stacks_waiting:
                try:
                    stack_status, msg = event_utils.poll_for_events(
                        heat_client, sid, action='DELETE', marker=marker)
                except heat_exc.CommandError:
                    continue
                if stack_status == 'DELETE_FAILED':
                    failure_count += 1
                    print(msg)

        if failure_count:
            msg = (_('Unable to delete %(count)d of the %(total)d stacks.') % {
                'count': failure_count,
                'total': len(parsed_args.stack)
            })
            raise exc.CommandError(msg)
예제 #15
0
    def take_action(self, parsed_args):
        self.log.debug('take_action(%s)', parsed_args)

        client = self.app.client_manager.orchestration

        tpl_files, template = template_utils.process_template_path(
            parsed_args.template,
            object_request=http.authenticated_fetcher(client),
            existing=parsed_args.existing,
            fetch_child=parsed_args.files_container is None)

        env_files_list = []
        env_files, env = (
            template_utils.process_multiple_environments_and_files(
                env_paths=parsed_args.environment,
                env_list_tracker=env_files_list,
                fetch_env_files=parsed_args.files_container is None))

        parameters = heat_utils.format_all_parameters(
            parsed_args.parameter, parsed_args.parameter_file,
            parsed_args.template)

        if parsed_args.pre_update:
            template_utils.hooks_to_env(env, parsed_args.pre_update,
                                        'pre-update')

        fields = {
            'stack_id': parsed_args.stack,
            'parameters': parameters,
            'existing': parsed_args.existing,
            'template': template,
            'files': dict(list(tpl_files.items()) + list(env_files.items())),
            'environment': env
        }

        # If one or more environments is found, pass the listing to the server
        if env_files_list:
            fields['environment_files'] = env_files_list

        if parsed_args.files_container:
            fields['files_container'] = parsed_args.files_container

        if parsed_args.tags:
            fields['tags'] = parsed_args.tags
        if parsed_args.timeout:
            fields['timeout_mins'] = parsed_args.timeout
        if parsed_args.clear_parameter:
            fields['clear_parameters'] = list(parsed_args.clear_parameter)

        if parsed_args.rollback:
            rollback = parsed_args.rollback.strip().lower()
            if rollback not in ('enabled', 'disabled', 'keep'):
                msg = _('--rollback invalid value: %s') % parsed_args.rollback
                raise exc.CommandError(msg)
            if rollback != 'keep':
                fields['disable_rollback'] = rollback == 'disabled'

        if parsed_args.dry_run:
            if parsed_args.show_nested:
                fields['show_nested'] = parsed_args.show_nested

            changes = client.stacks.preview_update(**fields)

            fields = [
                'state', 'resource_name', 'resource_type', 'resource_identity'
            ]

            columns = sorted(changes.get("resource_changes", {}).keys())
            data = [
                heat_utils.json_formatter(changes["resource_changes"][key])
                for key in columns
            ]

            return columns, data

        if parsed_args.wait:
            # find the last event to use as the marker
            events = event_utils.get_events(client,
                                            stack_id=parsed_args.stack,
                                            event_args={'sort_dir': 'desc'},
                                            limit=1)
            marker = events[0].id if events else None

        if parsed_args.converge:
            fields['converge'] = True

        client.stacks.update(**fields)

        if parsed_args.wait:
            stack = client.stacks.get(parsed_args.stack)
            stack_status, msg = event_utils.poll_for_events(client,
                                                            stack.stack_name,
                                                            action='UPDATE',
                                                            marker=marker)
            if stack_status == 'UPDATE_FAILED':
                raise exc.CommandError(msg)

        return _show_stack(client,
                           parsed_args.stack,
                           format='table',
                           short=True)
예제 #16
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,
            '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:
            columns.append('stack_name')
            nested_depth = parsed_args.nested_depth
        else:
            nested_depth = 0

        if parsed_args.sort:
            sorts = []
            sort_keys = []
            for sort in parsed_args.sort:
                if sort.startswith(":"):
                    sorts.append(":".join(["event_time", sort.lstrip(":")]))
                else:
                    sorts.append(sort)
                    sort_keys.append(sort.split(":")[0])
            kwargs['sort_keys'] = sort_keys

            if ":" in parsed_args.sort[0]:
                kwargs['sort_dir'] = parsed_args.sort[0].split(":")[1]

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

            marker = parsed_args.marker
            try:
                event_log_context = heat_utils.EventLogContext()
                while True:
                    events = event_utils.get_events(
                        client,
                        stack_id=parsed_args.stack,
                        event_args=kwargs,
                        nested_depth=nested_depth,
                        marker=marker)
                    if events:
                        marker = getattr(events[-1], 'id', None)
                        events_log = heat_utils.event_log_formatter(
                            events, event_log_context)
                        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, marker=parsed_args.marker,
            limit=parsed_args.limit)

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

        if parsed_args.formatter == 'log':
            return [], 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)
        )
예제 #17
0
    def _heat_deploy(self, stack, stack_name, template_path, parameters,
                     environments, timeout):
        """Verify the Baremetal nodes are available and do a stack update"""

        self.log.debug("Processing environment files")
        env_files, env = (
            template_utils.process_multiple_environments_and_files(
                environments))
        if stack:
            update.add_breakpoints_cleanup_into_env(env)

        self.log.debug("Getting template contents")
        template_files, template = template_utils.get_template_contents(
            template_path)

        files = dict(list(template_files.items()) + list(env_files.items()))

        clients = self.app.client_manager
        orchestration_client = clients.tripleoclient.orchestration

        self.log.debug("Deploying stack: %s", stack_name)
        self.log.debug("Deploying template: %s", template)
        self.log.debug("Deploying parameters: %s", parameters)
        self.log.debug("Deploying environment: %s", env)
        self.log.debug("Deploying files: %s", files)

        stack_args = {
            'stack_name': stack_name,
            'template': template,
            'environment': env,
            'files': files,
            'clear_parameters': env['parameter_defaults'].keys(),
        }

        if timeout:
            stack_args['timeout_mins'] = timeout

        if stack is None:
            self.log.info("Performing Heat stack create")
            action = 'CREATE'
            marker = None
            orchestration_client.stacks.create(**stack_args)
        else:
            self.log.info("Performing Heat stack update")
            # Make sure existing parameters for stack are reused
            stack_args['existing'] = 'true'
            # Find the last top-level event to use for the first marker
            events = event_utils.get_events(orchestration_client,
                                            stack_id=stack_name,
                                            event_args={'sort_dir': 'desc',
                                                        'limit': 1})
            marker = events[0].id if events else None
            action = 'UPDATE'

            orchestration_client.stacks.update(stack.id, **stack_args)

        verbose_events = self.app_args.verbose_level > 0
        create_result = utils.wait_for_stack_ready(
            orchestration_client, stack_name, marker, action, verbose_events)
        if not create_result:
            if stack is None:
                raise Exception("Heat Stack create failed.")
            else:
                raise Exception("Heat Stack update failed.")
예제 #18
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,
                        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, 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)
        )
예제 #19
0
    def take_action(self, parsed_args):
        self.log.debug('take_action(%s)', parsed_args)

        client = self.app.client_manager.orchestration

        tpl_files, template = template_utils.process_template_path(
            parsed_args.template,
            object_request=http.authenticated_fetcher(client),
            existing=parsed_args.existing)

        env_files, env = (
            template_utils.process_multiple_environments_and_files(
                env_paths=parsed_args.environment))

        parameters = heat_utils.format_all_parameters(
            parsed_args.parameter,
            parsed_args.parameter_file,
            parsed_args.template)

        if parsed_args.pre_update:
            template_utils.hooks_to_env(env, parsed_args.pre_update,
                                        'pre-update')

        fields = {
            'stack_id': parsed_args.stack,
            'parameters': parameters,
            'existing': parsed_args.existing,
            'template': template,
            'files': dict(list(tpl_files.items()) + list(env_files.items())),
            'environment': env
        }

        if parsed_args.tags:
            fields['tags'] = parsed_args.tags
        if parsed_args.timeout:
            fields['timeout_mins'] = parsed_args.timeout
        if parsed_args.clear_parameter:
            fields['clear_parameters'] = list(parsed_args.clear_parameter)

        if parsed_args.rollback:
            rollback = parsed_args.rollback.strip().lower()
            if rollback not in ('enabled', 'disabled', 'keep'):
                msg = _('--rollback invalid value: %s') % parsed_args.rollback
                raise exc.CommandError(msg)
            if rollback != 'keep':
                fields['disable_rollback'] = rollback == 'disabled'

        if parsed_args.dry_run:
            changes = client.stacks.preview_update(**fields)

            fields = ['state', 'resource_name', 'resource_type',
                      'resource_identity']

            columns = sorted(changes.get("resource_changes", {}).keys())
            data = [heat_utils.json_formatter(changes["resource_changes"][key])
                    for key in columns]

            return columns, data

        if parsed_args.wait:
            # find the last event to use as the marker
            events = event_utils.get_events(client,
                                            stack_id=parsed_args.stack,
                                            event_args={'sort_dir': 'desc',
                                                        'limit': 1})
            marker = events[0].id if events else None

        client.stacks.update(**fields)

        if parsed_args.wait:
            stack = client.stacks.get(parsed_args.stack)
            stack_status, msg = event_utils.poll_for_events(
                client, stack.stack_name, action='UPDATE', marker=marker)
            if stack_status == 'UPDATE_FAILED':
                raise exc.CommandError(msg)

        return _show_stack(client, parsed_args.stack, format='table',
                           short=True)
예제 #20
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        heat_client = self.app.client_manager.orchestration

        try:
            if not parsed_args.yes and sys.stdin.isatty():
                sys.stdout.write(
                    _("Are you sure you want to delete this stack(s) [y/N]? "))
                prompt_response = sys.stdin.readline().lower()
                if not prompt_response.startswith('y'):
                    self.log.info(_LI('User did not confirm stack delete so '
                                      'taking no action.'))
                    return
        except KeyboardInterrupt:  # ctrl-c
            self.log.info(_LI('User did not confirm stack delete '
                              '(ctrl-c) so taking no action.'))
            return
        except EOFError:  # ctrl-d
            self.log.info(_LI('User did not confirm stack delete '
                              '(ctrl-d) so taking no action.'))
            return

        failure_count = 0
        stacks_waiting = []
        for sid in parsed_args.stack:
            marker = None
            if parsed_args.wait:
                try:
                    # find the last event to use as the marker
                    events = event_utils.get_events(heat_client,
                                                    stack_id=sid,
                                                    event_args={
                                                        'sort_dir': 'desc',
                                                        'limit': 1})
                    if events:
                        marker = events[0].id
                except heat_exc.CommandError as ex:
                    failure_count += 1
                    print(ex)
                    continue

            try:
                heat_client.stacks.delete(sid)
                stacks_waiting.append((sid, marker))
            except heat_exc.HTTPNotFound:
                failure_count += 1
                print(_('Stack not found: %s') % sid)
            except heat_exc.Forbidden:
                failure_count += 1
                print(_('Forbidden: %s') % sid)

        if parsed_args.wait:
            for sid, marker in stacks_waiting:
                try:
                    stack_status, msg = event_utils.poll_for_events(
                        heat_client, sid, action='DELETE', marker=marker)
                except heat_exc.CommandError:
                    continue
                if stack_status == 'DELETE_FAILED':
                    failure_count += 1
                    print(msg)

        if failure_count:
            msg = (_('Unable to delete %(count)d of the %(total)d stacks.') %
                   {'count': failure_count, 'total': len(parsed_args.stack)})
            raise exc.CommandError(msg)
    def _heat_deploy(self, stack, stack_name, template_path, parameters,
                     environments, timeout):
        """Verify the Baremetal nodes are available and do a stack update"""

        self.log.debug("Processing environment files")
        env_files, env = (
            template_utils.process_multiple_environments_and_files(
                environments))
        if stack:
            update.add_breakpoints_cleanup_into_env(env)

        self.log.debug("Getting template contents")
        template_files, template = template_utils.get_template_contents(
            template_path)

        files = dict(list(template_files.items()) + list(env_files.items()))

        clients = self.app.client_manager
        orchestration_client = clients.tripleoclient.orchestration

        self.log.debug("Deploying stack: %s", stack_name)
        self.log.debug("Deploying template: %s", template)
        self.log.debug("Deploying parameters: %s", parameters)
        self.log.debug("Deploying environment: %s", env)
        self.log.debug("Deploying files: %s", files)

        stack_args = {
            'stack_name': stack_name,
            'template': template,
            'environment': env,
            'files': files,
            'clear_parameters': env['parameter_defaults'].keys(),
        }

        if timeout:
            stack_args['timeout_mins'] = timeout

        if stack is None:
            self.log.info("Performing Heat stack create")
            action = 'CREATE'
            marker = None
            orchestration_client.stacks.create(**stack_args)
        else:
            self.log.info("Performing Heat stack update")
            # Make sure existing parameters for stack are reused
            stack_args['existing'] = 'true'
            # Find the last top-level event to use for the first marker
            events = event_utils.get_events(orchestration_client,
                                            stack_id=stack_name,
                                            event_args={
                                                'sort_dir': 'desc',
                                                'limit': 1
                                            })
            marker = events[0].id if events else None
            action = 'UPDATE'

            orchestration_client.stacks.update(stack.id, **stack_args)

        verbose_events = self.app_args.verbose_level > 0
        create_result = utils.wait_for_stack_ready(orchestration_client,
                                                   stack_name, marker, action,
                                                   verbose_events)
        if not create_result:
            if stack is None:
                raise exceptions.DeploymentError("Heat Stack create failed.")
            else:
                raise exceptions.DeploymentError("Heat Stack update failed.")
예제 #22
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,
                                                    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,
                                        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))