Merge pull request #276 from mesosphere/remove-ssh-agent

remove ssh-agent from `dcos node ssh`
This commit is contained in:
mgummelt
2015-07-16 12:08:05 -07:00
7 changed files with 59 additions and 49 deletions

View File

@@ -23,7 +23,6 @@ Options:
--version Show version
"""
import os
import subprocess
import dcoscli
@@ -186,15 +185,7 @@ def _ssh(master, slave, option, config_file, user):
:returns: process return code
"""
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` depends on " +
"`ssh-agent` so we can safely use your private key to hop " +
"between nodes in your cluster. Please run `ssh-agent`, " +
"then add your private key with `ssh-add`.")
master_public_ip = mesos.DCOSClient().metadata()['PUBLIC_IPV4']
ssh_options = ' '.join('-o {}'.format(opt) for opt in option)
if config_file:
@@ -203,7 +194,7 @@ def _ssh(master, slave, option, config_file, user):
ssh_config = ''
if master:
host = 'leader.mesos'
host = mesos.MesosDNSClient().hosts('leader.mesos.')[0]['ip']
else:
summary = mesos.DCOSClient().get_state_summary()
slave_obj = next((slave_ for slave_ in summary['slaves']
@@ -214,11 +205,10 @@ def _ssh(master, slave, option, config_file, user):
else:
raise DCOSException('No slave found with ID [{}]'.format(slave))
cmd = "ssh -A -t {0} {1} {2}@{3} ssh -A -t {2}@{4}".format(
cmd = "ssh -t {0} {1} {2}@{3}".format(
ssh_options,
ssh_config,
user,
master_public_ip,
host)
return subprocess.call(cmd, shell=True)

View File

@@ -145,26 +145,14 @@ def test_node_ssh_user():
assert stderr.startswith(b'Permission denied')
def test_node_ssh_no_agent():
stderr = (b"There is no SSH_AUTH_SOCK env variable, which likely means "
b"you aren't running `ssh-agent`. `dcos node ssh` depends on"
b" `ssh-agent` so we can safely use your private key to hop "
b"between nodes in your cluster. Please run `ssh-agent`, then "
b"add your private key with `ssh-add`.\n")
assert_command(['dcos', 'node', 'ssh', '--master'],
stdout=b'',
stderr=stderr,
returncode=1)
def _node_ssh_output(args):
# ssh must run with stdin attached to a tty
master, slave = pty.openpty()
cmd = ('dcos node ssh --option ' +
'IdentityFile=/host-home/.vagrant.d/insecure_private_key ' +
'--option StrictHostKeyChecking=no ' +
'{}').format(' '.join(args))
cmd = ('ssh-agent /bin/bash -c ' +
'"ssh-add /host-home/.vagrant.d/insecure_private_key ' +
'2> /dev/null && dcos node ssh --option StrictHostKeyChecking=no' +
' {}"').format(' '.join(args))
proc = subprocess.Popen(cmd,
stdin=slave,
stdout=subprocess.PIPE,

View File

@@ -66,22 +66,21 @@ def request(method,
:rtype: Response
"""
if 'headers' not in kwargs:
kwargs['headers'] = {'Accept': 'application/json'}
request = requests.Request(
method=method,
url=url,
**kwargs)
logger.info(
'Sending HTTP [%r] to [%r]: %r',
request.method,
request.url,
request.headers)
try:
if 'headers' in kwargs:
request = requests.Request(method=method, url=url, **kwargs)
else:
request = requests.Request(
method=method,
url=url,
headers={'Accept': 'application/json'},
**kwargs)
logger.info(
'Sending HTTP [%r] to [%r]: %r',
request.method,
request.url,
request.headers)
with requests.Session() as session:
response = session.send(request.prepare(), timeout=timeout,
proxies=util.get_proxy_dict_from_env())

View File

@@ -37,7 +37,7 @@ def _get_marathon_url(config):
marathon_url = config.get('marathon.url')
if marathon_url is None:
dcos_url = util.get_config_vals(config, ['core.dcos_url'])[0]
dcos_url = util.get_config_vals(['core.dcos_url'], config)[0]
marathon_url = urllib.parse.urljoin(dcos_url, 'marathon/')
return marathon_url

View File

@@ -36,7 +36,7 @@ class DCOSClient(object):
mesos_master_url = config.get('core.mesos_master_url')
if mesos_master_url is None:
self._dcos_url = util.get_config_vals(config, ['core.dcos_url'])[0]
self._dcos_url = util.get_config_vals(['core.dcos_url'], config)[0]
else:
self._mesos_master_url = mesos_master_url
@@ -203,6 +203,38 @@ class DCOSClient(object):
return http.get(url).json()
class MesosDNSClient(object):
""" Mesos-DNS client
:param url: mesos-dns URL
:type url: str
"""
def __init__(self, url=None):
self.url = url or urllib.parse.urljoin(
util.get_config_vals(['core.dcos_url'])[0], '/mesos_dns/')
def _path(self, path):
""" Construct a full path
:param path: path suffix
:type path: str
:returns: full path
:rtype: str
"""
return urllib.parse.urljoin(self.url, path)
def hosts(self, host):
""" GET v1/hosts/<host>
:param host: host
:type host: str
:returns: {'ip', 'host'} dictionary
:rtype: dict(str, str)
"""
url = self._path('v1/hosts/{}'.format(host))
return http.get(url, headers={}).json()
class Master(object):
"""Mesos Master Model

View File

@@ -590,7 +590,7 @@ def list_sources(config):
:rtype: [Source]
"""
source_uris = util.get_config_vals(config, ['package.sources'])[0]
source_uris = util.get_config_vals(['package.sources'], config)[0]
sources = [url_to_source(s) for s in source_uris]
@@ -659,7 +659,7 @@ def update_sources(config, validate=False):
# ensure the cache directory is properly configured
cache_dir = os.path.expanduser(
util.get_config_vals(config, ['package.cache'])[0])
util.get_config_vals(['package.cache'], config)[0])
# ensure the cache directory exists
if not os.path.exists(cache_dir):
@@ -758,7 +758,7 @@ class Source:
"""
cache_dir = os.path.expanduser(
util.get_config_vals(config, ['package.cache'])[0])
util.get_config_vals(['package.cache'], config)[0])
return os.path.join(cache_dir, self.hash())
def copy_to_cache(self, target_dir):

View File

@@ -115,7 +115,7 @@ def get_config():
os.environ[constants.DCOS_CONFIG_ENV])
def get_config_vals(config, keys):
def get_config_vals(keys, config=None):
"""Gets config values for each of the keys. Raises a DCOSException if
any of the keys don't exist.
@@ -127,6 +127,7 @@ def get_config_vals(config, keys):
:rtype: [object]
"""
config = config or get_config()
missing = [key for key in keys if key not in config]
if missing:
raise missing_config_exception(keys)