Bulk spelling improvement to modules-core (#5225)

* Correct spelling mistakes

* Correct more spelling issues

* merge conflict

* Revert typo in parms
pull/18777/head
John R Barker 8 years ago committed by Matt Clay
parent a4077537e0
commit 25b6492d37

@ -769,7 +769,7 @@ def create_block_device(module, ec2, volume):
if int(volume['iops']) > MAX_IOPS_TO_SIZE_RATIO * size:
module.fail_json(msg = 'IOPS must be at most %d times greater than size' % MAX_IOPS_TO_SIZE_RATIO)
if 'encrypted' in volume:
module.fail_json(msg = 'You can not set encyrption when creating a volume from a snapshot')
module.fail_json(msg = 'You can not set encryption when creating a volume from a snapshot')
if 'ephemeral' in volume:
if 'snapshot' in volume:
module.fail_json(msg = 'Cannot set both ephemeral and snapshot')
@ -1023,7 +1023,7 @@ def create_instances(module, ec2, vpc, override_count=None):
if ebs_optimized:
params['ebs_optimized'] = ebs_optimized
# 'tenancy' always has a default value, but it is not a valid parameter for spot instance resquest
# 'tenancy' always has a default value, but it is not a valid parameter for spot instance request
if not spot_price:
params['tenancy'] = tenancy

@ -253,7 +253,7 @@ owner_id:
type: string
sample: "435210894375"
platform:
description: plaform of image
description: platform of image
returned: when AMI is created or already exists
type: string
sample: null

@ -228,7 +228,7 @@ owner_id:
type: string
sample: "435210894375"
platform:
description: plaform of image
description: platform of image
returned: when AMI found
type: string
sample: null

@ -77,7 +77,7 @@ options:
default: None
lc_check:
description:
- Check to make sure instances that are being replaced with replace_instances do not aready have the current launch_config.
- Check to make sure instances that are being replaced with replace_instances do not already have the current launch_config.
required: false
version_added: "1.8"
default: True
@ -118,7 +118,7 @@ options:
version_added: "2.0"
wait_timeout:
description:
- how long before wait instances to become viable when replaced. Used in concjunction with instance_ids option.
- how long before wait instances to become viable when replaced. Used in conjunction with instance_ids option.
default: 300
version_added: "1.8"
wait_for_instances:
@ -130,6 +130,7 @@ options:
termination_policies:
description:
- An ordered list of criteria used for selecting instances to be removed from the Auto Scaling group when reducing capacity.
- For 'Default', when used to create a new autoscaling group, the "Default"i value is used. When used to change an existent autoscaling group, the current termination policies are maintained.
required: false
default: Default. Eg, when used to create a new autoscaling group, the Default value is used. When used to change an existent autoscaling group, the current termination policies are mantained
choices: ['OldestInstance', 'NewestInstance', 'OldestLaunchConfiguration', 'ClosestToNextInstanceHour', 'Default']
@ -373,7 +374,7 @@ def wait_for_elb(asg_connection, module, group_name):
as_group = asg_connection.get_all_groups(names=[group_name])[0]
if as_group.load_balancers and as_group.health_check_type == 'ELB':
log.debug("Waiting for ELB to consider intances healthy.")
log.debug("Waiting for ELB to consider instances healthy.")
try:
elb_connection = connect_to_aws(boto.ec2.elb, region, **aws_connect_params)
except boto.exception.NoAuthHandlerFound as e:
@ -631,7 +632,7 @@ def replace(connection, module):
if desired_capacity is None:
desired_capacity = as_group.desired_capacity
# set temporary settings and wait for them to be reached
# This should get overriden if the number of instances left is less than the batch size.
# This should get overwritten if the number of instances left is less than the batch size.
as_group = connection.get_all_groups(names=[group_name])[0]
update_size(as_group, max_size + batch_size, min_size + batch_size, desired_capacity + batch_size)

@ -207,7 +207,7 @@ class ElbManager:
self.changed = True
break
elif self._is_instance_state_pending(instance_state):
# If it's pending, we'll skip further checks andd continue waiting
# If it's pending, we'll skip further checks and continue waiting
pass
elif (awaited_state == 'InService'
and instance_state.reason_code == "Instance"
@ -215,7 +215,7 @@ class ElbManager:
# If the reason_code for the instance being out of service is
# "Instance" this indicates a failure state, e.g. the instance
# has failed a health check or the ELB does not have the
# instance's availabilty zone enabled. The exact reason why is
# instance's availability zone enabled. The exact reason why is
# described in InstantState.description.
msg = ("The instance %s could not be put in service on %s."
" Reason: %s")

@ -135,7 +135,7 @@ options:
version_added: "1.8"
stickiness:
description:
- An associative array of stickness policy settings. Policy will be applied to all listeners ( see example )
- An associative array of stickiness policy settings. Policy will be applied to all listeners ( see example )
required: false
version_added: "2.0"
wait:
@ -314,7 +314,7 @@ EXAMPLES = """
- load_balancer_port: 80
- instance_port: 80
# Create an ELB with load balanacer stickiness enabled
# Create an ELB with load balancer stickiness enabled
- local_action:
module: ec2_elb_lb
name: "New ELB"

@ -268,7 +268,7 @@ def rtb_changed(route_tables=None, vpc_conn=None, module=None, vpc=None, igw=Non
Checks if the remote routes match the local routes.
route_tables : Route_tables parameter in the module
vpc_conn : The VPC conection object
vpc_conn : The VPC connection object
module : The module object
vpc : The vpc object for this route table
igw : The internet gateway object for this vpc
@ -497,7 +497,7 @@ def create_vpc(module, vpc_conn):
# Handle route tables - this may be worth splitting into a
# different module but should work fine here. The strategy to stay
# indempotent is to basically build all the route tables as
# idempotent is to basically build all the route tables as
# defined, track the route table ids, and then run through the
# remote list of route tables and delete any that we didn't
# create. This shouldn't interrupt traffic in theory, but is the

@ -25,7 +25,7 @@ author: Jonathan Davila (@defionscode)
options:
name:
description:
- The name to give your VPC. This is used in combination with the cidr_block paramater to determine if a VPC already exists.
- The name to give your VPC. This is used in combination with the cidr_block parameter to determine if a VPC already exists.
required: yes
cidr_block:
description:

@ -82,7 +82,7 @@ options:
aliases: []
access_key_ids:
description:
- A list of the keys that you want impacted by the access_key_state paramter.
- A list of the keys that you want impacted by the access_key_state parameter.
groups:
description:
- A list of groups the user should belong to. When update, will gracefully remove groups not listed.
@ -340,7 +340,7 @@ def update_user(module, iam, name, new_name, new_path, key_state, key_count, key
except boto.exception.BotoServerError as err:
error_msg = boto_exception(str(err))
if 'Password does not conform to the account password policy' in error_msg:
module.fail_json(changed=False, msg="Passsword doesn't conform to policy")
module.fail_json(changed=False, msg="Password doesn't conform to policy")
else:
module.fail_json(msg=error_msg)
@ -397,7 +397,7 @@ def update_user(module, iam, name, new_name, new_path, key_state, key_count, key
def set_users_groups(module, iam, name, groups, updated=None,
new_name=None):
""" Sets groups for a user, will purge groups not explictly passed, while
""" Sets groups for a user, will purge groups not explicitly passed, while
retaining pre-existing groups that also are in the new list.
"""
changed = False
@ -630,7 +630,7 @@ def main():
if iam_type == 'role' and state == 'update':
module.fail_json(changed=False, msg="iam_type: role, cannot currently be updated, "
"please specificy present or absent")
"please specify present or absent")
# check if trust_policy is present -- it can be inline JSON or a file path to a JSON file
if trust_policy_filepath:

@ -115,7 +115,7 @@ options:
description:
- Port number that the DB instance uses for connections. Used only when command=create or command=replicate.
- Prior to 2.0 it always defaults to null and the API would use 3306, it had to be set to other DB default values when not using MySql.
Starting at 2.0 it auotmaticaly defaults to what is expected for each c(db_engine).
Starting at 2.0 it automatically defaults to what is expected for each c(db_engine).
required: false
default: 3306 for mysql, 1521 for Oracle, 1433 for SQL Server, 5432 for PostgreSQL.
upgrade:

@ -492,9 +492,9 @@ def terminate_virtual_machine(module, azure):
except AzureException as e:
module.fail_json(msg="failed to delete the deployment %s, error was: %s" % (deployment.name, str(e)))
# It's unclear when disks associated with terminated deployment get detatched.
# It's unclear when disks associated with terminated deployment get detached.
# Thus, until the wait_timeout is reached, we continue to delete disks as they
# become detatched by polling the list of remaining disks and examining the state.
# become detached by polling the list of remaining disks and examining the state.
try:
_delete_disks_when_detached(azure, wait_timeout, disk_names)
except (AzureException, TimeoutError) as e:

@ -185,7 +185,7 @@ blob:
"type": "BlockBlob"
}
container:
description: Facts about the current state of the selcted container.
description: Facts about the current state of the selected container.
returned: always
type: dict
sample: {

@ -158,7 +158,7 @@ options:
required: false
public_ip_allocation_method:
description:
- If a public IP address is created when creating the VM (beacuse a Network Interface was not provided),
- If a public IP address is created when creating the VM (because a Network Interface was not provided),
determines if the public IP address remains permanently associated with the Network Interface. If set
to 'Dynamic' the public IP address may change any time the VM is rebooted or power cycled.
choices:
@ -300,7 +300,7 @@ deleted_network_interfaces:
type: list
example: ["testvm1001"]
deleted_public_ips:
description: List of deleted publid IP addrees names.
description: List of deleted public IP address names.
returned: 'on delete'
type: list
example: ["testvm1001"]
@ -913,7 +913,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
interface_dict['name'] = int_dict['networkInterfaces']
interface_dict['properties'] = nic_dict['properties']
# Expand public IPs to include config porperties
# Expand public IPs to include config properties
for interface in result['properties']['networkProfile']['networkInterfaces']:
for config in interface['properties']['ipConfigurations']:
if config['properties'].get('publicIPAddress'):

@ -289,7 +289,7 @@ options:
required: false
pid_mode:
description:
- Set the PID namespace mode for the container. Currenly only supports 'host'.
- Set the PID namespace mode for the container. Currently only supports 'host'.
default: null
required: false
privileged:
@ -361,7 +361,7 @@ options:
description:
- Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes).
- Ommitting the unit defaults to bytes. If you omit the size entirely, the system uses `64m`.
- Omitting the unit defaults to bytes. If you omit the size entirely, the system uses `64m`.
default: null
required: false
security_opts:
@ -411,7 +411,7 @@ options:
description:
- If true, skip image verification.
default: false
requried: false
required: false
tty:
description:
- Allocate a psuedo-TTY.
@ -514,7 +514,7 @@ EXAMPLES = '''
image: ubuntu:14.04
command: sleep infinity
- name: Stop a contianer
- name: Stop a container
docker_container:
name: mycontainer
state: stopped
@ -1799,7 +1799,7 @@ class ContainerManager(DockerBaseClass):
self.results['actions'].append(dict(added_to_network=diff['parameter']['name'], network_parameters=params))
if not self.check_mode:
try:
self.log("Connecting conainer to network %s" % diff['parameter']['id'])
self.log("Connecting container to network %s" % diff['parameter']['id'])
self.log(params, pretty_print=True)
self.client.connect_container_to_network(container.Id, diff['parameter']['id'], **params)
except Exception as exc:

@ -69,7 +69,7 @@ options:
ipam_driver:
description:
- Specifiy an IPAM driver.
- Specify an IPAM driver.
default: null
ipam_options:

@ -423,7 +423,7 @@ actions:
returned: always
type: string
id:
desription: image hash
description: image hash
returned: always
type: string

@ -229,7 +229,7 @@ def ensure_user_exists(keystone, user_name, password, email, tenant_name,
check_mode):
""" Check if user exists
Return (True, id) if a new user was created, (False, id) user alrady
Return (True, id) if a new user was created, (False, id) user already
exists
"""

@ -71,7 +71,7 @@ options:
default: present
name:
description:
- Name to be assigned to the nework
- Name to be assigned to the network
required: true
default: None
provider_network_type:

@ -30,9 +30,9 @@ module: quantum_router_interface
version_added: "1.2"
author: "Benno Joy (@bennojoy)"
deprecated: Deprecated in 2.0. Use os_router instead
short_description: Attach/Dettach a subnet's interface to a router
short_description: Attach/Detach a subnet's interface to a router
description:
- Attach/Dettach a subnet interface to a router, to provide a gateway for the subnet.
- Attach/Detach a subnet interface to a router, to provide a gateway for the subnet.
options:
login_username:
description:

@ -186,7 +186,7 @@ def main():
# Requirements are met
module.exit_json(changed=False, floating_ip=f_ip)
# Requirments are vague enough to ignore exisitng f_ip and try
# Requirements are vague enough to ignore existing f_ip and try
# to create a new f_ip to the server.
server = cloud.add_ips_to_server(

@ -186,7 +186,7 @@ def _choose_id_value(module):
def _choose_if_password_only(module, patch):
if len(patch) is 1:
if 'password' in patch[0]['path'] and module.params['skip_update_of_masked_password']:
# Return false to aabort update as the password appears
# Return false to abort update as the password appears
# to be the only element in the patch.
return False
return True

@ -42,7 +42,7 @@ options:
network_name:
description:
- Name of the network to which the subnet should be attached
- requried when I(state) is 'present'
- Required when I(state) is 'present'
required: false
name:
description:

@ -259,7 +259,7 @@ EXAMPLES = '''
vm_extra_config:
folder: MyFolder
# Task to gather facts from a vSphere cluster only if the system is a VMWare guest
# Task to gather facts from a vSphere cluster only if the system is a VMware guest
- vsphere_guest:
vcenter_hostname: vcenter.mydomain.local

@ -88,7 +88,7 @@ EXAMPLES = '''
# Dumps all databases to hostname.sql
- mysql_db: state=dump name=all target=/tmp/{{ inventory_hostname }}.sql
# Imports file.sql similiar to mysql -u <username> -p <password> < hostname.sql
# Imports file.sql similar to mysql -u <username> -p <password> < hostname.sql
- mysql_db: state=import name=all target=/tmp/{{ inventory_hostname }}.sql
'''

@ -103,7 +103,7 @@ notes:
without providing any login_user/login_password details. The second must drop a ~/.my.cnf file containing
the new root credentials. Subsequent runs of the playbook will then succeed by reading the new credentials from
the file."
- Currently, there is only support for the `mysql_native_password` encryted password hash module.
- Currently, there is only support for the `mysql_native_password` encrypted password hash module.
author: "Jonathan Mainguy (@Jmainguy)"
extends_documentation_fragment: mysql

@ -78,7 +78,7 @@ options:
required: false
default: null
description:
- DEPRECATED. The acl to set or remove. This must always be quoted in the form of '<etype>:<qualifier>:<perms>'. The qualifier may be empty for some types, but the type and perms are always requried. '-' can be used as placeholder when you do not care about permissions. This is now superseded by entity, type and permissions fields.
- DEPRECATED. The acl to set or remove. This must always be quoted in the form of '<etype>:<qualifier>:<perms>'. The qualifier may be empty for some types, but the type and perms are always required. '-' can be used as placeholder when you do not care about permissions. This is now superseded by entity, type and permissions fields.
recursive:
version_added: "2.0"
@ -202,7 +202,7 @@ def acl_changed(module, cmd):
if get_platform().lower() == 'freebsd':
return True
cmd = cmd[:] # lists are mutables so cmd would be overriden without this
cmd = cmd[:] # lists are mutables so cmd would be overwritten without this
cmd.insert(1, '--test')
lines = run_acl(module, cmd)

@ -48,7 +48,7 @@ options:
required: false
default: '*'
description:
- One or more (shell or regex) patterns, which type is controled by C(use_regex) option.
- One or more (shell or regex) patterns, which type is controlled by C(use_regex) option.
- The patterns restrict the list of files to be returned to those whose basenames match at
least one of the patterns specified. Multiple patterns can be specified using a list.
aliases: ['pattern']

@ -174,7 +174,7 @@ def do_ini(module, filename, section=None, option=None, value=None, state='prese
changed = ini_lines[index] != newline
ini_lines[index] = newline
if changed:
# remove all possible option occurences from the rest of the section
# remove all possible option occurrences from the rest of the section
index = index + 1
while index < len(ini_lines):
line = ini_lines[index]

@ -172,7 +172,7 @@ stat:
type: int
sample: 1003
size:
description: Size in bytes for a plain file, ammount of data for some special files
description: Size in bytes for a plain file, amount of data for some special files
returned: success, path exists and user can read stats
type: int
sample: 203

@ -248,7 +248,7 @@ synchronize: src=some/relative/path dest=/some/absolute/path rsync_path="su -c r
# Synchronize passing in extra rsync options
synchronize:
src: /tmp/helloworld
dest: /var/www/helloword
dest: /var/www/helloworld
rsync_opts:
- "--no-motd"
- "--exclude=.git"
@ -413,7 +413,7 @@ def main():
if not source.startswith('"rsync://') and not dest.startswith('"rsync://'):
# If the user specified a port value
# Note: The action plugin takes care of setting this to a port from
# inventory if the user didn't specify an explict dest_port
# inventory if the user didn't specify an explicit dest_port
if dest_port is not None:
cmd += " --rsh 'ssh %s %s -o Port=%s'" % (private_key, ssh_opts, dest_port)
else:

@ -100,7 +100,7 @@ options:
If you worry about portability, only the sha1 algorithm is available
on all platforms and python versions. The third party hashlib
library can be installed for access to additional algorithms.
Additionaly, if a checksum is passed to this parameter, and the file exist under
Additionally, if a checksum is passed to this parameter, and the file exist under
the C(dest) location, the destination_checksum would be calculated, and if
checksum equals destination_checksum, the file download would be skipped
(unless C(force) is true). '
@ -237,7 +237,7 @@ def url_get(module, url, dest, use_proxy, last_mod_time, force, timeout=10, head
if os.path.exists(tmp_dest):
module.fail_json(msg="%s is a file but should be a directory." % tmp_dest)
else:
module.fail_json(msg="%s directoy does not exist." % tmp_dest)
module.fail_json(msg="%s directory does not exist." % tmp_dest)
fd, tempname = tempfile.mkstemp(dir=tmp_dest)
else:

@ -66,7 +66,7 @@ options:
body:
description:
- The body of the http request/response to the web service. If C(body_format) is set
to 'json' it will take an already formated JSON string or convert a data structure
to 'json' it will take an already formatted JSON string or convert a data structure
into JSON.
required: false
default: null
@ -383,7 +383,7 @@ def main():
dict_headers = module.params['headers']
if body_format == 'json':
# Encode the body unless its a string, then assume it is preformatted JSON
# Encode the body unless its a string, then assume it is pre-formatted JSON
if not isinstance(body, basestring):
body = json.dumps(body)
dict_headers['Content-Type'] = 'application/json'

@ -154,7 +154,7 @@ cl_bond: name=bond1 slaves="swp1s0 swp2s0" clag_id=1
notify: reload networking
# define cl_bond once in tasks file
# then write inteface config in variables file
# then write interface config in variables file
# with just the options you want.
cl_bond:
name: "{{ item.key }}"

@ -109,7 +109,7 @@ cl_bridge: name=bridge ports='swp1-12' vlan_aware='yes' vids='1-100'
notify: reload networking
# define cl_bridge once in tasks file
# then write inteface config in variables file
# then write interface config in variables file
# with just the options you want.
cl_bridge:
name: "{{ item.key }}"

@ -131,7 +131,7 @@ cl_interface: name=bond0.100 alias_name='my bond' ipv4=10.1.1.1/24
notify: reload networking
# define cl_interfaces once in tasks
# then write intefaces in variables file
# then write interfaces in variables file
# with just the options you want.
cl_interface:
name: "{{ item.key }}"

@ -73,7 +73,7 @@ def read_current_int_dir(module):
module.custom_currentportlist = os.listdir(module.params.get('location'))
# take the allowed list and conver it to into a list
# take the allowed list and convert it to into a list
# of ports.
def convert_allowed_list_to_port_range(module):
allowedlist = module.params.get('allowed')

@ -123,7 +123,7 @@ options:
choices: ['yes', 'no']
config:
description:
- The C(config) argument allows the playbook desginer to supply
- The C(config) argument allows the playbook designer to supply
the base configuration to be used to validate configuration
changes necessary. If this argument is provided, the module
will not download the running-config from the remote node.

@ -36,10 +36,10 @@ options:
gather_subset:
description:
- When supplied, this argument will restrict the facts collected
to a given subset. Possible values for this argument inlcude
to a given subset. Possible values for this argument include
all, hardware, config, and interfaces. Can specify a list of
values to include a larger subset. Values can also be used
with an initial M(!) to specify that a specific subset should
with an initial C(M(!)) to specify that a specific subset should
not be collected.
required: false
default: '!config'

@ -38,7 +38,7 @@ options:
description:
- List of commands to send to the remote dellos6 device over the
configured provider. The resulting output from the command
is returned. If the I(waitfor) argument is provided, the
is returned. If the I(wait_for) argument is provided, the
module is not returned until the condition is satisfied or
the number of I(retries) as expired.
required: true
@ -56,7 +56,7 @@ options:
- Specifies the number of retries a command should be tried
before it is considered failed. The command is run on the
target device every retry and evaluated against the
I(waitfor) conditions.
I(wait_for) conditions.
required: false
default: 10
interval:
@ -80,7 +80,7 @@ vars:
transport: cli
tasks:
- name: run show verion on remote devices
- name: run show version on remote devices
dellos6_command:
commands: show version
provider "{{ cli }}"

@ -36,10 +36,10 @@ options:
gather_subset:
description:
- When supplied, this argument will restrict the facts collected
to a given subset. Possible values for this argument inlcude
to a given subset. Possible values for this argument include
all, hardware, config, and interfaces. Can specify a list of
values to include a larger subset. Values can also be used
with an initial M(!) to specify that a specific subset should
with an initial C(M(!)) to specify that a specific subset should
not be collected.
required: false
default: '!config'

@ -39,7 +39,7 @@ options:
to a given subset. Possible values for this argument include
all, hardware, config, and interfaces. Can specify a list of
values to include a larger subset. Values can also be used
with an initial M(!) to specify that a specific subset should
with an initial C(M(!)) to specify that a specific subset should
not be collected.
required: false
default: '!config'

@ -19,7 +19,7 @@ DOCUMENTATION = """
---
module: eos_template
version_added: "2.1"
author: "Peter sprygada (@privateip)"
author: "Peter Sprygada (@privateip)"
short_description: Manage Arista EOS device configurations
description:
- Manages network device configurations over SSH or eAPI. This module
@ -112,7 +112,7 @@ updates:
responses:
description: The set of responses from issuing the commands on the device
retured: when not check_mode
returned: when not check_mode
type: list
sample: ['...', '...']
"""

@ -88,7 +88,7 @@ vars:
password: admin
transport: cli
- name: run show verion on remote devices
- name: run show version on remote devices
eos_command:
commands: show version
provider: "{{ cli }}"
@ -106,7 +106,7 @@ vars:
- show interfaces
provider: "{{ cli }}"
- name: run multiple commands and evalute the output
- name: run multiple commands and evaluate the output
eos_command:
commands:
- show version
@ -139,7 +139,7 @@ stdout_lines:
failed_conditions:
description: the conditionals that failed
retured: failed
returned: failed
type: list
sample: ['...', '...']
"""

@ -103,7 +103,7 @@ ansible_net_fqdn:
# hardware
ansible_net_filesystems:
description: All file system names availabe on the device
description: All file system names available on the device
returned: when hardware is configured
type: list
ansible_net_memfree_mb:

@ -94,7 +94,7 @@ EXAMPLES = """
src: config.j2
force: yes
- name: provide the base configuration for comparision
- name: provide the base configuration for comparison
ios_template:
host: hostname
username: foo

@ -35,7 +35,7 @@ options:
to a given subset. Possible values for this argument include
all, hardware, config, and interfaces. Can specify a list of
values to include a larger subset. Values can also be used
with an initial M(!) to specify that a specific subset should
with an initial C(M(!)) to specify that a specific subset should
not be collected.
required: false
default: '!config'
@ -87,7 +87,7 @@ ansible_net_image:
# hardware
ansible_net_filesystems:
description: All file system names availabe on the device
description: All file system names available on the device
returned: when hardware is configured
type: list
ansible_net_memfree_mb:

@ -19,7 +19,7 @@ DOCUMENTATION = """
---
module: iosxr_template
version_added: "2.1"
author: "Peter sprygada (@privateip)"
author: "Peter Sprygada (@privateip)"
short_description: Manage Cisco IOSXR device configurations over SSH
description:
- Manages network device configurations over SSH. This module
@ -97,7 +97,7 @@ updates:
responses:
description: The set of responses from issuing the commands on the device
retured: when not check_mode
returned: when not check_mode
type: list
sample: ['...', '...']
"""

@ -79,7 +79,7 @@ ansible_net_image:
# hardware
ansible_net_filesystems:
description: All file system names availabe on the device
description: All file system names available on the device
returned: when hardware is configured
type: list
ansible_net_memfree_mb:

@ -148,7 +148,7 @@ stdout_lines:
failed_conditionals:
description: the conditionals that failed
retured: failed
returned: failed
type: list
sample: ['...', '...']
"""

@ -45,7 +45,7 @@ options:
format of the configuration file. Devices support three
configuration file formats. By default, the configuration
from the device is returned as text. The other options include
set and xml. If the xml option is choosen, the configuration file
set and xml. If the xml option is chosen, the configuration file
is returned as both xml and json.
required: false
default: text
@ -81,7 +81,7 @@ EXAMPLES = """
RETURN = """
ansible_facts:
descrption: Returns the facts collect from the device
description: Returns the facts collect from the device
returned: always
type: dict
"""

@ -97,7 +97,7 @@ options:
1 and 255 or 0 to unset.
pn_bgp_options:
description:
- Specify other BGP options as a whitespaces separted string within
- Specify other BGP options as a whitespaces separated string within
single quotes ''.
pn_rip_redistribute:
description:

@ -32,7 +32,7 @@ description:
- Execute vrouter-interface-add, vrouter-interface-remove,
vrouter-interface-modify command.
- You configure interfaces to vRouter services on a fabric, cluster,
standalone switch or virtula network(VNET).
standalone switch or virtual network(VNET).
options:
pn_cliusername:
description:

@ -90,7 +90,7 @@ EXAMPLES = """
src: config.j2
force: yes
- name: provide the base configuration for comparision
- name: provide the base configuration for comparison
nxos_template:
src: candidate_config.txt
config: current_config.txt
@ -105,7 +105,7 @@ updates:
responses:
description: The set of responses from issuing the commands on the device
retured: when not check_mode
returned: when not check_mode
type: list
sample: ['...', '...']
"""

@ -38,8 +38,8 @@ notes:
there is any difference, what is in Ansible will be pushed (configured
options will be overridden). This is to improve security, but at the
same time remember an ACE is removed, then re-added, so if there is a
change, the new ACE will be exacty what params you are sending to the
module.
change, the new ACE will be exactly what parameters you are sending to
the module.
options:
seq:
description:

@ -1460,7 +1460,7 @@ def main():
if module.params['vrf'] != 'default':
for param, inserted_value in module.params.iteritems():
if param in GLOBAL_PARAMS and inserted_value:
module.fail_json(msg='Global params can be modifed only'
module.fail_json(msg='Global params can be modified only'
' under "default" VRF.',
vrf=module.params['vrf'],
global_param=param)

@ -50,7 +50,7 @@ options:
required: true
afi:
description:
- Address Family Identifie.
- Address Family Identifier.
required: true
choices: ['ipv4','ipv6', 'vpnv4', 'vpnv6', 'l2vpn']
safi:

@ -93,7 +93,7 @@ vars:
password: admin
transport: cli
- name: run show verion on remote devices
- name: run show version on remote devices
nxos_command:
commands: show version
provider: "{{ cli }}"
@ -111,7 +111,7 @@ vars:
- show interfaces
provider: "{{ cli }}"
- name: run multiple commands and evalute the output
- name: run multiple commands and evaluate the output
nxos_command:
commands:
- show version
@ -144,7 +144,7 @@ stdout_lines:
failed_conditions:
description: the conditionals that failed
retured: failed
returned: failed
type: list
sample: ['...', '...']
"""

@ -27,8 +27,8 @@ description:
author: Gabriele Gerbino (@GGabriele)
extends_documentation_fragment: nxos
notes:
- default, where supported, restores params default value
- RD override is not permitted. You should set it to the defalt values
- default, where supported, restores params default value.
- RD override is not permitted. You should set it to the default values
first and then reconfigure it.
- route_target_both, route_target_import and route_target_export valid
values are a list of extended communities, (i.e. ['1.2.3.4:5', '33:55'])

@ -100,7 +100,7 @@ ansible_net_image:
# hardware
ansible_net_filesystems:
description: All file system names availabe on the device
description: All file system names available on the device
returned: when hardware is configured
type: list
ansible_net_memfree_mb:

@ -60,7 +60,7 @@ EXAMPLES = '''
RETURN = '''
transfer_status:
description: Whether a file was transfered. "No Transfer" or "Sent".
description: Whether a file was transferred. "No Transfer" or "Sent".
returned: success
type: string
sample: 'Sent'

@ -39,7 +39,7 @@ options:
default: null
mode:
description:
- Configure the profile as Maintenance or Normale mode.
- Configure the profile as Maintenance or Normal mode.
required: true
choices: ['maintenance', 'normal']
state:

@ -36,7 +36,7 @@ notes:
- You must know if your platform supports taking a kickstart image as a
parameter. If supplied but not supported, errors may occur.
- This module attempts to install the software immediately,
wich may trigger a reboot.
which may trigger a reboot.
- In check mode, the module tells you if the current boot images are set
to the desired images.
author:
@ -364,7 +364,7 @@ def set_boot_options(module, image_name, kickstart=None):
Args:
The main system image file name.
Keyword Args: many implementors may choose
to supply a kickstart parameter to specicify a kickstart image.
to supply a kickstart parameter to specify a kickstart image.
"""
commands = ['terminal dont-ask']
if kickstart is None:

@ -28,7 +28,7 @@ extends_documentation_fragment: nxos
author:
- Jason Edelman (@jedelman8)
notes:
- If C(state=absent), the moudle will attempt to remove the given key configuration.
- If C(state=absent), the module will attempt to remove the given key configuration.
If a matching key configuration isn't found on the device, the module will fail.
- If C(state=absent) and C(authentication=on), authentication will be turned off.
- If C(state=absent) and C(authentication=off), authentication will be turned on.
@ -59,7 +59,7 @@ options:
choices: ['true', 'false']
authentication:
description:
- Turns NTP authenication on or off.
- Turns NTP authentication on or off.
required: false
default: null
choices: ['on', 'off']
@ -96,7 +96,7 @@ existing:
type: dict
sample: {"authentication": "off", "trusted_key": "false"}
end_state:
description: k/v pairs of ntp autherntication after module execution
description: k/v pairs of ntp authentication after module execution
returned: always
type: dict
sample: {"authentication": "off", "key_id": "32",

@ -277,7 +277,7 @@ def main():
sandbox=dict(aliases=['enable_sandbox'], default=False, type='bool'),
# Only allow configuration of NXAPI using cli transpsort
# Only allow configuration of NXAPI using cli transport
transport=dict(required=True, choices=['cli']),
config=dict(),

@ -867,7 +867,7 @@ def main():
remote_exists = remote_file_exists(module, pkg, file_system=file_system)
if not remote_exists:
module.fail_json(msg="The requested package does't exist "
module.fail_json(msg="The requested package doesn't exist "
"on the device")
commands = get_commands(module, pkg, file_system)

@ -29,7 +29,7 @@ extends_documentation_fragment: nxos
author:
- Gabriele Gerbino (@GGabriele)
notes:
- C(transpot=cli) may cause timeout errors.
- C(transport=cli) may cause timeout errors.
- The C(element_key1) and C(element_key2) parameter specify the tags used
to distinguish among row entries. In most cases, only the element_key1
parameter needs to specified to be able to distinguish among row entries.

@ -473,7 +473,7 @@ def main():
if privacy and encrypt:
if not pwd and authentication:
module.fail_json(msg='pwd and authentication must be proviced '
module.fail_json(msg='pwd and authentication must be provided '
'when using privacy and encrypt')
if group and group not in get_snmp_groups(module):

@ -487,7 +487,7 @@ def get_switchport_config_commands(interface, existing, proposed, module):
def is_switchport_default(existing):
"""Determines if switchport has a default config based on mode
Args:
existing (dict): existing switcport configuration from Ansible mod
existing (dict): existing switchport configuration from Ansible mod
Returns:
boolean: True if switchport has OOB Layer 2 config, i.e.
vlan 1 and trunk all and mode is access

@ -28,7 +28,7 @@ extends_documentation_fragment: nxos
author:
- Jason Edelman (@jedelman8)
notes:
- When C(state=absent), it unconfigures existing setings C(msg_time) and set it
- When C(state=absent), it unconfigures existing settings C(msg_time) and set it
to its default value of 15. It is cleaner to always use C(state=present).
- Module will fail if the udld feature has not been previously enabled.
options:

@ -363,6 +363,7 @@ def get_udld_interface(module, interface):
table = body['TABLE_interface']['ROW_interface']
status = str(table.get('mib-port-status', None))
# Note: 'mib-aggresive-mode' is NOT a typo
agg = str(table.get('mib-aggresive-mode', 'disabled'))
if agg == 'enabled':

@ -46,7 +46,7 @@ options:
default: null
peer_link:
description:
- Set to true/false for peer link config on assoicated portchannel
- Set to true/false for peer link config on associated portchannel.
required: false
default: null
state:

@ -29,7 +29,7 @@ notes:
- VTP feature must be active on the device to use this module.
- This module is used to manage only VTP domain names.
- VTP domain names are case-sensible.
- If it's never been configured before, VTP version is setted to 1 by default.
- If it's never been configured before, VTP version is set to 1 by default.
Otherwise, it leaves the previous configured version untouched.
Use M(nxos_vtp_version) to change it.
- Use this in combination with M(nxos_vtp_password) and M(nxos_vtp_version)

@ -77,6 +77,26 @@ options:
required: false
default: present
choices: ['present','absent']
include_defaults:
description:
- Specify to use or not the complete running configuration
for module operations.
required: false
default: true
choices: ['true','true']
config:
description:
- Configuration string to be used for module operations. If not
specified, the module will use the current running configuration.
required: false
default: null
save:
description:
- Specify to save the running configuration after
module operations.
required: false
default: false
choices: ['true','false']
'''
EXAMPLES = '''
- nxos_vxlan_vtep_vni:

@ -87,11 +87,11 @@ EXAMPLES = """
RETURN = """
updates:
description: The list of configuration updates to be merged
retured: always
returned: always
type: dict
sample: {obj, obj}
responses:
desription: returns the responses when configuring using cli
description: returns the responses when configuring using cli
returned: when transport == cli
type: list
sample: [...]

@ -20,7 +20,7 @@ DOCUMENTATION = """
---
module: ops_command
version_added: "2.1"
author: "Peter sprygada (@privateip)"
author: "Peter Sprygada (@privateip)"
short_description: Run arbitrary commands on OpenSwitch devices.
description:
- Sends arbitrary commands to an OpenSwitch node and returns the results
@ -33,7 +33,7 @@ options:
description:
- List of commands to send to the remote ops device over the
configured provider. The resulting output from the command
is returned. If the I(waitfor) argument is provided, the
is returned. If the I(wait_for) argument is provided, the
module is not returned until the condition is satisfied or
the number of retires as expired.
required: true
@ -65,7 +65,7 @@ options:
- Specifies the number of retries a command should by tried
before it is considered failed. The command is run on the
target device every retry and evaluated against the
I(waitfor) conditions.
I(wait_for) conditions.
required: false
default: 10
interval:
@ -122,7 +122,7 @@ stdout_lines:
failed_conditions:
description: the conditionals that failed
retured: failed
returned: failed
type: list
sample: ['...', '...']
"""

@ -117,7 +117,7 @@ stdout_lines:
sample: [['...', '...'], ['...'], ['...']]
failed_conditions:
description: The conditionals that failed
retured: failed
returned: failed
type: list
sample: ['...', '...']
warnings:

@ -35,7 +35,7 @@ options:
to a given subset. Possible values for this argument include
all, hardware, config, and interfaces. Can specify a list of
values to include a larger subset. Values can also be used
with an initial M(!) to specify that a specific subset should
with an initial C(M(!)) to specify that a specific subset should
not be collected.
required: false
default: "!config"
@ -70,7 +70,7 @@ ansible_net_config:
returned: when config is configured
type: str
ansible_net_commits:
descrption: The set of available configuration revisions
description: The set of available configuration revisions
returned: when present
type: list
ansible_net_hostname:

@ -266,8 +266,8 @@ def package_version_compare(version, other_version):
def package_status(m, pkgname, version, cache, state):
try:
# get the package from the cache, as well as the
# the low-level apt_pkg.Package object which contains
# state fields not directly acccesible from the
# low-level apt_pkg.Package object which contains
# state fields not directly accessible from the
# higher-level apt.package.Package object.
pkg = cache[pkgname]
ll_pkg = cache._cache[pkgname] # the low-level package object
@ -819,7 +819,7 @@ def main():
updated_cache = True
mtimestamp, updated_cache_time = get_updated_cache_time()
# If theres nothing else to do exit. This will set state as
# If there is nothing else to do exit. This will set state as
# changed based on if the cache was updated.
if not p['package'] and not p['upgrade'] and not p['deb']:
module.exit_json(
@ -879,7 +879,7 @@ def main():
# Store when the update time was last
retvals['cache_update_time'] = updated_cache_time
# If the cache was updated and the general state change was set to
# False make sure that the change in cache state is acurately
# False make sure that the change in cache state is accurately
# updated by setting the general changed state to the same as
# the cache state.
if updated_cache and not retvals['changed']:

@ -71,7 +71,7 @@ options:
default: null
org_id:
description:
- Organisation ID to use in conjunction with activationkey
- Organization ID to use in conjunction with activationkey
required: False
default: null
version_added: "2.0"

@ -39,7 +39,7 @@ options:
default: "present"
choices: [present, absent]
description:
- Wheather the key will be imported or removed from the rpm db.
- If the key will be imported or removed from the rpm db.
validate_certs:
description:
- If C(no) and the C(key) is a url starting with https, SSL certificates will not be validated. This should only be used

@ -551,7 +551,7 @@ def get_head_branch(git_path, module, dest, remote, bare=False):
if os.path.isfile(repo_path):
try:
gitdir = yaml.safe_load(open(repo_path)).get('gitdir')
# There is a posibility the .git file to have an absolute path.
# There is a possibility the .git file to have an absolute path.
if os.path.isabs(gitdir):
repo_path = gitdir
else:
@ -590,7 +590,7 @@ def set_remote_url(git_path, module, repo, dest, remote):
label = "set a new url %s for %s" % (repo, remote)
module.fail_json(msg="Failed to %s: %s %s" % (label, out, err))
# Return False if remote_url is None to maintain previous bevhavior
# Return False if remote_url is None to maintain previous behavior
# for Git versions prior to 1.7.5 that lack required functionality.
return remote_url is not None
@ -614,7 +614,7 @@ def fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec, g
refspecs.append(currenthead)
elif is_remote_branch(git_path, module, dest, repo, version):
if currenthead != version:
# this workaroung is only needed for older git versions
# this workaround is only needed for older git versions
# 1.8.3 is broken, 1.9.x works
# ensure that remote branch is available as both local and remote ref
refspecs.append('+refs/heads/%s:refs/heads/%s' % (version, version))

@ -174,7 +174,7 @@ class Subversion(object):
# The --quiet option will return only modified files.
# Match only revisioned files, i.e. ignore status '?'.
regex = re.compile(r'^[^?X]')
# Has local mods if more than 0 modifed revisioned files.
# Has local mods if more than 0 modified revisioned files.
return len(filter(regex.match, lines)) > 0
def needs_update(self):

@ -22,7 +22,7 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
# Cron Plugin: The goal of this plugin is to provide an indempotent method for
# Cron Plugin: The goal of this plugin is to provide an idempotent method for
# setting up cron jobs on a host. The script will play well with other manually
# entered crons. Each cron job entered will be preceded with a comment
# describing the job so that it can be found later, which is required to be
@ -139,8 +139,8 @@ options:
env:
description:
- If set, manages a crontab's environment variable. New variables are added on top of crontab.
"name" and "value" paramenters are the name and the value of environment variable.
version_added: "2"
"name" and "value" parameters are the name and the value of environment variable.
version_added: "2.1"
required: false
default: "no"
choices: [ "yes", "no" ]

@ -258,7 +258,7 @@ class DarwinGroup(Group):
- group_add()
- group_mod()
group manupulation are done using dseditgroup(1).
group manipulation are done using dseditgroup(1).
"""
platform = 'Darwin'

@ -1350,7 +1350,7 @@ class SunOSService(Service):
def service_control(self):
status = self.get_sunos_svcs_status()
# if starting or reloading, clear maintenace states
# if starting or reloading, clear maintenance states
if self.action in ['start', 'reload', 'restart'] and status in ['maintenance', 'degraded']:
rc, stdout, stderr = self.execute_command("%s clear %s" % (self.svcadm_cmd, self.name))
if rc != 0:

@ -75,7 +75,7 @@ EXAMPLES = '''
- systemd: state=started name=httpd
# Example action to stop service cron on debian, if running
- systemd: name=cron state=stopped
# Example action to restart service cron on centos, in all cases, also issue deamon-reload to pick up config changes
# Example action to restart service cron on centos, in all cases, also issue daemon-reload to pick up config changes
- systemd: state=restarted daemon_reload=yes name=crond
# Example action to reload service httpd, in all cases
- systemd: name=httpd state=reloaded

@ -1527,7 +1527,7 @@ class DarwinUser(User):
def _change_user_password(self):
'''Change password for SELF.NAME against SELF.PASSWORD.
Please note that password must be cleatext.
Please note that password must be cleartext.
'''
# some documentation on how is stored passwords on OSX:
# http://blog.lostpassword.com/2012/07/cracking-mac-os-x-lion-accounts-passwords/
@ -1559,7 +1559,7 @@ class DarwinUser(User):
def __modify_group(self, group, action):
'''Add or remove SELF.NAME to or from GROUP depending on ACTION.
ACTION can be 'add' or 'remove' otherwhise 'remove' is assumed. '''
ACTION can be 'add' or 'remove' otherwise 'remove' is assumed. '''
if action == 'add':
option = '-a'
else:
@ -1573,7 +1573,7 @@ class DarwinUser(User):
def _modify_group(self):
'''Add or remove SELF.NAME to or from GROUP depending on ACTION.
ACTION can be 'add' or 'remove' otherwhise 'remove' is assumed. '''
ACTION can be 'add' or 'remove' otherwise 'remove' is assumed. '''
rc = 0
out = ''

@ -0,0 +1,741 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2013, James Cammarata <jcammarata@ansible.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
DOCUMENTATION = '''
---
module: accelerate
short_description: Enable accelerated mode on remote node
deprecated: "in favor of SSH with ControlPersist"
description:
- This modules launches an ephemeral I(accelerate) daemon on the remote node which
Ansible can use to communicate with nodes at high speed.
- The daemon listens on a configurable port for a configurable amount of time.
- Fireball mode is AES encrypted
version_added: "1.3"
options:
port:
description:
- TCP port for the socket connection
required: false
default: 5099
aliases: []
timeout:
description:
- The number of seconds the socket will wait for data. If none is received when the timeout value is reached, the connection will be closed.
required: false
default: 300
aliases: []
minutes:
description:
- The I(accelerate) listener daemon is started on nodes and will stay around for
this number of minutes before turning itself off.
required: false
default: 30
ipv6:
description:
- The listener daemon on the remote host will bind to the ipv6 localhost socket
if this parameter is set to true.
required: false
default: false
multi_key:
description:
- When enabled, the daemon will open a local socket file which can be used by future daemon executions to
upload a new key to the already running daemon, so that multiple users can connect using different keys.
This access still requires an ssh connection as the uid for which the daemon is currently running.
required: false
default: no
version_added: "1.6"
notes:
- See the advanced playbooks chapter for more about using accelerated mode.
requirements:
- "python >= 2.4"
- "python-keyczar"
author: "James Cammarata (@jimi-c)"
'''
EXAMPLES = '''
# To use accelerate mode, simply add "accelerate: true" to your play. The initial
# key exchange and starting up of the daemon will occur over SSH, but all commands and
# subsequent actions will be conducted over the raw socket connection using AES encryption
- hosts: devservers
accelerate: true
tasks:
- command: /usr/bin/anything
'''
import base64
import errno
import getpass
import json
import os
import os.path
import pwd
import signal
import socket
import struct
import sys
import syslog
import tempfile
import time
import traceback
import SocketServer
import datetime
from threading import Thread, Lock
# import module snippets
# we must import this here at the top so we can use get_module_path()
from ansible.module_utils.basic import *
# the chunk size to read and send, assuming mtu 1500 and
# leaving room for base64 (+33%) encoding and header (100 bytes)
# 4 * (975/3) + 100 = 1400
# which leaves room for the TCP/IP header
CHUNK_SIZE=10240
# FIXME: this all should be moved to module_common, as it's
# pretty much a copy from the callbacks/util code
DEBUG_LEVEL=0
def log(msg, cap=0):
global DEBUG_LEVEL
if DEBUG_LEVEL >= cap:
syslog.syslog(syslog.LOG_NOTICE|syslog.LOG_DAEMON, msg)
def v(msg):
log(msg, cap=1)
def vv(msg):
log(msg, cap=2)
def vvv(msg):
log(msg, cap=3)
def vvvv(msg):
log(msg, cap=4)
HAS_KEYCZAR = False
try:
from keyczar.keys import AesKey
HAS_KEYCZAR = True
except ImportError:
pass
SOCKET_FILE = os.path.join(get_module_path(), '.ansible-accelerate', ".local.socket")
def get_pid_location(module):
"""
Try to find a pid directory in the common locations, falling
back to the user's home directory if no others exist
"""
for dir in ['/var/run', '/var/lib/run', '/run', os.path.expanduser("~/")]:
try:
if os.path.isdir(dir) and os.access(dir, os.R_OK|os.W_OK):
return os.path.join(dir, '.accelerate.pid')
except:
pass
module.fail_json(msg="couldn't find any valid directory to use for the accelerate pid file")
# NOTE: this shares a fair amount of code in common with async_wrapper, if async_wrapper were a new module we could move
# this into utils.module_common and probably should anyway
def daemonize_self(module, password, port, minutes, pid_file):
# daemonizing code: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
try:
pid = os.fork()
if pid > 0:
vvv("exiting pid %s" % pid)
# exit first parent
module.exit_json(msg="daemonized accelerate on port %s for %s minutes with pid %s" % (port, minutes, str(pid)))
except OSError:
e = get_exception()
message = "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
module.fail_json(msg=message)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(int('O22', 8))
# do second fork
try:
pid = os.fork()
if pid > 0:
log("daemon pid %s, writing %s" % (pid, pid_file))
pid_file = open(pid_file, "w")
pid_file.write("%s" % pid)
pid_file.close()
vvv("pid file written")
sys.exit(0)
except OSError:
e = get_exception()
log('fork #2 failed: %d (%s)' % (e.errno, e.strerror))
sys.exit(1)
dev_null = file('/dev/null','rw')
os.dup2(dev_null.fileno(), sys.stdin.fileno())
os.dup2(dev_null.fileno(), sys.stdout.fileno())
os.dup2(dev_null.fileno(), sys.stderr.fileno())
log("daemonizing successful")
class LocalSocketThread(Thread):
server = None
terminated = False
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, Verbose=None):
self.server = kwargs.get('server')
Thread.__init__(self, group, target, name, args, kwargs, Verbose)
def run(self):
try:
if os.path.exists(SOCKET_FILE):
os.remove(SOCKET_FILE)
else:
dir = os.path.dirname(SOCKET_FILE)
if os.path.exists(dir):
if not os.path.isdir(dir):
log("The socket file path (%s) exists, but is not a directory. No local connections will be available" % dir)
return
else:
# make sure the directory is accessible only to this
# user, as socket files derive their permissions from
# the directory that contains them
os.chmod(dir, int('0700', 8))
elif not os.path.exists(dir):
os.makedirs(dir, int('O700', 8))
except OSError:
pass
self.s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.s.bind(SOCKET_FILE)
self.s.listen(5)
while not self.terminated:
try:
conn, addr = self.s.accept()
vv("received local connection")
data = ""
while "\n" not in data:
data += conn.recv(2048)
try:
try:
new_key = AesKey.Read(data.strip())
found = False
for key in self.server.key_list:
try:
new_key.Decrypt(key.Encrypt("foo"))
found = True
break
except:
pass
if not found:
vv("adding new key to the key list")
self.server.key_list.append(new_key)
conn.sendall("OK\n")
else:
vv("key already exists in the key list, ignoring")
conn.sendall("EXISTS\n")
# update the last event time so the server doesn't
# shutdown sooner than expected for new clients
try:
self.server.last_event_lock.acquire()
self.server.last_event = datetime.datetime.now()
finally:
self.server.last_event_lock.release()
except Exception:
e = get_exception()
vv("key loaded locally was invalid, ignoring (%s)" % e)
conn.sendall("BADKEY\n")
finally:
try:
conn.close()
except:
pass
except:
pass
def terminate(self):
super(LocalSocketThread, self).terminate()
self.terminated = True
self.s.shutdown(socket.SHUT_RDWR)
self.s.close()
class ThreadWithReturnValue(Thread):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, Verbose=None):
Thread.__init__(self, group, target, name, args, kwargs, Verbose)
self._return = None
def run(self):
if self._Thread__target is not None:
self._return = self._Thread__target(*self._Thread__args,
**self._Thread__kwargs)
def join(self,timeout=None):
Thread.join(self, timeout=timeout)
return self._return
class ThreadedTCPServer(SocketServer.ThreadingTCPServer):
key_list = []
last_event = datetime.datetime.now()
last_event_lock = Lock()
def __init__(self, server_address, RequestHandlerClass, module, password, timeout, use_ipv6=False):
self.module = module
self.key_list.append(AesKey.Read(password))
self.allow_reuse_address = True
self.timeout = timeout
if use_ipv6:
self.address_family = socket.AF_INET6
if self.module.params.get('multi_key', False):
vv("starting thread to handle local connections for multiple keys")
self.local_thread = LocalSocketThread(kwargs=dict(server=self))
self.local_thread.start()
SocketServer.ThreadingTCPServer.__init__(self, server_address, RequestHandlerClass)
def shutdown(self):
self.running = False
SocketServer.ThreadingTCPServer.shutdown(self)
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
# the key to use for this connection
active_key = None
def send_data(self, data):
try:
self.server.last_event_lock.acquire()
self.server.last_event = datetime.datetime.now()
finally:
self.server.last_event_lock.release()
packed_len = struct.pack('!Q', len(data))
return self.request.sendall(packed_len + data)
def recv_data(self):
header_len = 8 # size of a packed unsigned long long
data = ""
vvvv("in recv_data(), waiting for the header")
while len(data) < header_len:
try:
d = self.request.recv(header_len - len(data))
if not d:
vvv("received nothing, bailing out")
return None
data += d
except:
# probably got a connection reset
vvvv("exception received while waiting for recv(), returning None")
return None
vvvv("in recv_data(), got the header, unpacking")
data_len = struct.unpack('!Q',data[:header_len])[0]
data = data[header_len:]
vvvv("data received so far (expecting %d): %d" % (data_len,len(data)))
while len(data) < data_len:
try:
d = self.request.recv(data_len - len(data))
if not d:
vvv("received nothing, bailing out")
return None
data += d
vvvv("data received so far (expecting %d): %d" % (data_len,len(data)))
except:
# probably got a connection reset
vvvv("exception received while waiting for recv(), returning None")
return None
vvvv("received all of the data, returning")
try:
self.server.last_event_lock.acquire()
self.server.last_event = datetime.datetime.now()
finally:
self.server.last_event_lock.release()
return data
def handle(self):
try:
while True:
vvvv("waiting for data")
data = self.recv_data()
if not data:
vvvv("received nothing back from recv_data(), breaking out")
break
vvvv("got data, decrypting")
if not self.active_key:
for key in self.server.key_list:
try:
data = key.Decrypt(data)
self.active_key = key
break
except:
pass
else:
vv("bad decrypt, exiting the connection handler")
return
else:
try:
data = self.active_key.Decrypt(data)
except:
vv("bad decrypt, exiting the connection handler")
return
vvvv("decryption done, loading json from the data")
data = json.loads(data)
mode = data['mode']
response = {}
last_pong = datetime.datetime.now()
if mode == 'command':
vvvv("received a command request, running it")
twrv = ThreadWithReturnValue(target=self.command, args=(data,))
twrv.start()
response = None
while twrv.is_alive():
if (datetime.datetime.now() - last_pong).seconds >= 15:
last_pong = datetime.datetime.now()
vvvv("command still running, sending keepalive packet")
data2 = json.dumps(dict(pong=True))
data2 = self.active_key.Encrypt(data2)
self.send_data(data2)
time.sleep(0.1)
response = twrv._return
vvvv("thread is done, response from join was %s" % response)
elif mode == 'put':
vvvv("received a put request, putting it")
response = self.put(data)
elif mode == 'fetch':
vvvv("received a fetch request, getting it")
response = self.fetch(data)
elif mode == 'validate_user':
vvvv("received a request to validate the user id")
response = self.validate_user(data)
vvvv("response result is %s" % str(response))
json_response = json.dumps(response)
vvvv("dumped json is %s" % json_response)
data2 = self.active_key.Encrypt(json_response)
vvvv("sending the response back to the controller")
self.send_data(data2)
vvvv("done sending the response")
if mode == 'validate_user' and response.get('rc') == 1:
vvvv("detected a uid mismatch, shutting down")
self.server.shutdown()
except:
tb = traceback.format_exc()
log("encountered an unhandled exception in the handle() function")
log("error was:\n%s" % tb)
if self.active_key:
data2 = json.dumps(dict(rc=1, failed=True, msg="unhandled error in the handle() function"))
data2 = self.active_key.Encrypt(data2)
self.send_data(data2)
def validate_user(self, data):
if 'username' not in data:
return dict(failed=True, msg='No username specified')
vvvv("validating we're running as %s" % data['username'])
# get the current uid
c_uid = os.getuid()
try:
# the target uid
t_uid = pwd.getpwnam(data['username']).pw_uid
except:
vvvv("could not find user %s" % data['username'])
return dict(failed=True, msg='could not find user %s' % data['username'])
# and return rc=0 for success, rc=1 for failure
if c_uid == t_uid:
return dict(rc=0)
else:
return dict(rc=1)
def command(self, data):
if 'cmd' not in data:
return dict(failed=True, msg='internal error: cmd is required')
vvvv("executing: %s" % data['cmd'])
use_unsafe_shell = False
executable = data.get('executable')
if executable:
use_unsafe_shell = True
rc, stdout, stderr = self.server.module.run_command(data['cmd'], executable=executable, use_unsafe_shell=use_unsafe_shell, close_fds=True)
if stdout is None:
stdout = ''
if stderr is None:
stderr = ''
vvvv("got stdout: %s" % stdout)
vvvv("got stderr: %s" % stderr)
return dict(rc=rc, stdout=stdout, stderr=stderr)
def fetch(self, data):
if 'in_path' not in data:
return dict(failed=True, msg='internal error: in_path is required')
try:
fd = file(data['in_path'], 'rb')
fstat = os.stat(data['in_path'])
vvv("FETCH file is %d bytes" % fstat.st_size)
while fd.tell() < fstat.st_size:
data = fd.read(CHUNK_SIZE)
last = False
if fd.tell() >= fstat.st_size:
last = True
data = dict(data=base64.b64encode(data), last=last)
data = json.dumps(data)
data = self.active_key.Encrypt(data)
if self.send_data(data):
return dict(failed=True, stderr="failed to send data")
response = self.recv_data()
if not response:
log("failed to get a response, aborting")
return dict(failed=True, stderr="Failed to get a response from %s" % self.host)
response = self.active_key.Decrypt(response)
response = json.loads(response)
if response.get('failed',False):
log("got a failed response from the master")
return dict(failed=True, stderr="Master reported failure, aborting transfer")
except Exception:
e = get_exception()
fd.close()
tb = traceback.format_exc()
log("failed to fetch the file: %s" % tb)
return dict(failed=True, stderr="Could not fetch the file: %s" % str(e))
fd.close()
return dict()
def put(self, data):
if 'data' not in data:
return dict(failed=True, msg='internal error: data is required')
if 'out_path' not in data:
return dict(failed=True, msg='internal error: out_path is required')
final_path = None
if 'user' in data and data.get('user') != getpass.getuser():
vvv("the target user doesn't match this user, we'll move the file into place via sudo")
tmp_path = os.path.expanduser('~/.ansible/tmp/')
if not os.path.exists(tmp_path):
try:
os.makedirs(tmp_path, int('O700', 8))
except:
return dict(failed=True, msg='could not create a temporary directory at %s' % tmp_path)
(fd,out_path) = tempfile.mkstemp(prefix='ansible.', dir=tmp_path)
out_fd = os.fdopen(fd, 'w', 0)
final_path = data['out_path']
else:
out_path = data['out_path']
out_fd = open(out_path, 'w')
try:
bytes=0
while True:
out = base64.b64decode(data['data'])
bytes += len(out)
out_fd.write(out)
response = json.dumps(dict())
response = self.active_key.Encrypt(response)
self.send_data(response)
if data['last']:
break
data = self.recv_data()
if not data:
raise ""
data = self.active_key.Decrypt(data)
data = json.loads(data)
except:
out_fd.close()
tb = traceback.format_exc()
log("failed to put the file: %s" % tb)
return dict(failed=True, stdout="Could not write the file")
vvvv("wrote %d bytes" % bytes)
out_fd.close()
if final_path:
vvv("moving %s to %s" % (out_path, final_path))
self.server.module.atomic_move(out_path, final_path)
return dict()
def daemonize(module, password, port, timeout, minutes, use_ipv6, pid_file):
try:
daemonize_self(module, password, port, minutes, pid_file)
def timer_handler(signum, _):
try:
try:
server.last_event_lock.acquire()
td = datetime.datetime.now() - server.last_event
# older python timedelta objects don't have total_seconds(),
# so we use the formula from the docs to calculate it
total_seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
if total_seconds >= minutes * 60:
log("server has been idle longer than the timeout, shutting down")
server.running = False
server.shutdown()
else:
# reschedule the check
signal.alarm(1)
except:
pass
finally:
server.last_event_lock.release()
signal.signal(signal.SIGALRM, timer_handler)
signal.alarm(1)
tries = 5
while tries > 0:
try:
if use_ipv6:
address = ("::", port)
else:
address = ("0.0.0.0", port)
server = ThreadedTCPServer(address, ThreadedTCPRequestHandler, module, password, timeout, use_ipv6=use_ipv6)
server.allow_reuse_address = True
break
except Exception:
e = get_exception()
vv("Failed to create the TCP server (tries left = %d) (error: %s) " % (tries,e))
tries -= 1
time.sleep(0.2)
if tries == 0:
vv("Maximum number of attempts to create the TCP server reached, bailing out")
raise Exception("max # of attempts to serve reached")
# run the server in a separate thread to make signal handling work
server_thread = Thread(target=server.serve_forever, kwargs=dict(poll_interval=0.1))
server_thread.start()
server.running = True
v("serving!")
while server.running:
time.sleep(1)
# wait for the thread to exit fully
server_thread.join()
v("server thread terminated, exiting!")
sys.exit(0)
except Exception:
e = get_exception()
tb = traceback.format_exc()
log("exception caught, exiting accelerated mode: %s\n%s" % (e, tb))
sys.exit(0)
def main():
global DEBUG_LEVEL
module = AnsibleModule(
argument_spec = dict(
port=dict(required=False, default=5099),
ipv6=dict(required=False, default=False, type='bool'),
multi_key=dict(required=False, default=False, type='bool'),
timeout=dict(required=False, default=300),
password=dict(required=True),
minutes=dict(required=False, default=30),
debug=dict(required=False, default=0, type='int')
),
supports_check_mode=True
)
syslog.openlog('ansible-%s' % module._name)
password = base64.b64decode(module.params['password'])
port = int(module.params['port'])
timeout = int(module.params['timeout'])
minutes = int(module.params['minutes'])
debug = int(module.params['debug'])
ipv6 = module.params['ipv6']
multi_key = module.params['multi_key']
if not HAS_KEYCZAR:
module.fail_json(msg="keyczar is not installed (on the remote side)")
DEBUG_LEVEL=debug
pid_file = get_pid_location(module)
daemon_pid = None
daemon_running = False
if os.path.exists(pid_file):
try:
daemon_pid = int(open(pid_file).read())
try:
# sending signal 0 doesn't do anything to the
# process, other than tell the calling program
# whether other signals can be sent
os.kill(daemon_pid, 0)
except OSError:
e = get_exception()
message = 'the accelerate daemon appears to be running'
message += 'as a different user that this user cannot access'
message += 'pid=%s' % daemon_pid
if e.errno == errno.EPERM:
# no permissions means the pid is probably
# running, but as a different user, so fail
module.fail_json(msg=message)
else:
daemon_running = True
except ValueError:
# invalid pid file, unlink it - otherwise we don't care
try:
os.unlink(pid_file)
except:
pass
if daemon_running and multi_key:
# try to connect to the file socket for the daemon if it exists
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
try:
s.connect(SOCKET_FILE)
s.sendall(password + '\n')
data = ""
while '\n' not in data:
data += s.recv(2048)
res = data.strip()
except:
module.fail_json(msg="failed to connect to the local socket file")
finally:
try:
s.close()
except:
pass
if res in ("OK", "EXISTS"):
module.exit_json(msg="transferred new key to the existing daemon")
else:
module.fail_json(msg="could not transfer new key: %s" % data.strip())
else:
# try to start up the daemon
daemonize(module, password, port, timeout, minutes, ipv6, pid_file)
main()

@ -40,7 +40,7 @@ options:
required: true
default: null
notes:
- meta is not really a module nor action_plugin as such it cannot be overriden.
- meta is not really a module nor action_plugin as such it cannot be overwritten.
author:
- "Ansible Core Team"
'''

@ -222,7 +222,7 @@ if __name__ == '__main__':
if pid:
# Notify the overlord that the async process started
# we need to not return immmediately such that the launched command has an attempt
# we need to not return immediately such that the launched command has an attempt
# to initialize PRIOR to ansible trying to clean up the launch directory (and argsfile)
# this probably could be done with some IPC later. Modules should always read
# the argsfile at the very first start of their execution anyway

@ -118,10 +118,7 @@ options:
newline:
required: false
description:
- Specifies the line separator style to use for the modified file. This defaults
to the windows line separator (\r\n). Note that the indicated line separator
will be used for file output regardless of the original line seperator that
appears in the input file.
- "Specifies the line separator style to use for the modified file. This defaults to the windows line separator (\r\n). Note that the indicated line separator will be used for file output regardless of the original line separator that appears in the input file."
choices: [ "windows", "unix" ]
default: "windows"
@ -138,7 +135,7 @@ EXAMPLES = r"""
- win_lineinfile: dest=C:\\temp\\services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"
# Create file if it doesnt exist with a specific encoding
# Create file if it doesn't exist with a specific encoding
- win_lineinfile: dest=C:\\temp\\utf16.txt create="yes" encoding="utf-16" line="This is a utf-16 encoded file"
# Add a line to a file and ensure the resulting file uses unix line separators

Loading…
Cancel
Save