def cluster_node_present(name, node, extra_args=None):
    '''
    Add a node to the Pacemaker cluster via PCS
    Should be run on one cluster node only
    (there may be races)
    Can only be run on a already setup/added node

    name
        Irrelevant, not used (recommended: pcs_setup__node_add_{{node}})
    node
        node that should be added
    extra_args
        list of extra args for the \'pcs cluster node add\' command

    Example:

    .. code-block:: yaml

        pcs_setup__node_add_node1.example.com:
            pcs.cluster_node_present:
                - node: node1.example.com
                - extra_args:
                    - '--start'
                    - '--enable'
    '''

    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
    node_add_required = True
    current_nodes = []

    is_member_cmd = ['pcs', 'status', 'nodes', 'corosync']
    is_member = __salt__['cmd.run_all'](is_member_cmd, output_loglevel='trace', python_shell=False)
    log.trace('Output of pcs status nodes corosync: %s', is_member)

    for line in is_member['stdout'].splitlines():
        try:
            key, value = [x.strip() for x in line.split(':')]
        except ValueError:
            continue
        else:
            if not value or key not in ('Offline', 'Online'):
                continue
            values = value.split(':')
            if node in values:
                node_add_required = False
                ret['comment'] += 'Node {0} is already member of the cluster\n'.format(node)
            else:
                current_nodes += values

    if not node_add_required:
        return ret

    if __opts__['test']:
        ret['result'] = None
        ret['comment'] += 'Node {0} is set to be added to the cluster\n'.format(node)
        return ret

    if not isinstance(extra_args, (list, tuple)):
        extra_args = []

    node_add = __salt__['pcs.cluster_node_add'](node=node, extra_args=extra_args)
    log.trace('Output of pcs.cluster_node_add: %s', node_add)

    node_add_dict = {}
    for line in node_add['stdout'].splitlines():
        log.trace('line: %s', line)
        log.trace('line.split(:).len: %s', len(line.split(':')))
        if len(line.split(':')) in [2]:
            current_node = line.split(':')[0].strip()
            current_node_add_state = line.split(':')[1].strip()
            if current_node in current_nodes + [node]:
                node_add_dict.update({current_node: current_node_add_state})
    log.trace('node_add_dict: %s', node_add_dict)

    for current_node in current_nodes:
        if current_node in node_add_dict:
            if node_add_dict[current_node] not in ['Corosync updated']:
                ret['result'] = False
                ret['comment'] += 'Failed to update corosync.conf on node {0}\n'.format(current_node)
                ret['comment'] += '{0}: node_add_dict: {1}\n'.format(current_node, node_add_dict[current_node])
        else:
            ret['result'] = False
            ret['comment'] += 'Failed to update corosync.conf on node {0}\n'.format(current_node)

    if node in node_add_dict and node_add_dict[node] in ['Succeeded', 'Success']:
        ret['comment'] += 'Added node {0}\n'.format(node)
        ret['changes'].update({node: {'old': '', 'new': 'Added'}})
    else:
        ret['result'] = False
        ret['comment'] += 'Failed to add node{0}\n'.format(node)
        if node in node_add_dict:
            ret['comment'] += '{0}: node_add_dict: {1}\n'.format(node, node_add_dict[node])
        ret['comment'] += six.text_type(node_add)

    log.trace('ret: %s', ret)

    return ret
def cluster_node_present ( name , node , extra_args = None ) : ret = { 'name' : name , 'result' : True , 'comment' : '' , 'changes' : { } } node_add_required = True current_nodes = [ ] is_member_cmd = [ 'pcs' , 'status' , 'nodes' , 'corosync' ] is_member = __salt__ [ 'cmd.run_all' ] ( is_member_cmd , output_loglevel = 'trace' , python_shell = False ) log . trace ( 'Output of pcs status nodes corosync: %s' , is_member ) for line in is_member [ 'stdout' ] . splitlines ( ) : try : key , value = [ x . strip ( ) for x in line . split ( ':' ) ] except ValueError : continue else : if not value or key not in ( 'Offline' , 'Online' ) : continue values = value . split ( ':' ) if node in values : node_add_required = False ret [ 'comment' ] += 'Node {0} is already member of the cluster\n' . format ( node ) else : current_nodes += values if not node_add_required : return ret if __opts__ [ 'test' ] : ret [ 'result' ] = None ret [ 'comment' ] += 'Node {0} is set to be added to the cluster\n' . format ( node ) return ret if not isinstance ( extra_args , ( list , tuple ) ) : extra_args = [ ] node_add = __salt__ [ 'pcs.cluster_node_add' ] ( node = node , extra_args = extra_args ) log . trace ( 'Output of pcs.cluster_node_add: %s' , node_add ) node_add_dict = { } for line in node_add [ 'stdout' ] . splitlines ( ) : log . trace ( 'line: %s' , line ) log . trace ( 'line.split(:).len: %s' , len ( line . split ( ':' ) ) ) if len ( line . split ( ':' ) ) in [ 2 ] : current_node = line . split ( ':' ) [ 0 ] . strip ( ) current_node_add_state = line . split ( ':' ) [ 1 ] . strip ( ) if current_node in current_nodes + [ node ] : node_add_dict . update ( { current_node : current_node_add_state } ) log . trace ( 'node_add_dict: %s' , node_add_dict ) for current_node in current_nodes : if current_node in node_add_dict : if node_add_dict [ current_node ] not in [ 'Corosync updated' ] : ret [ 'result' ] = False ret [ 'comment' ] += 'Failed to update corosync.conf on node {0}\n' . format ( current_node ) ret [ 'comment' ] += '{0}: node_add_dict: {1}\n' . format ( current_node , node_add_dict [ current_node ] ) else : ret [ 'result' ] = False ret [ 'comment' ] += 'Failed to update corosync.conf on node {0}\n' . format ( current_node ) if node in node_add_dict and node_add_dict [ node ] in [ 'Succeeded' , 'Success' ] : ret [ 'comment' ] += 'Added node {0}\n' . format ( node ) ret [ 'changes' ] . update ( { node : { 'old' : '' , 'new' : 'Added' } } ) else : ret [ 'result' ] = False ret [ 'comment' ] += 'Failed to add node{0}\n' . format ( node ) if node in node_add_dict : ret [ 'comment' ] += '{0}: node_add_dict: {1}\n' . format ( node , node_add_dict [ node ] ) ret [ 'comment' ] += six . text_type ( node_add ) log . trace ( 'ret: %s' , ret ) return ret
Add a node to the Pacemaker cluster via PCS
    Should be run on one cluster node only
    (there may be races)
    Can only be run on a already setup/added node

    name
        Irrelevant, not used (recommended: pcs_setup__node_add_{{node}})
    node
        node that should be added
    extra_args
        list of extra args for the \'pcs cluster node add\' command

    Example:

    .. code-block:: yaml

        pcs_setup__node_add_node1.example.com:
            pcs.cluster_node_present:
                - node: node1.example.com
                - extra_args:
                    - '--start'
                    - '--enable'