コード例 #1
0
ファイル: caasp_etcd.py プロジェクト: nirmoy/salt
def get_endpoints(with_id=False, skip_this=False, skip_removed=False, port=ETCD_CLIENT_PORT, sep=','):
    '''
    Build a comma-separated list of etcd endpoints

    It will skip

      * current node, when `skip_this=True`
      * nodes with G@node_removal_in_progress=true, when `skip_removed=True`

    '''
    expr = 'G@roles:etcd'
    if skip_removed:
        expr += ' and not G@node_removal_in_progress:true'

    etcd_members_lst = []
    for (node_id, name) in __salt__['caasp_grains.get'](expr).items():
        if skip_this and name == __salt__['caasp_net.get_nodename']():
            continue
        member_endpoint = 'https://{}:{}'.format(name, port)
        if with_id:
            member_endpoint = "{}={}".format(node_id, member_endpoint)
        etcd_members_lst.append(member_endpoint)

    if len(etcd_members_lst) == 0:
        error('no etcd members available!!')
        raise NoEtcdServersException()

    etcd_members_lst.sort()
    return sep.join(etcd_members_lst)
コード例 #2
0
def get_member_id(nodename=None):
    '''
    Return the member ID (different from the node ID) for
    a etcd member of the cluster.

    Arguments:

    * `nodename`: (optional) the nodename for the member we
                  want the ID for. if no name is provided (or empty),
                  the local node will be used.
    '''
    command = ["etcdctl"] + get_etcdctl_args() + ["member", "list"]

    target_nodename = nodename or __salt__['caasp_net.get_nodename']()

    debug("getting etcd member ID with: %s", command)
    try:
        target_url = 'https://{}:{}'.format(target_nodename, ETCD_CLIENT_PORT)
        members_output = subprocess.check_output(command)
        for member_line in members_output.splitlines():
            if target_url in member_line:
                return member_line.split(':')[0]

    except Exception as e:
        error('cannot get member ID for "%s": %s', e, target_nodename)
        error('output: %s', members_output)

    return ''
コード例 #3
0
def get_additional_etcd_members(num_wanted=None, **kwargs):
    '''
    Taking into account

      1) the current number of etcd members, and
      2) the number of etcd nodes we should be running in the
         cluster (obtained with `get_cluster_size()`)

    get a list of additional nodes (IDs) that should run `etcd` too.

    Optional arguments:

      * `etcd_members`: list of current etcd members
      * `excluded`: list of nodes to exclude
    '''
    excluded = kwargs.get('excluded', [])

    current_etcd_members = __salt__['caasp_nodes.get_from_args_or_with_expr'](
        'etcd_members', kwargs, 'G@roles:etcd')
    num_current_etcd_members = len(current_etcd_members)

    # the number of etcd masters that should be in the cluster
    num_wanted_etcd_members = num_wanted or get_cluster_size(**kwargs)
    # ... and the number we are missing
    num_additional_etcd_members = num_wanted_etcd_members - num_current_etcd_members

    if num_additional_etcd_members <= 0:
        debug('get_additional_etcd_members: we dont need more etcd members')
        return []

    debug('get_additional_etcd_members: curr:%d wanted:%d -> %d missing',
          num_current_etcd_members, num_wanted_etcd_members,
          num_additional_etcd_members)

    # Get a list of `num_additional_etcd_members` nodes that could be used
    # for running etcd. A valid node is a node that:
    #
    #   1) is not the `admin` or `ca`
    #   2) has no `etcd` role (bootstrapped or not)
    #   2) is not being removed/added/updated
    #   3) (in preference order, first for non bootstrapped nodes)
    #       1) has no role assigned
    #       2) is a master
    #       3) is a minion
    #
    new_etcd_members = __salt__['caasp_nodes.get_with_prio_for_role'](
        num_additional_etcd_members,
        'etcd',
        excluded=current_etcd_members + excluded)

    if len(new_etcd_members) < num_additional_etcd_members:
        error(
            'get_additional_etcd_members: cannot satisfy the %s members missing',
            num_additional_etcd_members)

    return new_etcd_members
コード例 #4
0
ファイル: caasp_net.py プロジェクト: andaok/salt-kube
def get_primary_ips_for(compound, **kwargs):
    """
    given a compound expression 'compound', return the primary IPs for all the
    nodes that match that expression
    """
    try:
        all_ifaces = __salt__["caasp_grains.get"](compound,
                                                  "network.interfaces")
        return [
            get_primary_ip(host=host, **kwargs) for host in all_ifaces.keys()
        ]
    except Exception as e:
        error("could not get primary IPs for %s: %s", compound, e)
        return []
コード例 #5
0
ファイル: caasp_net.py プロジェクト: andaok/salt-kube
def get_nodename(host=None, **kwargs):
    """
    (given some optional 'host')
    return the `nodename`
    """
    try:
        if not host:
            assert __opts__["__role"] != "master"
            return __salt__["grains.get"](NODENAME_GRAIN)
        else:
            all_nodenames = __salt__["caasp_grains.get"](host,
                                                         grain=NODENAME_GRAIN,
                                                         type="glob")
            return all_nodenames[host]
    except Exception as e:
        error("could not get nodename: %s", e)
        return ""
コード例 #6
0
def get_nodename(host=None, **kwargs):
    '''
    (given some optional 'host')
    return the `nodename`
    '''
    try:
        if not host:
            assert __opts__['__role'] != 'master'
            return __salt__['grains.get']('nodename')
        else:
            all_nodenames = __salt__['caasp_grains.get'](host,
                                                         'nodename',
                                                         type='glob')
            return all_nodenames[host]
    except Exception as e:
        error('could not get nodename: %s', e)
        return ''
コード例 #7
0
def get_primary_iface(host=None):
    '''
    (given some optional 'host')
    return the name of the primary iface (the iface associated with the default route)
    '''
    try:
        if not host or host == get_nodename():
            default_route_lst = __salt__['network.default_route']()
            return default_route_lst[0]['interface']
        else:
            all_routes = __salt__['caasp_grains.get'](host,
                                                      'network.default_route',
                                                      type='glob')
            return all_routes[host][0]['interface']
    except Exception as e:
        error('could not get the primary interface: %s', e)
        return __salt__['caasp_pillar.get']('hw:netiface', DEFAULT_INTERFACE)
コード例 #8
0
ファイル: caasp_net.py プロジェクト: andaok/salt-kube
def get_iface_ip(iface, host=None, ifaces=None):
    """
    given an 'iface' (and an optional 'host' and list of 'ifaces'),
    return the IP address associated with 'iface'
    """
    try:
        if not ifaces:
            if not host or host == get_nodename():
                ifaces = __salt__["network.interfaces"]()
            else:
                ifaces = __salt__["caasp_grains.get"](host,
                                                      "network.interfaces",
                                                      type="glob")

        iface = ifaces.get(iface)
        ipv4addr = iface.get("inet", [{}])
        return ipv4addr[0].get("address")
    except Exception as e:
        error("could not get IP for interface %s: %s", iface, e)
        return ""
コード例 #9
0
def get_iface_ip(iface, host=None, ifaces=None):
    '''
    given an 'iface' (and an optional 'host' and list of 'ifaces'),
    return the IP address associated with 'iface'
    '''
    try:
        if not ifaces:
            if not host or host == get_nodename():
                ifaces = __salt__['network.interfaces']()
            else:
                ifaces = __salt__['caasp_grains.get'](host,
                                                      'network.interfaces',
                                                      type='glob')

        iface = ifaces.get(iface)
        ipv4addr = iface.get('inet', [{}])
        return ipv4addr[0].get('address')
    except Exception as e:
        error('could not get IP for interface %s: %s', iface, e)
        return ''
コード例 #10
0
def get_registries_certs(lst, default_port=5000):
    '''
    Given a list of "valid" items, return a dictionay of
    "<HOST>[:<PORT>]" -> <CERT>
    "valid" items must be get'able objects, with attributes
    "url", "cert" and (optional) "mirrors"
    "url"s can be [<PROTO>://]<HOST>[:<PORT>]
    '''
    certs = {}

    debug('Finding certificates in: %s', lst)
    for registry in lst:
        try:
            url = registry.get('url')

            cert = registry.get('cert', '')
            if cert:

                # parse the name as an URL or "host:port", and return <HOST>[:<PORT>]
                hostname, port = _get_hostname_and_port(url)
                host_port = hostname
                if port:
                    host_port += ":" + str(port)

                debug('Adding certificate for: %s', host_port)
                certs[host_port] = cert

                if port:
                    if port == default_port:
                        # When using the standar port (5000), if the user introduces
                        # "my-registry:5000" as a trusted registry, he/she will be able
                        # to do "docker pull my-registry:5000/some/image" but not
                        # "docker pull my-registry/some/image".
                        # So we must also create the "ca.crt" for "my-registry"
                        # as he/she could just access "docker pull my-registry/some/image",
                        # and Docker would fail to find "my-registry/ca.crt"
                        name = hostname
                        debug(
                            'Using default port: adding certificate for "%s" too', name)
                        certs[name] = cert
                else:
                    # the same happens if the user introduced a certificate for
                    # "my-registry": we must fix the "docker pull my-registry:5000/some/image" case...
                    name = hostname + ':' + str(default_port)
                    debug(
                        'Adding certificate for default port, "%s", too', name)
                    certs[name] = cert

        except Exception as e:
            error('Could not parse certificate: %s', e)

        try:
            mirrors = registry.get('mirrors', [])
            if mirrors:
                debug('Looking recursively for certificates in mirrors')
                certs_mirrors = get_registries_certs(mirrors,
                                                     default_port=default_port)
                certs.update(certs_mirrors)
        except Exception as e:
            error('Could not parse mirrors: %s', e)

    return certs