validate-modules: Fix net_tools modules (#52489)

This PR includes:

* Fixes to open validate-modules issues
* Adding parameter types
pull/52921/head
Dag Wieers 5 years ago committed by GitHub
parent cb67235eab
commit 4670e41a30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,8 +7,6 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
# see examples/playbooks/get_url.yml
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'], 'status': ['stableinterface'],
'supported_by': 'core'} 'supported_by': 'core'}
@ -162,6 +160,11 @@ options:
- If C(client_cert) contains both the certificate and key, this option is not required. - If C(client_cert) contains both the certificate and key, this option is not required.
type: path type: path
version_added: '2.4' version_added: '2.4'
http_agent:
description:
- Header to identify as, generally appears in web server logs.
type: str
default: ansible-httpget
# informational: requirements for nodes # informational: requirements for nodes
extends_documentation_fragment: extends_documentation_fragment:
- files - files

@ -27,6 +27,7 @@ options:
- The file on the remote system to fetch. This I(must) be a file, not a directory. - The file on the remote system to fetch. This I(must) be a file, not a directory.
type: path type: path
required: true required: true
aliases: [ path ]
notes: notes:
- This module returns an 'in memory' base64 encoded version of the file, take into account that this will require at least twice the RAM as the - This module returns an 'in memory' base64 encoded version of the file, take into account that this will require at least twice the RAM as the
original file size. original file size.

@ -32,14 +32,16 @@ options:
- A path of where to download the file to (if desired). If I(dest) is a - A path of where to download the file to (if desired). If I(dest) is a
directory, the basename of the file on the remote server will be used. directory, the basename of the file on the remote server will be used.
type: path type: path
user: url_username:
description: description:
- A username for the module to use for Digest, Basic or WSSE authentication. - A username for the module to use for Digest, Basic or WSSE authentication.
type: str type: str
password: aliases: [ user ]
url_password:
description: description:
- A password for the module to use for Digest, Basic or WSSE authentication. - A password for the module to use for Digest, Basic or WSSE authentication.
type: str type: str
aliases: [ password ]
body: body:
description: description:
- The body of the http request/response to the web service. If C(body_format) is set - The body of the http request/response to the web service. If C(body_format) is set
@ -102,7 +104,7 @@ options:
description: description:
- A list of valid, numeric, HTTP status codes that signifies success of the request. - A list of valid, numeric, HTTP status codes that signifies success of the request.
type: list type: list
default: 200 default: [ 200 ]
timeout: timeout:
description: description:
- The socket level timeout in seconds - The socket level timeout in seconds
@ -174,6 +176,11 @@ options:
description: description:
- Path to Unix domain socket to use for connection - Path to Unix domain socket to use for connection
version_added: '2.8' version_added: '2.8'
http_agent:
description:
- Header to identify as, generally appears in web server logs.
type: str
default: ansible-httpget
notes: notes:
- The dependency on httplib2 was removed in Ansible 2.1. - The dependency on httplib2 was removed in Ansible 2.1.
- The module returns all the HTTP headers in lower-case. - The module returns all the HTTP headers in lower-case.
@ -190,9 +197,8 @@ EXAMPLES = r'''
uri: uri:
url: http://www.example.com url: http://www.example.com
# Check that a page returns a status 200 and fail if the word AWESOME is not - name: Check that a page returns a status 200 and fail if the word AWESOME is not in the page contents
# in the page contents. uri:
- uri:
url: http://www.example.com url: http://www.example.com
return_content: yes return_content: yes
register: this register: this
@ -201,18 +207,16 @@ EXAMPLES = r'''
- name: Create a JIRA issue - name: Create a JIRA issue
uri: uri:
url: https://your.jira.example.com/rest/api/2/issue/ url: https://your.jira.example.com/rest/api/2/issue/
method: POST
user: your_username user: your_username
password: your_pass password: your_pass
method: POST
body: "{{ lookup('file','issue.json') }}" body: "{{ lookup('file','issue.json') }}"
force_basic_auth: yes force_basic_auth: yes
status_code: 201 status_code: 201
body_format: json body_format: json
# Login to a form based webpage, then use the returned cookie to - name: Login to a form based webpage, then use the returned cookie to access the app in later tasks
# access the app in later tasks uri:
- uri:
url: https://your.form.based.auth.example.com/index.php url: https://your.form.based.auth.example.com/index.php
method: POST method: POST
body_format: form-urlencoded body_format: form-urlencoded
@ -223,8 +227,8 @@ EXAMPLES = r'''
status_code: 302 status_code: 302
register: login register: login
# Same, but now using a list of tuples - name: Login to a form based webpage using a list of tuples
- uri: uri:
url: https://your.form.based.auth.example.com/index.php url: https://your.form.based.auth.example.com/index.php
method: POST method: POST
body_format: form-urlencoded body_format: form-urlencoded
@ -235,7 +239,8 @@ EXAMPLES = r'''
status_code: 302 status_code: 302
register: login register: login
- uri: - name: Connect to website using a previously stored cookie
uri:
url: https://your.form.based.auth.example.com/dashboard.php url: https://your.form.based.auth.example.com/dashboard.php
method: GET method: GET
return_content: yes return_content: yes
@ -245,24 +250,24 @@ EXAMPLES = r'''
- name: Queue build of a project in Jenkins - name: Queue build of a project in Jenkins
uri: uri:
url: http://{{ jenkins.host }}/job/{{ jenkins.job }}/build?token={{ jenkins.token }} url: http://{{ jenkins.host }}/job/{{ jenkins.job }}/build?token={{ jenkins.token }}
method: GET
user: "{{ jenkins.user }}" user: "{{ jenkins.user }}"
password: "{{ jenkins.password }}" password: "{{ jenkins.password }}"
method: GET
force_basic_auth: yes force_basic_auth: yes
status_code: 201 status_code: 201
- name: POST from contents of local file - name: POST from contents of local file
uri: uri:
url: "https://httpbin.org/post" url: https://httpbin.org/post
method: POST method: POST
src: file.json src: file.json
- name: POST from contents of remote file - name: POST from contents of remote file
uri: uri:
url: "https://httpbin.org/post" url: https://httpbin.org/post
method: POST method: POST
src: /path/to/my/file.json src: /path/to/my/file.json
remote_src: true remote_src: yes
''' '''
RETURN = r''' RETURN = r'''
@ -301,7 +306,6 @@ import os
import shutil import shutil
import sys import sys
import tempfile import tempfile
import traceback
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import PY2, iteritems, string_types from ansible.module_utils.six import PY2, iteritems, string_types
@ -327,7 +331,7 @@ def write_file(module, url, dest, content, resp):
except Exception as e: except Exception as e:
os.remove(tmpsrc) os.remove(tmpsrc)
msg = format_message("Failed to create temporary content file: %s" % to_native(e), resp) msg = format_message("Failed to create temporary content file: %s" % to_native(e), resp)
module.fail_json(msg=msg, exception=traceback.format_exc(), **resp) module.fail_json(msg=msg, **resp)
f.close() f.close()
checksum_src = None checksum_src = None
@ -368,7 +372,7 @@ def write_file(module, url, dest, content, resp):
except Exception as e: except Exception as e:
os.remove(tmpsrc) os.remove(tmpsrc)
msg = format_message("failed to copy %s to %s: %s" % (tmpsrc, dest, to_native(e)), resp) msg = format_message("failed to copy %s to %s: %s" % (tmpsrc, dest, to_native(e)), resp)
module.fail_json(msg=msg, exception=traceback.format_exc(), **resp) module.fail_json(msg=msg, **resp)
os.remove(tmpsrc) os.remove(tmpsrc)
@ -449,7 +453,7 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
}) })
data = open(src, 'rb') data = open(src, 'rb')
except OSError: except OSError:
module.fail_json(msg='Unable to open source file %s' % src, exception=traceback.format_exc(), elapsed=0) module.fail_json(msg='Unable to open source file %s' % src, elapsed=0)
else: else:
data = body data = body

@ -1,128 +1,159 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# (c) 2016 Michael Gruener <michael.gruener@chaosmoon.net> # Copyright: (c) 2016 Michael Gruener <michael.gruener@chaosmoon.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = r'''
DOCUMENTATION = '''
--- ---
module: cloudflare_dns module: cloudflare_dns
author: "Michael Gruener (@mgruener)" author:
- Michael Gruener (@mgruener)
requirements: requirements:
- "python >= 2.6" - python >= 2.6
version_added: "2.1" version_added: "2.1"
short_description: manage Cloudflare DNS records short_description: Manage Cloudflare DNS records
description: description:
- "Manages dns records via the Cloudflare API, see the docs: U(https://api.cloudflare.com/)" - "Manages dns records via the Cloudflare API, see the docs: U(https://api.cloudflare.com/)"
options: options:
account_api_token: account_api_token:
description: description:
- > - Account API token.
Account API token. You can obtain your API key from the bottom of the Cloudflare 'My Account' page, found here: U(https://dash.cloudflare.com/) - "You can obtain your API key from the bottom of the Cloudflare 'My Account' page, found here: U(https://dash.cloudflare.com/)"
type: str
required: true required: true
account_email: account_email:
description: description:
- "Account email." - Account email.
type: str
required: true required: true
algorithm: algorithm:
description: description:
- Algorithm number. Required for C(type=DS) and C(type=SSHFP) when C(state=present). - Algorithm number.
- Required for C(type=DS) and C(type=SSHFP) when C(state=present).
type: int type: int
version_added: 2.7 version_added: '2.7'
cert_usage: cert_usage:
description: description:
- Certificate usage number. Required for C(type=TLSA) when C(state=present). - Certificate usage number.
choices: [ 0, 1, 2, 3 ] - Required for C(type=TLSA) when C(state=present).
type: int type: int
version_added: 2.7 choices: [ 0, 1, 2, 3 ]
version_added: '2.7'
hash_type: hash_type:
description: description:
- Hash type number. Required for C(type=DS), C(type=SSHFP) and C(type=TLSA) when C(state=present). - Hash type number.
choices: [ 1, 2 ] - Required for C(type=DS), C(type=SSHFP) and C(type=TLSA) when C(state=present).
type: int type: int
version_added: 2.7 choices: [ 1, 2 ]
version_added: '2.7'
key_tag: key_tag:
description: description:
- DNSSEC key tag. Needed for C(type=DS) when C(state=present). - DNSSEC key tag.
- Needed for C(type=DS) when C(state=present).
type: int type: int
version_added: 2.7 version_added: '2.7'
port: port:
description: Service port. Required for C(type=SRV) and C(type=TLSA). description:
- Service port.
- Required for C(type=SRV) and C(type=TLSA).
type: int
priority: priority:
description: Record priority. Required for C(type=MX) and C(type=SRV) description:
default: "1" - Record priority.
- Required for C(type=MX) and C(type=SRV)
default: 1
proto: proto:
description: description:
- Service protocol. Required for C(type=SRV) and C(type=TLSA). - Service protocol. Required for C(type=SRV) and C(type=TLSA).
- Common values are tcp and udp. - Common values are TCP and UDP.
- Before Ansible 2.6 only tcp and udp were available. - Before Ansible 2.6 only TCP and UDP were available.
type: str
proxied: proxied:
description: Proxy through cloudflare network or just use DNS description:
- Proxy through Cloudflare network or just use DNS.
type: bool type: bool
default: 'no' default: no
version_added: "2.3" version_added: '2.3'
record: record:
description: description:
- Record to add. Required if C(state=present). Default is C(@) (e.g. the zone name) - Record to add.
default: "@" - Required if C(state=present).
aliases: [ "name" ] - Default is C(@) (e.g. the zone name).
type: str
default: '@'
aliases: [ name ]
selector: selector:
description: description:
- Selector number. Required for C(type=TLSA) when C(state=present). - Selector number.
- Required for C(type=TLSA) when C(state=present).
choices: [ 0, 1 ] choices: [ 0, 1 ]
type: int type: int
version_added: 2.7 version_added: '2.7'
service: service:
description: Record service. Required for C(type=SRV) description:
- Record service.
- Required for C(type=SRV)
solo: solo:
description: description:
- Whether the record should be the only one for that record type and record name. Only use with C(state=present) - Whether the record should be the only one for that record type and record name.
- This will delete all other records with the same record name and type. - Only use with C(state=present).
- This will delete all other records with the same record name and type.
type: bool type: bool
state: state:
description: description:
- Whether the record(s) should exist or not - Whether the record(s) should exist or not.
choices: [ 'present', 'absent' ] type: str
choices: [ absent, present ]
default: present default: present
timeout: timeout:
description: description:
- Timeout for Cloudflare API calls - Timeout for Cloudflare API calls.
type: int
default: 30 default: 30
ttl: ttl:
description: description:
- The TTL to give the new record. Must be between 120 and 2,147,483,647 seconds, or 1 for automatic. - The TTL to give the new record.
default: 1 (automatic) - Must be between 120 and 2,147,483,647 seconds, or 1 for automatic.
type: int
default: 1
type: type:
description: description:
- The type of DNS record to create. Required if C(state=present) - The type of DNS record to create. Required if C(state=present).
- C(type=DS), C(type=SSHFP) and C(type=TLSA) added in Ansible 2.7. - C(type=DS), C(type=SSHFP) and C(type=TLSA) added in Ansible 2.7.
choices: [ 'A', 'AAAA', 'CNAME', 'TXT', 'SRV', 'MX', 'NS', 'DS', 'SPF', 'SSHFP', 'TLSA' ] type: str
choices: [ A, AAAA, CNAME, DS, MX, NS, SPF, SRV, SSHFP, TLSA, TXT ]
value: value:
description: description:
- The record value. Required for C(state=present) - The record value.
aliases: [ "content" ] - Required for C(state=present).
type: str
aliases: [ content ]
weight: weight:
description: Service weight. Required for C(type=SRV) description:
default: "1" - Service weight.
- Required for C(type=SRV).
type: int
default: 1
zone: zone:
description: description:
- The name of the Zone to work with (e.g. "example.com"). The Zone must already exist. - The name of the Zone to work with (e.g. "example.com").
- The Zone must already exist.
type: str
required: true required: true
aliases: ["domain"] aliases: [ domain ]
''' '''
EXAMPLES = ''' EXAMPLES = r'''
# create a test.my.com A record to point to 127.0.0.1 - name: Create a test.my.com A record to point to 127.0.0.1
- cloudflare_dns: cloudflare_dns:
zone: my.com zone: my.com
record: test record: test
type: A type: A
@ -131,58 +162,58 @@ EXAMPLES = '''
account_api_token: dummyapitoken account_api_token: dummyapitoken
register: record register: record
# create a my.com CNAME record to example.com - name: Create a my.com CNAME record to example.com
- cloudflare_dns: cloudflare_dns:
zone: my.com zone: my.com
type: CNAME type: CNAME
value: example.com value: example.com
state: present
account_email: test@example.com account_email: test@example.com
account_api_token: dummyapitoken account_api_token: dummyapitoken
state: present
# change it's ttl - name: Change its TTL
- cloudflare_dns: cloudflare_dns:
zone: my.com zone: my.com
type: CNAME type: CNAME
value: example.com value: example.com
ttl: 600 ttl: 600
state: present
account_email: test@example.com account_email: test@example.com
account_api_token: dummyapitoken account_api_token: dummyapitoken
state: present
# and delete the record - name: Delete the record
- cloudflare_dns: cloudflare_dns:
zone: my.com zone: my.com
type: CNAME type: CNAME
value: example.com value: example.com
state: absent
account_email: test@example.com account_email: test@example.com
account_api_token: dummyapitoken account_api_token: dummyapitoken
state: absent
# create a my.com CNAME record to example.com and proxy through cloudflare's network - name: create a my.com CNAME record to example.com and proxy through Cloudflare's network
- cloudflare_dns: cloudflare_dns:
zone: my.com zone: my.com
type: CNAME type: CNAME
value: example.com value: example.com
state: present
proxied: yes proxied: yes
account_email: test@example.com account_email: test@example.com
account_api_token: dummyapitoken account_api_token: dummyapitoken
state: present
# create TXT record "test.my.com" with value "unique value" # This deletes all other TXT records named "test.my.com"
# delete all other TXT records named "test.my.com" - name: Create TXT record "test.my.com" with value "unique value"
- cloudflare_dns: cloudflare_dns:
domain: my.com domain: my.com
record: test record: test
type: TXT type: TXT
value: unique value value: unique value
state: present
solo: true solo: true
account_email: test@example.com account_email: test@example.com
account_api_token: dummyapitoken account_api_token: dummyapitoken
state: present
# create a SRV record _foo._tcp.my.com - name: Create an SRV record _foo._tcp.my.com
- cloudflare_dns: cloudflare_dns:
domain: my.com domain: my.com
service: foo service: foo
proto: tcp proto: tcp
@ -192,8 +223,8 @@ EXAMPLES = '''
type: SRV type: SRV
value: fooserver.my.com value: fooserver.my.com
# create a SSHFP record login.example.com - name: Create a SSHFP record login.example.com
- cloudflare_dns: cloudflare_dns:
zone: example.com zone: example.com
record: login record: login
type: SSHFP type: SSHFP
@ -201,8 +232,8 @@ EXAMPLES = '''
hash_type: 2 hash_type: 2
value: 9dc1d6742696d2f51ca1f1a78b3d16a840f7d111eb9454239e70db31363f33e1 value: 9dc1d6742696d2f51ca1f1a78b3d16a840f7d111eb9454239e70db31363f33e1
# create a TLSA record _25._tcp.mail.example.com - name: Create a TLSA record _25._tcp.mail.example.com
- cloudflare_dns: cloudflare_dns:
zone: example.com zone: example.com
record: mail record: mail
port: 25 port: 25
@ -213,8 +244,8 @@ EXAMPLES = '''
hash_type: 1 hash_type: 1
value: 6b76d034492b493e15a7376fccd08e63befdad0edab8e442562f532338364bf3 value: 6b76d034492b493e15a7376fccd08e63befdad0edab8e442562f532338364bf3
# Create a DS record for subdomain.example.com - name: Create a DS record for subdomain.example.com
- cloudflare_dns: cloudflare_dns:
zone: example.com zone: example.com
record: subdomain record: subdomain
type: DS type: DS
@ -224,24 +255,24 @@ EXAMPLES = '''
value: B4EB5AC4467D2DFB3BAF9FB9961DC1B6FED54A58CDFAA3E465081EC86F89BFAB value: B4EB5AC4467D2DFB3BAF9FB9961DC1B6FED54A58CDFAA3E465081EC86F89BFAB
''' '''
RETURN = ''' RETURN = r'''
record: record:
description: dictionary containing the record data description: A dictionary containing the record data.
returned: success, except on record deletion returned: success, except on record deletion
type: complex type: complex
contains: contains:
content: content:
description: the record content (details depend on record type) description: The record content (details depend on record type).
returned: success returned: success
type: str type: str
sample: 192.0.2.91 sample: 192.0.2.91
created_on: created_on:
description: the record creation date description: The record creation date.
returned: success returned: success
type: str type: str
sample: 2016-03-25T19:09:42.516553Z sample: 2016-03-25T19:09:42.516553Z
data: data:
description: additional record data description: Additional record data.
returned: success, if type is SRV, DS, SSHFP or TLSA returned: success, if type is SRV, DS, SSHFP or TLSA
type: dict type: dict
sample: { sample: {
@ -254,62 +285,62 @@ record:
weight: 5, weight: 5,
} }
id: id:
description: the record id description: The record ID.
returned: success returned: success
type: str type: str
sample: f9efb0549e96abcb750de63b38c9576e sample: f9efb0549e96abcb750de63b38c9576e
locked: locked:
description: No documentation available description: No documentation available.
returned: success returned: success
type: bool type: bool
sample: False sample: False
meta: meta:
description: No documentation available description: No documentation available.
returned: success returned: success
type: dict type: dict
sample: { auto_added: false } sample: { auto_added: false }
modified_on: modified_on:
description: record modification date description: Record modification date.
returned: success returned: success
type: str type: str
sample: 2016-03-25T19:09:42.516553Z sample: 2016-03-25T19:09:42.516553Z
name: name:
description: the record name as FQDN (including _service and _proto for SRV) description: The record name as FQDN (including _service and _proto for SRV).
returned: success returned: success
type: str type: str
sample: www.sample.com sample: www.sample.com
priority: priority:
description: priority of the MX record description: Priority of the MX record.
returned: success, if type is MX returned: success, if type is MX
type: int type: int
sample: 10 sample: 10
proxiable: proxiable:
description: whether this record can be proxied through cloudflare description: Whether this record can be proxied through Cloudflare.
returned: success returned: success
type: bool type: bool
sample: False sample: False
proxied: proxied:
description: whether the record is proxied through cloudflare description: Whether the record is proxied through Cloudflare.
returned: success returned: success
type: bool type: bool
sample: False sample: False
ttl: ttl:
description: the time-to-live for the record description: The time-to-live for the record.
returned: success returned: success
type: int type: int
sample: 300 sample: 300
type: type:
description: the record type description: The record type.
returned: success returned: success
type: str type: str
sample: A sample: A
zone_id: zone_id:
description: the id of the zone containing the record description: The ID of the zone containing the record.
returned: success returned: success
type: str type: str
sample: abcede0bf9f0066f94029d2e6b73856a sample: abcede0bf9f0066f94029d2e6b73856a
zone_name: zone_name:
description: the name of the zone containing the record description: The name of the zone containing the record.
returned: success returned: success
type: str type: str
sample: sample.com sample: sample.com
@ -735,27 +766,27 @@ class CloudflareAPI(object):
def main(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
account_api_token=dict(required=True, no_log=True, type='str'), account_api_token=dict(type='str', required=True, no_log=True),
account_email=dict(required=True, type='str'), account_email=dict(type='str', required=True),
algorithm=dict(required=False, default=None, type='int'), algorithm=dict(type='int'),
cert_usage=dict(required=False, default=None, choices=[0, 1, 2, 3], type='int'), cert_usage=dict(type='int', choices=[0, 1, 2, 3]),
hash_type=dict(required=False, default=None, choices=[1, 2], type='int'), hash_type=dict(type='int', choices=[1, 2]),
key_tag=dict(required=False, default=None, type='int'), key_tag=dict(type='int'),
port=dict(required=False, default=None, type='int'), port=dict(type='int'),
priority=dict(required=False, default=1, type='int'), priority=dict(type='int', default=1),
proto=dict(required=False, default=None, type='str'), proto=dict(type='str'),
proxied=dict(required=False, default=False, type='bool'), proxied=dict(type='bool', default=False),
record=dict(required=False, default='@', aliases=['name'], type='str'), record=dict(type='str', default='@', aliases=['name']),
selector=dict(required=False, default=None, choices=[0, 1], type='int'), selector=dict(type='int', choices=[0, 1]),
service=dict(required=False, default=None, type='str'), service=dict(type='str'),
solo=dict(required=False, default=None, type='bool'), solo=dict(type='bool'),
state=dict(required=False, default='present', choices=['present', 'absent'], type='str'), state=dict(type='str', default='present', choices=['absent', 'present']),
timeout=dict(required=False, default=30, type='int'), timeout=dict(type='int', default=30),
ttl=dict(required=False, default=1, type='int'), ttl=dict(type='int', default=1),
type=dict(required=False, default=None, choices=['A', 'AAAA', 'CNAME', 'TXT', 'SRV', 'MX', 'NS', 'DS', 'SPF', 'SSHFP', 'TLSA'], type='str'), type=dict(type='str', choices=['A', 'AAAA', 'CNAME', 'DS', 'MX', 'NS', 'SPF', 'SRV', 'SSHFP', 'TLSA', 'TXT']),
value=dict(required=False, default=None, aliases=['content'], type='str'), value=dict(type='str', aliases=['content']),
weight=dict(required=False, default=1, type='int'), weight=dict(type='int', default=1),
zone=dict(required=True, default=None, aliases=['domain'], type='str'), zone=dict(type='str', required=True, aliases=['domain']),
), ),
supports_check_mode=True, supports_check_mode=True,
required_if=([ required_if=([
@ -763,7 +794,7 @@ def main():
('state', 'absent', ['record']), ('state', 'absent', ['record']),
('type', 'SRV', ['proto', 'service']), ('type', 'SRV', ['proto', 'service']),
('type', 'TLSA', ['proto', 'port']), ('type', 'TLSA', ['proto', 'port']),
] ],
), ),
) )
@ -811,8 +842,8 @@ def main():
result, changed = cf_api.ensure_dns_record() result, changed = cf_api.ensure_dns_record()
if isinstance(result, list): if isinstance(result, list):
module.exit_json(changed=changed, result={'record': result[0]}) module.exit_json(changed=changed, result={'record': result[0]})
else:
module.exit_json(changed=changed, result={'record': result}) module.exit_json(changed=changed, result={'record': result})
else: else:
# force solo to False, just to be sure # force solo to False, just to be sure
changed = cf_api.delete_dns_records(solo=False) changed = cf_api.delete_dns_records(solo=False)

@ -1,27 +1,25 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# (c) 2014, Ravi Bhure <ravibhure@gmail.com> # Copyright: (c) 2014, Ravi Bhure <ravibhure@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = r'''
DOCUMENTATION = '''
--- ---
module: haproxy module: haproxy
version_added: "1.9" version_added: "1.9"
short_description: Enable, disable, and set weights for HAProxy backend servers using socket commands. short_description: Enable, disable, and set weights for HAProxy backend servers using socket commands
author: "Ravi Bhure (@ravibhure)" author:
- Ravi Bhure (@ravibhure)
description: description:
- Enable, disable, drain and set weights for HAProxy backend servers using socket - Enable, disable, drain and set weights for HAProxy backend servers using socket commands.
commands.
notes: notes:
- Enable, disable and drain commands are restricted and can only be issued on - Enable, disable and drain commands are restricted and can only be issued on
sockets configured for level 'admin'. For example, you can add the line sockets configured for level 'admin'. For example, you can add the line
@ -33,90 +31,99 @@ options:
backend: backend:
description: description:
- Name of the HAProxy backend pool. - Name of the HAProxy backend pool.
default: auto-detected - If this parameter is unset, it will be auto-detected.
type: str
drain: drain:
description: description:
- Wait until the server has no active connections or until the timeout - Wait until the server has no active connections or until the timeout
determined by wait_interval and wait_retries is reached. Continue only determined by wait_interval and wait_retries is reached.
after the status changes to 'MAINT'. This overrides the - Continue only after the status changes to 'MAINT'.
shutdown_sessions option. - This overrides the shutdown_sessions option.
type: bool type: bool
version_added: "2.4" version_added: "2.4"
host: host:
description: description:
- Name of the backend host to change. - Name of the backend host to change.
type: str
required: true required: true
shutdown_sessions: shutdown_sessions:
description: description:
- When disabling a server, immediately terminate all the sessions attached - When disabling a server, immediately terminate all the sessions attached
to the specified server. This can be used to terminate long-running to the specified server.
sessions after a server is put into maintenance mode. Overridden by the - This can be used to terminate long-running sessions after a server is put
drain option. into maintenance mode. Overridden by the drain option.
type: bool type: bool
default: 'no' default: no
socket: socket:
description: description:
- Path to the HAProxy socket file. - Path to the HAProxy socket file.
type: path
default: /var/run/haproxy.sock default: /var/run/haproxy.sock
state: state:
description: description:
- Desired state of the provided backend host. - Desired state of the provided backend host.
- Note that C(drain) state was added in version 2.4. It is supported only by HAProxy version 1.5 or later, - Note that C(drain) state was added in version 2.4.
if used on versions < 1.5, it will be ignored. - It is supported only by HAProxy version 1.5 or later,
- When used on versions < 1.5, it will be ignored.
type: str
required: true required: true
choices: [ "enabled", "disabled", "drain" ] choices: [ disabled, drain, enabled ]
fail_on_not_found: fail_on_not_found:
description: description:
- Fail whenever trying to enable/disable a backend host that does not exist - Fail whenever trying to enable/disable a backend host that does not exist
type: bool type: bool
default: 'no' default: no
version_added: "2.2" version_added: "2.2"
wait: wait:
description: description:
- Wait until the server reports a status of 'UP' when `state=enabled`, - Wait until the server reports a status of 'UP' when C(state=enabled),
status of 'MAINT' when `state=disabled` or status of 'DRAIN' when `state=drain` status of 'MAINT' when C(state=disabled) or status of 'DRAIN' when C(state=drain)
type: bool type: bool
default: 'no' default: no
version_added: "2.0" version_added: "2.0"
wait_interval: wait_interval:
description: description:
- Number of seconds to wait between retries. - Number of seconds to wait between retries.
type: int
default: 5 default: 5
version_added: "2.0" version_added: "2.0"
wait_retries: wait_retries:
description: description:
- Number of times to check for status after changing the state. - Number of times to check for status after changing the state.
type: int
default: 25 default: 25
version_added: "2.0" version_added: "2.0"
weight: weight:
description: description:
- The value passed in argument. If the value ends with the `%` sign, then - The value passed in argument.
the new weight will be relative to the initially configured weight. - If the value ends with the `%` sign, then the new weight will be
Relative weights are only permitted between 0 and 100% and absolute relative to the initially configured weight.
- Relative weights are only permitted between 0 and 100% and absolute
weights are permitted between 0 and 256. weights are permitted between 0 and 256.
type: str
''' '''
EXAMPLES = ''' EXAMPLES = r'''
# disable server in 'www' backend pool - name: Disable server in 'www' backend pool
- haproxy: haproxy:
state: disabled state: disabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
backend: www backend: www
# disable server without backend pool name (apply to all available backend pool) - name: Disable server without backend pool name (apply to all available backend pool)
- haproxy: haproxy:
state: disabled state: disabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
# disable server, provide socket file - name: Disable server, provide socket file
- haproxy: haproxy:
state: disabled state: disabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
socket: /var/run/haproxy.sock socket: /var/run/haproxy.sock
backend: www backend: www
# disable server, provide socket file, wait until status reports in maintenance - name: Disable server, provide socket file, wait until status reports in maintenance
- haproxy: haproxy:
state: disabled state: disabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
socket: /var/run/haproxy.sock socket: /var/run/haproxy.sock
@ -136,35 +143,35 @@ EXAMPLES = '''
wait_interval: 1 wait_interval: 1
wait_retries: 60 wait_retries: 60
# disable backend server in 'www' backend pool and drop open sessions to it - name: Disable backend server in 'www' backend pool and drop open sessions to it
- haproxy: haproxy:
state: disabled state: disabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
backend: www backend: www
socket: /var/run/haproxy.sock socket: /var/run/haproxy.sock
shutdown_sessions: true shutdown_sessions: yes
# disable server without backend pool name (apply to all available backend pool) but fail when the backend host is not found - name: Disable server without backend pool name (apply to all available backend pool) but fail when the backend host is not found
- haproxy: haproxy:
state: disabled state: disabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
fail_on_not_found: yes fail_on_not_found: yes
# enable server in 'www' backend pool - name: Enable server in 'www' backend pool
- haproxy: haproxy:
state: enabled state: enabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
backend: www backend: www
# enable server in 'www' backend pool wait until healthy - name: Enable server in 'www' backend pool wait until healthy
- haproxy: haproxy:
state: enabled state: enabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
backend: www backend: www
wait: yes wait: yes
# enable server in 'www' backend pool wait until healthy. Retry 10 times with intervals of 5 seconds to retrieve the health - name: Enable server in 'www' backend pool wait until healthy. Retry 10 times with intervals of 5 seconds to retrieve the health
- haproxy: haproxy:
state: enabled state: enabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
backend: www backend: www
@ -172,16 +179,16 @@ EXAMPLES = '''
wait_retries: 10 wait_retries: 10
wait_interval: 5 wait_interval: 5
# enable server in 'www' backend pool with change server(s) weight - name: Enable server in 'www' backend pool with change server(s) weight
- haproxy: haproxy:
state: enabled state: enabled
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
socket: /var/run/haproxy.sock socket: /var/run/haproxy.sock
weight: 10 weight: 10
backend: www backend: www
# set the server in 'www' backend pool to drain mode - name: Set the server in 'www' backend pool to drain mode
- haproxy: haproxy:
state: drain state: drain
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
socket: /var/run/haproxy.sock socket: /var/run/haproxy.sock
@ -395,8 +402,7 @@ class HAProxy(object):
Figure out what you want to do from ansible, and then do it. Figure out what you want to do from ansible, and then do it.
""" """
# Get the state before the run # Get the state before the run
state_before = self.get_state_for(self.backend, self.host) self.command_results['state_before'] = self.get_state_for(self.backend, self.host)
self.command_results['state_before'] = state_before
# toggle enable/disbale server # toggle enable/disbale server
if self.state == 'enabled': if self.state == 'enabled':
@ -411,16 +417,12 @@ class HAProxy(object):
self.module.fail_json(msg="unknown state specified: '%s'" % self.state) self.module.fail_json(msg="unknown state specified: '%s'" % self.state)
# Get the state after the run # Get the state after the run
state_after = self.get_state_for(self.backend, self.host) self.command_results['state_after'] = self.get_state_for(self.backend, self.host)
self.command_results['state_after'] = state_after
# Report change status # Report change status
if state_before != state_after: self.command_results['changed'] = (self.command_results['state_before'] != self.command_results['state_after'])
self.command_results['changed'] = True
self.module.exit_json(**self.command_results) self.module.exit_json(**self.command_results)
else:
self.command_results['changed'] = False
self.module.exit_json(**self.command_results)
def main(): def main():
@ -428,17 +430,17 @@ def main():
# load ansible module object # load ansible module object
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
state=dict(required=True, default=None, choices=ACTION_CHOICES), state=dict(type='str', required=True, choices=ACTION_CHOICES),
host=dict(required=True, default=None), host=dict(type='str', required=True),
backend=dict(required=False, default=None), backend=dict(type='str'),
weight=dict(required=False, default=None), weight=dict(type='str'),
socket=dict(required=False, default=DEFAULT_SOCKET_LOCATION), socket=dict(type='path', default=DEFAULT_SOCKET_LOCATION),
shutdown_sessions=dict(required=False, default=False, type='bool'), shutdown_sessions=dict(type='bool', default=False),
fail_on_not_found=dict(required=False, default=False, type='bool'), fail_on_not_found=dict(type='bool', default=False),
wait=dict(required=False, default=False, type='bool'), wait=dict(type='bool', default=False),
wait_retries=dict(required=False, default=WAIT_RETRIES, type='int'), wait_retries=dict(type='int', default=WAIT_RETRIES),
wait_interval=dict(required=False, default=WAIT_INTERVAL, type='int'), wait_interval=dict(type='int', default=WAIT_INTERVAL),
drain=dict(default=False, type='bool'), drain=dict(type='bool', default=False),
), ),
) )

@ -1,105 +1,92 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#
# Copyright (c), meiliu@fusionlayer.com, 2017 # Copyright: (c) 2017, <meiliu@fusionlayer.com>
# # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# 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.
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = r'''
DOCUMENTATION = """
module: infinity module: infinity
short_description: "manage Infinity IPAM using Rest API" short_description: Manage Infinity IPAM using Rest API
description: description:
- "Manage Infinity IPAM using REST API" - Manage Infinity IPAM using REST API.
version_added: "2.4" version_added: "2.4"
author: author:
- "Meirong Liu (@MeganLiu)" - Meirong Liu (@MeganLiu)
options: options:
server_ip: server_ip:
description: description:
- Infinity server_ip with IP address - Infinity server_ip with IP address.
type: str
required: true required: true
username: username:
description: description:
- Username to access Infinity - Username to access Infinity.
- The user must have Rest API privileges - The user must have REST API privileges.
type: str
required: true required: true
password: password:
description: description:
- Infinity password - Infinity password.
type: str
required: true required: true
action: action:
description: description:
- Action to perform - Action to perform
type: str
required: true required: true
choices: choices: [add_network, delete_network, get_network, get_network_id, release_ip, release_network, reserve_network, reserve_next_available_ip ]
- reserve_next_available_ip
- release_ip
- delete_network
- add_network
- reserve_network
- release_network
- get_network_id
network_id: network_id:
description: description:
- Network ID - Network ID.
type: str
default: '' default: ''
ip_address: ip_address:
description: description:
- IP Address for a reservation or a release - IP Address for a reservation or a release.
type: str
default: '' default: ''
network_address: network_address:
description: description:
- Network address with CIDR format (e.g., 192.168.310.0) - Network address with CIDR format (e.g., 192.168.310.0).
required: false type: str
default: "" default: ''
network_size: network_size:
description: description:
- Network bitmask (e.g. 255.255.255.220) or CIDR format (e.g., /26) - Network bitmask (e.g. 255.255.255.220) or CIDR format (e.g., /26).
type: str
default: '' default: ''
network_name: network_name:
description: description:
- The name of a network - The name of a network.
type: str
default: '' default: ''
network_location: network_location:
description: description:
- the parent network id for a given network - The parent network id for a given network.
type: int
default: -1 default: -1
network_type: network_type:
description: description:
- Network type defined by Infinity - Network type defined by Infinity
choices: type: str
- lan choices: [ lan, shared_lan, supernet ]
- shared_lan default: lan
- supernet
default: "lan"
network_family: network_family:
description: description:
- Network family defined by Infinity, e.g. IPv4, IPv6 and Dual stack - Network family defined by Infinity, e.g. IPv4, IPv6 and Dual stack
choices: type: str
- 4 choices: [ 4, 6, dual ]
- 6 default: 4
- dual '''
default: "4"
"""
EXAMPLES = """ EXAMPLES = r'''
--- ---
- hosts: localhost - hosts: localhost
connection: local connection: local
@ -107,20 +94,19 @@ EXAMPLES = """
tasks: tasks:
- name: Reserve network into Infinity IPAM - name: Reserve network into Infinity IPAM
infinity: infinity:
server_ip: "80.75.107.12" server_ip: 80.75.107.12
username: "username" username: username
password: "password" password: password
action: "reserve_network" action: reserve_network
network_name: "reserve_new_ansible_network" network_name: reserve_new_ansible_network
network_family: "4" network_family: 4
network_type: 'lan' network_type: lan
network_id: "1201" network_id: 1201
network_size: "/28" network_size: /28
register: infinity register: infinity
'''
""" RETURN = r'''
RETURN = """
network_id: network_id:
description: id for a given network description: id for a given network
returned: success returned: success
@ -139,11 +125,10 @@ network_info:
"network_size": null,"description": null,"network_location": "3085", "network_size": null,"description": null,"network_location": "3085",
"ranges": { "id": 0, "name": null,"first_ip": null,"type": null,"last_ip": null}, "ranges": { "id": 0, "name": null,"first_ip": null,"type": null,"last_ip": null},
"network_type": "lan","network_name": "'reserve_new_ansible_network'"} "network_type": "lan","network_name": "'reserve_new_ansible_network'"}
""" '''
from ansible.module_utils.basic import json from ansible.module_utils.basic import AnsibleModule, json
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
@ -486,61 +471,73 @@ class Infinity(object):
def main(): def main():
my_module = AnsibleModule(argument_spec=dict( module = AnsibleModule(
server_ip=dict(required=True, type='str'), argument_spec=dict(
username=dict(required=True, type='str'), server_ip=dict(type='str', required=True),
password=dict(required=True, type='str', no_log=True), username=dict(type='str', required=True),
network_id=dict(type='str'), password=dict(type='str', required=True, no_log=True),
ip_address=dict(type='str'), network_id=dict(type='str'),
network_name=dict(type='str'), ip_address=dict(type='str'),
network_location=dict(default=-1, type='int'), network_name=dict(type='str'),
network_family=dict(default='4', choices=['4', '6', 'dual']), network_location=dict(type='int', default=-1),
network_type=dict(default='lan', choices=['lan', 'shared_lan', 'supernet']), network_family=dict(type='str', default='4', choices=['4', '6', 'dual']),
network_address=dict(type='str'), network_type=dict(type='str', default='lan', choices=['lan', 'shared_lan', 'supernet']),
network_size=dict(type='str'), network_address=dict(type='str'),
action=dict(required=True, choices=['get_network', 'reserve_next_available_ip', 'release_ip', network_size=dict(type='str'),
'delete_network', 'reserve_network', 'release_network', action=dict(type='str', required=True, choices=[
'add_network', 'get_network_id'],), 'add_network',
), required_together=(['username', 'password'],),) 'delete_network',
server_ip = my_module.params["server_ip"] 'get_network',
username = my_module.params["username"] 'get_network_id',
password = my_module.params["password"] 'release_ip',
action = my_module.params["action"] 'release_network',
network_id = my_module.params["network_id"] 'reserve_network',
released_ip = my_module.params["ip_address"] 'reserve_next_available_ip',
network_name = my_module.params["network_name"] ],),
network_family = my_module.params["network_family"] ),
network_type = my_module.params["network_type"] required_together=(
network_address = my_module.params["network_address"] ['username', 'password'],
network_size = my_module.params["network_size"] ),
network_location = my_module.params["network_location"] )
my_infinity = Infinity(my_module, server_ip, username, password) server_ip = module.params["server_ip"]
username = module.params["username"]
password = module.params["password"]
action = module.params["action"]
network_id = module.params["network_id"]
released_ip = module.params["ip_address"]
network_name = module.params["network_name"]
network_family = module.params["network_family"]
network_type = module.params["network_type"]
network_address = module.params["network_address"]
network_size = module.params["network_size"]
network_location = module.params["network_location"]
my_infinity = Infinity(module, server_ip, username, password)
result = '' result = ''
if action == "reserve_next_available_ip": if action == "reserve_next_available_ip":
if network_id: if network_id:
result = my_infinity.reserve_next_available_ip(network_id) result = my_infinity.reserve_next_available_ip(network_id)
if not result: if not result:
result = 'There is an error in calling method of reserve_next_available_ip' result = 'There is an error in calling method of reserve_next_available_ip'
my_module.exit_json(changed=False, meta=result) module.exit_json(changed=False, meta=result)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "release_ip": elif action == "release_ip":
if network_id and released_ip: if network_id and released_ip:
result = my_infinity.release_ip( result = my_infinity.release_ip(
network_id=network_id, ip_address=released_ip) network_id=network_id, ip_address=released_ip)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "delete_network": elif action == "delete_network":
result = my_infinity.delete_network( result = my_infinity.delete_network(
network_id=network_id, network_name=network_name) network_id=network_id, network_name=network_name)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "get_network_id": elif action == "get_network_id":
result = my_infinity.get_network_id( result = my_infinity.get_network_id(
network_name=network_name, network_type=network_type) network_name=network_name, network_type=network_type)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "get_network": elif action == "get_network":
result = my_infinity.get_network( result = my_infinity.get_network(
network_id=network_id, network_name=network_name) network_id=network_id, network_name=network_name)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "reserve_network": elif action == "reserve_network":
result = my_infinity.reserve_network( result = my_infinity.reserve_network(
network_id=network_id, network_id=network_id,
@ -549,13 +546,13 @@ def main():
reserved_network_family=network_family, reserved_network_family=network_family,
reserved_network_type=network_type, reserved_network_type=network_type,
reserved_network_address=network_address) reserved_network_address=network_address)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "release_network": elif action == "release_network":
result = my_infinity.release_network( result = my_infinity.release_network(
network_id=network_id, network_id=network_id,
released_network_name=network_name, released_network_name=network_name,
released_network_type=network_type) released_network_type=network_type)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
elif action == "add_network": elif action == "add_network":
result = my_infinity.add_network( result = my_infinity.add_network(
@ -566,7 +563,7 @@ def main():
network_family=network_family, network_family=network_family,
network_type=network_type) network_type=network_type)
my_module.exit_json(changed=True, meta=result) module.exit_json(changed=True, meta=result)
if __name__ == '__main__': if __name__ == '__main__':

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# (c) 2015, René Moser <mail@renemoser.net> # Copyright: (c) 2015, René Moser <mail@renemoser.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 from __future__ import absolute_import, division, print_function
@ -13,51 +13,51 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = ''' DOCUMENTATION = r'''
--- ---
module: ipify_facts module: ipify_facts
short_description: Retrieve the public IP of your internet gateway. short_description: Retrieve the public IP of your internet gateway
description: description:
- If behind NAT and need to know the public IP of your internet gateway. - If behind NAT and need to know the public IP of your internet gateway.
version_added: '2.0' version_added: '2.0'
author: "René Moser (@resmo)" author:
- René Moser (@resmo)
options: options:
api_url: api_url:
description: description:
- URL of the ipify.org API service. - URL of the ipify.org API service.
- C(?format=json) will be appended per default. - C(?format=json) will be appended per default.
required: false type: str
default: 'https://api.ipify.org' default: https://api.ipify.org/
timeout: timeout:
description: description:
- HTTP connection timeout in seconds. - HTTP connection timeout in seconds.
required: false type: int
default: 10 default: 10
version_added: "2.3" version_added: "2.3"
validate_certs: validate_certs:
description: description:
- When set to C(NO), SSL certificates will not be validated. - When set to C(NO), SSL certificates will not be validated.
required: false
default: "yes"
type: bool type: bool
default: yes
version_added: "2.4" version_added: "2.4"
notes: notes:
- "Visit https://www.ipify.org to get more information." - Visit https://www.ipify.org to get more information.
''' '''
EXAMPLES = ''' EXAMPLES = r'''
# Gather IP facts from ipify.org # Gather IP facts from ipify.org
- name: get my public IP - name: Get my public IP
ipify_facts: ipify_facts:
# Gather IP facts from your own ipify service endpoint with a custom timeout # Gather IP facts from your own ipify service endpoint with a custom timeout
- name: get my public IP - name: Get my public IP
ipify_facts: ipify_facts:
api_url: http://api.example.com/ipify api_url: http://api.example.com/ipify
timeout: 20 timeout: 20
''' '''
RETURN = ''' RETURN = r'''
--- ---
ipify_public_ip: ipify_public_ip:
description: Public IP of the internet gateway. description: Public IP of the internet gateway.
@ -97,7 +97,7 @@ def main():
global module global module
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
api_url=dict(default='https://api.ipify.org/'), api_url=dict(type='str', default='https://api.ipify.org/'),
timeout=dict(type='int', default=10), timeout=dict(type='int', default=10),
validate_certs=dict(type='bool', default=True), validate_certs=dict(type='bool', default=True),
), ),

@ -3,24 +3,21 @@
# Copyright: (c) 2016, Peter Sagerson <psagers@ignorare.net> # Copyright: (c) 2016, Peter Sagerson <psagers@ignorare.net>
# Copyright: (c) 2016, Jiri Tyr <jiri.tyr@gmail.com> # Copyright: (c) 2016, Jiri Tyr <jiri.tyr@gmail.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = { ANSIBLE_METADATA = {
'metadata_version': '1.1', 'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community' 'supported_by': 'community'
} }
DOCUMENTATION = r'''
DOCUMENTATION = """
--- ---
module: ldap_attr module: ldap_attr
short_description: Add or remove LDAP attribute values. short_description: Add or remove LDAP attribute values
description: description:
- Add or remove LDAP attribute values. - Add or remove LDAP attribute values.
notes: notes:
@ -47,28 +44,33 @@ options:
name: name:
description: description:
- The name of the attribute to modify. - The name of the attribute to modify.
type: str
required: true required: true
state: state:
description: description:
- The state of the attribute values. If C(present), all given - The state of the attribute values.
values will be added if they're missing. If C(absent), all given - If C(present), all given values will be added if they're missing.
values will be removed if present. If C(exact), the set of values - If C(absent), all given values will be removed if present.
will be forced to exactly those provided and no others. If - If C(exact), the set of values will be forced to exactly those provided and no others.
I(state=exact) and I(value) is an empty list, all values for this - If I(state=exact) and I(value) is an empty list, all values for this attribute will be removed.
attribute will be removed. choices: [ absent, exact, present ]
choices: [present, absent, exact]
default: present default: present
values: values:
description: description:
- The value(s) to add or remove. This can be a string or a list of - The value(s) to add or remove. This can be a string or a list of
strings. The complex argument format is required in order to pass strings. The complex argument format is required in order to pass
a list of strings (see examples). a list of strings (see examples).
type: raw
required: true required: true
extends_documentation_fragment: ldap.documentation params:
""" description:
- Additional module parameters.
type: dict
extends_documentation_fragment:
- ldap.documentation
'''
EXAMPLES = """ EXAMPLES = r'''
- name: Configure directory number 1 for example.com - name: Configure directory number 1 for example.com
ldap_attr: ldap_attr:
dn: olcDatabase={1}hdb,cn=config dn: olcDatabase={1}hdb,cn=config
@ -138,16 +140,15 @@ EXAMPLES = """
values: [] values: []
state: exact state: exact
params: "{{ ldap_auth }}" params: "{{ ldap_auth }}"
""" '''
RETURN = """ RETURN = r'''
modlist: modlist:
description: list of modified parameters description: list of modified parameters
returned: success returned: success
type: list type: list
sample: '[[2, "olcRootDN", ["cn=root,dc=example,dc=com"]]]' sample: '[[2, "olcRootDN", ["cn=root,dc=example,dc=com"]]]'
""" '''
import traceback import traceback
@ -237,12 +238,10 @@ class LdapAttr(LdapGeneric):
def main(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=gen_specs( argument_spec=gen_specs(
name=dict(required=True), name=dict(type='str', required=True),
params=dict(type='dict'), params=dict(type='dict'),
state=dict( state=dict(type='str', default='present', choices=['absent', 'exact', 'present']),
default='present', values=dict(type='raw', required=True),
choices=['present', 'absent', 'exact']),
values=dict(required=True, type='raw'),
), ),
supports_check_mode=True, supports_check_mode=True,
) )
@ -279,8 +278,7 @@ def main():
try: try:
ldap.connection.modify_s(ldap.dn, modlist) ldap.connection.modify_s(ldap.dn, modlist)
except Exception as e: except Exception as e:
module.fail_json(msg="Attribute action failed.", details=to_native(e), module.fail_json(msg="Attribute action failed.", details=to_native(e))
exception=traceback.format_exc())
module.exit_json(changed=changed, modlist=modlist) module.exit_json(changed=changed, modlist=modlist)

@ -1,104 +1,106 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# (c) 2016, Loic Blot <loic.blot@unix-experience.fr> # copyright: (c) 2016, Loic Blot <loic.blot@unix-experience.fr>
# Sponsored by Infopro Digital. http://www.infopro-digital.com/ # Sponsored by Infopro Digital. http://www.infopro-digital.com/
# Sponsored by E.T.A.I. http://www.etai.fr/ # Sponsored by E.T.A.I. http://www.etai.fr/
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = r'''
DOCUMENTATION = '''
--- ---
module: omapi_host module: omapi_host
short_description: Setup OMAPI hosts. short_description: Setup OMAPI hosts.
description: description: Manage OMAPI hosts into compatible DHCPd servers
- Create, update and remove OMAPI hosts into compatible DHCPd servers.
version_added: "2.3" version_added: "2.3"
requirements: requirements:
- pypureomapi - pypureomapi
author: "Loic Blot (@nerzhul)" author:
- Loic Blot (@nerzhul)
options: options:
state: state:
description: description:
- Create or remove OMAPI host. - Create or remove OMAPI host.
type: str
required: true required: true
choices: ['present', 'absent'] choices: [ absent, present ]
name: hostname:
description: description:
- Sets the host lease hostname (mandatory if state=present). - Sets the host lease hostname (mandatory if state=present).
type: str
aliases: [ name ]
host: host:
description: description:
- Sets OMAPI server host to interact with. - Sets OMAPI server host to interact with.
type: str
default: localhost default: localhost
port: port:
description: description:
- Sets the OMAPI server port to interact with. - Sets the OMAPI server port to interact with.
type: int
default: 7911 default: 7911
key_name: key_name:
description: description:
- Sets the TSIG key name for authenticating against OMAPI server. - Sets the TSIG key name for authenticating against OMAPI server.
type: str
required: true required: true
key: key:
description: description:
- Sets the TSIG key content for authenticating against OMAPI server. - Sets the TSIG key content for authenticating against OMAPI server.
type: str
required: true required: true
macaddr: macaddr:
description: description:
- Sets the lease host MAC address. - Sets the lease host MAC address.
type: str
required: true required: true
ip: ip:
description: description:
- Sets the lease host IP address. - Sets the lease host IP address.
type: str
statements: statements:
description: description:
- Attach a list of OMAPI DHCP statements with host lease (without ending semicolon). - Attach a list of OMAPI DHCP statements with host lease (without ending semicolon).
type: list
default: [] default: []
ddns: ddns:
description: description:
- Enable dynamic DNS updates for this host. - Enable dynamic DNS updates for this host.
type: bool type: bool
default: 'no' default: no
''' '''
EXAMPLES = ''' EXAMPLES = r'''
- name: Remove a host using OMAPI
omapi_host:
key_name: "defomapi"
key: "+bFQtBCta6j2vWkjPkNFtgA=="
host: "10.1.1.1"
macaddr: "00:66:ab:dd:11:44"
state: absent
- name: Add a host using OMAPI - name: Add a host using OMAPI
omapi_host: omapi_host:
key_name: "defomapi" key_name: defomapi
key: "+bFQtBCta6j2vWkjPkNFtgA==" key: +bFQtBCta6j2vWkjPkNFtgA==
host: "10.98.4.55" host: 10.98.4.55
macaddr: "44:dd:ab:dd:11:44" macaddr: 44:dd:ab:dd:11:44
name: "server01" name: server01
ip: "192.168.88.99" ip: 192.168.88.99
ddns: yes ddns: yes
statements: statements:
- 'filename "pxelinux.0"' - filename "pxelinux.0"
- 'next-server 1.1.1.1' - next-server 1.1.1.1
state: present state: present
- name: Remove a host using OMAPI
omapi_host:
key_name: defomapi
key: +bFQtBCta6j2vWkjPkNFtgA==
host: 10.1.1.1
macaddr: 00:66:ab:dd:11:44
state: absent
''' '''
RETURN = ''' RETURN = r'''
changed:
description: If module has modified a host
returned: success
type: str
lease: lease:
description: dictionary containing host information description: dictionary containing host information
returned: success returned: success
@ -212,8 +214,7 @@ class OmapiHostManager:
stmt_join += "; ".join(self.module.params['statements']) stmt_join += "; ".join(self.module.params['statements'])
stmt_join += "; " stmt_join += "; "
except TypeError as e: except TypeError as e:
self.module.fail_json(msg="Invalid statements found: %s" % to_native(e), self.module.fail_json(msg="Invalid statements found: %s" % to_native(e))
exception=traceback.format_exc())
if len(stmt_join) > 0: if len(stmt_join) > 0:
msg.obj.append(('statements', stmt_join)) msg.obj.append(('statements', stmt_join))
@ -225,7 +226,7 @@ class OmapiHostManager:
"are valid.") "are valid.")
self.module.exit_json(changed=True, lease=self.unpack_facts(response.obj)) self.module.exit_json(changed=True, lease=self.unpack_facts(response.obj))
except OmapiError as e: except OmapiError as e:
self.module.fail_json(msg="OMAPI error: %s" % to_native(e), exception=traceback.format_exc()) self.module.fail_json(msg="OMAPI error: %s" % to_native(e))
# Forge update message # Forge update message
else: else:
response_obj = self.unpack_facts(host_response.obj) response_obj = self.unpack_facts(host_response.obj)
@ -262,7 +263,7 @@ class OmapiHostManager:
"are valid.") "are valid.")
self.module.exit_json(changed=True) self.module.exit_json(changed=True)
except OmapiError as e: except OmapiError as e:
self.module.fail_json(msg="OMAPI error: %s" % to_native(e), exception=traceback.format_exc()) self.module.fail_json(msg="OMAPI error: %s" % to_native(e))
def remove_host(self): def remove_host(self):
try: try:
@ -271,24 +272,24 @@ class OmapiHostManager:
except OmapiErrorNotFound: except OmapiErrorNotFound:
self.module.exit_json() self.module.exit_json()
except OmapiError as e: except OmapiError as e:
self.module.fail_json(msg="OMAPI error: %s" % to_native(e), exception=traceback.format_exc()) self.module.fail_json(msg="OMAPI error: %s" % to_native(e))
def main(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
state=dict(required=True, type='str', choices=['present', 'absent']), state=dict(type='str', required=True, choices=['absent', 'present']),
host=dict(type='str', default="localhost"), host=dict(type='str', default="localhost"),
port=dict(type='int', default=7911), port=dict(type='int', default=7911),
key_name=dict(required=True, type='str', default=None), key_name=dict(type='str', required=True),
key=dict(required=True, type='str', default=None, no_log=True), key=dict(type='str', required=True, no_log=True),
macaddr=dict(required=True, type='str', default=None), macaddr=dict(type='str', required=True),
hostname=dict(type='str', default=None, aliases=['name']), hostname=dict(type='str', aliases=['name']),
ip=dict(type='str', default=None), ip=dict(type='str'),
ddns=dict(type='bool', default=False), ddns=dict(type='bool', default=False),
statements=dict(type='list', default=[]) statements=dict(type='list', default=[]),
), ),
supports_check_mode=False supports_check_mode=False,
) )
if not pureomapi_found: if not pureomapi_found:
@ -307,7 +308,7 @@ def main():
elif module.params['state'] == 'absent': elif module.params['state'] == 'absent':
host_manager.remove_host() host_manager.remove_host()
except ValueError as e: except ValueError as e:
module.fail_json(msg="OMAPI input value error: %s" % to_native(e), exception=traceback.format_exc()) module.fail_json(msg="OMAPI input value error: %s" % to_native(e))
if __name__ == '__main__': if __name__ == '__main__':

@ -1,4 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of Networklore's snmp library for Ansible # This file is part of Networklore's snmp library for Ansible
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@ -6,18 +7,17 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = r'''
DOCUMENTATION = '''
--- ---
module: snmp_facts module: snmp_facts
version_added: "1.9" version_added: "1.9"
author: "Patrick Ogenstad (@ogenstad)" author:
short_description: Retrieve facts for a device using SNMP. - Patrick Ogenstad (@ogenstad)
short_description: Retrieve facts for a device using SNMP
description: description:
- Retrieve facts for a device using SNMP, the facts will be - Retrieve facts for a device using SNMP, the facts will be
inserted to the ansible_facts key. inserted to the ansible_facts key.
@ -26,56 +26,64 @@ requirements:
options: options:
host: host:
description: description:
- Set to target snmp server (normally {{inventory_hostname}}) - Set to target snmp server (normally C({{ inventory_hostname }})).
type: str
required: true required: true
version: version:
description: description:
- SNMP Version to use, v2/v2c or v3 - SNMP Version to use, v2/v2c or v3.
choices: [ 'v2', 'v2c', 'v3' ] type: str
required: true required: true
choices: [ v2, v2c, v3 ]
community: community:
description: description:
- The SNMP community string, required if version is v2/v2c - The SNMP community string, required if version is v2/v2c.
required: false type: str
level: level:
description: description:
- Authentication level, required if version is v3 - Authentication level.
choices: [ 'authPriv', 'authNoPriv' ] - Required if version is v3.
required: false type: str
choices: [ authNoPriv, authPriv ]
username: username:
description: description:
- Username for SNMPv3, required if version is v3 - Username for SNMPv3.
required: false - Required if version is v3.
type: str
integrity: integrity:
description: description:
- Hashing algorithm, required if version is v3 - Hashing algorithm.
choices: [ 'md5', 'sha' ] - Required if version is v3.
required: false type: str
choices: [ md5, sha ]
authkey: authkey:
description: description:
- Authentication key, required if version is v3 - Authentication key.
required: false - Required if version is v3.
type: str
privacy: privacy:
description: description:
- Encryption algorithm, required if level is authPriv - Encryption algorithm.
choices: [ 'des', 'aes' ] - Required if level is authPriv.
required: false type: str
choices: [ aes, des ]
privkey: privkey:
description: description:
- Encryption key, required if version is authPriv - Encryption key.
required: false - Required if version is authPriv.
type: str
''' '''
EXAMPLES = ''' EXAMPLES = r'''
# Gather facts with SNMP version 2 - name: Gather facts with SNMP version 2
- snmp_facts: snmp_facts:
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
version: v2c version: v2c
community: public community: public
delegate_to: local delegate_to: local
# Gather facts using SNMP version 3 - name: Gather facts using SNMP version 3
- snmp_facts: snmp_facts:
host: '{{ inventory_hostname }}' host: '{{ inventory_hostname }}'
version: v3 version: v3
level: authPriv level: authPriv
@ -87,7 +95,7 @@ EXAMPLES = '''
delegate_to: localhost delegate_to: localhost
''' '''
RETURN = ''' RETURN = r'''
ansible_sysdescr: ansible_sysdescr:
description: A textual description of the entity. description: A textual description of the entity.
returned: success returned: success
@ -262,18 +270,22 @@ def lookup_operstatus(int_operstatus):
def main(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
host=dict(required=True), host=dict(type='str', required=True),
version=dict(required=True, choices=['v2', 'v2c', 'v3']), version=dict(type='str', required=True, choices=['v2', 'v2c', 'v3']),
community=dict(required=False, default=False), community=dict(type='str'),
username=dict(required=False), username=dict(type='str'),
level=dict(required=False, choices=['authNoPriv', 'authPriv']), level=dict(type='str', choices=['authNoPriv', 'authPriv']),
integrity=dict(required=False, choices=['md5', 'sha']), integrity=dict(type='str', choices=['md5', 'sha']),
privacy=dict(required=False, choices=['des', 'aes']), privacy=dict(type='str', choices=['aes', 'des']),
authkey=dict(required=False), authkey=dict(type='str'),
privkey=dict(required=False), privkey=dict(type='str'),
removeplaceholder=dict(required=False)), ),
required_together=(['username', 'level', 'integrity', 'authkey'], ['privacy', 'privkey'],), required_together=(
supports_check_mode=False) ['username', 'level', 'integrity', 'authkey'],
['privacy', 'privkey'],
),
supports_check_mode=False,
)
m_args = module.params m_args = module.params
@ -284,7 +296,7 @@ def main():
# Verify that we receive a community when using snmp v2 # Verify that we receive a community when using snmp v2
if m_args['version'] == "v2" or m_args['version'] == "v2c": if m_args['version'] == "v2" or m_args['version'] == "v2c":
if m_args['community'] is False: if m_args['community'] is None:
module.fail_json(msg='Community not set when using snmp version 2') module.fail_json(msg='Community not set when using snmp version 2')
if m_args['version'] == "v3": if m_args['version'] == "v3":

@ -437,24 +437,8 @@ lib/ansible/modules/monitoring/sensu_check.py E324
lib/ansible/modules/monitoring/sensu_client.py E324 lib/ansible/modules/monitoring/sensu_client.py E324
lib/ansible/modules/monitoring/sensu_handler.py E326 lib/ansible/modules/monitoring/sensu_handler.py E326
lib/ansible/modules/monitoring/zabbix/zabbix_maintenance.py E317 lib/ansible/modules/monitoring/zabbix/zabbix_maintenance.py E317
lib/ansible/modules/net_tools/basics/get_url.py E322
lib/ansible/modules/net_tools/basics/get_url.py E324
lib/ansible/modules/net_tools/basics/slurp.py E322
lib/ansible/modules/net_tools/basics/uri.py E322
lib/ansible/modules/net_tools/basics/uri.py E323 lib/ansible/modules/net_tools/basics/uri.py E323
lib/ansible/modules/net_tools/basics/uri.py E324
lib/ansible/modules/net_tools/basics/uri.py E326 lib/ansible/modules/net_tools/basics/uri.py E326
lib/ansible/modules/net_tools/cloudflare_dns.py E317
lib/ansible/modules/net_tools/cloudflare_dns.py E327
lib/ansible/modules/net_tools/haproxy.py E317
lib/ansible/modules/net_tools/haproxy.py E324
lib/ansible/modules/net_tools/infinity/infinity.py E326
lib/ansible/modules/net_tools/ipify_facts.py E324
lib/ansible/modules/net_tools/ldap/ldap_attr.py E322
lib/ansible/modules/net_tools/omapi_host.py E317
lib/ansible/modules/net_tools/omapi_host.py E322
lib/ansible/modules/net_tools/snmp_facts.py E322
lib/ansible/modules/net_tools/snmp_facts.py E324
lib/ansible/modules/network/a10/a10_server_axapi3.py E326 lib/ansible/modules/network/a10/a10_server_axapi3.py E326
lib/ansible/modules/network/a10/a10_virtual_server.py E324 lib/ansible/modules/network/a10/a10_virtual_server.py E324
lib/ansible/modules/network/aci/aci_epg_to_domain.py E325 lib/ansible/modules/network/aci/aci_epg_to_domain.py E325

Loading…
Cancel
Save