def __get_all_nodes_instances():
    node_instances = set()
    ctx.graph_mode()
    for node in ctx.nodes:
        for instance in node.instances:
            node_instances.add(instance)
    return node_instances
def update(type_name, operation_kwargs, **kwargs):
    graph = ctx.graph_mode()

    send_event_starting_tasks = {}
    send_event_done_tasks = {}

    for node in ctx.nodes:
        if type_name in node.type_hierarchy:
            for instance in node.instances:
                send_event_starting_tasks[instance.id] = instance.send_event("Starting to run update workflow")
                send_event_done_tasks[instance.id] = instance.send_event("Done running update workflow")

    for node in ctx.nodes:
        if type_name in node.type_hierarchy:
            for instance in node.instances:

                sequence = graph.sequence()

                sequence.add(
                    send_event_starting_tasks[instance.id],
                    _execute_one_operation(instance, "cloudify.interfaces.lifecycle.configure", True, operation_kwargs),
                    send_event_done_tasks[instance.id],
                )

    return graph.execute()
def execute_node_instance_operation(_node_instance, _operation, _params=None):
    """
    Handles sending events and executing operations.

    :param _node_instance: A NodeInstance object from cloudify.manager.
    :param _operation: A string with the name of the workflow operation.
    :param _params: Optional parameters to the workflow operation.
    """

    # Prepare the kwargs to the execute_operation method.
    _params = _params or {}
    operation_args = {
        'operation': _operation,
    }
    if _params:
        operation_args['kwargs'] = _params

    graph = ctx.graph_mode()
    sequence = graph.sequence()
    sequence.add(
        _node_instance.send_event(
            'Starting to run operation: {0}'.format(operation_args)),
        _node_instance.execute_operation(**operation_args),
        _node_instance.send_event(
            'Finished running operation: {0}'.format(operation_args)))
    return graph.execute()
def a4c_uninstall(**kwargs):
    graph = ctx.graph_mode()
    nodes = _get_all_nodes(ctx)
    instances = _get_all_nodes_instances(ctx)
    custom_context = CustomContext(ctx, instances, nodes)
    ctx.internal.send_workflow_event(event_type='a4c_workflow_started', message=build_pre_event(WfStartEvent('uninstall')))
    _a4c_uninstall(ctx, graph, custom_context)
    return graph.execute()
def a4c_uninstall(**kwargs):
    graph = ctx.graph_mode()
    nodes = _get_all_nodes(ctx)
    instances = _get_all_nodes_instances(ctx)
    custom_context = CustomContext(ctx, instances, nodes)
    ctx.internal.send_workflow_event(event_type='a4c_workflow_started', message=build_pre_event(WfStartEvent('uninstall')))
    _a4c_uninstall(ctx, graph, custom_context)
    return graph.execute()
Beispiel #6
0
def a4c_uninstall(**kwargs):
    graph = ctx.graph_mode()
    custom_context = CustomContext(ctx)
    ctx.internal.send_workflow_event(
        event_type='workflow_started',
        message="Starting A4C generated '{0}' workflow execution".format(ctx.workflow_id))
    _a4c_uninstall(ctx, graph, custom_context)
    return graph.execute()
def a4c_uninstall(**kwargs):
    graph = ctx.graph_mode()
    custom_context = CustomContext(ctx)
    ctx.internal.send_workflow_event(
        event_type='workflow_started',
        message="Starting A4C generated '{0}' workflow execution".format(ctx.workflow_id))
    _a4c_uninstall(ctx, graph, custom_context)
    return graph.execute()
def swap(**kwargs):

    server_ids = {}
    switch_node = None
    graph = wctx.graph_mode()
    skip_test = kwargs.get("skip_test", False)

    # find the bg_switch node
    switch_node = _get_switch_node()

    # store the switch instance and currently connected server id
    connected_server_id = _get_connected_server_id(switch_node)

    # iterate through all node instances that are related to the switch.
    # find the one that's disconnected, test it (unless opted out) and make the swap
    is_swap_initialized = False
    for node in wctx.nodes:
        rel = node.get_relationship(switch_node.id)
        if rel is not None and rel._relationship["type"] == CONNECTED_TO_BG_SWITCH:
            for instance in node.instances:
                server_id = _get_runtime_property(instance, EXTERNAL_RESOURCE_ID, "")
                if server_id == connected_server_id:
                    continue
                else:

                    # test step
                    test_task = None
                    if skip_test:
                        wctx.logger.warn("skipping test")
                    elif connected_server_id:
                        test_task = _queue_test_task(graph, instance.contained_instances)
                    else:
                        wctx.logger.info("initial deployment, skipping test")

                    for instance_relationship in instance.relationships:

                        if instance_relationship.relationship._relationship["type"] != CONNECTED_TO_BG_SWITCH:
                            continue

                        # update the switch runtime info
                        swap_task = _get_first_instance(switch_node).execute_operation("update_switch_state", { "connected_instance_id": instance.id, "connected_server_id": server_id }, True)
                        graph.add_task(swap_task)
                        if test_task:
                            graph.add_dependency(swap_task, test_task)
                        # make the swap
                        update_task = instance_relationship.execute_source_operation('connection.establish')
                        graph.add_task(update_task)
                        graph.add_dependency(update_task, swap_task)

                    is_swap_initialized = True
        # stop node iteration if swap has been initialized
        if is_swap_initialized:
            break


    return graph.execute()
def run_operation(**kwargs):
    graph = ctx.graph_mode()

    for node in ctx.nodes:
        for instance in node.instances:
            graph.add_task(
                instance.execute_operation(
                    'cloudify.interfaces.lifecycle.start'))

    return graph.execute()
def run_operation(operation, nodes_type_update, operation_kwargs, **kwargs):
    graph = ctx.graph_mode()
    send_event_starting_tasks = {}
    send_event_done_tasks = {}


    for node_type_update in nodes_type_update:
        for node in ctx.nodes:
            if node.type == node_type_update:
                for instance in node.instances:
                    send_event_starting_tasks[instance.id] = instance.send_event('Starting to run operation')
                    send_event_done_tasks[instance.id] = instance.send_event('Done running operation')


    for node_type_update in nodes_type_update:
        previous_task = None
        for node in ctx.nodes:
            if node.type == node_type_update:
                for instance in node.instances:

                    sequence = graph.sequence()

                    #operation_task = instance.execute_operation(operation, kwargs=operation_kwargs)

                    forkjoin_tasks_unlink = []
                    for relationship in instance.relationships:
                        if relationship.relationship.target_id == 'bind':
                            operation_unlink = 'cloudify.interfaces.relationship_lifecycle.unlink'
                            forkjoin_tasks_unlink.append(relationship.execute_source_operation(operation_unlink))
                            forkjoin_tasks_unlink.append(relationship.execute_target_operation(operation_unlink))
                    operation_task_unlink = forkjoin(*forkjoin_tasks_unlink)

                    forkjoin_tasks_link = []
                    for relationship in instance.relationships:
                        if relationship.relationship.target_id == 'bind':
                            operation_link = 'cloudify.interfaces.relationship_lifecycle.establish'
                            forkjoin_tasks_link.append(relationship.execute_source_operation(operation_link))
                            forkjoin_tasks_link.append(relationship.execute_target_operation(operation_link))
                    operation_task_link = forkjoin(*forkjoin_tasks_link)

                    sequence.add(
                        send_event_starting_tasks[instance.id],
                        operation_task_unlink,
                        instance.execute_operation('cloudify.interfaces.lifecycle.update', kwargs=operation_kwargs),
                        operation_task_link,
                        send_event_done_tasks[instance.id])

                    if previous_task:
                        graph.add_dependency(send_event_starting_tasks.get(instance.id), send_event_done_tasks.get(previous_task))
                        with open("/file_out.txt", "w") as f:
                            pprint.pprint(previous_task, f)
                    previous_task = instance.id


    return graph.execute()
Beispiel #11
0
def logging_workflow(**kwargs):
    kwargs.pop('ctx', None)
    graph = workflow_ctx.graph_mode()
    instance = next(workflow_ctx.node_instances)
    task = instance.execute_operation('test.op', kwargs=kwargs)

    def on_failure(tsk):
        return workflow_tasks.HandlerResult.ignore()
    task.on_failure = on_failure
    graph.add_task(task)
    graph.execute()
Beispiel #12
0
def create_graph(ctx, parameter):
    graph = ctx.graph_mode()
    sequence = graph.sequence()
    # Iterate over all node instances of type "cloudify.nodes.SoftwareComponent"
    # and invoke the "update" and "commit" operations for each.
    for node_instance in ctx.node_instances:
        if node_instance.node.type == 'cloudify.nodes.SoftwareComponent':
            sequence.add(node_instance.execute_operation('maintenance.update'))
            sequence.add(node_instance.execute_operation('maintenance.commit'))

    return graph
def hello(**kwargs):
    log = logging.getLogger(__name__)
    log.warn('in hello')
       
    graph = ctx.graph_mode()

    for node in ctx.nodes:
        if 'cloudify.hello.Instance' in node.type_hierarchy:
            for instance in node.instances:
                graph.add_task(instance.execute_operation('cloudify.interfaces.hello.hello'))

    return graph.execute()
def upgrade(type_name, operation_kwargs, **kwargs):
    graph = ctx.graph_mode()

    send_event_starting_tasks = {}
    send_event_done_tasks = {}

    for node in ctx.nodes:
        if type_name in node.type_hierarchy:
            for instance in node.instances:
                send_event_starting_tasks[instance.id] = instance.send_event("Starting to run upgrade workflow")
                send_event_done_tasks[instance.id] = instance.send_event("Done running upgrade workflow")

    for node in ctx.nodes:
        if type_name in node.type_hierarchy:
            for instance in node.instances:

                sequence = graph.sequence()

                sequence.add(
                    send_event_starting_tasks[instance.id],
                    _execute_one_operation(instance, "cloudify.interfaces.lifecycle.stop", True, operation_kwargs),
                    _execute_one_operation(
                        instance, "cloudify.interfaces.relationship_lifecycle.unlink", False, operation_kwargs
                    ),
                    _execute_one_operation(instance, "cloudify.interfaces.lifecycle.delete", True, operation_kwargs),
                    _execute_one_operation(instance, "cloudify.interfaces.lifecycle.create", True, operation_kwargs),
                    _execute_one_operation(
                        instance, "cloudify.interfaces.relationship_lifecycle.preconfigure", False, operation_kwargs
                    ),
                    _execute_one_operation(instance, "cloudify.interfaces.lifecycle.configure", True, operation_kwargs),
                    _execute_one_operation(
                        instance, "cloudify.interfaces.relationship_lifecycle.postconfigure", False, operation_kwargs
                    ),
                    _execute_one_operation(instance, "cloudify.interfaces.lifecycle.start", True, operation_kwargs),
                    _execute_one_operation(
                        instance, "cloudify.interfaces.relationship_lifecycle.establish", False, operation_kwargs
                    ),
                    send_event_done_tasks[instance.id],
                )

    for node in ctx.nodes:
        for instance in node.instances:
            for rel in instance.relationships:

                instance_starting_task = send_event_starting_tasks.get(instance.id)
                target_done_task = send_event_done_tasks.get(rel.target_id)

                if instance_starting_task and target_done_task:
                    graph.add_dependency(instance_starting_task, target_done_task)

    return graph.execute()
Beispiel #15
0
def install_arcadia(operations, **kwargs):
	graph = wctx.graph_mode()
	send_event_starting_tasks = {}
	send_event_done_tasks = {}
	for node in wctx.nodes:
		for instance in node.instances:
			send_event_starting_tasks[instance.id] = instance.send_event('Starting to run operation')
			send_event_done_tasks[instance.id] = instance.send_event('Done running operation')

	for node in wctx.nodes:
		for instance in node.instances:
			sequence = graph.sequence()
			inst_kwargs = dict() 
			inst_kwargs['id'] = actx.test_component(instance)
			sequence.add(
				send_event_starting_tasks[instance.id],
				instance.execute_operation("create_and_configure", kwargs=inst_kwargs),
				send_event_done_tasks[instance.id])

	for node in wctx.nodes:
		sequence = graph.sequence()
		for instance in node.instances:
			for relationship in instance.relationships:
				rel_kwargs = dict()
				rel_kwargs['id'] = actx.test_relationship(relationship)
				sequence.add(
					relationship.execute_source_operation('preconfigure', kwargs=rel_kwargs))

	for node in wctx.nodes:
		for instance in node.instances:
			for rel in instance.relationships:
				instance_starting_task = send_event_starting_tasks.get(instance.id)
				target_done_task = send_event_done_tasks.get(rel.target_id)
				if instance_starting_task and target_done_task:
					graph.add_dependency(instance_starting_task, target_done_task)

	graph.execute()

	try:
		actx.client.generate_service_graph(actx.service_graph)
		actx.client.install_service_graph()
	except NotImplementedError:
		message = 'cancel service graph deployment: failed to generate or install graph, due too some missing functionality'
		wctx.logger.error(message)
		raise api.ExecutionCancelled(message)
	except ARCADIAServerRequestError as ex:
		message = 'cancel service graph deployment: arcadia server responded with an error message: {0}'.format(ex.message)
		wctx.logger.error(message)
		raise api.ExecutionCancelled(message)
def start_gateway(**kwargs):
    graph = ctx.graph_mode()
    management_instance = None
    gateway_instance = None
    for node in ctx.nodes:
        if "xap_management" == node.id:
            for i in node.instances:
                management_instance = i
                break
        if "xap_gateway" == node.id:
            for i in node.instances:
                gateway_instance = i
                break
        if management_instance is not None and gateway_instance is not None:
            break

    sequence = graph.sequence()
    ctx.logger.info("executing instance {}".format(management_instance))

    lookups = kwargs['gateway_lookups']

    sequence.add(
        management_instance.send_event('Deploying space'),
        management_instance.execute_operation("admin.commands.deploy_gateway_space",
                                              kwargs={'space_name': kwargs['space_name'],
                                                      'space_zones': kwargs['space_zones'],
                                                      'gateway_name': kwargs['gateway_name'],
                                                      'gateway_targets': kwargs['gateway_targets']}),
        gateway_instance.send_event('Deploying gateway'),
        gateway_instance.execute_operation("admin.commands.deploy_gateway_pu",
                                              kwargs={'space_name': kwargs['space_name'],
                                                      'gateway_zones': kwargs['gateway_pu_zones'],
                                                      'gateway_name': kwargs['gateway_name'],
                                                      'gateway_discoport': kwargs['gateway_discoport'],
                                                      'gateway_commport': kwargs['gateway_commport'],
                                                      'gateway_targets': kwargs['gateway_targets'],
                                                      'gateway_sources': kwargs['gateway_sources'],
                                                      'gateway_lookups': lookups,
                                                      'gateway_natmappings': kwargs['gateway_natmappings']}),
        management_instance.send_event('Deploying rest service'),
        management_instance.execute_operation("admin.commands.deploy_rest",
                                              kwargs={'space_name': kwargs['space_name'],
                                                      'rest_zones': kwargs['rest_zones'],
                                                      'rest_port': kwargs['rest_port']}),
        management_instance.send_event('Done running workflow')

    )

    graph.execute()
def disconnect(**kwargs):
    """
    disconnect blue/green from color switch
    """

    # find all nodes that have a connected_to_color_switch relationship and
    # execute their connection.unlink operation
    graph = wctx.graph_mode()
    for node in wctx.nodes:
        for relationship in node.relationships:
            if "connection.unlink" in relationship.source_operations:
                for instance in node.instances:
                    for instance_relationship in instance.relationships:
                        if instance_relationship.relationship == relationship:
                            graph.add_task(instance_relationship.execute_source_operation('connection.unlink'))

    return graph.execute()
Beispiel #18
0
def a4c_heal(ctx, node_instance_id, diagnose_value='Not provided', **kwargs):
    """Reinstalls the whole subgraph of the system topology

    The subgraph consists of all the nodes that are hosted in the
    failing node's compute and the compute itself.
    Additionally it unlinks and establishes appropriate relationships

    :param ctx: cloudify context
    :param node_id: failing node's id
    :param diagnose_value: diagnosed reason of failure
    """

    ctx.logger.info("Starting 'heal' workflow on {0}, Diagnosis: {1}".format(
        node_instance_id, diagnose_value))
    failing_node = ctx.get_node_instance(node_instance_id)
    host_instance_id = failing_node._node_instance.host_id
    failing_node_host = ctx.get_node_instance(host_instance_id)
    node_id = failing_node_host.node_id
    subgraph_node_instances = failing_node_host.get_contained_subgraph()
    added_and_related = _get_all_nodes(ctx)
    try:
        graph = ctx.graph_mode()
        ctx.internal.send_workflow_event(event_type='a4c_workflow_started',
                                         message=build_pre_event(
                                             WfStartEvent('heal',
                                                          'uninstall')))
        custom_context = CustomContext(ctx, subgraph_node_instances,
                                       added_and_related)
        uninstall_host(ctx, graph, custom_context, node_id)
        graph.execute()
    except:
        ctx.logger.error('Uninstall while healing failed.')
    graph = ctx.internal.task_graph
    for task in graph.tasks_iter():
        graph.remove_task(task)
    ctx.internal.send_workflow_event(event_type='a4c_workflow_started',
                                     message=build_pre_event(
                                         WfStartEvent('heal', 'install')))
    custom_context = CustomContext(ctx, subgraph_node_instances,
                                   added_and_related)
    install_host(ctx, graph, custom_context, node_id)
    graph.execute()
def a4c_heal(
        ctx,
        node_instance_id,
        diagnose_value='Not provided',
        **kwargs):
    """Reinstalls the whole subgraph of the system topology

    The subgraph consists of all the nodes that are hosted in the
    failing node's compute and the compute itself.
    Additionally it unlinks and establishes appropriate relationships

    :param ctx: cloudify context
    :param node_id: failing node's id
    :param diagnose_value: diagnosed reason of failure
    """

    ctx.logger.info("Starting 'heal' workflow on {0}, Diagnosis: {1}"
                    .format(node_instance_id, diagnose_value))
    failing_node = ctx.get_node_instance(node_instance_id)
    host_instance_id = failing_node._node_instance.host_id
    failing_node_host = ctx.get_node_instance(host_instance_id)
    node_id = failing_node_host.node_id
    subgraph_node_instances = failing_node_host.get_contained_subgraph()
    added_and_related = _get_all_nodes(ctx)
    try:
      graph = ctx.graph_mode()
      ctx.internal.send_workflow_event(event_type='a4c_workflow_started',
                                               message=build_pre_event(WfStartEvent('heal', 'uninstall')))
      custom_context = CustomContext(ctx, subgraph_node_instances, added_and_related)
      uninstall_host(ctx, graph, custom_context, node_id)
      graph.execute()
    except:
      ctx.logger.error('Uninstall while healing failed.')
    graph = ctx.internal.task_graph
    for task in graph.tasks_iter():
      graph.remove_task(task)
    ctx.internal.send_workflow_event(event_type='a4c_workflow_started',
                                             message=build_pre_event(WfStartEvent('heal', 'install')))
    custom_context = CustomContext(ctx, subgraph_node_instances, added_and_related)
    install_host(ctx, graph, custom_context, node_id)
    graph.execute()
def run_operation(**kwargs):
    graph = ctx.graph_mode()

    send_event_starting_tasks = {}
    send_event_done_tasks = {}

    for node in ctx.nodes:
        for instance in node.instances:
            send_event_starting_tasks[instance.id] = \
                instance.send_event('Starting to run operation')
            send_event_done_tasks[instance.id] = \
                instance.send_event('Done running operation')

    for node in ctx.nodes:
        for instance in node.instances:

            sequence = graph.sequence()

            sequence.add(
                send_event_starting_tasks[instance.id],
                instance.execute_operation(
                    'cloudify.interfaces.lifecycle.configure'),
                instance.execute_operation(
                    'cloudify.interfaces.lifecycle.start'),
                send_event_done_tasks[instance.id])

    for node in ctx.nodes:
        for instance in node.instances:
            for rel in instance.relationships:

                instance_starting_task = \
                    send_event_starting_tasks.get(instance.id)
                target_done_task = send_event_done_tasks.get(rel.target_id)

                if instance_starting_task and target_done_task:
                    graph.add_dependency(instance_starting_task,
                                         target_done_task)

    return graph.execute()
def graph_scale_down_workflow(delta):
    """Scale down the kubernetes cluster.

    A maximum number of `delta` nodes will be removed from the cluster.

    """
    # Set the workflow to be in graph mode.
    graph = workctx.graph_mode()

    # Get a maximum of `delta` number of workers.
    node = workctx.get_node('kube_worker')
    instances = [instance for instance in node.instances][:delta]

    # Setup events to denote the beginning and end of tasks.
    start_events, done_events = {}, {}

    for i, instance in enumerate(instances):
        start_events[i] = instance.send_event('Removing node cluster')
        done_events[i] = instance.send_event('Node removed from cluster')

    # Create `delta` number of TaskSequence objects. That way we are able to
    # control the sequence of events and the dependencies amongst tasks. One
    # graph sequence corresponds to node being removed from the cluster.
    for i, instance in enumerate(instances):
        sequence = graph.sequence()
        sequence.add(
            start_events[i],
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.stop',
            ),
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.delete',
            ),
            done_events[i],
        )

    # Start execution.
    return graph.execute()
def upgrade(**kwargs):
    """
    run the upgrade script
    """

    op_name = "upgrade"

    connected_instance_id = _get_connected_instance_id()
    if connected_instance_id is None:
        wctx.logger.error("there's no server connected, aborting upgrade")
        return

    graph = wctx.graph_mode()
    # execute upgrade only in supporting nodes
    for node in _get_bg_nodes():
        server_instance = _get_first_instance(node)
        if server_instance.id == connected_instance_id:
            continue
        for instance in server_instance.contained_instances:
            if "{0}.{1}".format(INTERFACE_NAME, op_name) in instance.node.operations:
                graph.add_task(instance.execute_operation(op_name))

    return graph.execute()
def graph_scale_down_workflow(delta):
    """Scale down the kubernetes cluster.

    A maximum number of `delta` nodes will be removed from the cluster.

    """
    # Set the workflow to be in graph mode.
    graph = workctx.graph_mode()

    # Get a maximum of `delta` number of workers.
    node = workctx.get_node('kube_worker')
    instances = [instance for instance in node.instances][:delta]

    # Setup events to denote the beginning and end of tasks.
    start_events, done_events = {}, {}

    for i, instance in enumerate(instances):
        start_events[i] = instance.send_event('Removing node cluster')
        done_events[i] = instance.send_event('Node removed from cluster')

    # Create `delta` number of TaskSequence objects. That way we are able to
    # control the sequence of events and the dependencies amongst tasks. One
    # graph sequence corresponds to node being removed from the cluster.
    for i, instance in enumerate(instances):
        sequence = graph.sequence()
        sequence.add(
            start_events[i],
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.stop', ),
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.delete', ),
            done_events[i],
        )

    # Start execution.
    return graph.execute()
Beispiel #24
0
def graph_scale_up_workflow(delta, worker_data_list):
    """Scale up the kubernetes cluster.

    This method implements the scale up workflow using the Graph Framework.

    Scaling is based on the `delta` input, which must be greater than 0 for
    the workflow to run.

    """
    # Set the workflow to be in graph mode.
    graph = workctx.graph_mode()

    # Get the instance for which to add an execute operation task to the graph.
    node = workctx.get_node('kube_worker')
    instance = [instance for instance in node.instances][0]

    # Setup events to denote the beginning and end of tasks. The events will be
    # also used to control dependencies amongst tasks.
    start_events, done_events = {}, {}

    for i in range(delta):
        start_events[i] = instance.send_event('Adding node to cluster')
        done_events[i] = instance.send_event('Node added to cluster')

    # Prepare the operations' kwargs.
    operation_kwargs_list = []

    for worker_data in worker_data_list:
        if worker_data.get('machine_id'):
            operation_kwargs_list.append(
                {
                    'cloud_id': worker_data.get('cloud_id'),
                    'machine_id': worker_data['machine_id'],
                }
            )
        else:
            operation_kwargs_list.append(
                {
                    'key_id': worker_data.get('key_id', ''),
                    'size_id': worker_data.get('size_id', ''),
                    'image_id': worker_data.get('image_id', ''),
                    'cloud_id': worker_data.get('cloud_id', ''),
                    'machine_id': '',
                    'networks': worker_data.get('networks', []),
                    'location_id': worker_data.get('location_id', ''),
                }
            )

    # Create `delta` number of TaskSequence objects. That way we are able to
    # control the sequence of events and the dependencies amongst tasks. One
    # graph sequence corresponds to a new node added to the cluster.
    for i in range(delta):
        sequence = graph.sequence()
        sequence.add(
            start_events[i],
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.clone',
            ),
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.create',
                kwargs=operation_kwargs_list[i],
            ),
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.configure',
            ),
            done_events[i],
        )

    # Now, we use the events to control the tasks' dependencies, ensuring that
    # tasks are executed in the correct order. We aim to create dependencies
    # between a sequence's last event and the next sequence's initial event.
    # That way, we ensure that sequences are executed sequentially, and not in
    # parallel. This is required, since the cloudify.interfaces.lifecycle.clone
    # operation modifies the node instances in local-storage and we want to
    # avoid having multiple tasks messing with the same files at the same time.
    for i in range(delta - 1):
        graph.add_dependency(start_events[i + 1], done_events[i])

    # Start execution.
    return graph.execute()
def graph_scale_workflow(delta):
    """Scale up the kubernetes cluster.

    This method implements the scale up workflow using the Graph Framework.

    Scaling is based on the `delta` input, which must be greater than 0 for
    the workflow to run.

    """
    # Set the workflow to be in graph mode.
    graph = workctx.graph_mode()

    # Get the instance for which to add an execute operation task to the graph.
    node = workctx.get_node('kube_worker')
    instance = [instance for instance in node.instances][0]

    # Setup events to denote the beginning and end of tasks. The events will be
    # also used to control dependencies amongst tasks.
    start_events, done_events = {}, {}

    for i in range(delta):
        start_events[i] = instance.send_event('Adding node to cluster')
        done_events[i] = instance.send_event('Node added to cluster')

    # Create `delta` number of TaskSequence objects. That way we are able to
    # control the sequence of events and the dependencies amongst tasks. One
    # graph sequence corresponds to a new node added to the cluster.
    for i in range(delta):
        sequence = graph.sequence()
        sequence.add(
            start_events[i],
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.clone', ),
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.create',
                kwargs={
                    'cloud_id': inputs.get('mist_cloud', ''),
                    'image_id': inputs.get('mist_image', ''),
                    'size_id': inputs.get('mist_size', ''),
                    'location_id': inputs.get('mist_location', ''),
                    'networks': inputs.get('mist_networks', []),
                    'key': inputs.get('mist_key', ''),
                },
            ),
            instance.execute_operation(
                operation='cloudify.interfaces.lifecycle.configure', ),
            done_events[i],
        )

    # Now, we use the events to control the tasks' dependencies, ensuring that
    # tasks are executed in the correct order. We aim to create dependencies
    # between a sequence's last event and the next sequence's initial event.
    # That way, we ensure that sequences are executed sequentially, and not in
    # parallel. This is required, since the cloudify.interfaces.lifecycle.clone
    # operation modifies the node instances in local-storage and we want to
    # avoid having multiple tasks messing with the same files at the same time.
    for i in range(delta - 1):
        graph.add_dependency(start_events[i + 1], done_events[i])

    # Start execution.
    return graph.execute()
def a4c_scale(ctx, node_id, delta, scale_compute, **kwargs):
    scaled_node = ctx.get_node(node_id)
    if not scaled_node:
        raise ValueError("Node {0} doesn't exist".format(node_id))
    if not is_host_node(scaled_node):
        raise ValueError("Node {0} is not a host. This workflow can only scale hosts".format(node_id))
    if delta == 0:
        ctx.logger.info('delta parameter is 0, so no scaling will take place.')
        return

    curr_num_instances = scaled_node.number_of_instances
    planned_num_instances = curr_num_instances + delta
    if planned_num_instances < 1:
        raise ValueError('Provided delta: {0} is illegal. current number of'
                         'instances of node {1} is {2}'
                         .format(delta, node_id, curr_num_instances))

    modification = ctx.deployment.start_modification({
        scaled_node.id: {
            'instances': planned_num_instances
        }
    })
    ctx.logger.info(
        'Deployment modification started. [modification_id={0} : {1}]'.format(modification.id, dir(modification)))
    try:
        if delta > 0:
            ctx.logger.info('Scaling host {0} adding {1} instances'.format(node_id, delta))
            added_and_related = _get_all_nodes(modification.added)
            added = _get_all_modified_node_instances(added_and_related, 'added')
            graph = ctx.graph_mode()
            ctx.internal.send_workflow_event(event_type='a4c_workflow_started',
                                             message=build_pre_event(WfStartEvent('scale', 'install')))
            custom_context = CustomContext(ctx, added, added_and_related)
            install_host(ctx, graph, custom_context, node_id)
            try:
                graph.execute()
            except:
                ctx.logger.error('Scale failed. Uninstalling node {0}'.format(node_id))
                graph = ctx.internal.task_graph
                for task in graph.tasks_iter():
                    graph.remove_task(task)
                try:
                    custom_context = CustomContext(ctx, added, added_and_related)
                    uninstall_host(ctx, graph, custom_context, node_id)
                    graph.execute()
                except:
                    ctx.logger.error('Node {0} uninstallation following scale failure has failed'.format(node_id))
                raise
        else:
            ctx.logger.info('Unscaling host {0} removing {1} instances'.format(node_id, delta))
            removed_and_related = _get_all_nodes(modification.removed)
            removed = _get_all_modified_node_instances(removed_and_related, 'removed')
            graph = ctx.graph_mode()
            ctx.internal.send_workflow_event(event_type='a4c_workflow_started',
                                             message=build_pre_event(WfStartEvent('scale', 'uninstall')))
            custom_context = CustomContext(ctx, removed, removed_and_related)
            uninstall_host(ctx, graph, custom_context, node_id)
            try:
                graph.execute()
            except:
                ctx.logger.error('Unscale failed.')
                raise
    except:
        ctx.logger.warn('Rolling back deployment modification. [modification_id={0}]'.format(modification.id))
        try:
            modification.rollback()
        except:
            ctx.logger.warn('Deployment modification rollback failed. The '
                            'deployment model is most likely in some corrupted'
                            ' state.'
                            '[modification_id={0}]'.format(modification.id))
            raise
        raise
    else:
        try:
            modification.finish()
        except:
            ctx.logger.warn('Deployment modification finish failed. The '
                            'deployment model is most likely in some corrupted'
                            ' state.'
                            '[modification_id={0}]'.format(modification.id))
            raise
Beispiel #27
0
def run_operation(operation, nodes_types_list, nodes_types_dependency,
                  relations_unlink, operation_kwargs, **kwargs):
    graph = ctx.graph_mode()
    send_event_starting_tasks = {}
    send_event_done_tasks = {}

    for node_type_update in nodes_types_list:
        for node in ctx.nodes:
            if node.type == node_type_update:
                for instance in node.instances:
                    send_event_starting_tasks[
                        instance.id] = instance.send_event(
                            'Starting to run operation')
                    send_event_done_tasks[instance.id] = instance.send_event(
                        'Done running operation')

    previous_task = None
    for node_type_update in nodes_types_list:
        if not nodes_types_dependency:
            previous_task = None
        for node in ctx.nodes:
            if node.type == node_type_update:
                for instance in node.instances:

                    sequence = graph.sequence()

                    #operation_task = instance.execute_operation(operation, kwargs=operation_kwargs)

                    forkjoin_tasks_unlink = []
                    for relationship in instance.relationships:
                        ctx.logger.info(relationship.relationship.target_id)
                        if relationship.relationship.target_id in relations_unlink:
                            operation_unlink = 'cloudify.interfaces.relationship_lifecycle.unlink'
                            forkjoin_tasks_unlink.append(
                                relationship.execute_source_operation(
                                    operation_unlink))
                            forkjoin_tasks_unlink.append(
                                relationship.execute_target_operation(
                                    operation_unlink))
                    operation_task_unlink = forkjoin(*forkjoin_tasks_unlink)

                    forkjoin_tasks_link = []
                    for relationship in instance.relationships:
                        if relationship.relationship.target_id in relations_unlink:
                            ctx.logger.info('rel op')
                            operation_link = 'cloudify.interfaces.relationship_lifecycle.establish'
                            forkjoin_tasks_link.append(
                                relationship.execute_source_operation(
                                    operation_link))
                            forkjoin_tasks_link.append(
                                relationship.execute_target_operation(
                                    operation_link))
                    operation_task_link = forkjoin(*forkjoin_tasks_link)

                    sequence.add(
                        send_event_starting_tasks[instance.id],
                        operation_task_unlink,
                        instance.execute_operation(
                            'cloudify.interfaces.lifecycle.stop',
                            kwargs=operation_kwargs),
                        instance.execute_operation(
                            'cloudify.interfaces.lifecycle.upgrade',
                            kwargs=operation_kwargs),
                        instance.execute_operation(
                            'cloudify.interfaces.lifecycle.start',
                            kwargs=operation_kwargs), operation_task_link,
                        send_event_done_tasks[instance.id])

                    if previous_task:
                        graph.add_dependency(
                            send_event_starting_tasks.get(instance.id),
                            send_event_done_tasks.get(previous_task))
                        with open("/etc/cloudify/file_out.txt", "w") as f:
                            pprint.pprint(previous_task, f)
                    previous_task = instance.id

    return graph.execute()
Beispiel #28
0
def start_gateway(**kwargs):
    graph = ctx.graph_mode()
    management_instance = None
    gateway_instance = None
    for node in ctx.nodes:
        if "xap_management" == node.id:
            for i in node.instances:
                management_instance = i
                break
        if "xap_gateway" == node.id:
            for i in node.instances:
                gateway_instance = i
                break
        if management_instance is not None and gateway_instance is not None:
            break

    sequence = graph.sequence()
    ctx.logger.info("executing instance {}".format(management_instance))

    lookups = kwargs['gateway_lookups']

    sequence.add(
        management_instance.send_event('Deploying space'),
        management_instance.execute_operation(
            "admin.commands.deploy_gateway_space",
            kwargs={
                'space_name': kwargs['space_name'],
                'space_zones': kwargs['space_zones'],
                'gateway_name': kwargs['gateway_name'],
                'gateway_targets': kwargs['gateway_targets']
            }), gateway_instance.send_event('Deploying gateway'),
        gateway_instance.execute_operation("admin.commands.deploy_gateway_pu",
                                           kwargs={
                                               'space_name':
                                               kwargs['space_name'],
                                               'gateway_zones':
                                               kwargs['gateway_pu_zones'],
                                               'gateway_name':
                                               kwargs['gateway_name'],
                                               'gateway_discoport':
                                               kwargs['gateway_discoport'],
                                               'gateway_commport':
                                               kwargs['gateway_commport'],
                                               'gateway_targets':
                                               kwargs['gateway_targets'],
                                               'gateway_sources':
                                               kwargs['gateway_sources'],
                                               'gateway_lookups':
                                               lookups,
                                               'gateway_natmappings':
                                               kwargs['gateway_natmappings']
                                           }),
        management_instance.send_event('Deploying rest service'),
        management_instance.execute_operation("admin.commands.deploy_rest",
                                              kwargs={
                                                  'space_name':
                                                  kwargs['space_name'],
                                                  'rest_zones':
                                                  kwargs['rest_zones'],
                                                  'rest_port':
                                                  kwargs['rest_port']
                                              }),
        management_instance.send_event('Done running workflow'))

    graph.execute()
Beispiel #29
0
from cloudify.workflows import ctx
from cloudify.manager import get_rest_client
from cloudify.state import workflow_parameters as wf_input


def update_props(ni):
    client = get_rest_client()
    client_ni = client.node_instances.get(ni.id)
    props = client_ni.runtime_properties
    props['package_name'] = wf_input['package_name']
    client.node_instances.update(client_ni.id,
                                 version=client_ni.version,
                                 runtime_properties=props)


for ni in ctx.node_instances:
    if ni.node.type == 'kubernetes_helm_cluster_settings':
        update_props(ni)

ctx.refresh_node_instances()

op_base = 'cloudify.interfaces.lifecycle.'

graph = ctx.graph_mode()
seq = graph.sequence()
for ni in ctx.node_instances:
    if ni.node.type == 'kubernetes_helm_cluster':
        for op in ['helm_create', 'helm_configure', 'helm_install']:
            seq.add(ni.execute_operation(op_base + op, kwargs={}))
graph.execute()
Beispiel #30
0
def a4c_scale(ctx, node_id, delta, scale_compute, **kwargs):
    scaled_node = ctx.get_node(node_id)
    if not scaled_node:
        raise ValueError("Node {0} doesn't exist".format(node_id))
    if not is_host_node(scaled_node):
        raise ValueError(
            "Node {0} is not a host. This workflow can only scale hosts".
            format(node_id))
    if delta == 0:
        ctx.logger.info('delta parameter is 0, so no scaling will take place.')
        return

    curr_num_instances = scaled_node.number_of_instances
    planned_num_instances = curr_num_instances + delta
    if planned_num_instances < 1:
        raise ValueError('Provided delta: {0} is illegal. current number of'
                         'instances of node {1} is {2}'.format(
                             delta, node_id, curr_num_instances))

    modification = ctx.deployment.start_modification(
        {scaled_node.id: {
            'instances': planned_num_instances
        }})
    ctx.logger.info(
        'Deployment modification started. [modification_id={0} : {1}]'.format(
            modification.id, dir(modification)))
    try:
        if delta > 0:
            ctx.logger.info('Scaling host {0} adding {1} instances'.format(
                node_id, delta))
            added_and_related = _get_all_nodes(modification.added)
            added = _get_all_modified_node_instances(added_and_related,
                                                     'added')
            graph = ctx.graph_mode()
            ctx.internal.send_workflow_event(
                event_type='a4c_workflow_started',
                message=build_pre_event(WfStartEvent('scale', 'install')))
            custom_context = CustomContext(ctx, added, added_and_related)
            install_host(ctx, graph, custom_context, node_id)
            try:
                graph.execute()
            except:
                ctx.logger.error(
                    'Scale failed. Uninstalling node {0}'.format(node_id))
                graph = ctx.internal.task_graph
                for task in graph.tasks_iter():
                    graph.remove_task(task)
                try:
                    custom_context = CustomContext(ctx, added,
                                                   added_and_related)
                    uninstall_host(ctx, graph, custom_context, node_id)
                    graph.execute()
                except:
                    ctx.logger.error(
                        'Node {0} uninstallation following scale failure has failed'
                        .format(node_id))
                raise
        else:
            ctx.logger.info('Unscaling host {0} removing {1} instances'.format(
                node_id, delta))
            removed_and_related = _get_all_nodes(modification.removed)
            removed = _get_all_modified_node_instances(removed_and_related,
                                                       'removed')
            graph = ctx.graph_mode()
            ctx.internal.send_workflow_event(
                event_type='a4c_workflow_started',
                message=build_pre_event(WfStartEvent('scale', 'uninstall')))
            custom_context = CustomContext(ctx, removed, removed_and_related)
            uninstall_host(ctx, graph, custom_context, node_id)
            try:
                graph.execute()
            except:
                ctx.logger.error('Unscale failed.')
                raise
    except:
        ctx.logger.warn(
            'Rolling back deployment modification. [modification_id={0}]'.
            format(modification.id))
        try:
            modification.rollback()
        except:
            ctx.logger.warn('Deployment modification rollback failed. The '
                            'deployment model is most likely in some corrupted'
                            ' state.'
                            '[modification_id={0}]'.format(modification.id))
            raise
        raise
    else:
        try:
            modification.finish()
        except:
            ctx.logger.warn('Deployment modification finish failed. The '
                            'deployment model is most likely in some corrupted'
                            ' state.'
                            '[modification_id={0}]'.format(modification.id))
            raise