def _log_marathon(follow, lines, ssh_config_file): """Prints the contents of the marathon logs. :param follow: same as unix tail's -f :type follow: bool :param lines: number of lines to print :type lines: int :param ssh_config_file: SSH config file. :type ssh_config_file: str | None ;:returns: process return code :rtype: int """ ssh_options = util.get_ssh_options(ssh_config_file, []) journalctl_args = "" if follow: journalctl_args += "-f " if lines: journalctl_args += "-n {} ".format(lines) leader_ip = marathon.create_client().get_leader().split(":")[0] cmd = ("ssh {0}core@{1} " + "journalctl {2}-u marathon").format(ssh_options, leader_ip, journalctl_args) emitter.publish(DefaultError("Running `{}`".format(cmd))) return subprocess.call(cmd, shell=True)
def _log_marathon(follow, lines, ssh_config_file): """Prints the contents of the marathon logs. :param follow: same as unix tail's -f :type follow: bool :param lines: number of lines to print :type lines: int :param ssh_config_file: SSH config file. :type ssh_config_file: str | None ;:returns: process return code :rtype: int """ ssh_options = util.get_ssh_options(ssh_config_file, []) journalctl_args = '' if follow: journalctl_args += '-f ' if lines: journalctl_args += '-n {} '.format(lines) leader_ip = marathon.create_client().get_leader().split(':')[0] user_string = 'core@' if ssh_config_file: user_string = '' cmd = ("ssh {0}{1}{2} " + "journalctl {3}-u dcos-marathon").format( ssh_options, user_string, leader_ip, journalctl_args) emitter.publish(DefaultError("Running `{}`".format(cmd))) return subprocess.Subproc().call(cmd, shell=True)
def _socks(port, config_file, user, privileged, ssh_port, host, verbose, option): """ SOCKS proxy into a DC/OS node using the IP addresses found in master's state.json :param port: The port the SOCKS proxy listens on locally :type port: int | None :param config_file: SSH config file :type config_file: str | None :param user: SSH user :type user: str | None :param privileged: If True, override privilege checks :type privileged: bool :param ssh_port: The port SSH is accessible through :type ssh_port: int | None :param host: The host to connect to :type host: str | None :param verbose: Verbose output :type verbose: bool :param option: SSH option :type option: [str] :returns: process return code :rtype: int """ if verbose: set_verbose() if privileged: os.environ[constants.privileged] = '1' port = validate_port(port, default=1080) if port is None: return 1 if ssh_port is not None: option.append("Port={}".format(ssh_port)) ssh_options = util.get_ssh_options(config_file, option) host = get_host(host) other_options = '' if verbose: other_options += ' -v' scom = "ssh -N -D {} {} {} {}@{}".format( port, ssh_options, other_options, user, host) logger.debug('SSH command: "%s"', scom) emitter.publish('SOCKS proxy listening on port {}'.format(port)) return subprocess_call(shlex.split(scom))
def _socks(port, config_file, user, privileged, ssh_port, host, verbose, option): """ SOCKS proxy into a DC/OS node using the IP addresses found in master's state.json :param port: The port the SOCKS proxy listens on locally :type port: int | None :param config_file: SSH config file :type config_file: str | None :param user: SSH user :type user: str | None :param privileged: If True, override privilege checks :type privileged: bool :param ssh_port: The port SSH is accessible through :type ssh_port: int | None :param host: The host to connect to :type host: str | None :param verbose: Verbose output :type verbose: bool :param option: SSH option :type option: [str] :returns: process return code :rtype: int """ if verbose: set_verbose() if privileged: os.environ[constants.privileged] = '1' port = validate_port(port, default=1080) if port is None: return 1 if ssh_port is not None: option.append("Port={}".format(ssh_port)) ssh_options = util.get_ssh_options(config_file, option) host = get_host(host) other_options = '' if verbose: other_options += ' -v' scom = "ssh -N -D {} {} {} {}@{}".format(port, ssh_options, other_options, user, host) logger.debug('SSH command: "%s"', scom) emitter.publish('SOCKS proxy listening on port {}'.format(port)) return subprocess_call(shlex.split(scom))
def _log_marathon(follow, lines, ssh_config_file): """Prints the contents of the marathon logs. Proxy through the master because marathon only runs on the master. :param follow: same as unix tail's -f :type follow: bool :param lines: number of lines to print :type lines: int :param ssh_config_file: SSH config file. :type ssh_config_file: str | None ;:returns: process return code :rtype: int """ ssh_options = util.get_ssh_options(ssh_config_file, []) journalctl_args = '' if follow: journalctl_args += '-f ' if lines: journalctl_args += '-n {} '.format(lines) leader_ip = marathon.create_client().get_leader().split(':')[0] user_string = 'core@' if ssh_config_file: user_string = '' dcos_client = mesos.DCOSClient() master_public_ip = dcos_client.metadata().get('PUBLIC_IPV4') service = 'dcos-marathon' cmd = "ssh -At {0}{1}{2} ssh -At {0}{1}{3} journalctl {4}-u {5}".format( ssh_options, user_string, master_public_ip, leader_ip, journalctl_args, service) emitter.publish(DefaultError("Running `{}`".format(cmd))) return subprocess.Subproc().call(cmd, shell=True)
def _ssh(master, slave, option, config_file, user): """SSH into a DCOS node. Since only the masters are definitely publicly available, we first ssh into an arbitrary master, then hop to the desired node. :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)
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)
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)
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)
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)
def _ssh(leader, slave, option, config_file, user, master_proxy, 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 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 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 -t {0}{1}@{2} ssh -A -t {0}{1}@{3} {4}".format( ssh_options, user, master_public_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 master_public_ip: emitter.publish( DefaultError("If you are running this command from a separate " "network than DC/OS, consider using " "`--master-proxy`")) return subprocess.Subproc().call(cmd, shell=True)
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)