PEP8 fixes: Ansible system module and playbook base.py (#32322)

* Ansible files module sanity pep8 fixes

* Ansible system module and playbook base.py

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Undo empty lines not required by sanity checks

* Various changes

* Various changes

* Various changes

* Various changes

* Undo blank lines not required by sanity checks

* Various changes

* Various changes

* Various changes

* Various changes

* Various changes

* Undo blank line changes not required by sanity checks

* Various changes

* Various changes

* Various changes

* Various changes

* Various changes

* Missing piece after merge

* Blank lines

* Blank line

* Line too long

* Fix typo

* Unnecessary quotes

* Fix example error
pull/32370/merge
Yadnyawalkya Tale 7 years ago committed by Dag Wieers
parent a5da2e44a1
commit a2d34e914e

@ -181,15 +181,15 @@ def check_file_attrs(module, changed, message, diff):
def main():
module = AnsibleModule(
argument_spec=dict(
path=dict(required=True, aliases=['dest', 'destfile', 'name'], type='path'),
state=dict(default='present', choices=['absent', 'present']),
marker=dict(default='# {mark} ANSIBLE MANAGED BLOCK', type='str'),
block=dict(default='', type='str', aliases=['content']),
insertafter=dict(default=None),
insertbefore=dict(default=None),
create=dict(default=False, type='bool'),
backup=dict(default=False, type='bool'),
validate=dict(default=None, type='str'),
path=dict(type='path', required=True, aliases=['dest', 'destfile', 'name']),
state=dict(type='str', default='present', choices=['absent', 'present']),
marker=dict(type='str', default='# {mark} ANSIBLE MANAGED BLOCK'),
block=dict(type='str', default='', aliases=['content']),
insertafter=dict(type='str'),
insertbefore=dict(type='str'),
create=dict(type='bool', default=False),
backup=dict(type='bool', default=False),
validate=dict(type='str'),
),
mutually_exclusive=[['insertbefore', 'insertafter']],
add_file_common_args=True,
@ -271,7 +271,7 @@ def main():
elif insertafter is not None:
n0 += 1
elif insertbefore is not None:
n0 = 0 # insertbefore=BOF
n0 = 0 # insertbefore=BOF
else:
n0 = len(lines) # insertafter=EOF
elif n0 < n1:

@ -331,8 +331,8 @@ def is_rsh_needed(source, dest):
def main():
module = AnsibleModule(
argument_spec=dict(
src=dict(required=True),
dest=dict(required=True),
src=dict(type='str', required=True),
dest=dict(type='str', required=True),
dest_port=dict(type='int'),
delete=dict(type='bool', default=False),
private_key=dict(type='path'),

@ -1,25 +1,22 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2014, Brian Coca <briancoca+ansible@gmail.com>
# Copyright: (c) 2014, Brian Coca <briancoca+ansible@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'],
'supported_by': 'core'}
DOCUMENTATION = '''
---
module: debconf
short_description: Configure a .deb package
description:
- Configure a .deb package using debconf-set-selections. Or just query
existing selections.
- Configure a .deb package using debconf-set-selections. Or just query existing selections.
version_added: "1.6"
notes:
- This module requires the command line debconf tools.
@ -33,60 +30,54 @@ options:
description:
- Name of package to configure.
required: true
default: null
aliases: ['pkg']
aliases: [ pkg ]
question:
description:
- A debconf configuration setting
required: false
default: null
aliases: ['setting', 'selection']
- A debconf configuration setting.
aliases: [ selection, setting ]
vtype:
description:
- The type of the value supplied.
- C(seen) was added in 2.2.
required: false
default: null
choices: [string, password, boolean, select, multiselect, note, error, title, text, seen]
choices: [ boolean, error, multiselect, note, password, seen, select, string, text, title, text ]
value:
description:
- Value to set the configuration to
required: false
default: null
aliases: ['answer']
- Value to set the configuration to.
aliases: [ answer ]
unseen:
description:
- Do not set 'seen' flag when pre-seeding
required: false
- Do not set 'seen' flag when pre-seeding.
type: bool
default: False
author: "Brian Coca (@bcoca)"
author:
- Brian Coca (@bcoca)
'''
EXAMPLES = '''
# Set default locale to fr_FR.UTF-8
- debconf:
- name: Set default locale to fr_FR.UTF-8
debconf:
name: locales
question: locales/default_environment_locale
value: fr_FR.UTF-8
vtype: select
# set to generate locales:
- debconf:
- name: set to generate locales
debconf:
name: locales
question: locales/locales_to_be_generated
value: en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8
vtype: multiselect
# Accept oracle license
- debconf:
- name: Accept oracle license
debconf:
name: oracle-java7-installer
question: shared/accepted-oracle-license-v1-1
value: true
vtype: select
# Specifying package you can register/return the list of questions and current values
- debconf:
- name: Specifying package you can register/return the list of questions and current values
debconf:
name: tzdata
'''
@ -104,13 +95,12 @@ def get_selections(module, pkg):
for line in out.splitlines():
(key, value) = line.split(':', 1)
selections[ key.strip('*').strip() ] = value.strip()
selections[key.strip('*').strip()] = value.strip()
return selections
def set_selection(module, pkg, question, vtype, value, unseen):
setsel = module.get_bin_path('debconf-set-selections', True)
cmd = [setsel]
if unseen:
@ -125,27 +115,26 @@ def set_selection(module, pkg, question, vtype, value, unseen):
return module.run_command(cmd, data=data)
def main():
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True, aliases=['pkg'], type='str'),
question=dict(required=False, aliases=['setting', 'selection'], type='str'),
vtype=dict(required=False, type='str', choices=['string', 'password', 'boolean', 'select', 'multiselect', 'note', 'error', 'title',
'text', 'seen']),
value=dict(required=False, type='str', aliases=['answer']),
unseen=dict(required=False, type='bool'),
name=dict(type='str', required=True, aliases=['pkg']),
question=dict(type='str', aliases=['selection', 'setting']),
vtype=dict(type='str', choices=['boolean', 'error', 'multiselect', 'note', 'password', 'seen', 'select', 'string', 'text', 'title']),
value=dict(type='str', aliases=['answer']),
unseen=dict(type='bool'),
),
required_together=(['question','vtype', 'value'],),
required_together=(['question', 'vtype', 'value'],),
supports_check_mode=True,
)
#TODO: enable passing array of options and/or debconf file from get-selections dump
pkg = module.params["name"]
# TODO: enable passing array of options and/or debconf file from get-selections dump
pkg = module.params["name"]
question = module.params["question"]
vtype = module.params["vtype"]
value = module.params["value"]
unseen = module.params["unseen"]
vtype = module.params["vtype"]
value = module.params["value"]
unseen = module.params["unseen"]
prev = get_selections(module, pkg)
@ -156,7 +145,7 @@ def main():
if vtype is None or value is None:
module.fail_json(msg="when supplying a question you must supply a valid vtype and value")
if not question in prev or prev[question] != value:
if question not in prev or prev[question] != value:
changed = True
if changed:
@ -165,7 +154,7 @@ def main():
if rc:
module.fail_json(msg=e)
curr = { question: value }
curr = {question: value}
if question in prev:
prev = {question: prev[question]}
else:

@ -1,33 +1,31 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
# Copyright: (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: facter
short_description: Runs the discovery program I(facter) on the remote system
description:
- Runs the I(facter) discovery program
(U(https://github.com/puppetlabs/facter)) on the remote system, returning
JSON data that can be useful for inventory purposes.
- Runs the I(facter) discovery program
(U(https://github.com/puppetlabs/facter)) on the remote system, returning
JSON data that can be useful for inventory purposes.
version_added: "0.2"
options: {}
notes: []
requirements: [ "facter", "ruby-json" ]
requirements:
- facter
- ruby-json
author:
- "Ansible Core Team"
- "Michael DeHaan"
- Ansible Core Team
- Michael DeHaan
'''
EXAMPLES = '''
@ -41,7 +39,7 @@ from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec = dict()
argument_spec=dict()
)
facter_path = module.get_bin_path('facter', opt_dirs=['/opt/puppetlabs/bin'])

@ -1,21 +1,20 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2013, Alexander Bulimov <lazywolf0@gmail.com>
# Copyright: (c) 2013, Alexander Bulimov <lazywolf0@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
author: "Alexander Bulimov (@abulimov)"
author:
- Alexander Bulimov (@abulimov)
module: filesystem
short_description: Makes file system on block device
description:
@ -23,48 +22,48 @@ description:
version_added: "1.2"
options:
fstype:
choices: [ "ext4", "ext4dev", "ext3", "ext2", "xfs", "btrfs", "reiserfs", "lvm"]
choices: [ btrfs, ext2, ext3, ext4, ext4dev, lvm, reiserfs, xfs ]
description:
- File System type to be created.
- reiserfs support was added in 2.2.
- lvm support was added in 2.5.
required: true
required: yes
dev:
description:
- Target block device.
required: true
required: yes
force:
choices: [ "yes", "no" ]
default: "no"
description:
- If yes, allows to create new filesystem on devices that already has filesystem.
required: false
- If C(yes), allows to create new filesystem on devices that already has filesystem.
type: bool
default: 'no'
resizefs:
choices: [ "yes", "no" ]
default: "no"
description:
- If yes, if the block device and filessytem size differ, grow the filesystem into the space. Note, XFS Will only grow if mounted.
required: false
- If C(yes), if the block device and filessytem size differ, grow the filesystem into the space.
- Note, XFS Will only grow if mounted.
type: bool
default: 'no'
version_added: "2.0"
opts:
description:
- List of options to be passed to mkfs command.
notes:
- uses mkfs command
- Uses mkfs command.
'''
EXAMPLES = '''
# Create a ext2 filesystem on /dev/sdb1.
- filesystem:
- name: Create a ext2 filesystem on /dev/sdb1
filesystem:
fstype: ext2
dev: /dev/sdb1
# Create a ext4 filesystem on /dev/sdb1 and check disk blocks.
- filesystem:
- name: Create a ext4 filesystem on /dev/sdb1 and check disk blocks
filesystem:
fstype: ext4
dev: /dev/sdb1
opts: -cc
'''
import os
from ansible.module_utils.basic import AnsibleModule
@ -91,7 +90,7 @@ def _get_fs_size(fssize_cmd, dev, module):
block_size = int(line.split(':')[1].strip())
break
else:
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err )
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err)
elif 'xfs_growfs' == fssize_cmd:
# Get Block count and Block size
rc, size, err = module.run_command([cmd, '-n', dev])
@ -107,9 +106,9 @@ def _get_fs_size(fssize_cmd, dev, module):
block_count = int(col[3].split(',')[0])
break
else:
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err )
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err)
elif 'btrfs' == fssize_cmd:
#ToDo
# ToDo
# There is no way to get the blocksize and blockcount for btrfs filesystems
block_size = 1
block_count = 1
@ -119,9 +118,9 @@ def _get_fs_size(fssize_cmd, dev, module):
block_count = int(size[:-1])
block_size = 1
else:
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err )
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err)
return block_size*block_count
return block_size * block_count
def main():
@ -131,77 +130,76 @@ def main():
# There is no "single command" to manipulate filesystems, so we map them all out and their options
fs_cmd_map = {
'ext2' : {
'mkfs' : 'mkfs.ext2',
'grow' : 'resize2fs',
'grow_flag' : None,
'force_flag' : '-F',
'ext2': {
'mkfs': 'mkfs.ext2',
'grow': 'resize2fs',
'grow_flag': None,
'force_flag': '-F',
'fsinfo': 'tune2fs',
},
'ext3' : {
'mkfs' : 'mkfs.ext3',
'grow' : 'resize2fs',
'grow_flag' : None,
'force_flag' : '-F',
'ext3': {
'mkfs': 'mkfs.ext3',
'grow': 'resize2fs',
'grow_flag': None,
'force_flag': '-F',
'fsinfo': 'tune2fs',
},
'ext4' : {
'mkfs' : 'mkfs.ext4',
'grow' : 'resize2fs',
'grow_flag' : None,
'force_flag' : '-F',
'ext4': {
'mkfs': 'mkfs.ext4',
'grow': 'resize2fs',
'grow_flag': None,
'force_flag': '-F',
'fsinfo': 'tune2fs',
},
'reiserfs' : {
'mkfs' : 'mkfs.reiserfs',
'grow' : 'resize_reiserfs',
'grow_flag' : None,
'force_flag' : '-f',
'reiserfs': {
'mkfs': 'mkfs.reiserfs',
'grow': 'resize_reiserfs',
'grow_flag': None,
'force_flag': '-f',
'fsinfo': 'reiserfstune',
},
'ext4dev' : {
'mkfs' : 'mkfs.ext4',
'grow' : 'resize2fs',
'grow_flag' : None,
'force_flag' : '-F',
'ext4dev': {
'mkfs': 'mkfs.ext4',
'grow': 'resize2fs',
'grow_flag': None,
'force_flag': '-F',
'fsinfo': 'tune2fs',
},
'xfs' : {
'mkfs' : 'mkfs.xfs',
'grow' : 'xfs_growfs',
'grow_flag' : None,
'force_flag' : '-f',
'xfs': {
'mkfs': 'mkfs.xfs',
'grow': 'xfs_growfs',
'grow_flag': None,
'force_flag': '-f',
'fsinfo': 'xfs_growfs',
},
'btrfs' : {
'mkfs' : 'mkfs.btrfs',
'grow' : 'btrfs',
'grow_flag' : 'filesystem resize',
'force_flag' : '-f',
'btrfs': {
'mkfs': 'mkfs.btrfs',
'grow': 'btrfs',
'grow_flag': 'filesystem resize',
'force_flag': '-f',
'fsinfo': 'btrfs',
},
'LVM2_member' : {
'mkfs' : 'pvcreate',
'grow' : 'pvresize',
'grow_flag' : None,
'force_flag' : '-f' ,
'LVM2_member': {
'mkfs': 'pvcreate',
'grow': 'pvresize',
'grow_flag': None,
'force_flag': '-f',
'fsinfo': 'pvs',
}
}
module = AnsibleModule(
argument_spec = dict(
fstype=dict(required=True, aliases=['type'],
choices=fs_cmd_map.keys() + friendly_names.keys()),
dev=dict(required=True, aliases=['device']),
opts=dict(),
force=dict(type='bool', default='no'),
resizefs=dict(type='bool', default='no'),
argument_spec=dict(
fstype=dict(type='str', required=True, aliases=['type'],
choices=fs_cmd_map.keys() + friendly_names.keys()),
dev=dict(type='str', required=True, aliases=['device']),
opts=dict(type='str'),
force=dict(type='bool', default=False),
resizefs=dict(type='bool', default=False),
),
supports_check_mode=True,
)
dev = module.params['dev']
fstype = module.params['fstype']
opts = module.params['opts']
@ -224,11 +222,11 @@ def main():
fssize_cmd = fs_cmd_map[fstype]['fsinfo']
if not os.path.exists(dev):
module.fail_json(msg="Device %s not found."%dev)
module.fail_json(msg="Device %s not found." % dev)
cmd = module.get_bin_path('blkid', required=True)
rc,raw_fs,err = module.run_command("%s -c /dev/null -o value -s TYPE %s" % (cmd, dev))
rc, raw_fs, err = module.run_command("%s -c /dev/null -o value -s TYPE %s" % (cmd, dev))
fs = raw_fs.strip()
if fs == fstype and resizefs is False and not force:
@ -242,27 +240,26 @@ def main():
else:
fs_smaller = False
if module.check_mode and fs_smaller:
module.exit_json(changed=True, msg="Resizing filesystem %s on device %s" % (fstype,dev))
module.exit_json(changed=True, msg="Resizing filesystem %s on device %s" % (fstype, dev))
elif module.check_mode and not fs_smaller:
module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (fstype, dev))
elif fs_smaller:
cmd = module.get_bin_path(growcmd, required=True)
rc,out,err = module.run_command("%s %s" % (cmd, dev))
rc, out, err = module.run_command("%s %s" % (cmd, dev))
# Sadly there is no easy way to determine if this has changed. For now, just say "true" and move on.
# in the future, you would have to parse the output to determine this.
# thankfully, these are safe operations if no change is made.
if rc == 0:
module.exit_json(changed=True, msg=out)
else:
module.fail_json(msg="Resizing filesystem %s on device '%s' failed"%(fstype,dev), rc=rc, err=err)
module.fail_json(msg="Resizing filesystem %s on device '%s' failed" % (fstype, dev), rc=rc, err=err)
else:
module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (fstype, dev))
elif fs and not force:
module.fail_json(msg="'%s' is already used as %s, use force=yes to overwrite"%(dev,fs), rc=rc, err=err)
module.fail_json(msg="'%s' is already used as %s, use force=yes to overwrite" % (dev, fs), rc=rc, err=err)
### create fs
# create fs
if module.check_mode:
changed = True
@ -274,11 +271,11 @@ def main():
cmd = "%s %s '%s'" % (mkfs, force_flag, dev)
else:
cmd = "%s %s %s '%s'" % (mkfs, force_flag, opts, dev)
rc,_,err = module.run_command(cmd)
rc, _, err = module.run_command(cmd)
if rc == 0:
changed = True
else:
module.fail_json(msg="Creating filesystem %s on device '%s' failed"%(fstype,dev), rc=rc, err=err)
module.fail_json(msg="Creating filesystem %s on device '%s' failed" % (fstype, dev), rc=rc, err=err)
module.exit_json(changed=changed)

@ -1,23 +1,21 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Kenneth D. Evensen <kevensen@redhat.com>
# (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
#
# Copyright: (c) 2016, Kenneth D. Evensen <kevensen@redhat.com>
# Copyright: (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = """
module: gconftool2
author:
- "Kenneth D. Evensen (@kevensen)"
- Kenneth D. Evensen (@kevensen)
short_description: Edit GNOME Configurations
description:
- This module allows for the manipulation of GNOME 2 Configuration via
@ -25,47 +23,35 @@ description:
version_added: "2.3"
options:
key:
required: true
description:
- A GConf preference key is an element in the GConf repository
that corresponds to an application preference. See man gconftool-2(1)
required: yes
value:
required: false
description:
- Preference keys typically have simple values such as strings,
integers, or lists of strings and integers. This is ignored if the state
is "get". See man gconftool-2(1)
value_type:
required: false
choices:
- int
- bool
- float
- string
description:
- The type of value being set. This is ignored if the state is "get".
choices: [ bool, float, int, string ]
state:
required: true
choices:
- get
- present
- absent
description:
- The action to take upon the key/value.
required: yes
choices: [ absent, get, present ]
config_source:
required: false
description:
- Specify a configuration source to use rather than the default path.
See man gconftool-2(1)
direct:
required: false
choices: [ "yes", "no" ]
default: no
description:
- Access the config database directly, bypassing server. If direct is
specified then the config_source must be specified as well.
See man gconftool-2(1)
type: bool
default: 'no'
"""
EXAMPLES = """
@ -81,12 +67,12 @@ RETURN = '''
description: The key specified in the module parameters
returned: success
type: string
sample: "/desktop/gnome/interface/font_name"
sample: /desktop/gnome/interface/font_name
value_type:
description: The type of the value that was changed
returned: success
type: string
sample: "string"
sample: string
value:
description: The value of the preference key after executing the module
returned: success
@ -165,18 +151,13 @@ def main():
# Setup the Ansible module
module = AnsibleModule(
argument_spec=dict(
key=dict(required=True, default=None, type='str'),
value_type=dict(required=False,
choices=['int', 'bool', 'float', 'string'],
type='str'),
value=dict(required=False, default=None, type='str'),
state=dict(required=True,
default=None,
choices=['present', 'get', 'absent'],
type='str'),
direct=dict(required=False, default=False, type='bool'),
config_source=dict(required=False, default=None, type='str')
),
key=dict(type='str', required=True),
value_type=dict(type='str', choices=['bool', 'float', 'int', 'string']),
value=dict(type='str'),
state=dict(type='str', required=True, choices=['absent', 'get', 'present']),
direct=dict(type='bool', default=False),
config_source=dict(type='str'),
),
supports_check_mode=True
)
@ -203,17 +184,17 @@ def main():
if state != "get":
if value is None or value == "":
module.fail_json(msg='State %s requires "value" to be set'
% str(state))
% str(state))
elif value_type is None or value_type == "":
module.fail_json(msg='State %s requires "value_type" to be set'
% str(state))
% str(state))
if direct and config_source is None:
module.fail_json(msg='If "direct" is "yes" then the ' +
'"config_source" must be specified')
'"config_source" must be specified')
elif not direct and config_source is not None:
module.fail_json(msg='If the "config_source" is specified ' +
'then "direct" must be "yes"')
'then "direct" must be "yes"')
# Create a gconf2 preference
gconf_pref = GConf2Preference(module, key, value_type,
@ -247,5 +228,6 @@ def main():
module.exit_json(changed=change, ansible_facts=facts)
if __name__ == '__main__':
main()

@ -1,18 +1,16 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2014, Taneli Leppä <taneli@crasman.fi>
# Copyright: (c) 2014, Taneli Leppä <taneli@crasman.fi>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = """
module: gluster_volume
short_description: Manage GlusterFS volumes
@ -22,75 +20,76 @@ version_added: '1.9'
options:
name:
description:
- The volume name
- The volume name.
required: true
state:
description:
- Use present/absent ensure if a volume exists or not.
Use started/stopped to control its availability.
required: true
choices: ['present', 'absent', 'started', 'stopped']
choices: ['absent', 'present', 'started', 'stopped']
cluster:
description:
- List of hosts to use for probing and brick setup
- List of hosts to use for probing and brick setup.
host:
description:
- Override local hostname (for peer probing purposes)
- Override local hostname (for peer probing purposes).
replicas:
description:
- Replica count for volume
- Replica count for volume.
arbiter:
description:
- Arbiter count for volume
- Arbiter count for volume.
version_added: '2.3'
stripes:
description:
- Stripe count for volume
- Stripe count for volume.
disperses:
description:
- Disperse count for volume
- Disperse count for volume.
version_added: '2.2'
redundancies:
description:
- Redundancy count for volume
- Redundancy count for volume.
version_added: '2.2'
transport:
description:
- Transport type for volume
default: 'tcp'
choices: ['tcp', 'rdma', 'tcp,rdma']
- Transport type for volume.
default: tcp
choices: [ rdma, tcp, tcp,rdma ]
bricks:
description:
- Brick paths on servers. Multiple brick paths can be separated by commas.
aliases: ['brick']
aliases: [ brick ]
start_on_create:
description:
- Controls whether the volume is started after creation or not
default: 'yes'
- Controls whether the volume is started after creation or not.
type: bool
default: 'yes'
rebalance:
description:
- Controls whether the cluster is rebalanced after changes
default: 'no'
- Controls whether the cluster is rebalanced after changes.
type: bool
default: 'no'
directory:
description:
- Directory for limit-usage
- Directory for limit-usage.
options:
description:
- A dictionary/hash with options/settings for the volume
- A dictionary/hash with options/settings for the volume.
quota:
description:
- Quota value for limit-usage (be sure to use 10.0MB instead of 10MB, see quota list)
- Quota value for limit-usage (be sure to use 10.0MB instead of 10MB, see quota list).
force:
description:
- If brick is being created in the root partition, module will fail.
Set force to true to override this behaviour.
type: bool
notes:
- Requires cli tools for GlusterFS on servers
- Will add new bricks, but not remove them
author: Taneli Leppä (@rosmo)
- Requires cli tools for GlusterFS on servers.
- Will add new bricks, but not remove them.
author:
- Taneli Leppä (@rosmo)
"""
EXAMPLES = """
@ -153,7 +152,6 @@ import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
glusterbin = ''
@ -166,12 +164,13 @@ def run_gluster(gargs, **kwargs):
rc, out, err = module.run_command(args, **kwargs)
if rc != 0:
module.fail_json(msg='error running gluster (%s) command (rc=%d): %s' %
(' '.join(args), rc, out or err), exception=traceback.format_exc())
(' '.join(args), rc, out or err), exception=traceback.format_exc())
except Exception as e:
module.fail_json(msg='error running gluster (%s) command: %s' % (' '.join(args),
to_native(e)), exception=traceback.format_exc())
to_native(e)), exception=traceback.format_exc())
return out
def run_gluster_nofail(gargs, **kwargs):
global glusterbin
global module
@ -182,8 +181,9 @@ def run_gluster_nofail(gargs, **kwargs):
return None
return out
def get_peers():
out = run_gluster([ 'peer', 'status'])
out = run_gluster(['peer', 'status'])
peers = {}
hostname = None
uuid = None
@ -208,8 +208,9 @@ def get_peers():
shortNames = False
return peers
def get_volumes():
out = run_gluster([ 'volume', 'info' ])
out = run_gluster(['volume', 'info'])
volumes = {}
volume = {}
@ -227,17 +228,17 @@ def get_volumes():
if key.lower() == 'transport-type':
volume['transport'] = value
if value.lower().endswith(' (arbiter)'):
if not 'arbiters' in volume:
if 'arbiters' not in volume:
volume['arbiters'] = []
value = value[:-10]
volume['arbiters'].append(value)
if key.lower() != 'bricks' and key.lower()[:5] == 'brick':
if not 'bricks' in volume:
if 'bricks' not in volume:
volume['bricks'] = []
volume['bricks'].append(value)
# Volume options
if '.' in key:
if not 'options' in volume:
if 'options' not in volume:
volume['options'] = {}
volume['options'][key] = value
if key == 'features.quota' and value == 'on':
@ -249,20 +250,22 @@ def get_volumes():
volume = {}
return volumes
def get_quotas(name, nofail):
quotas = {}
if nofail:
out = run_gluster_nofail([ 'volume', 'quota', name, 'list' ])
out = run_gluster_nofail(['volume', 'quota', name, 'list'])
if not out:
return quotas
else:
out = run_gluster([ 'volume', 'quota', name, 'list' ])
out = run_gluster(['volume', 'quota', name, 'list'])
for row in out.split('\n'):
if row[:1] == '/':
q = re.split('\s+', row)
quotas[q[0]] = q[1]
return quotas
def wait_for_peer(host):
for x in range(0, 4):
peers = get_peers()
@ -271,20 +274,23 @@ def wait_for_peer(host):
time.sleep(1)
return False
def probe(host, myhostname):
global module
out = run_gluster([ 'peer', 'probe', host ])
out = run_gluster(['peer', 'probe', host])
if out.find('localhost') == -1 and not wait_for_peer(host):
module.fail_json(msg='failed to probe peer %s on %s' % (host, myhostname))
def probe_all_peers(hosts, peers, myhostname):
for host in hosts:
host = host.strip() # Clean up any extra space for exact comparison
host = host.strip() # Clean up any extra space for exact comparison
if host not in peers:
probe(host, myhostname)
def create_volume(name, stripe, replica, arbiter, disperse, redundancy, transport, hosts, bricks, force):
args = [ 'volume', 'create' ]
args = ['volume', 'create']
args.append(name)
if stripe:
args.append('stripe')
@ -310,17 +316,21 @@ def create_volume(name, stripe, replica, arbiter, disperse, redundancy, transpor
args.append('force')
run_gluster(args)
def start_volume(name):
run_gluster([ 'volume', 'start', name ])
run_gluster(['volume', 'start', name])
def stop_volume(name):
run_gluster([ 'volume', 'stop', name ])
run_gluster(['volume', 'stop', name])
def set_volume_option(name, option, parameter):
run_gluster([ 'volume', 'set', name, option, parameter ])
run_gluster(['volume', 'set', name, option, parameter])
def add_bricks(name, new_bricks, stripe, replica, force):
args = [ 'volume', 'add-brick', name ]
args = ['volume', 'add-brick', name]
if stripe:
args.append('stripe')
args.append(str(stripe))
@ -332,41 +342,44 @@ def add_bricks(name, new_bricks, stripe, replica, force):
args.append('force')
run_gluster(args)
def do_rebalance(name):
run_gluster([ 'volume', 'rebalance', name, 'start' ])
run_gluster(['volume', 'rebalance', name, 'start'])
def enable_quota(name):
run_gluster([ 'volume', 'quota', name, 'enable' ])
run_gluster(['volume', 'quota', name, 'enable'])
def set_quota(name, directory, value):
run_gluster([ 'volume', 'quota', name, 'limit-usage', directory, value ])
run_gluster(['volume', 'quota', name, 'limit-usage', directory, value])
def main():
### MAIN ###
# MAIN
global module
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True, aliases=['volume']),
state=dict(required=True, choices=['present', 'absent', 'started', 'stopped']),
cluster=dict(default=None, type='list'),
host=dict(default=None),
stripes=dict(default=None, type='int'),
replicas=dict(default=None, type='int'),
arbiters=dict(default=None, type='int'),
disperses=dict(default=None, type='int'),
redundancies=dict(default=None, type='int'),
transport=dict(default='tcp', choices=['tcp', 'rdma', 'tcp,rdma']),
bricks=dict(default=None, aliases=['brick']),
start_on_create=dict(default=True, type='bool'),
rebalance=dict(default=False, type='bool'),
options=dict(default={}, type='dict'),
quota=dict(),
directory=dict(default=None),
force=dict(default=False, type='bool'),
)
)
name=dict(type='str', required=True, aliases=['volume']),
state=dict(type='str', required=True, choices=['absent', 'started', 'stopped', 'present']),
cluster=dict(type='list'),
host=dict(type='str'),
stripes=dict(type='int'),
replicas=dict(type='int'),
arbiters=dict(type='int'),
disperses=dict(type='int'),
redundancies=dict(type='int'),
transport=dict(type='str', default='tcp', choices=['tcp', 'rdma', 'tcp,rdma']),
bricks=dict(type='str', aliases=['brick']),
start_on_create=dict(type='bool', default=True),
rebalance=dict(type='bool', default=False),
options=dict(type='dict', default={}),
quota=dict(type='str'),
directory=dict(type='str'),
force=dict(type='bool', default=False),
),
)
global glusterbin
glusterbin = module.get_bin_path('gluster', True)
@ -375,7 +388,7 @@ def main():
action = module.params['state']
volume_name = module.params['name']
cluster= module.params['cluster']
cluster = module.params['cluster']
brick_paths = module.params['bricks']
stripes = module.params['stripes']
replicas = module.params['replicas']
@ -408,7 +421,6 @@ def main():
quota = module.params['quota']
directory = module.params['directory']
# get current state info
peers = get_peers()
volumes = get_volumes()
@ -421,7 +433,7 @@ def main():
if volume_name in volumes:
if volumes[volume_name]['status'].lower() != 'stopped':
stop_volume(volume_name)
run_gluster([ 'volume', 'delete', volume_name ])
run_gluster(['volume', 'delete', volume_name])
changed = True
if action == 'present':
@ -495,7 +507,7 @@ def main():
do_rebalance(volume_name)
facts = {}
facts['glusterfs'] = { 'peers': peers, 'volumes': volumes, 'quotas': quotas }
facts['glusterfs'] = {'peers': peers, 'volumes': volumes, 'quotas': quotas}
module.exit_json(changed=changed, ansible_facts=facts)

@ -1,56 +1,55 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2012, Stephen Fromm <sfromm@gmail.com>
# Copyright: (c) 2012, Stephen Fromm <sfromm@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'],
'supported_by': 'core'}
DOCUMENTATION = '''
---
module: group
author: "Stephen Fromm (@sfromm)"
author:
- Stephen Fromm (@sfromm)
version_added: "0.0.2"
short_description: Add or remove groups
requirements: [ groupadd, groupdel, groupmod ]
requirements:
- groupadd
- groupdel
- groupmod
description:
- Manage presence of groups on a host.
- For Windows targets, use the M(win_group) module instead.
options:
name:
required: true
description:
- Name of the group to manage.
required: true
gid:
required: false
description:
- Optional I(GID) to set for the group.
state:
required: false
default: "present"
choices: [ present, absent ]
description:
- Whether the group should be present or not on the remote host.
choices: [ absent, present ]
default: present
system:
required: false
default: "no"
choices: [ "yes", "no" ]
description:
- If I(yes), indicates that the group created is a system group.
type: bool
default: 'no'
notes:
- For Windows targets, use the M(win_group) module instead.
'''
EXAMPLES = '''
# Example group command from Ansible Playbooks
- group:
- name: Ensure group "somegroup" exists
group:
name: somegroup
state: present
'''
@ -81,11 +80,11 @@ class Group(object):
return load_platform_subclass(Group, args, kwargs)
def __init__(self, module):
self.module = module
self.state = module.params['state']
self.name = module.params['name']
self.gid = module.params['gid']
self.system = module.params['system']
self.module = module
self.state = module.params['state']
self.name = module.params['name']
self.gid = module.params['gid']
self.system = module.params['system']
def execute_command(self, cmd):
return self.module.run_command(cmd)
@ -136,6 +135,7 @@ class Group(object):
return False
return info
# ===========================================
class SunOS(Group):
@ -205,6 +205,7 @@ class AIX(Group):
cmd.append(self.name)
return self.execute_command(cmd)
# ===========================================
class FreeBsdGroup(Group):
@ -246,9 +247,8 @@ class FreeBsdGroup(Group):
return self.execute_command(cmd)
return (None, '', '')
# ===========================================
# ===========================================
class DarwinGroup(Group):
"""
@ -267,22 +267,22 @@ class DarwinGroup(Group):
def group_add(self, **kwargs):
cmd = [self.module.get_bin_path('dseditgroup', True)]
cmd += [ '-o', 'create' ]
cmd += ['-o', 'create']
if self.gid is not None:
cmd += [ '-i', self.gid ]
cmd += ['-i', self.gid]
elif 'system' in kwargs and kwargs['system'] is True:
gid = self.get_lowest_available_system_gid()
if gid is not False:
self.gid = str(gid)
cmd += [ '-i', self.gid ]
cmd += [ '-L', self.name ]
cmd += ['-i', self.gid]
cmd += ['-L', self.name]
(rc, out, err) = self.execute_command(cmd)
return (rc, out, err)
def group_del(self):
cmd = [self.module.get_bin_path('dseditgroup', True)]
cmd += [ '-o', 'delete' ]
cmd += [ '-L', self.name ]
cmd += ['-o', 'delete']
cmd += ['-L', self.name]
(rc, out, err) = self.execute_command(cmd)
return (rc, out, err)
@ -290,10 +290,10 @@ class DarwinGroup(Group):
info = self.group_info()
if self.gid is not None and int(self.gid) != info[2]:
cmd = [self.module.get_bin_path('dseditgroup', True)]
cmd += [ '-o', 'edit' ]
cmd += ['-o', 'edit']
if gid is not None:
cmd += [ '-i', gid ]
cmd += [ '-L', self.name ]
cmd += ['-i', gid]
cmd += ['-L', self.name]
(rc, out, err) = self.execute_command(cmd)
return (rc, out, err)
return (None, '', '')
@ -302,7 +302,7 @@ class DarwinGroup(Group):
# check for lowest available system gid (< 500)
try:
cmd = [self.module.get_bin_path('dscl', True)]
cmd += [ '/Local/Default', '-list', '/Groups', 'PrimaryGroupID']
cmd += ['/Local/Default', '-list', '/Groups', 'PrimaryGroupID']
(rc, out, err) = self.execute_command(cmd)
lines = out.splitlines()
highest = 0
@ -318,6 +318,7 @@ class DarwinGroup(Group):
except:
return False
class OpenBsdGroup(Group):
"""
This is a OpenBSD Group manipulation class.
@ -357,6 +358,7 @@ class OpenBsdGroup(Group):
cmd.append(self.name)
return self.execute_command(cmd)
# ===========================================
class NetBsdGroup(Group):
@ -398,17 +400,18 @@ class NetBsdGroup(Group):
cmd.append(self.name)
return self.execute_command(cmd)
# ===========================================
def main():
module = AnsibleModule(
argument_spec = dict(
state=dict(default='present', choices=['present', 'absent'], type='str'),
name=dict(required=True, type='str'),
gid=dict(default=None, type='str'),
system=dict(default=False, type='bool'),
argument_spec=dict(
state=dict(type='str', default='present', choices=['absent', 'present']),
name=dict(type='str', required=True),
gid=dict(type='str'),
system=dict(type='bool', default=False),
),
supports_check_mode=True
supports_check_mode=True,
)
group = Group(module)

@ -200,7 +200,7 @@ class DebianStrategy(GenericStrategy):
open(self.HOSTNAME_FILE, "a").write("")
except IOError as e:
self.module.fail_json(msg="failed to write file: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
try:
f = open(self.HOSTNAME_FILE)
try:
@ -209,7 +209,7 @@ class DebianStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
def set_permanent_hostname(self, name):
try:
@ -220,7 +220,7 @@ class DebianStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
class SLESStrategy(GenericStrategy):
@ -236,7 +236,7 @@ class SLESStrategy(GenericStrategy):
open(self.HOSTNAME_FILE, "a").write("")
except IOError as e:
self.module.fail_json(msg="failed to write file: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
try:
f = open(self.HOSTNAME_FILE)
try:
@ -245,7 +245,7 @@ class SLESStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
def set_permanent_hostname(self, name):
try:
@ -256,7 +256,7 @@ class SLESStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
class RedHatStrategy(GenericStrategy):
@ -278,7 +278,7 @@ class RedHatStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
def set_permanent_hostname(self, name):
try:
@ -303,7 +303,7 @@ class RedHatStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
class AlpineStrategy(GenericStrategy):
@ -325,7 +325,7 @@ class AlpineStrategy(GenericStrategy):
open(self.HOSTNAME_FILE, "a").write("")
except IOError as e:
self.module.fail_json(msg="failed to write file: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
try:
f = open(self.HOSTNAME_FILE)
try:
@ -334,7 +334,7 @@ class AlpineStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
def set_permanent_hostname(self, name):
try:
@ -345,7 +345,7 @@ class AlpineStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
def set_current_hostname(self, name):
cmd = [self.hostname_cmd, '-F', self.HOSTNAME_FILE]
@ -413,7 +413,7 @@ class OpenRCStrategy(GenericStrategy):
return line[10:].strip('"')
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
finally:
f.close()
@ -435,7 +435,7 @@ class OpenRCStrategy(GenericStrategy):
f.write('\n'.join(lines) + '\n')
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
finally:
f.close()
@ -454,7 +454,7 @@ class OpenBSDStrategy(GenericStrategy):
open(self.HOSTNAME_FILE, "a").write("")
except IOError as e:
self.module.fail_json(msg="failed to write file: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
try:
f = open(self.HOSTNAME_FILE)
try:
@ -463,7 +463,7 @@ class OpenBSDStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
def set_permanent_hostname(self, name):
try:
@ -474,7 +474,7 @@ class OpenBSDStrategy(GenericStrategy):
f.close()
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
class SolarisStrategy(GenericStrategy):
@ -521,7 +521,7 @@ class FreeBSDStrategy(GenericStrategy):
open(self.HOSTNAME_FILE, "a").write("hostname=temporarystub\n")
except IOError as e:
self.module.fail_json(msg="failed to write file: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
try:
try:
f = open(self.HOSTNAME_FILE, 'r')
@ -531,7 +531,7 @@ class FreeBSDStrategy(GenericStrategy):
return line[10:].strip('"')
except Exception as e:
self.module.fail_json(msg="failed to read hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
finally:
f.close()
@ -553,7 +553,7 @@ class FreeBSDStrategy(GenericStrategy):
f.write('\n'.join(lines) + '\n')
except Exception as e:
self.module.fail_json(msg="failed to update hostname: %s" %
to_native(e), exception=traceback.format_exc())
to_native(e), exception=traceback.format_exc())
finally:
f.close()

@ -1,17 +1,15 @@
#!/usr/bin/python
#
# (c) 2013, RSD Services S.A
# Copyright: (c) 2013, RSD Services S.A
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: java_cert
@ -65,10 +63,10 @@ options:
state:
description:
- Defines action which can be either certificate import or removal.
choices: [ 'present', 'absent' ]
choices: [ absent, present ]
default: present
author: Adam Hamsik @haad
author:
- Adam Hamsik (@haad)
'''
EXAMPLES = '''
@ -131,17 +129,19 @@ import os
# import module snippets
from ansible.module_utils.basic import AnsibleModule
def check_cert_present(module, executable, keystore_path, keystore_pass, alias):
''' Check if certificate with alias is present in keystore
located at keystore_path '''
test_cmd = ("%s -noprompt -list -keystore '%s' -storepass '%s' "
"-alias '%s'")%(executable, keystore_path, keystore_pass, alias)
"-alias '%s'") % (executable, keystore_path, keystore_pass, alias)
(check_rc, _, _) = module.run_command(test_cmd)
if check_rc == 0:
return True
return False
def import_cert_url(module, executable, url, port, keystore_path, keystore_pass, alias):
''' Import certificate from URL into keystore located at keystore_path '''
import re
@ -152,7 +152,7 @@ def import_cert_url(module, executable, url, port, keystore_path, keystore_pass,
proxy_opts = ''
if https_proxy is not None:
(proxy_host, proxy_port) = https_proxy.split(':')
proxy_opts = ("-J-Dhttps.proxyHost=%s -J-Dhttps.proxyPort=%s")%(proxy_host, proxy_port)
proxy_opts = ("-J-Dhttps.proxyHost=%s -J-Dhttps.proxyPort=%s") % (proxy_host, proxy_port)
if no_proxy is not None:
# For Java's nonProxyHosts property, items are separated by '|',
@ -162,13 +162,13 @@ def import_cert_url(module, executable, url, port, keystore_path, keystore_pass,
# The property name is http.nonProxyHosts, there is no
# separate setting for HTTPS.
proxy_opts += (" -J-Dhttp.nonProxyHosts='%s'")%(non_proxy_hosts)
proxy_opts += (" -J-Dhttp.nonProxyHosts='%s'") % (non_proxy_hosts)
fetch_cmd = ("%s -printcert -rfc -sslserver %s %s:%d")%(executable, proxy_opts, url, port)
fetch_cmd = ("%s -printcert -rfc -sslserver %s %s:%d") % (executable, proxy_opts, url, port)
import_cmd = ("%s -importcert -noprompt -keystore '%s' "
"-storepass '%s' -alias '%s'")%(executable, keystore_path,
keystore_pass, alias)
"-storepass '%s' -alias '%s'") % (executable, keystore_path,
keystore_pass, alias)
if module.check_mode:
module.exit_json(changed=True)
@ -180,7 +180,7 @@ def import_cert_url(module, executable, url, port, keystore_path, keystore_pass,
(import_rc, import_out, import_err) = module.run_command(import_cmd,
data=fetch_out,
check_rc=False)
diff = {'before': '\n', 'after': '%s\n'%alias}
diff = {'before': '\n', 'after': '%s\n' % alias}
if import_rc == 0:
return module.exit_json(changed=True, msg=import_out,
rc=import_rc, cmd=import_cmd, stdout=import_out,
@ -189,14 +189,15 @@ def import_cert_url(module, executable, url, port, keystore_path, keystore_pass,
return module.fail_json(msg=import_out, rc=import_rc, cmd=import_cmd,
error=import_err)
def import_cert_path(module, executable, path, keystore_path, keystore_pass, alias):
''' Import certificate from path into keystore located on
keystore_path as alias '''
import_cmd = ("%s -importcert -noprompt -keystore '%s' "
"-storepass '%s' -file '%s' -alias '%s'")%(executable,
keystore_path,
keystore_pass,
path, alias)
"-storepass '%s' -file '%s' -alias '%s'") % (executable,
keystore_path,
keystore_pass,
path, alias)
if module.check_mode:
module.exit_json(changed=True)
@ -205,7 +206,7 @@ def import_cert_path(module, executable, path, keystore_path, keystore_pass, ali
(import_rc, import_out, import_err) = module.run_command(import_cmd,
check_rc=False)
diff = {'before': '\n', 'after': '%s\n'%alias}
diff = {'before': '\n', 'after': '%s\n' % alias}
if import_rc == 0:
return module.exit_json(changed=True, msg=import_out,
rc=import_rc, cmd=import_cmd, stdout=import_out,
@ -213,6 +214,7 @@ def import_cert_path(module, executable, path, keystore_path, keystore_pass, ali
else:
return module.fail_json(msg=import_out, rc=import_rc, cmd=import_cmd)
def import_pkcs12_path(module, executable, path, keystore_path, keystore_pass, pkcs12_pass, pkcs12_alias, alias):
''' Import pkcs12 from path into keystore located on
keystore_path as alias '''
@ -228,7 +230,7 @@ def import_pkcs12_path(module, executable, path, keystore_path, keystore_pass, p
(import_rc, import_out, import_err) = module.run_command(import_cmd,
check_rc=False)
diff = {'before': '\n', 'after': '%s\n'%alias}
diff = {'before': '\n', 'after': '%s\n' % alias}
if import_rc == 0:
return module.exit_json(changed=True, msg=import_out,
rc=import_rc, cmd=import_cmd, stdout=import_out,
@ -240,7 +242,7 @@ def import_pkcs12_path(module, executable, path, keystore_path, keystore_pass, p
def delete_cert(module, executable, keystore_path, keystore_pass, alias):
''' Delete certificate identified with alias from keystore on keystore_path '''
del_cmd = ("%s -delete -keystore '%s' -storepass '%s' "
"-alias '%s'")%(executable, keystore_path, keystore_pass, alias)
"-alias '%s'") % (executable, keystore_path, keystore_pass, alias)
if module.check_mode:
module.exit_json(changed=True)
@ -248,28 +250,31 @@ def delete_cert(module, executable, keystore_path, keystore_pass, alias):
# Delete SSL certificate from keystore
(del_rc, del_out, del_err) = module.run_command(del_cmd, check_rc=True)
diff = {'before': '%s\n'%alias, 'after': None}
diff = {'before': '%s\n' % alias, 'after': None}
return module.exit_json(changed=True, msg=del_out,
rc=del_rc, cmd=del_cmd, stdout=del_out,
error=del_err, diff=diff)
def test_keytool(module, executable):
''' Test if keytool is actuall executable or not '''
test_cmd = "%s"%(executable)
test_cmd = "%s" % (executable)
module.run_command(test_cmd, check_rc=True)
def test_keystore(module, keystore_path):
''' Check if we can access keystore as file or not '''
if keystore_path is None:
keystore_path = ''
if not os.path.exists(keystore_path) and not os.path.isfile(keystore_path):
## Keystore doesn't exist we want to create it
# Keystore doesn't exist we want to create it
return module.fail_json(changed=False,
msg="Module require existing keystore at keystore_path '%s'"
% (keystore_path))
% (keystore_path))
def main():
argument_spec = dict(
@ -279,13 +284,12 @@ def main():
pkcs12_password=dict(type='str', no_log=True),
pkcs12_alias=dict(type='str'),
cert_alias=dict(type='str'),
cert_port=dict(default='443', type='int'),
cert_port=dict(type='int', default='443'),
keystore_path=dict(type='path'),
keystore_pass=dict(required=True, type='str', no_log=True),
keystore_create=dict(default=False, type='bool'),
executable=dict(default='keytool', type='str'),
state=dict(default='present',
choices=['present', 'absent'])
keystore_pass=dict(type='str', required=True, no_log=True),
keystore_create=dict(type='bool', default=False),
executable=dict(type='str', default='keytool'),
state=dict(type='str', default='present', choices=['absent', 'present']),
)
module = AnsibleModule(
@ -317,7 +321,7 @@ def main():
if path and not cert_alias:
module.fail_json(changed=False,
msg="Using local path import from %s requires alias argument."
%(keystore_path))
% (keystore_path))
test_keytool(module, executable)
@ -347,5 +351,6 @@ def main():
module.exit_json(changed=False)
if __name__ == "__main__":
main()

@ -1,49 +1,44 @@
#!/usr/bin/python
# encoding: utf-8 -*-
# (c) 2013, Matthias Vogelgesang <matthias.vogelgesang@gmail.com>
# Copyright: (c) 2013, Matthias Vogelgesang <matthias.vogelgesang@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: kernel_blacklist
author: "Matthias Vogelgesang (@matze)"
version_added: 1.4
author:
- Matthias Vogelgesang (@matze)
version_added: '1.4'
short_description: Blacklist kernel modules
description:
- Add or remove kernel modules from blacklist.
options:
name:
required: true
description:
- Name of kernel module to black- or whitelist.
required: true
state:
required: false
default: "present"
choices: [ present, absent ]
description:
- Whether the module should be present in the blacklist or absent.
choices: [ absent, present ]
default: present
blacklist_file:
required: false
description:
- If specified, use this blacklist file instead of
C(/etc/modprobe.d/blacklist-ansible.conf).
default: null
requirements: []
'''
EXAMPLES = '''
# Blacklist the nouveau driver module
- kernel_blacklist:
- name: Blacklist the nouveau driver module
kernel_blacklist:
name: nouveau
state: present
'''
@ -118,13 +113,13 @@ class Blacklist(object):
f.close()
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
state=dict(required=False, choices=['present', 'absent'],
default='present'),
blacklist_file=dict(required=False, default=None)
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['absent', 'present']),
blacklist_file=dict(type='str')
),
supports_check_mode=True,
)

@ -1,51 +1,46 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: locale_gen
short_description: Creates or removes locales.
short_description: Creates or removes locales
description:
- Manages locales by editing /etc/locale.gen and invoking locale-gen.
version_added: "1.6"
author: "Augustus Kling (@AugustusKling)"
author:
- Augustus Kling (@AugustusKling)
options:
name:
description:
- Name and encoding of the locale, such as "en_GB.UTF-8".
required: true
default: null
aliases: []
state:
description:
- Whether the locale shall be present.
required: false
choices: ["present", "absent"]
default: "present"
choices: [ absent, present ]
default: present
'''
EXAMPLES = '''
# Ensure a locale exists.
- locale_gen:
- name: Ensure a locale exists
locale_gen:
name: de_CH.UTF-8
state: present
'''
import os
import os.path
from subprocess import Popen, PIPE, call
import re
from subprocess import Popen, PIPE, call
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.pycompat24 import get_exception
@ -64,6 +59,7 @@ LOCALE_NORMALIZATION = {
".euctw": ".EUC-TW",
}
# ===========================================
# location module specific support methods.
#
@ -89,12 +85,14 @@ def is_available(name, ubuntuMode):
fd.close()
return False
def is_present(name):
"""Checks if the given locale is currently installed."""
output = Popen(["locale", "-a"], stdout=PIPE).communicate()[0]
output = to_native(output)
return any(fix_case(name) == fix_case(line) for line in output.splitlines())
def fix_case(name):
"""locale -a might return the encoding in either lower or upper case.
Passing through this function makes them uniform for comparisons."""
@ -102,6 +100,7 @@ def fix_case(name):
name = name.replace(s, r)
return name
def replace_line(existing_line, new_line):
"""Replaces lines in /etc/locale.gen"""
try:
@ -115,6 +114,7 @@ def replace_line(existing_line, new_line):
finally:
f.close()
def set_locale(name, enabled=True):
""" Sets the state of the locale. Defaults to enabled. """
search_string = '#{0,1}\s*%s (?P<charset>.+)' % name
@ -133,6 +133,7 @@ def set_locale(name, enabled=True):
finally:
f.close()
def apply_change(targetState, name):
"""Create or remove locale.
@ -140,7 +141,7 @@ def apply_change(targetState, name):
targetState -- Desired state, either present or absent.
name -- Name including encoding such as de_CH.UTF-8.
"""
if targetState=="present":
if targetState == "present":
# Create locale.
set_locale(name, enabled=True)
else:
@ -148,8 +149,9 @@ def apply_change(targetState, name):
set_locale(name, enabled=False)
localeGenExitValue = call("locale-gen")
if localeGenExitValue!=0:
raise EnvironmentError(localeGenExitValue, "locale.gen failed to execute, it returned "+str(localeGenExitValue))
if localeGenExitValue != 0:
raise EnvironmentError(localeGenExitValue, "locale.gen failed to execute, it returned " + str(localeGenExitValue))
def apply_change_ubuntu(targetState, name):
"""Create or remove locale.
@ -158,7 +160,7 @@ def apply_change_ubuntu(targetState, name):
targetState -- Desired state, either present or absent.
name -- Name including encoding such as de_CH.UTF-8.
"""
if targetState=="present":
if targetState == "present":
# Create locale.
# Ubuntu's patched locale-gen automatically adds the new locale to /var/lib/locales/supported.d/local
localeGenExitValue = call(["locale-gen", name])
@ -181,20 +183,17 @@ def apply_change_ubuntu(targetState, name):
# Please provide a patch if you know how to avoid regenerating the locales to keep!
localeGenExitValue = call(["locale-gen", "--purge"])
if localeGenExitValue!=0:
raise EnvironmentError(localeGenExitValue, "locale.gen failed to execute, it returned "+str(localeGenExitValue))
if localeGenExitValue != 0:
raise EnvironmentError(localeGenExitValue, "locale.gen failed to execute, it returned " + str(localeGenExitValue))
# ==============================================================
# main
def main():
module = AnsibleModule(
argument_spec = dict(
name = dict(required=True),
state = dict(choices=['present','absent'], default='present'),
argument_spec=dict(
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['absent', 'present']),
),
supports_check_mode=True
supports_check_mode=True,
)
name = module.params['name']
@ -218,7 +217,7 @@ def main():
prev_state = "present"
else:
prev_state = "absent"
changed = (prev_state!=state)
changed = (prev_state != state)
if module.check_mode:
module.exit_json(changed=changed)

@ -1,22 +1,21 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2013, Alexander Bulimov <lazywolf0@gmail.com>
# based on lvol module by Jeroen Hoekx <jeroen.hoekx@dsquare.be>
# Copyright: (c) 2013, Alexander Bulimov <lazywolf0@gmail.com>
# Based on lvol module by Jeroen Hoekx <jeroen.hoekx@dsquare.be>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
author: "Alexander Bulimov (@abulimov)"
author:
- Alexander Bulimov (@abulimov)
module: lvg
short_description: Configure LVM volume groups
description:
@ -31,61 +30,54 @@ options:
description:
- List of comma-separated devices to use as physical devices in this volume group. Required when creating or resizing volume group.
- The module will take care of running pvcreate if needed.
required: false
pesize:
description:
- The size of the physical extent in megabytes. Must be a power of 2.
default: 4
required: false
pv_options:
description:
- Additional options to pass to C(pvcreate) when creating the volume group.
default: null
required: false
version_added: "2.4"
vg_options:
description:
- Additional options to pass to C(vgcreate) when creating the volume group.
default: null
required: false
version_added: "1.6"
state:
choices: [ "present", "absent" ]
default: present
description:
- Control if the volume group exists.
required: false
choices: [ absent, present ]
default: present
force:
choices: [ "yes", "no" ]
default: "no"
description:
- If yes, allows to remove volume group with logical volumes.
required: false
- If C(yes), allows to remove volume group with logical volumes.
type: bool
default: 'no'
notes:
- module does not modify PE size for already present volume group
- This module does not modify PE size for already present volume group.
'''
EXAMPLES = '''
# Create a volume group on top of /dev/sda1 with physical extent size = 32MB.
- lvg:
- name: Create a volume group on top of /dev/sda1 with physical extent size = 32MB
lvg:
vg: vg.services
pvs: /dev/sda1
pesize: 32
# Create or resize a volume group on top of /dev/sdb1 and /dev/sdc5.
# If, for example, we already have VG vg.services on top of /dev/sdb1,
# this VG will be extended by /dev/sdc5. Or if vg.services was created on
# top of /dev/sda5, we first extend it with /dev/sdb1 and /dev/sdc5,
# and then reduce by /dev/sda5.
- lvg:
- name: Create or resize a volume group on top of /dev/sdb1 and /dev/sdc5.
lvg:
vg: vg.services
pvs: /dev/sdb1,/dev/sdc5
# Remove a volume group with name vg.services.
- lvg:
- name: Remove a volume group with name vg.services
lvg:
vg: vg.services
state: absent
'''
import os
from ansible.module_utils.basic import AnsibleModule
@ -102,6 +94,7 @@ def parse_vgs(data):
})
return vgs
def find_mapper_device_name(module, dm_device):
dmsetup_cmd = module.get_bin_path('dmsetup', True)
mapper_prefix = '/dev/mapper/'
@ -111,6 +104,7 @@ def find_mapper_device_name(module, dm_device):
mapper_device = mapper_prefix + dm_name.rstrip()
return mapper_device
def parse_pvs(module, data):
pvs = []
dm_prefix = '/dev/dm-'
@ -124,16 +118,17 @@ def parse_pvs(module, data):
})
return pvs
def main():
module = AnsibleModule(
argument_spec = dict(
vg=dict(required=True),
argument_spec=dict(
vg=dict(type='str', required=True),
pvs=dict(type='list'),
pesize=dict(type='int', default=4),
pv_options=dict(default=''),
vg_options=dict(default=''),
state=dict(choices=["absent", "present"], default='present'),
force=dict(type='bool', default='no'),
pv_options=dict(type='str', default=''),
vg_options=dict(type='str', default=''),
state=dict(type='str', default='present', choices=['absent', 'present']),
force=dict(type='bool', default=False),
),
supports_check_mode=True,
)
@ -155,29 +150,29 @@ def main():
for idx, dev in enumerate(dev_list):
dev_list[idx] = os.path.realpath(dev)
if state=='present':
### check given devices
if state == 'present':
# check given devices
for test_dev in dev_list:
if not os.path.exists(test_dev):
module.fail_json(msg="Device %s not found."%test_dev)
module.fail_json(msg="Device %s not found." % test_dev)
### get pv list
# get pv list
pvs_cmd = module.get_bin_path('pvs', True)
rc,current_pvs,err = module.run_command("%s --noheadings -o pv_name,vg_name --separator ';'" % pvs_cmd)
rc, current_pvs, err = module.run_command("%s --noheadings -o pv_name,vg_name --separator ';'" % pvs_cmd)
if rc != 0:
module.fail_json(msg="Failed executing pvs command.",rc=rc, err=err)
module.fail_json(msg="Failed executing pvs command.", rc=rc, err=err)
### check pv for devices
# check pv for devices
pvs = parse_pvs(module, current_pvs)
used_pvs = [ pv for pv in pvs if pv['name'] in dev_list and pv['vg_name'] and pv['vg_name'] != vg ]
used_pvs = [pv for pv in pvs if pv['name'] in dev_list and pv['vg_name'] and pv['vg_name'] != vg]
if used_pvs:
module.fail_json(msg="Device %s is already in %s volume group."%(used_pvs[0]['name'],used_pvs[0]['vg_name']))
module.fail_json(msg="Device %s is already in %s volume group." % (used_pvs[0]['name'], used_pvs[0]['vg_name']))
vgs_cmd = module.get_bin_path('vgs', True)
rc,current_vgs,err = module.run_command("%s --noheadings -o vg_name,pv_count,lv_count --separator ';'" % vgs_cmd)
rc, current_vgs, err = module.run_command("%s --noheadings -o vg_name,pv_count,lv_count --separator ';'" % vgs_cmd)
if rc != 0:
module.fail_json(msg="Failed executing vgs command.",rc=rc, err=err)
module.fail_json(msg="Failed executing vgs command.", rc=rc, err=err)
changed = False
@ -192,42 +187,42 @@ def main():
if this_vg is None:
if state == 'present':
### create VG
# create VG
if module.check_mode:
changed = True
else:
### create PV
# create PV
pvcreate_cmd = module.get_bin_path('pvcreate', True)
for current_dev in dev_list:
rc,_,err = module.run_command([pvcreate_cmd] + pvoptions + ['-f', str(current_dev)])
rc, _, err = module.run_command([pvcreate_cmd] + pvoptions + ['-f', str(current_dev)])
if rc == 0:
changed = True
else:
module.fail_json(msg="Creating physical volume '%s' failed" % current_dev, rc=rc, err=err)
vgcreate_cmd = module.get_bin_path('vgcreate')
rc,_,err = module.run_command([vgcreate_cmd] + vgoptions + ['-s', str(pesize), vg] + dev_list)
rc, _, err = module.run_command([vgcreate_cmd] + vgoptions + ['-s', str(pesize), vg] + dev_list)
if rc == 0:
changed = True
else:
module.fail_json(msg="Creating volume group '%s' failed"%vg, rc=rc, err=err)
module.fail_json(msg="Creating volume group '%s' failed" % vg, rc=rc, err=err)
else:
if state == 'absent':
if module.check_mode:
module.exit_json(changed=True)
else:
if this_vg['lv_count'] == 0 or force:
### remove VG
# remove VG
vgremove_cmd = module.get_bin_path('vgremove', True)
rc,_,err = module.run_command("%s --force %s" % (vgremove_cmd, vg))
rc, _, err = module.run_command("%s --force %s" % (vgremove_cmd, vg))
if rc == 0:
module.exit_json(changed=True)
else:
module.fail_json(msg="Failed to remove volume group %s"%(vg),rc=rc, err=err)
module.fail_json(msg="Failed to remove volume group %s" % (vg), rc=rc, err=err)
else:
module.fail_json(msg="Refuse to remove non-empty volume group %s without force=yes"%(vg))
module.fail_json(msg="Refuse to remove non-empty volume group %s without force=yes" % (vg))
### resize VG
current_devs = [ os.path.realpath(pv['name']) for pv in pvs if pv['vg_name'] == vg ]
# resize VG
current_devs = [os.path.realpath(pv['name']) for pv in pvs if pv['vg_name'] == vg]
devs_to_remove = list(set(current_devs) - set(dev_list))
devs_to_add = list(set(dev_list) - set(current_devs))
@ -237,31 +232,31 @@ def main():
else:
if devs_to_add:
devs_to_add_string = ' '.join(devs_to_add)
### create PV
# create PV
pvcreate_cmd = module.get_bin_path('pvcreate', True)
for current_dev in devs_to_add:
rc,_,err = module.run_command([pvcreate_cmd] + pvoptions + ['-f', str(current_dev)])
rc, _, err = module.run_command([pvcreate_cmd] + pvoptions + ['-f', str(current_dev)])
if rc == 0:
changed = True
else:
module.fail_json(msg="Creating physical volume '%s' failed"%current_dev, rc=rc, err=err)
### add PV to our VG
module.fail_json(msg="Creating physical volume '%s' failed" % current_dev, rc=rc, err=err)
# add PV to our VG
vgextend_cmd = module.get_bin_path('vgextend', True)
rc,_,err = module.run_command("%s %s %s" % (vgextend_cmd, vg, devs_to_add_string))
rc, _, err = module.run_command("%s %s %s" % (vgextend_cmd, vg, devs_to_add_string))
if rc == 0:
changed = True
else:
module.fail_json(msg="Unable to extend %s by %s."%(vg, devs_to_add_string),rc=rc,err=err)
module.fail_json(msg="Unable to extend %s by %s." % (vg, devs_to_add_string), rc=rc, err=err)
### remove some PV from our VG
# remove some PV from our VG
if devs_to_remove:
devs_to_remove_string = ' '.join(devs_to_remove)
vgreduce_cmd = module.get_bin_path('vgreduce', True)
rc,_,err = module.run_command("%s --force %s %s" % (vgreduce_cmd, vg, devs_to_remove_string))
rc, _, err = module.run_command("%s --force %s %s" % (vgreduce_cmd, vg, devs_to_remove_string))
if rc == 0:
changed = True
else:
module.fail_json(msg="Unable to reduce %s by %s."%(vg, devs_to_remove_string),rc=rc,err=err)
module.fail_json(msg="Unable to reduce %s by %s." % (vg, devs_to_remove_string), rc=rc, err=err)
module.exit_json(changed=changed)

@ -1,23 +1,21 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2013, Jeroen Hoekx <jeroen.hoekx@dsquare.be>, Alexander Bulimov <lazywolf0@gmail.com>
# Copyright: (c) 2013, Jeroen Hoekx <jeroen.hoekx@dsquare.be>, Alexander Bulimov <lazywolf0@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
author:
- "Jeroen Hoekx (@jhoekx)"
- "Alexander Bulimov (@abulimov)"
- Jeroen Hoekx (@jhoekx)
- Alexander Bulimov (@abulimov)
module: lvol
short_description: Configure LVM logical volumes
description:
@ -40,152 +38,147 @@ options:
Float values must begin with a digit.
Resizing using percentage values was not supported prior to 2.1.
state:
choices: [ "present", "absent" ]
default: present
description:
- Control if the logical volume exists. If C(present) and the
volume does not already exist then the C(size) option is required.
required: false
choices: [ absent, present ]
default: present
active:
version_added: "2.2"
choices: [ "yes", "no" ]
default: "yes"
description:
- Whether the volume is activate and visible to the host.
required: false
type: bool
default: 'yes'
version_added: "2.2"
force:
version_added: "1.5"
choices: [ "yes", "no" ]
default: "no"
description:
- Shrink or remove operations of volumes requires this switch. Ensures that
that filesystems get never corrupted/destroyed by mistake.
required: false
type: bool
default: 'no'
version_added: "1.5"
opts:
version_added: "2.0"
description:
- Free-form options to be passed to the lvcreate command
version_added: "2.0"
snapshot:
version_added: "2.1"
description:
- The name of the snapshot volume
required: false
version_added: "2.1"
pvs:
version_added: "2.2"
description:
- Comma separated list of physical volumes e.g. /dev/sda,/dev/sdb
required: false
shrink:
version_added: "2.2"
shrink:
description:
- shrink if current size is higher than size requested
required: false
default: yes
type: bool
default: 'yes'
version_added: "2.2"
notes:
- Filesystems on top of the volume are not resized.
'''
EXAMPLES = '''
# Create a logical volume of 512m.
- lvol:
- name: Create a logical volume of 512m
lvol:
vg: firefly
lv: test
size: 512
# Create a logical volume of 512m with disks /dev/sda and /dev/sdb
- lvol:
- name: Create a logical volume of 512m with disks /dev/sda and /dev/sdb
lvol:
vg: firefly
lv: test
size: 512
pvs: /dev/sda,/dev/sdb
# Create cache pool logical volume
- lvol:
- name: Create cache pool logical volume
lvol:
vg: firefly
lv: lvcache
size: 512m
opts: --type cache-pool
# Create a logical volume of 512g.
- lvol:
- name: Create a logical volume of 512g.
lvol:
vg: firefly
lv: test
size: 512g
# Create a logical volume the size of all remaining space in the volume group
- lvol:
- name: Create a logical volume the size of all remaining space in the volume group
lvol:
vg: firefly
lv: test
size: 100%FREE
# Create a logical volume with special options
- lvol:
- name: Create a logical volume with special options
lvol:
vg: firefly
lv: test
size: 512g
opts: -r 16
# Extend the logical volume to 1024m.
- lvol:
- name: Extend the logical volume to 1024m.
lvol:
vg: firefly
lv: test
size: 1024
# Extend the logical volume to consume all remaining space in the volume group
- lvol:
- name: Extend the logical volume to consume all remaining space in the volume group
lvol:
vg: firefly
lv: test
size: +100%FREE
# Extend the logical volume to take all remaining space of the PVs
- lvol:
- name: Extend the logical volume to take all remaining space of the PVs
lvol:
vg: firefly
lv: test
size: 100%PVS
# Resize the logical volume to % of VG
- lvol:
- name: Resize the logical volume to % of VG
lvol:
vg: firefly
lv: test
size: 80%VG
force: yes
# Reduce the logical volume to 512m
- lvol:
- name: Reduce the logical volume to 512m
lvol:
vg: firefly
lv: test
size: 512
force: yes
# Set the logical volume to 512m and do not try to shrink if size is lower than current one
- lvol:
- name: Set the logical volume to 512m and do not try to shrink if size is lower than current one
lvol:
vg: firefly
lv: test
size: 512
shrink: no
# Remove the logical volume.
- lvol:
- name: Remove the logical volume.
lvol:
vg: firefly
lv: test
state: absent
force: yes
# Create a snapshot volume of the test logical volume.
- lvol:
- name: Create a snapshot volume of the test logical volume.
lvol:
vg: firefly
lv: test
snapshot: snap1
size: 100m
# Deactivate a logical volume
- lvol:
- name: Deactivate a logical volume
lvol:
vg: firefly
lv: test
active: false
# Create a deactivated logical volume
- lvol:
- name: Create a deactivated logical volume
lvol:
vg: firefly
lv: test
size: 512g
@ -196,24 +189,25 @@ import re
from ansible.module_utils.basic import AnsibleModule
decimal_point = re.compile(r"(\d+)")
def mkversion(major, minor, patch):
return (1000 * 1000 * int(major)) + (1000 * int(minor)) + int(patch)
def parse_lvs(data):
lvs = []
for line in data.splitlines():
parts = line.strip().split(';')
lvs.append({
'name': parts[0].replace('[','').replace(']',''),
'name': parts[0].replace('[', '').replace(']', ''),
'size': int(decimal_point.match(parts[1]).group(1)),
'active': (parts[2][4] == 'a')
})
return lvs
def parse_vgs(data):
vgs = []
for line in data.splitlines():
@ -241,15 +235,15 @@ def get_lvm_version(module):
def main():
module = AnsibleModule(
argument_spec=dict(
vg=dict(required=True),
lv=dict(required=True),
vg=dict(type='str', required=True),
lv=dict(type='str', required=True),
size=dict(type='str'),
opts=dict(type='str'),
state=dict(choices=["absent", "present"], default='present'),
force=dict(type='bool', default='no'),
shrink=dict(type='bool', default='yes'),
active=dict(type='bool', default='yes'),
snapshot=dict(type='str', default=None),
state=dict(type='str', default='present', choices=['absent', 'present']),
force=dict(type='bool', default=False),
shrink=dict(type='bool', default=True),
active=dict(type='bool', default=True),
snapshot=dict(type='str'),
pvs=dict(type='str')
),
supports_check_mode=True,
@ -259,7 +253,7 @@ def main():
version_found = get_lvm_version(module)
if version_found is None:
module.fail_json(msg="Failed to get LVM version number")
version_yesopt = mkversion(2, 2, 99) # First LVM with the "--yes" option
version_yesopt = mkversion(2, 2, 99) # First LVM with the "--yes" option
if version_found >= version_yesopt:
yesopt = "--yes"
else:
@ -307,7 +301,7 @@ def main():
size_opt = 'l'
size_unit = ''
if not '%' in size:
if '%' not in size:
# LVCREATE(8) -L --size option unit
if size[-1].lower() in 'bskmgtpe':
size_unit = size[-1].lower()
@ -373,7 +367,7 @@ def main():
msg = ''
if this_lv is None:
if state == 'present':
### create LV
# create LV
lvcreate_cmd = module.get_bin_path("lvcreate", required=True)
if snapshot is not None:
cmd = "%s %s %s -%s %s%s -s -n %s %s %s/%s" % (lvcreate_cmd, test_opt, yesopt, size_opt, size, size_unit, snapshot, opts, vg, lv)
@ -386,7 +380,7 @@ def main():
module.fail_json(msg="Creating logical volume '%s' failed" % lv, rc=rc, err=err)
else:
if state == 'absent':
### remove LV
# remove LV
if not force:
module.fail_json(msg="Sorry, no removal of logical volume %s without force=yes." % (this_lv['name']))
lvremove_cmd = module.get_bin_path("lvremove", required=True)
@ -400,12 +394,12 @@ def main():
pass
elif size_opt == 'l':
### Resize LV based on % value
# Resize LV based on % value
tool = None
size_free = this_vg['free']
if size_whole == 'VG' or size_whole == 'PVS':
size_requested = size_percent * this_vg['size'] / 100
else: # size_whole == 'FREE':
else: # size_whole == 'FREE':
size_requested = size_percent * this_vg['free'] / 100
if '+' in size:
size_requested += this_lv['size']
@ -415,7 +409,7 @@ def main():
else:
module.fail_json(
msg="Logical Volume %s could not be extended. Not enough free space left (%s%s required / %s%s available)" %
(this_lv['name'], (size_requested - this_lv['size']), unit, size_free, unit)
(this_lv['name'], (size_requested - this_lv['size']), unit, size_free, unit)
)
elif shrink and this_lv['size'] > size_requested + this_vg['ext_size']: # more than an extent too large
if size_requested == 0:
@ -433,7 +427,7 @@ def main():
module.fail_json(msg="Unable to resize %s to %s%s" % (lv, size, size_unit), rc=rc, err=err, out=out)
elif rc == 0:
changed = True
msg="Volume %s resized to %s%s" % (this_lv['name'], size_requested, unit)
msg = "Volume %s resized to %s%s" % (this_lv['name'], size_requested, unit)
elif "matches existing size" in err:
module.exit_json(changed=False, vg=vg, lv=this_lv['name'], size=this_lv['size'])
elif "not larger than existing size" in err:
@ -442,7 +436,7 @@ def main():
module.fail_json(msg="Unable to resize %s to %s%s" % (lv, size, size_unit), rc=rc, err=err)
else:
### resize LV based on absolute values
# resize LV based on absolute values
tool = None
if int(size) > this_lv['size']:
tool = module.get_bin_path("lvextend", required=True)

@ -5,14 +5,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ohai
@ -42,7 +41,7 @@ from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec = dict()
argument_spec=dict()
)
cmd = ["/usr/bin/env", "ohai"]
rc, out, err = module.run_command(cmd, check_rc=True)

@ -5,14 +5,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: open_iscsi
@ -113,19 +112,16 @@ import time
from ansible.module_utils.basic import AnsibleModule
ISCSIADM = 'iscsiadm'
def compare_nodelists(l1, l2):
l1.sort()
l2.sort()
return l1 == l2
def iscsi_get_cached_nodes(module, portal=None):
cmd = '%s --mode node' % iscsiadm_cmd
(rc, out, err) = module.run_command(cmd)
@ -156,7 +152,6 @@ def iscsi_get_cached_nodes(module, portal=None):
def iscsi_discover(module, portal, port):
cmd = '%s --mode discovery --type sendtargets --portal %s:%s' % (iscsiadm_cmd, portal, port)
(rc, out, err) = module.run_command(cmd)
@ -165,7 +160,6 @@ def iscsi_discover(module, portal, port):
def target_loggedon(module, target):
cmd = '%s --mode session' % iscsiadm_cmd
(rc, out, err) = module.run_command(cmd)
@ -178,7 +172,6 @@ def target_loggedon(module, target):
def target_login(module, target):
node_auth = module.params['node_auth']
node_user = module.params['node_user']
node_pass = module.params['node_pass']
@ -201,7 +194,6 @@ def target_login(module, target):
def target_logout(module, target):
cmd = '%s --mode node --targetname %s --logout' % (iscsiadm_cmd, target)
(rc, out, err) = module.run_command(cmd)
@ -210,7 +202,6 @@ def target_logout(module, target):
def target_device_node(module, target):
# if anyone know a better way to find out which devicenodes get created for
# a given target...
@ -227,7 +218,6 @@ def target_device_node(module, target):
def target_isauto(module, target):
cmd = '%s --mode node --targetname %s' % (iscsiadm_cmd, target)
(rc, out, err) = module.run_command(cmd)
@ -242,7 +232,6 @@ def target_isauto(module, target):
def target_setauto(module, target):
cmd = '%s --mode node --targetname %s --op=update --name node.startup --value automatic' % (iscsiadm_cmd, target)
(rc, out, err) = module.run_command(cmd)
@ -251,7 +240,6 @@ def target_setauto(module, target):
def target_setmanual(module, target):
cmd = '%s --mode node --targetname %s --op=update --name node.startup --value manual' % (iscsiadm_cmd, target)
(rc, out, err) = module.run_command(cmd)
@ -260,24 +248,23 @@ def target_setmanual(module, target):
def main():
# load ansible module object
module = AnsibleModule(
argument_spec = dict(
argument_spec=dict(
# target
portal = dict(required=False, aliases=['ip']),
port = dict(required=False, default=3260),
target = dict(required=False, aliases=['name', 'targetname']),
node_auth = dict(required=False, default='CHAP'),
node_user = dict(required=False),
node_pass = dict(required=False, no_log=True),
portal=dict(required=False, aliases=['ip']),
port=dict(required=False, default=3260),
target=dict(required=False, aliases=['name', 'targetname']),
node_auth=dict(required=False, default='CHAP'),
node_user=dict(required=False),
node_pass=dict(required=False, no_log=True),
# actions
login = dict(type='bool', aliases=['state']),
auto_node_startup = dict(type='bool', aliases=['automatic']),
discover = dict(type='bool', default=False),
show_nodes = dict(type='bool', default=False)
login=dict(type='bool', aliases=['state']),
auto_node_startup=dict(type='bool', aliases=['automatic']),
discover=dict(type='bool', default=False),
show_nodes=dict(type='bool', default=False)
),
required_together=[['discover_user', 'discover_pass'],
@ -307,7 +294,7 @@ def main():
if discover:
if portal is None:
module.fail_json(msg = "Need to specify at least the portal (ip) to discover")
module.fail_json(msg="Need to specify at least the portal (ip) to discover")
elif check:
nodes = cached
else:
@ -322,7 +309,7 @@ def main():
if login is not None or automatic is not None:
if target is None:
if len(nodes) > 1:
module.fail_json(msg = "Need to specify a target")
module.fail_json(msg="Need to specify a target")
else:
target = nodes[0]
else:
@ -333,7 +320,7 @@ def main():
check_target = True
break
if not check_target:
module.fail_json(msg = "Specified target not found")
module.fail_json(msg="Specified target not found")
if show_nodes:
result['nodes'] = nodes

@ -4,14 +4,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
module: openwrt_init
author:
@ -85,6 +84,7 @@ from ansible.module_utils._text import to_bytes, to_native
module = None
init_script = None
# ===============================
# Check if service is enabled
def is_enabled():
@ -93,6 +93,7 @@ def is_enabled():
return True
return False
# ===========================================
# Main control flow
@ -100,15 +101,15 @@ def main():
global module, init_script
# init
module = AnsibleModule(
argument_spec = dict(
name = dict(required=True, type='str', aliases=['service']),
state = dict(choices=['started', 'stopped', 'restarted', 'reloaded'], type='str'),
enabled = dict(type='bool'),
pattern = dict(required=False, default=None),
argument_spec=dict(
name=dict(required=True, type='str', aliases=['service']),
state=dict(choices=['started', 'stopped', 'restarted', 'reloaded'], type='str'),
enabled=dict(type='bool'),
pattern=dict(required=False, default=None),
),
supports_check_mode=True,
required_one_of=[['state', 'enabled']],
)
)
# initialize
service = module.params['name']
@ -116,7 +117,7 @@ def main():
rc = 0
out = err = ''
result = {
'name': service,
'name': service,
'changed': False,
}
@ -164,7 +165,7 @@ def main():
if rc == 0:
lines = psout.split("\n")
for line in lines:
if module.params['pattern'] in line and not "pattern=" in line:
if module.params['pattern'] in line and "pattern=" not in line:
# so as to not confuse ./hacking/test-module
running = True
break
@ -187,7 +188,7 @@ def main():
action = 'stop'
result['changed'] = True
else:
action = module.params['state'][:-2] # remove 'ed' from restarted/reloaded
action = module.params['state'][:-2] # remove 'ed' from restarted/reloaded
result['state'] = 'started'
result['changed'] = True
@ -197,8 +198,8 @@ def main():
if rc != 0:
module.fail_json(msg="Unable to %s service %s: %s" % (action, service, err))
module.exit_json(**result)
if __name__ == '__main__':
main()

@ -5,14 +5,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: osx_defaults
@ -118,15 +117,17 @@ from ansible.module_utils.six import binary_type, text_type
# exceptions --------------------------------------------------------------- {{{
class OSXDefaultsException(Exception):
pass
# /exceptions -------------------------------------------------------------- }}}
# class MacDefaults -------------------------------------------------------- {{{
class OSXDefaults(object):
""" Class to manage Mac OS user defaults """
# init ---------------------------------------------------------------- {{{
""" Initialize this module. Finds 'defaults' executable and preps the parameters """
def __init__(self, **kwargs):
# Initial var for storing current defaults value
@ -157,6 +158,7 @@ class OSXDefaults(object):
# tools --------------------------------------------------------------- {{{
""" Converts value to given type """
def _convert_type(self, type, value):
if type == "string":
@ -194,6 +196,7 @@ class OSXDefaults(object):
raise OSXDefaultsException('Type is not supported: {0}'.format(type))
""" Returns a normalized list of commandline arguments based on the "host" attribute """
def _host_args(self):
if self.host is None:
return []
@ -203,10 +206,12 @@ class OSXDefaults(object):
return ['-host', self.host]
""" Returns a list containing the "defaults" executable and any common base arguments """
def _base_command(self):
return [self.executable] + self._host_args()
""" Converts array output from defaults to an list """
@staticmethod
def _convert_defaults_str_to_list(value):
@ -221,10 +226,12 @@ class OSXDefaults(object):
value = [re.sub(',$', '', x.strip(' ')) for x in value]
return value
# /tools -------------------------------------------------------------- }}}
# commands ------------------------------------------------------------ {{{
""" Reads value of this domain & key from defaults """
def read(self):
# First try to find out the type
rc, out, err = self.module.run_command(self._base_command() + ["read-type", self.domain, self.key])
@ -258,6 +265,7 @@ class OSXDefaults(object):
self.current_value = self._convert_type(type, out)
""" Writes value to this domain & key to defaults """
def write(self):
# We need to convert some values so the defaults commandline understands it
@ -289,6 +297,7 @@ class OSXDefaults(object):
raise OSXDefaultsException('An error occurred while writing value to defaults: ' + out)
""" Deletes defaults key from domain """
def delete(self):
rc, out, err = self.module.run_command(self._base_command() + ['delete', self.domain, self.key])
if rc != 0:
@ -298,6 +307,7 @@ class OSXDefaults(object):
# run ----------------------------------------------------------------- {{{
""" Does the magic! :) """
def run(self):
# Get the current value from defaults
@ -319,10 +329,9 @@ class OSXDefaults(object):
# Current value matches the given value. Nothing need to be done. Arrays need extra care
if self.type == "array" and self.current_value is not None and not self.array_add and \
set(self.current_value) == set(self.value):
set(self.current_value) == set(self.value):
return False
elif self.type == "array" and self.current_value is not None and self.array_add and \
len(list(set(self.value) - set(self.current_value))) == 0:
elif self.type == "array" and self.current_value is not None and self.array_add and len(list(set(self.value) - set(self.current_value))) == 0:
return False
elif self.current_value == self.value:
return False
@ -334,7 +343,8 @@ class OSXDefaults(object):
self.write()
return True
# /run ---------------------------------------------------------------- }}}
# /run ---------------------------------------------------------------- }}}
# /class MacDefaults ------------------------------------------------------ }}}
@ -410,6 +420,7 @@ def main():
except OSXDefaultsException as e:
module.fail_json(msg=e.message)
# /main ------------------------------------------------------------------- }}}
if __name__ == '__main__':

@ -5,14 +5,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: pam_limits
@ -133,38 +132,37 @@ from ansible.module_utils._text import to_native
def main():
pam_items = ['core', 'data', 'fsize', 'memlock', 'nofile', 'rss', 'stack', 'cpu', 'nproc', 'as', 'maxlogins', 'maxsyslogins', 'priority', 'locks',
'sigpending', 'msgqueue', 'nice', 'rtprio', 'chroot']
pam_types = [ 'soft', 'hard', '-' ]
pam_types = ['soft', 'hard', '-']
limits_conf = '/etc/security/limits.conf'
module = AnsibleModule(
# not checking because of daisy chain to file module
argument_spec = dict(
domain = dict(required=True, type='str'),
limit_type = dict(required=True, type='str', choices=pam_types),
limit_item = dict(required=True, type='str', choices=pam_items),
value = dict(required=True, type='str'),
use_max = dict(default=False, type='bool'),
use_min = dict(default=False, type='bool'),
backup = dict(default=False, type='bool'),
dest = dict(default=limits_conf, type='str'),
comment = dict(required=False, default='', type='str')
argument_spec=dict(
domain=dict(required=True, type='str'),
limit_type=dict(required=True, type='str', choices=pam_types),
limit_item=dict(required=True, type='str', choices=pam_items),
value=dict(required=True, type='str'),
use_max=dict(default=False, type='bool'),
use_min=dict(default=False, type='bool'),
backup=dict(default=False, type='bool'),
dest=dict(default=limits_conf, type='str'),
comment=dict(required=False, default='', type='str')
)
)
domain = module.params['domain']
limit_type = module.params['limit_type']
limit_item = module.params['limit_item']
value = module.params['value']
use_max = module.params['use_max']
use_min = module.params['use_min']
backup = module.params['backup']
limits_conf = module.params['dest']
new_comment = module.params['comment']
domain = module.params['domain']
limit_type = module.params['limit_type']
limit_item = module.params['limit_item']
value = module.params['value']
use_max = module.params['use_max']
use_min = module.params['use_min']
backup = module.params['backup']
limits_conf = module.params['dest']
new_comment = module.params['comment']
changed = False
@ -192,7 +190,7 @@ def main():
space_pattern = re.compile(r'\s+')
message = ''
f = open (limits_conf, 'rb')
f = open(limits_conf, 'rb')
# Tempfile
nf = tempfile.NamedTemporaryFile(mode='w+')
@ -211,9 +209,9 @@ def main():
continue
# Remove comment in line
newline = newline.split('#',1)[0]
newline = newline.split('#', 1)[0]
try:
old_comment = line.split('#',1)[1]
old_comment = line.split('#', 1)[1]
except:
old_comment = ''
@ -228,10 +226,10 @@ def main():
nf.write(line)
continue
line_domain = line_fields[0]
line_type = line_fields[1]
line_item = line_fields[2]
actual_value = line_fields[3]
line_domain = line_fields[0]
line_type = line_fields[1]
line_item = line_fields[2]
actual_value = line_fields[3]
if not (actual_value in ['unlimited', 'infinity', '-1'] or actual_value.isdigit()):
module.fail_json(msg="Invalid configuration of '%s'. Current value of %s is unsupported." % (limits_conf, line_item))
@ -280,7 +278,7 @@ def main():
if not found:
changed = True
if new_comment:
new_comment = "\t#"+new_comment
new_comment = "\t#" + new_comment
new_limit = domain + "\t" + limit_type + "\t" + limit_item + "\t" + new_value + new_comment + "\n"
message = new_limit
nf.write(new_limit)
@ -297,7 +295,7 @@ def main():
pass
res_args = dict(
changed = changed, msg = message
changed=changed, msg=message
)
if backup:

@ -4,14 +4,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: puppet
@ -130,16 +129,16 @@ def _get_facter_dir():
def _write_structured_data(basedir, basename, data):
if not os.path.exists(basedir):
os.makedirs(basedir)
file_path = os.path.join(basedir, "{0}.json".format(basename))
# This is more complex than you might normally expect because we want to
# open the file with only u+rw set. Also, we use the stat constants
# because ansible still supports python 2.4 and the octal syntax changed
out_file = os.fdopen(
os.open(
file_path, os.O_CREAT | os.O_WRONLY,
stat.S_IRUSR | stat.S_IWUSR), 'w')
out_file.write(json.dumps(data).encode('utf8'))
out_file.close()
file_path = os.path.join(basedir, "{0}.json".format(basename))
# This is more complex than you might normally expect because we want to
# open the file with only u+rw set. Also, we use the stat constants
# because ansible still supports python 2.4 and the octal syntax changed
out_file = os.fdopen(
os.open(
file_path, os.O_CREAT | os.O_WRONLY,
stat.S_IRUSR | stat.S_IWUSR), 'w')
out_file.write(json.dumps(data).encode('utf8'))
out_file.close()
def main():
@ -217,8 +216,8 @@ def main():
cmd = ("%(base_cmd)s agent --onetime"
" --ignorecache --no-daemonize --no-usecacheonfailure --no-splay"
" --detailed-exitcodes --verbose --color 0") % dict(
base_cmd=base_cmd,
)
base_cmd=base_cmd,
)
if p['puppetmaster']:
cmd += " --server %s" % pipes.quote(p['puppetmaster'])
if p['show_diff']:

@ -1,36 +1,33 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2015, Brian Coca <bcoca@ansible.com>
# Copyright: (c) 2015, Brian Coca <bcoca@ansible.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'],
'supported_by': 'community'}
# This is a modification of @bcoca's `svc` module
DOCUMENTATION = '''
---
module: runit
author: "James Sumners (@jsumners)"
author:
- James Sumners (@jsumners)
version_added: "2.3"
short_description: Manage runit services.
short_description: Manage runit services
description:
- Controls runit services on remote hosts using the sv utility.
options:
name:
required: true
description:
- Name of the service to manage.
required: yes
state:
required: false
choices: [ started, stopped, restarted, killed, reloaded, once ]
description:
- C(started)/C(stopped) are idempotent actions that will not run
commands unless necessary. C(restarted) will always bounce the
@ -38,51 +35,49 @@ options:
C(reloaded) will send a HUP (sv reload).
C(once) will run a normally downed sv once (sv once), not really
an idempotent operation.
choices: [ killed, once, reloaded, restarted, started, stopped ]
enabled:
required: false
choices: [ "yes", "no" ]
description:
- Wheater the service is enabled or not, if disabled it also implies stopped.
type: bool
service_dir:
required: false
default: /var/service
description:
- directory runsv watches for services
default: /var/service
service_src:
required: false
default: /etc/sv
description:
- directory where services are defined, the source of symlinks to service_dir.
default: /etc/sv
'''
EXAMPLES = '''
# Example action to start sv dnscache, if not running
- runit:
- name: Start sv dnscache, if not running
runit:
name: dnscache
state: started
# Example action to stop sv dnscache, if running
- runit:
- name: Stop sv dnscache, if running
runit:
name: dnscache
state: stopped
# Example action to kill sv dnscache, in all cases
- runit:
- name: Kill sv dnscache, in all cases
runit:
name: dnscache
state: killed
# Example action to restart sv dnscache, in all cases
- runit:
- name: Restart sv dnscache, in all cases
runit:
name: dnscache
state: restarted
# Example action to reload sv dnscache, in all cases
- runit:
- name: Reload sv dnscache, in all cases
runit:
name: dnscache
state: reloaded
# Example using alt sv directory location
- runit:
- name: Use alternative sv directory location
runit:
name: dnscache
state: reloaded
service_dir: /run/service
@ -114,37 +109,35 @@ def _load_dist_subclass(cls, *args, **kwargs):
return super(cls, subclass).__new__(subclass)
class Sv(object):
"""
Main class that handles daemontools, can be subclassed and overridden in case
we want to use a 'derivative' like encore, s6, etc
"""
#def __new__(cls, *args, **kwargs):
# def __new__(cls, *args, **kwargs):
# return _load_dist_subclass(cls, args, kwargs)
def __init__(self, module):
self.extra_paths = [ ]
self.extra_paths = []
self.report_vars = ['state', 'enabled', 'svc_full', 'src_full', 'pid', 'duration', 'full_state']
self.module = module
self.module = module
self.name = module.params['name']
self.service_dir = module.params['service_dir']
self.service_src = module.params['service_src']
self.enabled = None
self.full_state = None
self.state = None
self.pid = None
self.duration = None
self.name = module.params['name']
self.service_dir = module.params['service_dir']
self.service_src = module.params['service_src']
self.enabled = None
self.full_state = None
self.state = None
self.pid = None
self.duration = None
self.svc_cmd = module.get_bin_path('sv', opt_dirs=self.extra_paths, required=True)
self.svstat_cmd = module.get_bin_path('sv', opt_dirs=self.extra_paths)
self.svc_full = '/'.join([ self.service_dir, self.name ])
self.src_full = '/'.join([ self.service_src, self.name ])
self.svc_cmd = module.get_bin_path('sv', opt_dirs=self.extra_paths, required=True)
self.svstat_cmd = module.get_bin_path('sv', opt_dirs=self.extra_paths)
self.svc_full = '/'.join([self.service_dir, self.name])
self.src_full = '/'.join([self.service_src, self.name])
self.enabled = os.path.lexists(self.svc_full)
if self.enabled:
@ -152,7 +145,6 @@ class Sv(object):
else:
self.state = 'stopped'
def enable(self):
if os.path.exists(self.src_full):
try:
@ -163,7 +155,7 @@ class Sv(object):
self.module.fail_json(msg="Could not find source for service to enable (%s)." % self.src_full)
def disable(self):
self.execute_command([self.svc_cmd,'force-stop',self.src_full])
self.execute_command([self.svc_cmd, 'force-stop', self.src_full])
try:
os.unlink(self.svc_full)
except OSError as e:
@ -240,18 +232,16 @@ class Sv(object):
states[k] = self.__dict__[k]
return states
# ===========================================
# Main control flow
def main():
module = AnsibleModule(
argument_spec = dict(
name = dict(required=True),
state = dict(choices=['started', 'stopped', 'restarted', 'killed', 'reloaded', 'once']),
enabled = dict(required=False, type='bool'),
dist = dict(required=False, default='runit'),
service_dir = dict(required=False, default='/var/service'),
service_src = dict(required=False, default='/etc/sv'),
argument_spec=dict(
name=dict(type='str', required=True),
state=dict(type='str', choices=['killed', 'once', 'reloaded', 'restarted', 'started', 'stopped']),
enabled=dict(type='bool'),
dist=dict(type='str', default='runit'),
service_dir=dict(type='str', default='/var/service'),
service_src=dict(type='str', default='/etc/sv'),
),
supports_check_mode=True,
)
@ -279,7 +269,7 @@ def main():
if state is not None and state != sv.state:
changed = True
if not module.check_mode:
getattr(sv,state)()
getattr(sv, state)()
module.exit_json(changed=changed, sv=sv.report())

@ -42,8 +42,8 @@ author:
'''
EXAMPLES = '''
# Set (httpd_can_network_connect) flag on and keep it persistent across reboots
- seboolean:
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots
seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
@ -173,7 +173,7 @@ def main():
argument_spec=dict(
name=dict(type='str', required=True),
persistent=dict(type='bool', default=False),
state=dict(type='bool', required=True)
state=dict(type='bool', required=True),
),
supports_check_mode=True,
)
@ -190,6 +190,7 @@ def main():
name = module.params['name']
persistent = module.params['persistent']
state = module.params['state']
result = dict(
name=name,
)
@ -205,12 +206,11 @@ def main():
cur_value = get_boolean_value(module, name)
if cur_value == state:
result['state'] = cur_value
result['changed'] = False
module.exit_json(**result)
module.exit_json(changed=False, state=cur_value, **result)
if module.check_mode:
module.exit_json(changed=True)
if persistent:
r = semanage_boolean_value(module, name, state)
else:
@ -223,6 +223,7 @@ def main():
selinux.security_commit_booleans()
except:
module.fail_json(msg="Failed to commit pending boolean %s value" % name)
module.exit_json(**result)

@ -1,17 +1,15 @@
#!/usr/bin/python
# (c) 2014, Dan Keder <dan.keder@gmail.com>
# Copyright: (c) 2014, Dan Keder <dan.keder@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: seport
@ -22,55 +20,55 @@ version_added: "2.0"
options:
ports:
description:
- Ports or port ranges, separated by a comma
- Ports or port ranges, separated by a comma.
required: true
default: null
proto:
description:
- Protocol for the specified port.
required: true
default: null
choices: [ 'tcp', 'udp' ]
choices: [ tcp, udp ]
setype:
description:
- SELinux type for the specified port.
required: true
default: null
state:
description:
- Desired boolean value.
required: true
choices: [ absent, present ]
default: present
choices: [ 'present', 'absent' ]
reload:
description:
- Reload SELinux policy after commit.
required: false
default: yes
type: bool
default: 'yes'
notes:
- The changes are persistent across reboots
- Not tested on any debian based system
requirements: [ 'libselinux-python', 'policycoreutils-python' ]
author: Dan Keder
- The changes are persistent across reboots.
- Not tested on any debian based system.
requirements:
- libselinux-python
- policycoreutils-python
author:
- Dan Keder
'''
EXAMPLES = '''
# Allow Apache to listen on tcp port 8888
- seport:
- name: Allow Apache to listen on tcp port 8888
seport:
ports: 8888
proto: tcp
setype: http_port_t
state: present
# Allow sshd to listen on tcp port 8991
- seport:
- name: Allow sshd to listen on tcp port 8991
seport:
ports: 8991
proto: tcp
setype: ssh_port_t
state: present
# Allow memcached to listen on tcp ports 10000-10100 and 10112
- seport:
- name: Allow memcached to listen on tcp ports 10000-10100 and 10112
seport:
ports: 10000-10100,10112
proto: tcp
setype: memcache_port_t
@ -81,15 +79,15 @@ import traceback
try:
import selinux
HAVE_SELINUX=True
HAVE_SELINUX = True
except ImportError:
HAVE_SELINUX=False
HAVE_SELINUX = False
try:
import seobject
HAVE_SEOBJECT=True
HAVE_SEOBJECT = True
except ImportError:
HAVE_SEOBJECT=False
HAVE_SEOBJECT = False
from ansible.module_utils.basic import AnsibleModule, HAVE_SELINUX
from ansible.module_utils._text import to_native
@ -232,29 +230,16 @@ def semanage_port_del(module, ports, proto, setype, do_reload, sestore=''):
def main():
module = AnsibleModule(
argument_spec={
'ports': {
'required': True,
},
'proto': {
'required': True,
'choices': ['tcp', 'udp'],
},
'setype': {
'required': True,
},
'state': {
'required': True,
'choices': ['present', 'absent'],
},
'reload': {
'required': False,
'type': 'bool',
'default': 'yes',
},
},
supports_check_mode=True
argument_spec=dict(
ports=dict(type='str', required=True),
proto=dict(type='str', required=True, choices=['tcp', 'udp']),
setype=dict(type='str', required=True),
state=dict(type='str', required=True, choices=['absent', 'present']),
reload=dict(type='bool', default=True),
),
supports_check_mode=True,
)
if not HAVE_SELINUX:
module.fail_json(msg="This module requires libselinux-python")

@ -959,7 +959,7 @@ class LinuxService(Service):
stdout = stdout1 + stdout2
stderr = stderr1 + stderr2
return(rc_state, stdout, stderr)
return (rc_state, stdout, stderr)
class FreeBsdService(Service):

@ -6,12 +6,10 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: solaris_zone
@ -20,12 +18,12 @@ description:
- Create, start, stop and delete Solaris zones. This module doesn't currently allow
changing of options for a zone that's already been created.
version_added: "2.0"
author: Paul Markham
author:
- Paul Markham
requirements:
- Solaris 10 or 11
options:
state:
required: true
description:
- C(present), configure and install the zone.
- C(installed), synonym for C(present).
@ -37,8 +35,9 @@ options:
- C(configured), configure the ready so that it's to be attached.
- C(attached), attach a zone, but do not boot it.
- C(detached), shutdown and detach a zone
choices: ['present', 'installed', 'started', 'running', 'stopped', 'absent', 'configured', 'attached', 'detached']
choices: [ absent, attached, configured, detached, installed, present, running, started, stopped ]
default: present
required: true
name:
description:
- Zone name.
@ -47,48 +46,39 @@ options:
description:
- The path where the zone will be created. This is required when the zone is created, but not
used otherwise.
required: false
default: null
sparse:
description:
- Whether to create a sparse (C(true)) or whole root (C(false)) zone.
required: false
default: false
type: bool
default: 'no'
root_password:
description:
- The password hash for the root account. If not specified, the zone's root account
will not have a password.
required: false
default: null
config:
description:
- 'The zonecfg configuration commands for this zone. See zonecfg(1M) for the valid options
and syntax. Typically this is a list of options separated by semi-colons or new lines, e.g.
"set auto-boot=true;add net;set physical=bge0;set address=10.1.1.1;end"'
required: false
default: empty string
create_options:
description:
- 'Extra options to the zonecfg(1M) create command.'
required: false
default: empty string
install_options:
description:
- 'Extra options to the zoneadm(1M) install command. To automate Solaris 11 zone creation,
use this to specify the profile XML file, e.g. install_options="-c sc_profile.xml"'
required: false
default: empty string
attach_options:
description:
- 'Extra options to the zoneadm attach command. For example, this can be used to specify
whether a minimum or full update of packages is required and if any packages need to
be deleted. For valid values, see zoneadm(1M)'
required: false
default: empty string
timeout:
description:
- Timeout, in seconds, for zone to boot.
required: false
default: 600
'''
@ -156,21 +146,21 @@ from ansible.module_utils.basic import AnsibleModule
class Zone(object):
def __init__(self, module):
self.changed = False
self.msg = []
self.module = module
self.path = self.module.params['path']
self.name = self.module.params['name']
self.sparse = self.module.params['sparse']
self.root_password = self.module.params['root_password']
self.timeout = self.module.params['timeout']
self.config = self.module.params['config']
self.create_options = self.module.params['create_options']
self.msg = []
self.module = module
self.path = self.module.params['path']
self.name = self.module.params['name']
self.sparse = self.module.params['sparse']
self.root_password = self.module.params['root_password']
self.timeout = self.module.params['timeout']
self.config = self.module.params['config']
self.create_options = self.module.params['create_options']
self.install_options = self.module.params['install_options']
self.attach_options = self.module.params['attach_options']
self.attach_options = self.module.params['attach_options']
self.zoneadm_cmd = self.module.get_bin_path('zoneadm', True)
self.zonecfg_cmd = self.module.get_bin_path('zonecfg', True)
self.zoneadm_cmd = self.module.get_bin_path('zoneadm', True)
self.zonecfg_cmd = self.module.get_bin_path('zonecfg', True)
self.ssh_keygen_cmd = self.module.get_bin_path('ssh-keygen', True)
if self.module.check_mode:
@ -188,7 +178,7 @@ class Zone(object):
self.module.fail_json(msg='Missing required argument: path')
if not self.module.check_mode:
t = tempfile.NamedTemporaryFile(delete = False)
t = tempfile.NamedTemporaryFile(delete=False)
if self.sparse:
t.write('create %s\n' % self.create_options)
@ -434,21 +424,23 @@ class Zone(object):
else:
self.msg.append('zone already attached')
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
state=dict(default='present', choices=['running', 'started', 'present', 'installed', 'stopped', 'absent', 'configured', 'detached', 'attached']),
path=dict(default=None),
sparse=dict(default=False, type='bool'),
root_password=dict(default=None, no_log=True),
timeout=dict(default=600, type='int'),
config=dict(default=''),
create_options=dict(default=''),
install_options=dict(default=''),
attach_options=dict(default=''),
name=dict(type='str', required=True),
state=dict(type='str', default='present',
choices=['absent', 'attached', 'configured', 'detached', 'installed', 'present', 'running', 'started', 'stopped']),
path=dict(type='str'),
sparse=dict(type='bool', default=False),
root_password=dict(type='str', no_log=True),
timeout=dict(type='int', default=600),
config=dict(type='str', default=''),
create_options=dict(type='str', default=''),
install_options=dict(type='str', default=''),
attach_options=dict(type='str', default=''),
),
supports_check_mode=True
supports_check_mode=True,
)
zone = Zone(module)

@ -1,34 +1,31 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2015, Brian Coca <bcoca@ansible.com>
# Copyright: (c) 2015, Brian Coca <bcoca@ansible.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: svc
author: "Brian Coca (@bcoca)"
author:
- Brian Coca (@bcoca)
version_added: "1.9"
short_description: Manage daemontools services.
short_description: Manage daemontools services
description:
- Controls daemontools services on remote hosts using the svc utility.
options:
name:
required: true
description:
- Name of the service to manage.
required: true
state:
required: false
choices: [ started, stopped, restarted, reloaded, once, killed ]
description:
- C(Started)/C(stopped) are idempotent actions that will not run
commands unless necessary. C(restarted) will always bounce the
@ -36,58 +33,55 @@ options:
C(reloaded) will send a sigusr1 (svc -1).
C(once) will run a normally downed svc once (svc -o), not really
an idempotent operation.
choices: [ killed, once, reloaded, restarted, started, stopped ]
downed:
required: false
choices: [ "yes", "no" ]
default: no
description:
- Should a 'down' file exist or not, if it exists it disables auto startup.
defaults to no. Downed does not imply stopped.
type: bool
default: 'no'
enabled:
required: false
choices: [ "yes", "no" ]
description:
- Wheater the service is enabled or not, if disabled it also implies stopped.
Make note that a service can be enabled and downed (no auto restart).
type: bool
service_dir:
required: false
default: /service
description:
- directory svscan watches for services
default: /service
service_src:
required: false
description:
- directory where services are defined, the source of symlinks to service_dir.
'''
EXAMPLES = '''
# Example action to start svc dnscache, if not running
- svc:
- name: Start svc dnscache, if not running
svc:
name: dnscache
state: started
# Example action to stop svc dnscache, if running
- svc:
- name: Stop svc dnscache, if running
svc:
name: dnscache
state: stopped
# Example action to kill svc dnscache, in all cases
- svc:
- name: Kill svc dnscache, in all cases
svc:
name: dnscache
state: killed
# Example action to restart svc dnscache, in all cases
- svc:
- name: Restart svc dnscache, in all cases
svc:
name: dnscache
state: restarted
# Example action to reload svc dnscache, in all cases
- svc:
- name: Reload svc dnscache, in all cases
svc:
name: dnscache
state: reloaded
# Example using alt svc directory location
- svc:
- name: Using alternative svc directory location
svc:
name: dnscache
state: reloaded
service_dir: /var/service
@ -119,38 +113,36 @@ def _load_dist_subclass(cls, *args, **kwargs):
return super(cls, subclass).__new__(subclass)
class Svc(object):
"""
Main class that handles daemontools, can be subclassed and overridden in case
we want to use a 'derivative' like encore, s6, etc
"""
#def __new__(cls, *args, **kwargs):
# def __new__(cls, *args, **kwargs):
# return _load_dist_subclass(cls, args, kwargs)
def __init__(self, module):
self.extra_paths = [ '/command', '/usr/local/bin' ]
self.extra_paths = ['/command', '/usr/local/bin']
self.report_vars = ['state', 'enabled', 'downed', 'svc_full', 'src_full', 'pid', 'duration', 'full_state']
self.module = module
self.module = module
self.name = module.params['name']
self.service_dir = module.params['service_dir']
self.service_src = module.params['service_src']
self.enabled = None
self.downed = None
self.full_state = None
self.state = None
self.pid = None
self.duration = None
self.name = module.params['name']
self.service_dir = module.params['service_dir']
self.service_src = module.params['service_src']
self.enabled = None
self.downed = None
self.full_state = None
self.state = None
self.pid = None
self.duration = None
self.svc_cmd = module.get_bin_path('svc', opt_dirs=self.extra_paths)
self.svstat_cmd = module.get_bin_path('svstat', opt_dirs=self.extra_paths)
self.svc_full = '/'.join([ self.service_dir, self.name ])
self.src_full = '/'.join([ self.service_src, self.name ])
self.svc_cmd = module.get_bin_path('svc', opt_dirs=self.extra_paths)
self.svstat_cmd = module.get_bin_path('svstat', opt_dirs=self.extra_paths)
self.svc_full = '/'.join([self.service_dir, self.name])
self.src_full = '/'.join([self.service_src, self.name])
self.enabled = os.path.lexists(self.svc_full)
if self.enabled:
@ -160,7 +152,6 @@ class Svc(object):
self.downed = os.path.lexists('%s/down' % self.src_full)
self.state = 'stopped'
def enable(self):
if os.path.exists(self.src_full):
try:
@ -175,11 +166,11 @@ class Svc(object):
os.unlink(self.svc_full)
except OSError as e:
self.module.fail_json(path=self.svc_full, msg='Error while unlinking: %s' % to_native(e))
self.execute_command([self.svc_cmd,'-dx',self.src_full])
self.execute_command([self.svc_cmd, '-dx', self.src_full])
src_log = '%s/log' % self.src_full
if os.path.exists(src_log):
self.execute_command([self.svc_cmd,'-dx',src_log])
self.execute_command([self.svc_cmd, '-dx', src_log])
def get_status(self):
(rc, out, err) = self.execute_command([self.svstat_cmd, self.svc_full])
@ -245,19 +236,20 @@ class Svc(object):
states[k] = self.__dict__[k]
return states
# ===========================================
# Main control flow
def main():
module = AnsibleModule(
argument_spec = dict(
name = dict(required=True),
state = dict(choices=['started', 'stopped', 'restarted', 'killed', 'reloaded', 'once']),
enabled = dict(required=False, type='bool'),
downed = dict(required=False, type='bool'),
dist = dict(required=False, default='daemontools'),
service_dir = dict(required=False, default='/service'),
service_src = dict(required=False, default='/etc/service'),
argument_spec=dict(
name=dict(type='str', required=True),
state=dict(type='str', choices=['killed', 'once', 'reloaded', 'restarted', 'started', 'stopped']),
enabled=dict(type='bool'),
downed=dict(type='bool'),
dist=dict(type='str', default='daemontools'),
service_dir=dict(type='str', default='/service'),
service_src=dict(type='str', default='/etc/service'),
),
supports_check_mode=True,
)
@ -286,7 +278,7 @@ def main():
if state is not None and state != svc.state:
changed = True
if not module.check_mode:
getattr(svc,state[:-2])()
getattr(svc, state[:-2])()
if downed is not None and downed != svc.downed:
changed = True
@ -303,7 +295,5 @@ def main():
module.exit_json(changed=changed, svc=svc.report())
if __name__ == '__main__':
main()

@ -390,9 +390,8 @@ def main():
elif rc == 1:
# if not a user service and both init script and unit file exist stdout should have enabled/disabled, otherwise use rc entries
if not module.params['user'] and \
is_initd and \
(not out.strip().endswith('disabled') or sysv_is_enabled(unit)):
is_initd and \
(not out.strip().endswith('disabled') or sysv_is_enabled(unit)):
enabled = True
# default to current state

@ -1,18 +1,16 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Shinichi TAMURA (@tmshn)
# Copyright: (c) 2016, Shinichi TAMURA (@tmshn)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: timezone
@ -33,7 +31,6 @@ options:
- Name of the timezone for the system clock.
Default is to keep current setting. B(At least one of name and
hwclock are required.)
required: false
hwclock:
description:
- Whether the hardware clock is in UTC or in local timezone.
@ -42,14 +39,13 @@ options:
to configure, especially on virtual environments such as AWS.
B(At least one of name and hwclock are required.)
I(Only used on Linux.)
required: false
aliases: ['rtc']
aliases: [ rtc ]
notes:
- On SmartOS the C(sm-set-timezone) utility (part of the smtools package) is required to set the zone timezone
author:
- "Shinichi TAMURA (@tmshn)"
- "Jasper Lievisse Adriaanse (@jasperla)"
- "Indrajit Raychaudhuri (@indrajitr)"
- Shinichi TAMURA (@tmshn)
- Jasper Lievisse Adriaanse (@jasperla)
- Indrajit Raychaudhuri (@indrajitr)
'''
RETURN = '''
@ -117,7 +113,7 @@ class Timezone(object):
# running in the global zone where changing the timezone has no effect.
zonename_cmd = module.get_bin_path('zonename')
if zonename_cmd is not None:
(rc, stdout, _ ) = module.run_command(zonename_cmd)
(rc, stdout, _) = module.run_command(zonename_cmd)
if rc == 0 and stdout.strip() == 'global':
module.fail_json(msg='Adjusting timezone is not supported in Global Zone')
@ -263,12 +259,12 @@ class SystemdTimezone(Timezone):
regexps = dict(
hwclock=re.compile(r'^\s*RTC in local TZ\s*:\s*([^\s]+)', re.MULTILINE),
name =re.compile(r'^\s*Time ?zone\s*:\s*([^\s]+)', re.MULTILINE)
name=re.compile(r'^\s*Time ?zone\s*:\s*([^\s]+)', re.MULTILINE)
)
subcmds = dict(
hwclock='set-local-rtc',
name ='set-timezone'
name='set-timezone'
)
def __init__(self, module):
@ -316,7 +312,7 @@ class NosystemdTimezone(Timezone):
"""
conf_files = dict(
name =None, # To be set in __init__
name=None, # To be set in __init__
hwclock=None, # To be set in __init__
adjtime='/etc/adjtime'
)
@ -324,7 +320,7 @@ class NosystemdTimezone(Timezone):
allow_no_file = dict()
regexps = dict(
name =None, # To be set in __init__
name=None, # To be set in __init__
hwclock=re.compile(r'^UTC\s*=\s*([^\s]+)', re.MULTILINE),
adjtime=re.compile(r'^(UTC|LOCAL)$', re.MULTILINE)
)
@ -334,32 +330,32 @@ class NosystemdTimezone(Timezone):
# Validate given timezone
if 'name' in self.value:
tzfile = self._verify_timezone()
self.update_timezone = ['%s %s /etc/localtime' % (self.module.get_bin_path('cp', required=True), tzfile)]
self.update_timezone = ['%s %s /etc/localtime' % (self.module.get_bin_path('cp', required=True), tzfile)]
self.update_hwclock = self.module.get_bin_path('hwclock', required=True)
self.allow_no_file['hwclock'] = True # Since this is only used for get values, file absense does not metter
# Distribution-specific configurations
if self.module.get_bin_path('dpkg-reconfigure') is not None:
# Debian/Ubuntu
# With additional hack for https://bugs.launchpad.net/ubuntu/+source/tzdata/+bug/1554806
self.update_timezone = ['rm -f /etc/localtime', '%s --frontend noninteractive tzdata' %
self.module.get_bin_path('dpkg-reconfigure', required=True)]
self.conf_files['name'] = '/etc/timezone'
self.update_timezone = ['rm -f /etc/localtime', '%s --frontend noninteractive tzdata' %
self.module.get_bin_path('dpkg-reconfigure', required=True)]
self.conf_files['name'] = '/etc/timezone'
self.allow_no_file['name'] = True
self.conf_files['hwclock'] = '/etc/default/rcS'
self.regexps['name'] = re.compile(r'^([^\s]+)', re.MULTILINE)
self.tzline_format = '%s\n'
self.regexps['name'] = re.compile(r'^([^\s]+)', re.MULTILINE)
self.tzline_format = '%s\n'
else:
# RHEL/CentOS
if self.module.get_bin_path('tzdata-update') is not None:
self.update_timezone = [self.module.get_bin_path('tzdata-update', required=True)]
self.update_timezone = [self.module.get_bin_path('tzdata-update', required=True)]
self.allow_no_file['name'] = True
# else:
# self.update_timezone = 'cp ...' <- configured above
# self.allow_no_file['name'] = False <- this is default behavior
self.conf_files['name'] = '/etc/sysconfig/clock'
self.conf_files['name'] = '/etc/sysconfig/clock'
self.conf_files['hwclock'] = '/etc/sysconfig/clock'
self.regexps['name'] = re.compile(r'^ZONE\s*=\s*"?([^"\s]+)"?', re.MULTILINE)
self.tzline_format = 'ZONE="%s"\n'
self.regexps['name'] = re.compile(r'^ZONE\s*=\s*"?([^"\s]+)"?', re.MULTILINE)
self.tzline_format = 'ZONE="%s"\n'
def _allow_ioerror(self, err, key):
# In some cases, even if the target file does not exist,
@ -535,7 +531,7 @@ class DarwinTimezone(Timezone):
"""
regexps = dict(
name = re.compile(r'^\s*Time ?Zone\s*:\s*([^\s]+)', re.MULTILINE)
name=re.compile(r'^\s*Time ?Zone\s*:\s*([^\s]+)', re.MULTILINE)
)
def __init__(self, module):
@ -558,7 +554,7 @@ class DarwinTimezone(Timezone):
# Note: Skip the first line that contains the label 'Time Zones:'
out = self.execute(self.systemsetup, '-listtimezones').splitlines()[1:]
tz_list = list(map(lambda x: x.strip(), out))
if not tz in tz_list:
if tz not in tz_list:
self.abort('given timezone "%s" is not available' % tz)
return tz
@ -631,11 +627,13 @@ def main():
# Construct 'module' and 'tz'
module = AnsibleModule(
argument_spec=dict(
hwclock=dict(choices=['UTC', 'local'], aliases=['rtc']),
name=dict(),
hwclock=dict(type='str', choices=['local', 'UTC'], aliases=['rtc']),
name=dict(type='str'),
),
required_one_of=[['hwclock', 'name']],
supports_check_mode=True
required_one_of=[
['hwclock', 'name']
],
supports_check_mode=True,
)
tz = Timezone(module)

@ -1,22 +1,19 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2014, Ahti Kitsik <ak@ahtik.com>
# (c) 2014, Jarno Keskikangas <jarno.keskikangas@gmail.com>
# (c) 2013, Aleksey Ovcharenko <aleksey.ovcharenko@gmail.com>
# (c) 2013, James Martin <jmartin@basho.com>
#
# Copyright: (c) 2014, Ahti Kitsik <ak@ahtik.com>
# Copyright: (c) 2014, Jarno Keskikangas <jarno.keskikangas@gmail.com>
# Copyright: (c) 2013, Aleksey Ovcharenko <aleksey.ovcharenko@gmail.com>
# Copyright: (c) 2013, James Martin <jmartin@basho.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ufw
@ -25,9 +22,9 @@ description:
- Manage firewall with UFW.
version_added: 1.6
author:
- "Aleksey Ovcharenko (@ovcharenko)"
- "Jarno Keskikangas (@pyykkis)"
- "Ahti Kitsik (@ahtik)"
- Aleksey Ovcharenko (@ovcharenko)
- Jarno Keskikangas (@pyykkis)
- Ahti Kitsik (@ahtik)
notes:
- See C(man ufw) for more examples.
requirements:
@ -39,99 +36,82 @@ options:
- C(disabled) unloads firewall and disables firewall on boot.
- C(reloaded) reloads firewall.
- C(reset) disables and resets firewall to installation defaults.
required: false
choices: ['enabled', 'disabled', 'reloaded', 'reset']
choices: [ disabled, enabled, reloaded, reset ]
policy:
description:
- Change the default policy for incoming or outgoing traffic.
required: false
aliases: ['default']
choices: ['allow', 'deny', 'reject']
aliases: [ default ]
choices: [ allow, deny, reject ]
direction:
description:
- Select direction for a rule or default policy command.
required: false
choices: ['in', 'out', 'incoming', 'outgoing', 'routed']
choices: [ in, incoming, out, outgoing, routed ]
logging:
description:
- Toggles logging. Logged packets use the LOG_KERN syslog facility.
choices: ['on', 'off', 'low', 'medium', 'high', 'full']
required: false
choices: [ on, off, low, medium, high, full ]
insert:
description:
- Insert the corresponding rule as rule number NUM
required: false
rule:
description:
- Add firewall rule
required: false
choices: ['allow', 'deny', 'reject', 'limit']
choices: ['allow', 'deny', 'limit', 'reject']
log:
description:
- Log new connections matched to this rule
required: false
choices: ['yes', 'no']
type: bool
from_ip:
description:
- Source IP address.
required: false
aliases: ['from', 'src']
default: 'any'
aliases: [ from, src ]
default: any
from_port:
description:
- Source port.
required: false
to_ip:
description:
- Destination IP address.
required: false
aliases: ['to', 'dest']
default: 'any'
aliases: [ dest, to]
default: any
to_port:
description:
- Destination port.
required: false
aliases: ['port']
aliases: [ port ]
proto:
description:
- TCP/IP protocol.
choices: ['any', 'tcp', 'udp', 'ipv6', 'esp', 'ah']
required: false
choices: [ any, tcp, udp, ipv6, esp, ah ]
name:
description:
- Use profile located in C(/etc/ufw/applications.d)
required: false
aliases: ['app']
- Use profile located in C(/etc/ufw/applications.d).
aliases: [ app ]
delete:
description:
- Delete rule.
required: false
choices: ['yes', 'no']
type: bool
interface:
description:
- Specify interface for rule.
required: false
aliases: ['if']
aliases: [ if ]
route:
description:
- Apply the rule to routed/forwarded packets.
required: false
choices: ['yes', 'no']
type: bool
comment:
description:
- Add a comment to the rule. Requires UFW version >=0.35.
required: false
version_added: "2.4"
'''
EXAMPLES = '''
# Allow everything and enable UFW
- ufw:
- name: Allow everything and enable UFW
ufw:
state: enabled
policy: allow
# Set logging
- ufw:
- name: Set logging
ufw:
logging: on
# Sometimes it is desirable to let the sender know when traffic is
@ -159,30 +139,30 @@ EXAMPLES = '''
rule: allow
name: OpenSSH
# Delete OpenSSH rule
- ufw:
- name: Delete OpenSSH rule
ufw:
rule: allow
name: OpenSSH
delete: yes
# Deny all access to port 53:
- ufw:
- name: Deny all access to port 53
ufw:
rule: deny
port: 53
# Allow port range 60000-61000
- ufw:
- name: Allow port range 60000-61000
ufw:
rule: allow
port: '60000:61000'
port: 60000:61000
# Allow all access to tcp port 80:
- ufw:
- name: Allow all access to tcp port 80
ufw:
rule: allow
port: 80
proto: tcp
# Allow all access from RFC1918 networks to this host:
- ufw:
- name: Allow all access from RFC1918 networks to this host
ufw:
rule: allow
src: '{{ item }}'
with_items:
@ -190,16 +170,16 @@ EXAMPLES = '''
- 172.16.0.0/12
- 192.168.0.0/16
# Deny access to udp port 514 from host 1.2.3.4 and include a comment:
- ufw:
- name: Deny access to udp port 514 from host 1.2.3.4 and include a comment
ufw:
rule: deny
proto: udp
src: 1.2.3.4
port: 514
comment: "Block syslog"
comment: Block syslog
# Allow incoming access to eth0 from 1.2.3.5 port 5469 to 1.2.3.4 port 5469
- ufw:
- name: Allow incoming access to eth0 from 1.2.3.5 port 5469 to 1.2.3.4 port 5469
ufw:
rule: allow
interface: eth0
direction: in
@ -209,17 +189,17 @@ EXAMPLES = '''
dest: 1.2.3.4
to_port: 5469
# Deny all traffic from the IPv6 2001:db8::/32 to tcp port 25 on this host.
# Note that IPv6 must be enabled in /etc/default/ufw for IPv6 firewalling to work.
- ufw:
- name: Deny all traffic from the IPv6 2001:db8::/32 to tcp port 25 on this host
ufw:
rule: deny
proto: tcp
src: '2001:db8::/32'
src: 2001:db8::/32
port: 25
# Deny forwarded/routed traffic from subnet 1.2.3.0/24 to subnet 4.5.6.0/24.
# Can be used to further restrict a global FORWARD policy set to allow
- ufw:
- name: Deny forwarded/routed traffic from subnet 1.2.3.0/24 to subnet 4.5.6.0/24
ufw:
rule: deny
route: yes
src: 1.2.3.0/24
@ -234,27 +214,29 @@ from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec = dict(
state = dict(default=None, choices=['enabled', 'disabled', 'reloaded', 'reset']),
default = dict(default=None, aliases=['policy'], choices=['allow', 'deny', 'reject']),
logging = dict(default=None, choices=['on', 'off', 'low', 'medium', 'high', 'full']),
direction = dict(default=None, choices=['in', 'incoming', 'out', 'outgoing', 'routed']),
delete = dict(default=False, type='bool'),
route = dict(default=False, type='bool'),
insert = dict(default=None),
rule = dict(default=None, choices=['allow', 'deny', 'reject', 'limit']),
interface = dict(default=None, aliases=['if']),
log = dict(default=False, type='bool'),
from_ip = dict(default='any', aliases=['src', 'from']),
from_port = dict(default=None),
to_ip = dict(default='any', aliases=['dest', 'to']),
to_port = dict(default=None, aliases=['port']),
proto = dict(default=None, aliases=['protocol'], choices=['any', 'tcp', 'udp', 'ipv6', 'esp', 'ah']),
app = dict(default=None, aliases=['name']),
comment = dict(default=None, type='str')
argument_spec=dict(
state=dict(type='str', choices=['enabled', 'disabled', 'reloaded', 'reset']),
default=dict(type='str', aliases=['policy'], choices=['allow', 'deny', 'reject']),
logging=dict(type='str', choices=['full', 'high', 'low', 'medium', 'off', 'on']),
direction=dict(type='str', choices=['in', 'incoming', 'out', 'outgoing', 'routed']),
delete=dict(type='bool', default=False),
route=dict(type='bool', default=False),
insert=dict(type='str'),
rule=dict(type='str', choices=['allow', 'deny', 'limit', 'reject']),
interface=dict(type='str', aliases=['if']),
log=dict(type='bool', default=False),
from_ip=dict(type='str', default='any', aliases=['from', 'src']),
from_port=dict(type='str'),
to_ip=dict(type='str', default='any', aliases=['dest', 'to']),
to_port=dict(type='str', aliases=['port']),
proto=dict(type='str', aliases=['protocol'], choices=['ah', 'any', 'esp', 'ipv6', 'tcp', 'udp']),
app=dict(type='str', aliases=['name']),
comment=dict(type='str'),
),
supports_check_mode = True,
mutually_exclusive = [['app', 'proto', 'logging']]
supports_check_mode=True,
mutually_exclusive=[
['app', 'proto', 'logging']
],
)
cmds = []
@ -289,7 +271,7 @@ def main():
# Convert version to numbers
major = int(matches.group(1))
minor = int(matches.group(2))
rev = 0
rev = 0
if matches.group(3) is not None:
rev = int(matches.group(3))
@ -304,7 +286,7 @@ def main():
if len(commands) < 1:
module.fail_json(msg="Not any of the command arguments %s given" % commands)
if(params['interface'] is not None and params['direction'] is None):
if (params['interface'] is not None and params['direction'] is None):
module.fail_json(msg="Direction must be specified when creating a rule on an interface")
# Ensure ufw is available
@ -319,8 +301,8 @@ def main():
cmd = [[ufw_bin], [module.check_mode, '--dry-run']]
if command == 'state':
states = { 'enabled': 'enable', 'disabled': 'disable',
'reloaded': 'reload', 'reset': 'reset' }
states = {'enabled': 'enable', 'disabled': 'disable',
'reloaded': 'reload', 'reset': 'reset'}
execute(cmd + [['-f'], [states[value]]])
elif command == 'logging':
@ -343,10 +325,9 @@ def main():
cmd.append([params['interface'], "on %s" % params['interface']])
cmd.append([module.boolean(params['log']), 'log'])
for (key, template) in [('from_ip', "from %s" ), ('from_port', "port %s" ),
('to_ip', "to %s" ), ('to_port', "port %s" ),
('proto', "proto %s"), ('app', "app '%s'")]:
for (key, template) in [('from_ip', "from %s"), ('from_port', "port %s"),
('to_ip', "to %s"), ('to_port', "port %s"),
('proto', "proto %s"), ('app', "app '%s'")]:
value = params[key]
cmd.append([value, template % (value)])

@ -1081,7 +1081,7 @@ class OpenBSDUser(User):
cmd.append(self.login_class)
if self.update_password == 'always' and self.password is not None \
and self.password != '*' and info[1] != self.password:
and self.password != '*' and info[1] != self.password:
cmd.append('-p')
cmd.append(self.password)
@ -1093,8 +1093,6 @@ class OpenBSDUser(User):
return self.execute_command(cmd)
# ===========================================
class NetBSDUser(User):
"""
This is a NetBSD User manipulation class.
@ -1250,8 +1248,6 @@ class NetBSDUser(User):
return self.execute_command(cmd)
# ===========================================
class SunOS(User):
"""
This is a SunOS User manipulation class - The main difference between
@ -1613,7 +1609,7 @@ class DarwinUser(User):
(rc, out, err) = self.execute_command(cmd)
if rc != 0:
self.module.fail_json(msg='Cannot %s user "%s" to group "%s".'
% (action, self.name, group), err=err, out=out, rc=rc)
% (action, self.name, group), err=err, out=out, rc=rc)
return (rc, out, err)
def _modify_group(self):
@ -1681,7 +1677,7 @@ class DarwinUser(User):
return 0
else:
if self.name in hidden_users:
del(hidden_users[hidden_users.index(self.name)])
del (hidden_users[hidden_users.index(self.name)])
cmd = ['defaults', 'write', plist_file, 'HiddenUsersList', '-array'] + hidden_users
(rc, out, err) = self.execute_command(cmd)
@ -1784,7 +1780,7 @@ class DarwinUser(User):
if rc != 0:
self.module.fail_json(
msg='Cannot update property "%s" for user "%s".'
% (field[0], self.name), err=err, out=out, rc=rc)
% (field[0], self.name), err=err, out=out, rc=rc)
changed = rc
out += _out
err += _err
@ -2242,6 +2238,7 @@ def main():
module.exit_json(**result)
# import module snippets
if __name__ == '__main__':
main()

@ -321,26 +321,3 @@ lib/ansible/modules/system/aix_inittab.py
lib/ansible/modules/system/capabilities.py
lib/ansible/modules/system/cronvar.py
lib/ansible/modules/system/crypttab.py
lib/ansible/modules/system/debconf.py
lib/ansible/modules/system/facter.py
lib/ansible/modules/system/filesystem.py
lib/ansible/modules/system/gconftool2.py
lib/ansible/modules/system/gluster_volume.py
lib/ansible/modules/system/group.py
lib/ansible/modules/system/java_cert.py
lib/ansible/modules/system/kernel_blacklist.py
lib/ansible/modules/system/locale_gen.py
lib/ansible/modules/system/lvg.py
lib/ansible/modules/system/lvol.py
lib/ansible/modules/system/ohai.py
lib/ansible/modules/system/open_iscsi.py
lib/ansible/modules/system/openwrt_init.py
lib/ansible/modules/system/osx_defaults.py
lib/ansible/modules/system/pam_limits.py
lib/ansible/modules/system/puppet.py
lib/ansible/modules/system/runit.py
lib/ansible/modules/system/seport.py
lib/ansible/modules/system/solaris_zone.py
lib/ansible/modules/system/svc.py
lib/ansible/modules/system/timezone.py
lib/ansible/modules/system/ufw.py

Loading…
Cancel
Save