Example #1
0
def gen_hosts(option, config_file, user, master_proxy):
    dcos_client = mesos.DCOSClient()
    mesos_hosts = []
    dns_hosts = []

    for host in mesos.MesosDNSClient().hosts('master.mesos.'):
        mesos_hosts.append(host['ip'])

    summary = dcos_client.get_state_summary()
    for host in summary['slaves']:
        mesos_hosts.append(host['hostname'])

    scom = 'cat /etc/resolv.conf'
    output = _ssh(True,
                  None,
                  option,
                  config_file,
                  user,
                  master_proxy,
                  scom,
                  print_command=False,
                  short_circuit=True,
                  output=True,
                  tty=False)
    for line in output.splitlines():
        if line.startswith('nameserver'):
            host = line.strip().split()[1]
            dns_hosts.append(host)

    return (mesos_hosts, dns_hosts)
Example #2
0
def _list_components(leader, slave, use_json):
    """ List components for a leader or slave_ip node

    :param leader: use leader ip flag
    :type leader: bool
    :param slave_ip: agent ip address
    :type slave_ip: str
    :param use_json: print components in json format
    :type use_json: bool
    """
    if not (leader or slave):
        raise DCOSException('--leader or --mesos-id must be provided')

    if leader and slave:
        raise DCOSException(
            'Unable to use leader and mesos id at the same time')

    slave_ip = _get_slave_ip(slave)
    if slave_ip:
        print_components(slave_ip, use_json)
        return

    leaders = mesos.MesosDNSClient().hosts('leader.mesos')
    if len(leaders) != 1:
        raise DCOSException('Expecting one leader. Got {}'.format(leaders))

    if 'ip' not in leaders[0]:
        raise DCOSException(
            'Invalid leader response, missing field `ip`. '
            'Got {}'.format(leaders[0]))

    print_components(leaders[0]['ip'], use_json)
Example #3
0
def _ssh(leader, slave, option, config_file, user, master_proxy, proxy_ip,
         private_ip, command):
    """SSH into a DC/OS node using the IP addresses found in master's
       state.json

    :param leader: True if the user has opted to SSH into the leading
                   master
    :type leader: bool | None
    :param slave: The slave ID if the user has opted to SSH into a slave
    :type slave: str | None
    :param option: SSH option
    :type option: [str]
    :param config_file: SSH config file
    :type config_file: str | None
    :param user: SSH user
    :type user: str | None
    :param master_proxy: If True, SSH-hop from a master
    :type master_proxy: bool | None
    :param proxy_ip: If set, SSH-hop from this IP address
    :type proxy_ip: str | None
    :param private_ip: The private IP address of the node we want to SSH to.
    :type private_ip: str | None
    :param command: Command to run on the node
    :type command: str | None
    :rtype: int
    :returns: process return code
    """

    dcos_client = mesos.DCOSClient()

    if leader:
        host = mesos.MesosDNSClient().leader()[0]['ip']
    elif private_ip:
        host = private_ip
    else:
        summary = dcos_client.get_state_summary()
        slave_obj = next(
            (slave_ for slave_ in summary['slaves'] if slave_['id'] == slave),
            None)
        if slave_obj:
            host = mesos.parse_pid(slave_obj['pid'])[1]
        else:
            raise DCOSException('No slave found with ID [{}]'.format(slave))

    if command is None:
        command = ''

    ssh_options = ssh_util.get_ssh_options(config_file, option, user, proxy_ip,
                                           master_proxy)
    cmd = "ssh {0} {1} -- {2}".format(ssh_options, host, command)

    emitter.publish(DefaultError("Running `{}`".format(cmd)))
    if not master_proxy and not proxy_ip:
        emitter.publish(
            DefaultError("If you are running this command from a separate "
                         "network than DC/OS, consider using "
                         "`--master-proxy` or `--proxy-ip`"))

    return subprocess.Subproc().call(cmd, shell=True)
Example #4
0
def get_host(host):
    if not host:
        dcos_client = mesos.DCOSClient()
        host = dcos_client.metadata().get('PUBLIC_IPV4')
    if not host:
        host = mesos.MesosDNSClient().hosts('leader.mesos.')[0]['ip']
    if not host:
        raise DCOSException("*** No host detected. Please set one manually.")
    return host
Example #5
0
 def __init__(self, ssh_client, r_addroute, r_delroute, disablevips,
              disableoverlay):
     self.dcos_client = mesos.DCOSClient()
     self.dns_client = mesos.MesosDNSClient()
     self.ssh_client = ssh_client
     self.addroute = marshal_networks(r_addroute)
     self.delroute = marshal_networks(r_delroute)
     self.disablevips = disablevips
     self.disableoverlay = disableoverlay
Example #6
0
def _list(json_, extra_field_names):
    """List DC/OS nodes

    :param json_: If true, output json.
        Otherwise, output a human readable table.
    :type json_: bool
    :param extra_field_names: List of additional field names to include in
        table output
    :type extra_field_names: [str]
    :returns: process return code
    :rtype: int
    """

    client = mesos.DCOSClient()
    masters = mesos.MesosDNSClient().masters()
    master_state = client.get_master_state()
    slaves = client.get_state_summary()['slaves']
    for master in masters:
        if master['ip'] == master_state['hostname']:
            master['type'] = 'master (leader)'
            region, zone = util.get_fault_domain(master_state)
            master['region'] = region
            master['zone'] = zone
            for key in ('id', 'pid', 'version'):
                master[key] = master_state.get(key)
        else:
            master['type'] = 'master'
    for slave in slaves:
        region, zone = util.get_fault_domain(slave)
        slave['type'] = 'agent'
        slave['region'] = region
        slave['zone'] = zone
    nodes = masters + slaves
    if json_:
        emitter.publish(nodes)
    else:
        for extra_field_name in extra_field_names:
            field_name = extra_field_name.split(':')[-1]
            if len(slaves) > 0:
                try:
                    tables._dotted_itemgetter(field_name)(slaves[0])
                except KeyError:
                    emitter.publish(
                        errors.DefaultError('Field "%s" is invalid.' %
                                            field_name))
                    return
        table = tables.node_table(nodes, extra_field_names)
        output = six.text_type(table)
        if output:
            emitter.publish(output)
        else:
            emitter.publish(errors.DefaultError('No agents found.'))
Example #7
0
def setup_universe_server():
    # Add test repos to Marathon and Cosmos
    for name, url in UNIVERSE_TEST_REPOS.items():
        add_app('tests/data/' + name + '.json', False)
        watch_all_deployments()

        # wait for DNS records for the universe app to be propagated
        host = urlparse(url).netloc
        for i in range(30):
            for record in mesos.MesosDNSClient().hosts(host):
                if record['host'] == host and record['ip'] != '':
                    break
            time.sleep(1)

        assert_command(['dcos', 'package', 'repo', 'add', name, url])
Example #8
0
    def show_leader(self, json_):
        """
        Returns the Marathon leader in the cluster

        :param json_: output json if True
        :type json_: bool
        :returns: process return code
        :rtype: int
        """

        hosts = mesos.MesosDNSClient().hosts('marathon.mesos')
        leader = hosts[0]

        if json_:
            emitter.publish(leader)
        else:
            table = tables.dns_table(hosts)
            emitter.publish(table)
        return 0
Example #9
0
    def ping(self, once):
        """ Pings the marathon client X times where X is the number of masters.

        :param once: run ping once regardless of number of masters
        :type once: bool
        :returns: str response
        :rtype: str
        """
        if once:
            count = 1
        else:
            count = len(mesos.MesosDNSClient().masters())

        consecutive_count = 0
        client = self._create_marathon_client()
        timeout = 10

        @retrying.retry(stop_max_delay=timeout*1000)
        def ping_for_each_master():
            nonlocal consecutive_count
            try:
                response = client.ping()
                consecutive_count = consecutive_count + 1
            except Exception:
                consecutive_count = 0

            if consecutive_count < count:
                msg = 'The consecutive count: {} is less than master count: {}'
                raise DCOSException(msg.format(consecutive_count, count))
            else:
                return response

        try:
            response = ping_for_each_master()
        except Exception:
            response = 'Unable to get ping for all {} masters in {}s'.format(
                count, timeout
            )
        emitter.publish('Marathon ping response[{}x]: {}'.format(
            count, response
        ))
        return 0
Example #10
0
def gen_hosts(ssh_client):
    dcos_client = mesos.DCOSClient()
    mesos_hosts = []
    dns_hosts = []

    for host in mesos.MesosDNSClient().hosts('master.mesos.'):
        mesos_hosts.append(host['ip'])

    summary = dcos_client.get_state_summary()
    for host in summary['slaves']:
        mesos_hosts.append(host['hostname'])

    scom = 'cat /etc/resolv.conf'
    _, query_stdout, _ = ssh_client.exec_command(scom, get_pty=True)
    for line in query_stdout.readlines():
        if line.startswith('nameserver'):
            host = line.strip().split()[1]
            dns_hosts.append(host)

    return (mesos_hosts, dns_hosts)
Example #11
0
def setup_universe_server():
    # add both Unvierse servers with static packages
    add_app('tests/data/universe-v3-stub.json', False)
    add_app('tests/data/helloworld-v3-stub.json', False)

    assert_command(['dcos', 'package', 'repo', 'remove', 'Universe'])

    watch_all_deployments()

    # Add the two test repos to Cosmos
    for name, url in UNIVERSE_TEST_REPOS.items():
        # wait for DNS records for the universe app to be propagated
        host = urlparse(url).netloc
        for i in range(30):
            for record in mesos.MesosDNSClient().hosts(host):
                if record['host'] == host and record['ip'] != '':
                    break
            time.sleep(1)

        assert_command(['dcos', 'package', 'repo', 'add', name, url])
Example #12
0
def _ssh(master, slave, option, config_file, user):
    """SSH into a DCOS node using the IP addresses found in master's
       state.json

    :param master: True if the user has opted to SSH into the leading
                   master
    :type master: bool | None
    :param slave: The slave ID if the user has opted to SSH into a slave
    :type slave: str | None
    :param option: SSH option
    :type option: [str]
    :param config_file: SSH config file
    :type config_file: str | None
    :param user: SSH user
    :type user: str | None
    :rtype: int
    :returns: process return code
    """

    ssh_options = util.get_ssh_options(config_file, option)

    if master:
        host = mesos.MesosDNSClient().hosts('leader.mesos.')[0]['ip']
    else:
        summary = mesos.DCOSClient().get_state_summary()
        slave_obj = next((slave_ for slave_ in summary['slaves']
                          if slave_['id'] == slave),
                         None)
        if slave_obj:
            host = mesos.parse_pid(slave_obj['pid'])[1]
        else:
            raise DCOSException('No slave found with ID [{}]'.format(slave))

    cmd = "ssh -t {0}{1}@{2}".format(
        ssh_options,
        user,
        host)

    emitter.publish(DefaultError("Running `{}`".format(cmd)))

    return subprocess.call(cmd, shell=True)
Example #13
0
def _dns_lookup(dns_name, json_):
    """
    Returns the IP of the dns-name in the cluster

    :param dns_name: dns name to lookup
    :type dns_name: string
    :param json_: If true, output json.
        Otherwise, output a human readable table.
    :type json_: bool
    """

    ips = mesos.MesosDNSClient().hosts(dns_name)

    if json_:
        emitter.publish(ips)
    else:
        table = tables.dns_table(ips)
        output = six.text_type(table)
        if output:
            emitter.publish(output)

    return 0
Example #14
0
def _ssh(leader, slave, option, config_file, user, master_proxy, proxy_ip,
         command):
    """SSH into a DC/OS node using the IP addresses found in master's
       state.json

    :param leader: True if the user has opted to SSH into the leading
                   master
    :type leader: bool | None
    :param slave: The slave ID if the user has opted to SSH into a slave
    :type slave: str | None
    :param option: SSH option
    :type option: [str]
    :param config_file: SSH config file
    :type config_file: str | None
    :param user: SSH user
    :type user: str | None
    :param master_proxy: If True, SSH-hop from a master
    :type master_proxy: bool | None
    :param proxy_ip: If set, SSH-hop from this IP address
    :type proxy_ip: str | None
    :param command: Command to run on the node
    :type command: str | None
    :rtype: int
    :returns: process return code
    """

    ssh_options = util.get_ssh_options(config_file, option)
    dcos_client = mesos.DCOSClient()

    if leader:
        host = mesos.MesosDNSClient().hosts('leader.mesos.')[0]['ip']
    else:
        summary = dcos_client.get_state_summary()
        slave_obj = next((slave_ for slave_ in summary['slaves']
                          if slave_['id'] == slave),
                         None)
        if slave_obj:
            host = mesos.parse_pid(slave_obj['pid'])[1]
        else:
            raise DCOSException('No slave found with ID [{}]'.format(slave))

    if command is None:
        command = ''

    master_public_ip = dcos_client.metadata().get('PUBLIC_IPV4')

    if master_proxy:
        if not master_public_ip:
            raise DCOSException(("Cannot use --master-proxy.  Failed to find "
                                 "'PUBLIC_IPV4' at {}").format(
                                     dcos_client.get_dcos_url('metadata')))
        proxy_ip = master_public_ip

    if proxy_ip:
        if not os.environ.get('SSH_AUTH_SOCK'):
            raise DCOSException(
                "There is no SSH_AUTH_SOCK env variable, which likely means "
                "you aren't running `ssh-agent`.  `dcos node ssh "
                "--master-proxy/--proxy-ip` depends on `ssh-agent` to safely "
                "use your private key to hop between nodes in your cluster.  "
                "Please run `ssh-agent`, then add your private key with "
                "`ssh-add`.")
        cmd = "ssh -A -t {0}{1}@{2} ssh -A -t {0}{1}@{3} {4}".format(
            ssh_options,
            user,
            proxy_ip,
            host,
            command)
    else:
        cmd = "ssh -t {0}{1}@{2} {3}".format(
            ssh_options,
            user,
            host,
            command)

    emitter.publish(DefaultError("Running `{}`".format(cmd)))
    if (not master_proxy and not proxy_ip) and master_public_ip:
        emitter.publish(
            DefaultError("If you are running this command from a separate "
                         "network than DC/OS, consider using "
                         "`--master-proxy` or `--proxy-ip`"))

    return subprocess.Subproc().call(cmd, shell=True)
Example #15
0
def _ssh(leader,
         slave,
         option,
         config_file,
         user,
         master_proxy,
         command,
         flag=[],
         print_command=True,
         short_circuit=False,
         output=False,
         output_dst=None,
         tty=True,
         raw=False):
    """SSH into a DCOS node using the IP addresses found in master's
       state.json

    :param leader: True if the user has opted to SSH into the leading
                   master
    :type leader: bool | None
    :param slave: The slave ID if the user has opted to SSH into a slave
    :type slave: str | None
    :param option: SSH option
    :type option: [str]
    :param config_file: SSH config file
    :type config_file: str | None
    :param user: SSH user
    :type user: str | None
    :param master_proxy: If True, SSH-hop from a master
    :type master_proxy: bool | None
    :param command: Command to run on the node
    :type command: str | None
    :param flag: SSH flags
    :type flag: [str]
    :param print_command: If True, print the raw SSH command
    :type print_command: bool
    :param short_circuit: Only use the first SSH connection made
    :type short_circuit: bool
    :param output: If True, return the output of the ssh command
    :type output: boolean
    :param output_dst: Where to send the output of SSH
    :type output_dst: object | None
    :param tty: If True, have SSH allocate a TTY
    :type tty: boolean
    :param raw: If True, return a subprocess.Popen object
    :type raw: boolean
    :rtype: int
    :returns: process return code | str
    """

    ssh_options = util.get_ssh_options(config_file, option)
    dcos_client = mesos.DCOSClient()
    flagstr = " ".join(flag)

    if tty:
        flagstr += ' -t'
    else:
        flagstr += ' -T'

    if leader:
        host = mesos.MesosDNSClient().hosts('leader.mesos.')[0]['ip']
    else:
        summary = dcos_client.get_state_summary()
        slave_obj = next(
            (slave_ for slave_ in summary['slaves'] if slave_['id'] == slave),
            None)
        if slave_obj:
            host = mesos.parse_pid(slave_obj['pid'])[1]
        else:
            raise DCOSException('No slave found with ID [{}]'.format(slave))

    if command is None:
        command = ''

    master_public_ip = dcos_client.metadata().get('PUBLIC_IPV4')
    if master_proxy:
        if not os.environ.get('SSH_AUTH_SOCK'):
            raise DCOSException(
                "There is no SSH_AUTH_SOCK env variable, which likely means "
                "you aren't running `ssh-agent`.  `dcos node ssh "
                "--master-proxy` depends on `ssh-agent` to safely use your "
                "private key to hop between nodes in your cluster.  Please "
                "run `ssh-agent`, then add your private key with `ssh-add`.")
        if not master_public_ip:
            raise DCOSException(("Cannot use --master-proxy.  Failed to find "
                                 "'PUBLIC_IPV4' at {}").format(
                                     dcos_client.get_dcos_url('metadata')))

        cmd = "ssh -A {0} {1}{2}@{3} ssh {0} {1}{2}@{4} {5}"
        if short_circuit:
            cmd = "ssh -A {0} {1}{2}@{3} {5}"
        cmd = cmd.format(flagstr, ssh_options, user, master_public_ip, host,
                         command)
    else:
        cmd = "ssh {0} {1}{2}@{3} {4}".format(flagstr, ssh_options, user, host,
                                              command)

    if print_command:
        emitter.publish(DefaultError("Running `{}`".format(cmd)))
    if (not master_proxy) and master_public_ip:
        emitter.publish(
            DefaultError("If you are running this command from a separate "
                         "network than DC/OS, consider using "
                         "`--master-proxy`"))

    cmd = shlex.split(cmd)
    if output:
        return subprocess.check_output(cmd)
    if raw:
        if output_dst is not None:
            return subprocess.Popen(cmd, stderr=output_dst, stdout=output_dst)
        return subprocess.Popen(cmd)
    if output_dst is not None:
        return subprocess.call(cmd, stderr=output_dst, stdout=output_dst)
    return subprocess.call(cmd)