Merge pull request #4997 from s0undt3ch/develop

Improved handling of dns_check
This commit is contained in:
Thomas S Hatch 2013-05-12 11:08:50 -07:00
commit a57a3b330c
5 changed files with 107 additions and 83 deletions

View File

@ -88,11 +88,10 @@ class MasterKeys(dict):
log.debug('Loaded master key: {0}'.format(self.rsa_path))
else:
log.info('Generating keys: {0}'.format(self.opts['pki_dir']))
gen_keys(
self.opts['pki_dir'],
'master',
4096,
self.opts.get('user'))
gen_keys(self.opts['pki_dir'],
'master',
4096,
self.opts.get('user'))
key = RSA.load_key(self.rsa_path)
return key
@ -143,11 +142,10 @@ class Auth(object):
log.debug('Loaded minion key: {0}'.format(self.rsa_path))
else:
log.info('Generating keys: {0}'.format(self.opts['pki_dir']))
gen_keys(
self.opts['pki_dir'],
'minion',
4096,
self.opts.get('user'))
gen_keys(self.opts['pki_dir'],
'minion',
4096,
self.opts.get('user'))
key = RSA.load_key(self.rsa_path)
return key
@ -166,7 +164,9 @@ class Auth(object):
payload['load']['cmd'] = '_auth'
payload['load']['id'] = self.opts['id']
try:
pub = RSA.load_pub_key(os.path.join(self.opts['pki_dir'], self.mpub))
pub = RSA.load_pub_key(
os.path.join(self.opts['pki_dir'], self.mpub)
)
payload['load']['token'] = pub.public_encrypt(self.token, 4)
except Exception:
pass
@ -225,10 +225,14 @@ class Auth(object):
try:
aes, token = self.decrypt_aes(payload)
if token != self.token:
log.error('The master failed to decrypt the random minion token')
log.error(
'The master failed to decrypt the random minion token'
)
return ''
except Exception:
log.error('The master failed to decrypt the random minion token')
log.error(
'The master failed to decrypt the random minion token'
)
return ''
return aes
else:
@ -246,28 +250,29 @@ class Auth(object):
m_pub_fn = os.path.join(self.opts['pki_dir'], self.mpub)
try:
self.opts['master_ip'] = salt.utils.dns_check(
self.opts['master'],
True,
self.opts['ipv6']
)
self.opts['master'],
True,
self.opts['ipv6']
)
except SaltClientError:
if safe:
return 'retry'
else:
raise SaltClientError
raise SaltClientError
sreq = salt.payload.SREQ(
self.opts['master_uri'],
self.opts.get('id', '')
)
self.opts['master_uri'],
self.opts.get('id', '')
)
try:
payload = sreq.send_auto(
self.minion_sign_in_payload(),
timeout=timeout)
self.minion_sign_in_payload(),
timeout=timeout
)
except SaltReqTimeoutError:
if safe:
return 'retry'
else:
raise SaltClientError
raise SaltClientError
if 'load' in payload:
if 'ret' in payload['load']:
if not payload['load']['ret']:
@ -302,17 +307,17 @@ class Auth(object):
sys.exit(42)
if self.opts.get('master_finger', False):
if salt.utils.pem_finger(m_pub_fn) != self.opts['master_finger']:
log.critical((
log.critical(
'The specified fingerprint in the master configuration '
'file:\n{0}\nDoes not match the authenticating master\'s '
'key:\n{1}\nVerify that the configured fingerprint '
'matches the fingerprint of the correct master and that '
'this minion is not subject to a man in the middle attack'
).format(
.format(
self.opts['master_finger'],
salt.utils.pem_finger(m_pub_fn)
)
)
)
sys.exit(42)
auth['publish_port'] = payload['publish_port']
return auth
@ -417,14 +422,13 @@ class SAuth(Auth):
'''
while True:
creds = self.sign_in(
self.opts.get('_auth_timeout', 60),
self.opts.get('_safe_auth', True)
)
self.opts.get('_auth_timeout', 60),
self.opts.get('_safe_auth', True)
)
if creds == 'retry':
if self.opts.get('caller'):
msg = ('Minion failed to authenticate with the master, '
'has the minion key been accepted?')
print(msg)
print('Minion failed to authenticate with the master, '
'has the minion key been accepted?')
sys.exit(2)
continue
break

View File

@ -95,3 +95,7 @@ class SaltSystemExit(SystemExit):
This exception is raised when an unsolvable problem is found. There's
nothing else to do, salt should just exit.
'''
def __init__(self, code=0, msg=None):
SystemExit.__init__(self, code)
if msg:
self.message = msg

View File

@ -145,8 +145,10 @@ def _reinterpreted_state(state):
try:
data = json.loads(out)
if not isinstance(data, dict):
return _failout(state,
'script JSON output must be a JSON object (e.g., {})!')
return _failout(
state,
'script JSON output must be a JSON object (e.g., {})!'
)
is_json = True
except Exception:
idx = out.rstrip().rfind('\n')
@ -158,9 +160,11 @@ def _reinterpreted_state(state):
key, val = item.split('=')
data[key] = val
except ValueError:
return _failout(state,
return _failout(
state,
'Failed parsing script output! '
'Stdout must be JSON or a line of name=value pairs.')
'Stdout must be JSON or a line of name=value pairs.'
)
changed = _is_true(data.get('changed', 'no'))
@ -197,12 +201,14 @@ def _is_true(val):
raise ValueError('Failed parsing boolean value: {0}'.format(val))
def _run_check(cmd_kwargs, onlyif, unless, cwd, user, group, shell):
def _run_check(cmd_kwargs, onlyif, unless, cwd, user, group):
'''
Execute the onlyif logic and return data if the onlyif fails
'''
ret = {}
print 123, cmd_kwargs
if group and HAS_GRP:
try:
egid = grp.getgrnam(group).gr_gid
@ -432,8 +438,8 @@ def run(name,
key, val = var.split('=')
_env[key] = val
except ValueError:
ret['comment'] = 'Invalid environmental var: "{0}"'.format(
var)
ret['comment'] = \
'Invalid environmental var: "{0}"'.format(var)
return ret
env = _env
elif isinstance(env, dict):
@ -448,8 +454,8 @@ def run(name,
if isinstance(comp, dict):
_env.update(comp)
else:
ret['comment'] = 'Invalid environmental var: "{0}"'.format(
env)
ret['comment'] = \
'Invalid environmental var: "{0}"'.format(env)
return ret
except Exception:
_env = {}
@ -458,8 +464,8 @@ def run(name,
key, val = var.split('=')
_env[key] = val
except ValueError:
ret['comment'] = 'Invalid environmental var: "{0}"'.format(
var)
ret['comment'] = \
'Invalid environmental var: "{0}"'.format(var)
return ret
env = _env
@ -580,28 +586,31 @@ def script(name,
pgid = os.getegid()
cmd_kwargs = copy.deepcopy(kwargs)
cmd_kwargs.update({
'runas': user,
'shell': shell or __grains__['shell'],
'env': env,
'onlyif': onlyif,
'unless': unless,
'user': user,
'group': group,
'cwd': cwd,
'template': template,
'umask': umask})
cmd_kwargs.update({'runas': user,
'shell': shell or __grains__['shell'],
'env': env,
'onlyif': onlyif,
'unless': unless,
'user': user,
'group': group,
'cwd': cwd,
'template': template,
'umask': umask})
run_check_cmd_kwargs = {'cwd': cwd,
'runas': user,
'shell': shell or __grains__['shell'], }
run_check_cmd_kwargs = {
'cwd': cwd,
'runas': user,
'shell': shell or __grains__['shell']
}
# Change the source to be the name arg if it is not specified
if source is None:
source = name
try:
cret = _run_check(run_check_cmd_kwargs, onlyif, unless, cwd, user, group, shell)
cret = _run_check(
run_check_cmd_kwargs, onlyif, unless, cwd, user, group
)
if isinstance(cret, dict):
ret.update(cret)
return ret
@ -674,12 +683,11 @@ def call(name, func, args=(), kws=None,
'runas': kwargs.get('user'),
'shell': kwargs.get('shell') or __grains__['shell'],
'env': kwargs.get('env'),
'umask': kwargs.get('umask'),
}
'umask': kwargs.get('umask')}
if HAS_GRP:
pgid = os.getegid()
try:
cret = _run_check(cmd_kwargs, onlyif, unless, None, None, None, None)
cret = _run_check(cmd_kwargs, onlyif, unless, None, None, None)
if isinstance(cret, dict):
ret.update(cret)
return ret
@ -734,11 +742,8 @@ def mod_watch(name, **kwargs):
elif kwargs['sfun'] == 'wait_call' or kwargs['sfun'] == 'call':
return call(name, **kwargs)
return {'name': name,
'changes': {},
'comment': ('cmd.{0} does not work with the watch requisite, '
'please use cmd.wait or cmd.wait_script').format(
kwargs['sfun']
),
'comment': 'cmd.{0[sfun]} does not work with the watch requisite, '
'please use cmd.wait or cmd.wait_script'.format(kwargs),
'result': False}

View File

@ -33,6 +33,7 @@ except ImportError:
HAS_FNCTL = False
# Import salt libs
import salt.log
import salt.minion
import salt.payload
from salt.exceptions import (
@ -339,8 +340,9 @@ def dns_check(addr, safe=False, ipv6=False):
'''
error = False
try:
hostnames = socket.getaddrinfo(addr, None, socket.AF_UNSPEC,
socket.SOCK_STREAM)
hostnames = socket.getaddrinfo(
addr, None, socket.AF_UNSPEC, socket.SOCK_STREAM
)
if not hostnames:
error = True
else:
@ -351,7 +353,7 @@ def dns_check(addr, safe=False, ipv6=False):
break
if not addr:
error = True
except socket.gaierror:
except socket.error:
error = True
if error:
@ -359,17 +361,13 @@ def dns_check(addr, safe=False, ipv6=False):
'but now fails to resolve! The previously resolved ip addr '
'will continue to be used').format(addr)
if safe:
import salt.log
if salt.log.is_console_configured():
# If logging is not configured it also means that either
# the master or minion instance calling this hasn't even
# started running
logging.getLogger(__name__).error(err)
log.error(err)
raise SaltClientError()
else:
err = err.format(addr)
sys.stderr.write(err)
sys.exit(42)
raise SaltSystemExit(code=42, msg=err)
return addr

View File

@ -19,7 +19,12 @@ import traceback
from functools import partial
# Import salt libs
from salt import config, loader, log, version
import salt.log as log
import salt.config as config
import salt.loader as loader
import salt.utils as utils
import salt.version as version
import salt.exceptions as exceptions
def _sorted(mixins_or_funcs):
@ -725,17 +730,25 @@ class SyndicOptionParser(OptionParser, ConfigDirMixIn, MergeConfigMixIn,
# Override the name of the PID file.
opts['pidfile'] = '/var/run/salt-syndic.pid'
if 'syndic_master' not in opts:
if not opts.get('syndic_master', None):
self.error(
'The syndic_master needs to be configured in the salt master '
'config, EXITING!'
)
from salt import utils
# Some of the opts need to be changed to match the needed opts
# in the minion class.
opts['master'] = opts['syndic_master']
opts['master_ip'] = utils.dns_check(opts['master'], ipv6=opts['ipv6'])
opts['master'] = opts.get('syndic_master', opts['master'])
try:
opts['master_ip'] = utils.dns_check(
opts['master'],
ipv6=opts['ipv6']
)
except exceptions.SaltSystemExit as exc:
self.exit(
status=exc.code,
msg='{0}: {1}\n'.format(self.get_prog_name(), exc.message)
)
opts['master_uri'] = 'tcp://{0}:{1}'.format(
opts['master_ip'], str(opts['master_port'])