Making blocks support become, and cleaning up sudo/su references
This commit is contained in:
parent
b11be68249
commit
316284c56b
11 changed files with 44 additions and 21 deletions
|
@ -157,8 +157,11 @@ class ConnectionInformation:
|
||||||
new_info.copy(self)
|
new_info.copy(self)
|
||||||
|
|
||||||
for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'environment', 'no_log'):
|
for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'environment', 'no_log'):
|
||||||
|
attr_val = None
|
||||||
if hasattr(task, attr):
|
if hasattr(task, attr):
|
||||||
attr_val = getattr(task, attr)
|
attr_val = getattr(task, attr)
|
||||||
|
if task._block and hasattr(task._block, attr) and not attr_val:
|
||||||
|
attr_val = getattr(task._block, attr)
|
||||||
if attr_val:
|
if attr_val:
|
||||||
setattr(new_info, attr, attr_val)
|
setattr(new_info, attr, attr_val)
|
||||||
|
|
||||||
|
|
|
@ -382,7 +382,7 @@ class TaskExecutor:
|
||||||
self._connection_info.password = this_info.get('ansible_ssh_pass', self._connection_info.password)
|
self._connection_info.password = this_info.get('ansible_ssh_pass', self._connection_info.password)
|
||||||
self._connection_info.private_key_file = this_info.get('ansible_ssh_private_key_file', self._connection_info.private_key_file)
|
self._connection_info.private_key_file = this_info.get('ansible_ssh_private_key_file', self._connection_info.private_key_file)
|
||||||
self._connection_info.connection = this_info.get('ansible_connection', self._connection_info.connection)
|
self._connection_info.connection = this_info.get('ansible_connection', self._connection_info.connection)
|
||||||
self._connection_info.sudo_pass = this_info.get('ansible_sudo_pass', self._connection_info.sudo_pass)
|
self._connection_info.become_pass = this_info.get('ansible_sudo_pass', self._connection_info.become_pass)
|
||||||
|
|
||||||
if self._connection_info.remote_addr in ('127.0.0.1', 'localhost'):
|
if self._connection_info.remote_addr in ('127.0.0.1', 'localhost'):
|
||||||
self._connection_info.connection = 'local'
|
self._connection_info.connection = 'local'
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError
|
from ansible.errors import AnsibleError, AnsibleParserError
|
||||||
from ansible.playbook.attribute import Attribute, FieldAttribute
|
from ansible.playbook.attribute import Attribute, FieldAttribute
|
||||||
#from ansible.utils.display import deprecated
|
#from ansible.utils.display import deprecated
|
||||||
|
@ -85,4 +86,12 @@ class Become:
|
||||||
|
|
||||||
#deprecated("Instead of su/su_user, use become/become_user and set become_method to 'su' (default is sudo)")
|
#deprecated("Instead of su/su_user, use become/become_user and set become_method to 'su' (default is sudo)")
|
||||||
|
|
||||||
|
# if we are becoming someone else, but some fields are unset,
|
||||||
|
# make sure they're initialized to the default config values
|
||||||
|
if ds.get('become', False):
|
||||||
|
if ds.get('become_method', None) is None:
|
||||||
|
ds['become_method'] = C.DEFAULT_BECOME_METHOD
|
||||||
|
if ds.get('become_user', None) is None:
|
||||||
|
ds['become_user'] = C.DEFAULT_BECOME_USER
|
||||||
|
|
||||||
return ds
|
return ds
|
||||||
|
|
|
@ -21,13 +21,13 @@ __metaclass__ = type
|
||||||
|
|
||||||
from ansible.playbook.attribute import Attribute, FieldAttribute
|
from ansible.playbook.attribute import Attribute, FieldAttribute
|
||||||
from ansible.playbook.base import Base
|
from ansible.playbook.base import Base
|
||||||
#from ansible.playbook.become import Become
|
from ansible.playbook.become import Become
|
||||||
from ansible.playbook.conditional import Conditional
|
from ansible.playbook.conditional import Conditional
|
||||||
from ansible.playbook.helpers import load_list_of_tasks
|
from ansible.playbook.helpers import load_list_of_tasks
|
||||||
from ansible.playbook.role import Role
|
from ansible.playbook.role import Role
|
||||||
from ansible.playbook.taggable import Taggable
|
from ansible.playbook.taggable import Taggable
|
||||||
|
|
||||||
class Block(Base, Conditional, Taggable):
|
class Block(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
_block = FieldAttribute(isa='list', default=[])
|
_block = FieldAttribute(isa='list', default=[])
|
||||||
_rescue = FieldAttribute(isa='list', default=[])
|
_rescue = FieldAttribute(isa='list', default=[])
|
||||||
|
@ -71,16 +71,18 @@ class Block(Base, Conditional, Taggable):
|
||||||
If a simple task is given, an implicit block for that single task
|
If a simple task is given, an implicit block for that single task
|
||||||
is created, which goes in the main portion of the block
|
is created, which goes in the main portion of the block
|
||||||
'''
|
'''
|
||||||
|
|
||||||
is_block = False
|
is_block = False
|
||||||
for attr in ('block', 'rescue', 'always'):
|
for attr in ('block', 'rescue', 'always'):
|
||||||
if attr in ds:
|
if attr in ds:
|
||||||
is_block = True
|
is_block = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if not is_block:
|
if not is_block:
|
||||||
if isinstance(ds, list):
|
if isinstance(ds, list):
|
||||||
return dict(block=ds)
|
return super(Block, self).munge(dict(block=ds))
|
||||||
else:
|
else:
|
||||||
return dict(block=[ds])
|
return super(Block, self).munge(dict(block=[ds]))
|
||||||
|
|
||||||
return super(Block, self).munge(ds)
|
return super(Block, self).munge(ds)
|
||||||
|
|
||||||
|
@ -166,7 +168,11 @@ class Block(Base, Conditional, Taggable):
|
||||||
a task we don't want to include the attribute list of tasks.
|
a task we don't want to include the attribute list of tasks.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
data = dict(when=self.when)
|
data = dict()
|
||||||
|
for attr in self._get_base_attributes():
|
||||||
|
if attr not in ('block', 'rescue', 'always'):
|
||||||
|
data[attr] = getattr(self, attr)
|
||||||
|
|
||||||
data['dep_chain'] = self._dep_chain
|
data['dep_chain'] = self._dep_chain
|
||||||
|
|
||||||
if self._role is not None:
|
if self._role is not None:
|
||||||
|
@ -184,8 +190,12 @@ class Block(Base, Conditional, Taggable):
|
||||||
|
|
||||||
from ansible.playbook.task import Task
|
from ansible.playbook.task import Task
|
||||||
|
|
||||||
# unpack the when attribute, which is the only one we want
|
# we don't want the full set of attributes (the task lists), as that
|
||||||
self.when = data.get('when')
|
# would lead to a serialize/deserialize loop
|
||||||
|
for attr in self._get_base_attributes():
|
||||||
|
if attr in data and attr not in ('block', 'rescue', 'always'):
|
||||||
|
setattr(self, attr, data.get(attr))
|
||||||
|
|
||||||
self._dep_chain = data.get('dep_chain', [])
|
self._dep_chain = data.get('dep_chain', [])
|
||||||
|
|
||||||
# if there was a serialized role, unpack it too
|
# if there was a serialized role, unpack it too
|
||||||
|
|
|
@ -117,7 +117,7 @@ class ActionModule(ActionBase):
|
||||||
xfered = self._transfer_data('src', resultant)
|
xfered = self._transfer_data('src', resultant)
|
||||||
|
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root':
|
if self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
self._remote_chmod('a+r', xfered, tmp)
|
self._remote_chmod('a+r', xfered, tmp)
|
||||||
|
|
||||||
# run the copy module
|
# run the copy module
|
||||||
|
|
|
@ -231,7 +231,7 @@ class ActionModule(ActionBase):
|
||||||
self._remove_tempfile_if_content_defined(content, content_tempfile)
|
self._remove_tempfile_if_content_defined(content, content_tempfile)
|
||||||
|
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if (self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root') and not raw:
|
if (self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
self._remote_chmod('a+r', tmp_src, tmp)
|
self._remote_chmod('a+r', tmp_src, tmp)
|
||||||
|
|
||||||
if raw:
|
if raw:
|
||||||
|
|
|
@ -57,7 +57,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
# use slurp if sudo and permissions are lacking
|
# use slurp if sudo and permissions are lacking
|
||||||
remote_data = None
|
remote_data = None
|
||||||
if remote_checksum in ('1', '2') or self._connection_info.sudo:
|
if remote_checksum in ('1', '2') or self._connection_info.become:
|
||||||
slurpres = self._execute_module(module_name='slurp', module_args=dict(src=source), tmp=tmp)
|
slurpres = self._execute_module(module_name='slurp', module_args=dict(src=source), tmp=tmp)
|
||||||
if slurpres.get('rc') == 0:
|
if slurpres.get('rc') == 0:
|
||||||
if slurpres['encoding'] == 'base64':
|
if slurpres['encoding'] == 'base64':
|
||||||
|
|
|
@ -74,8 +74,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
sudoable = True
|
sudoable = True
|
||||||
# set file permissions, more permissive when the copy is done as a different user
|
# set file permissions, more permissive when the copy is done as a different user
|
||||||
if ((self._connection_info.sudo and self._connection_info.sudo_user != 'root') or
|
if self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
(self._connection_info.su and self._connection_info.su_user != 'root')):
|
|
||||||
chmod_mode = 'a+rx'
|
chmod_mode = 'a+rx'
|
||||||
sudoable = False
|
sudoable = False
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -26,8 +26,6 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
TRANSFERS_FILES = True
|
TRANSFERS_FILES = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_checksum(self, tmp, dest, try_directory=False, source=None):
|
def get_checksum(self, tmp, dest, try_directory=False, source=None):
|
||||||
remote_checksum = self._remote_checksum(tmp, dest)
|
remote_checksum = self._remote_checksum(tmp, dest)
|
||||||
|
|
||||||
|
@ -92,7 +90,9 @@ class ActionModule(ActionBase):
|
||||||
# Expand any user home dir specification
|
# Expand any user home dir specification
|
||||||
dest = self._remote_expand_user(dest, tmp)
|
dest = self._remote_expand_user(dest, tmp)
|
||||||
|
|
||||||
|
directory_prepended = False
|
||||||
if dest.endswith("/"): # CCTODO: Fix path for Windows hosts.
|
if dest.endswith("/"): # CCTODO: Fix path for Windows hosts.
|
||||||
|
directory_prepended = True
|
||||||
base = os.path.basename(source)
|
base = os.path.basename(source)
|
||||||
dest = os.path.join(dest, base)
|
dest = os.path.join(dest, base)
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ class ActionModule(ActionBase):
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
return dict(failed=True, msg=type(e).__name__ + ": " + str(e))
|
return dict(failed=True, msg=type(e).__name__ + ": " + str(e))
|
||||||
|
|
||||||
local_checksum = utils.checksum_s(resultant)
|
local_checksum = checksum_s(resultant)
|
||||||
remote_checksum = self.get_checksum(tmp, dest, not directory_prepended, source=source)
|
remote_checksum = self.get_checksum(tmp, dest, not directory_prepended, source=source)
|
||||||
if isinstance(remote_checksum, dict):
|
if isinstance(remote_checksum, dict):
|
||||||
# Error from remote_checksum is a dict. Valid return is a str
|
# Error from remote_checksum is a dict. Valid return is a str
|
||||||
|
@ -129,7 +129,7 @@ class ActionModule(ActionBase):
|
||||||
xfered = self._transfer_data(self._shell.join_path(tmp, 'source'), resultant)
|
xfered = self._transfer_data(self._shell.join_path(tmp, 'source'), resultant)
|
||||||
|
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root':
|
if self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
self._remote_chmod('a+r', xfered, tmp)
|
self._remote_chmod('a+r', xfered, tmp)
|
||||||
|
|
||||||
# run the copy module
|
# run the copy module
|
||||||
|
|
|
@ -81,7 +81,7 @@ class ActionModule(ActionBase):
|
||||||
# handle check mode client side
|
# handle check mode client side
|
||||||
# fix file permissions when the copy is done as a different user
|
# fix file permissions when the copy is done as a different user
|
||||||
if copy:
|
if copy:
|
||||||
if self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root':
|
if self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
# FIXME: noop stuff needs to be reworked
|
# FIXME: noop stuff needs to be reworked
|
||||||
#if not self.runner.noop_on_check(task_vars):
|
#if not self.runner.noop_on_check(task_vars):
|
||||||
# self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp)
|
# self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp)
|
||||||
|
|
|
@ -3,4 +3,6 @@
|
||||||
tasks:
|
tasks:
|
||||||
- command: whoami
|
- command: whoami
|
||||||
become_user: testing
|
become_user: testing
|
||||||
become_method: su
|
- block:
|
||||||
|
- command: whoami
|
||||||
|
become_user: testing
|
||||||
|
|
Loading…
Reference in a new issue