mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-01 04:30:22 -07:00
made subcategories for cloud modules for better organization
This commit is contained in:
parent
bb9433f198
commit
32e85c0944
68 changed files with 0 additions and 0 deletions
281
lib/ansible/modules/cloud/amazon/route53.py
Normal file
281
lib/ansible/modules/cloud/amazon/route53.py
Normal file
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/python
|
||||
# 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: route53
|
||||
version_added: "1.3"
|
||||
short_description: add or delete entries in Amazons Route53 DNS service
|
||||
description:
|
||||
- Creates and deletes DNS records in Amazons Route53 service
|
||||
options:
|
||||
command:
|
||||
description:
|
||||
- Specifies the action to take.
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
choices: [ 'get', 'create', 'delete' ]
|
||||
zone:
|
||||
description:
|
||||
- The DNS zone to modify
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
record:
|
||||
description:
|
||||
- The full DNS record to create or delete
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
ttl:
|
||||
description:
|
||||
- The TTL to give the new record
|
||||
required: false
|
||||
default: 3600 (one hour)
|
||||
aliases: []
|
||||
type:
|
||||
description:
|
||||
- The type of DNS record to create
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
choices: [ 'A', 'CNAME', 'MX', 'AAAA', 'TXT', 'PTR', 'SRV', 'SPF', 'NS' ]
|
||||
value:
|
||||
description:
|
||||
- The new value when creating a DNS record. Multiple comma-spaced values are allowed. When deleting a record all values for the record must be specified or Route53 will not delete it.
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
aws_secret_key:
|
||||
description:
|
||||
- AWS secret key.
|
||||
required: false
|
||||
default: null
|
||||
aliases: ['ec2_secret_key', 'secret_key']
|
||||
aws_access_key:
|
||||
description:
|
||||
- AWS access key.
|
||||
required: false
|
||||
default: null
|
||||
aliases: ['ec2_access_key', 'access_key']
|
||||
overwrite:
|
||||
description:
|
||||
- Whether an existing record should be overwritten on create if values do not match
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
retry_interval:
|
||||
description:
|
||||
- In the case that route53 is still servicing a prior request, this module will wait and try again after this many seconds. If you have many domain names, the default of 500 seconds may be too long.
|
||||
required: false
|
||||
default: 500
|
||||
aliases: []
|
||||
requirements: [ "boto" ]
|
||||
author: Bruce Pennypacker
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Add new.foo.com as an A record with 3 IPs
|
||||
- route53: >
|
||||
command=create
|
||||
zone=foo.com
|
||||
record=new.foo.com
|
||||
type=A
|
||||
ttl=7200
|
||||
value=1.1.1.1,2.2.2.2,3.3.3.3
|
||||
|
||||
# Retrieve the details for new.foo.com
|
||||
- route53: >
|
||||
command=get
|
||||
zone=foo.com
|
||||
record=new.foo.com
|
||||
type=A
|
||||
register: rec
|
||||
|
||||
# Delete new.foo.com A record using the results from the get command
|
||||
- route53: >
|
||||
command=delete
|
||||
zone=foo.com
|
||||
record={{ rec.set.record }}
|
||||
type={{ rec.set.type }}
|
||||
value={{ rec.set.value }}
|
||||
|
||||
# Add an AAAA record. Note that because there are colons in the value
|
||||
# that the entire parameter list must be quoted:
|
||||
- route53: >
|
||||
command=create
|
||||
zone=foo.com
|
||||
record=localhost.foo.com
|
||||
type=AAAA
|
||||
ttl=7200
|
||||
value="::1"
|
||||
|
||||
# Add a TXT record. Note that TXT and SPF records must be surrounded
|
||||
# by quotes when sent to Route 53:
|
||||
- route53: >
|
||||
command=create
|
||||
zone=foo.com
|
||||
record=localhost.foo.com
|
||||
type=TXT
|
||||
ttl=7200
|
||||
value="\"bar\""
|
||||
|
||||
|
||||
'''
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
||||
try:
|
||||
import boto
|
||||
from boto import route53
|
||||
from boto.route53.record import ResourceRecordSets
|
||||
except ImportError:
|
||||
print "failed=True msg='boto required for this module'"
|
||||
sys.exit(1)
|
||||
|
||||
def commit(changes, retry_interval):
|
||||
"""Commit changes, but retry PriorRequestNotComplete errors."""
|
||||
retry = 10
|
||||
while True:
|
||||
try:
|
||||
retry -= 1
|
||||
return changes.commit()
|
||||
except boto.route53.exception.DNSServerError, e:
|
||||
code = e.body.split("<Code>")[1]
|
||||
code = code.split("</Code>")[0]
|
||||
if code != 'PriorRequestNotComplete' or retry < 0:
|
||||
raise e
|
||||
time.sleep(retry_interval)
|
||||
|
||||
def main():
|
||||
argument_spec = ec2_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
command = dict(choices=['get', 'create', 'delete'], required=True),
|
||||
zone = dict(required=True),
|
||||
record = dict(required=True),
|
||||
ttl = dict(required=False, default=3600),
|
||||
type = dict(choices=['A', 'CNAME', 'MX', 'AAAA', 'TXT', 'PTR', 'SRV', 'SPF', 'NS'], required=True),
|
||||
value = dict(required=False),
|
||||
overwrite = dict(required=False, type='bool'),
|
||||
retry_interval = dict(required=False, default=500)
|
||||
)
|
||||
)
|
||||
module = AnsibleModule(argument_spec=argument_spec)
|
||||
|
||||
command_in = module.params.get('command')
|
||||
zone_in = module.params.get('zone')
|
||||
ttl_in = module.params.get('ttl')
|
||||
record_in = module.params.get('record')
|
||||
type_in = module.params.get('type')
|
||||
value_in = module.params.get('value')
|
||||
retry_interval_in = module.params.get('retry_interval')
|
||||
|
||||
ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module)
|
||||
|
||||
value_list = ()
|
||||
|
||||
if type(value_in) is str:
|
||||
if value_in:
|
||||
value_list = sorted(value_in.split(','))
|
||||
elif type(value_in) is list:
|
||||
value_list = sorted(value_in)
|
||||
|
||||
if zone_in[-1:] != '.':
|
||||
zone_in += "."
|
||||
|
||||
if record_in[-1:] != '.':
|
||||
record_in += "."
|
||||
|
||||
if command_in == 'create' or command_in == 'delete':
|
||||
if not value_in:
|
||||
module.fail_json(msg = "parameter 'value' required for create/delete")
|
||||
|
||||
# connect to the route53 endpoint
|
||||
try:
|
||||
conn = boto.route53.connection.Route53Connection(aws_access_key, aws_secret_key)
|
||||
except boto.exception.BotoServerError, e:
|
||||
module.fail_json(msg = e.error_message)
|
||||
|
||||
# Get all the existing hosted zones and save their ID's
|
||||
zones = {}
|
||||
results = conn.get_all_hosted_zones()
|
||||
for r53zone in results['ListHostedZonesResponse']['HostedZones']:
|
||||
zone_id = r53zone['Id'].replace('/hostedzone/', '')
|
||||
zones[r53zone['Name']] = zone_id
|
||||
|
||||
# Verify that the requested zone is already defined in Route53
|
||||
if not zone_in in zones:
|
||||
errmsg = "Zone %s does not exist in Route53" % zone_in
|
||||
module.fail_json(msg = errmsg)
|
||||
|
||||
record = {}
|
||||
|
||||
found_record = False
|
||||
sets = conn.get_all_rrsets(zones[zone_in])
|
||||
for rset in sets:
|
||||
# Due to a bug in either AWS or Boto, "special" characters are returned as octals, preventing round
|
||||
# tripping of things like * and @.
|
||||
decoded_name = rset.name.replace(r'\052', '*')
|
||||
decoded_name = decoded_name.replace(r'\100', '@')
|
||||
|
||||
if rset.type == type_in and decoded_name == record_in:
|
||||
found_record = True
|
||||
record['zone'] = zone_in
|
||||
record['type'] = rset.type
|
||||
record['record'] = decoded_name
|
||||
record['ttl'] = rset.ttl
|
||||
record['value'] = ','.join(sorted(rset.resource_records))
|
||||
record['values'] = sorted(rset.resource_records)
|
||||
if value_list == sorted(rset.resource_records) and int(record['ttl']) == ttl_in and command_in == 'create':
|
||||
module.exit_json(changed=False)
|
||||
|
||||
if command_in == 'get':
|
||||
module.exit_json(changed=False, set=record)
|
||||
|
||||
if command_in == 'delete' and not found_record:
|
||||
module.exit_json(changed=False)
|
||||
|
||||
changes = ResourceRecordSets(conn, zones[zone_in])
|
||||
|
||||
if command_in == 'create' and found_record:
|
||||
if not module.params['overwrite']:
|
||||
module.fail_json(msg = "Record already exists with different value. Set 'overwrite' to replace it")
|
||||
else:
|
||||
change = changes.add_change("DELETE", record_in, type_in, record['ttl'])
|
||||
for v in record['values']:
|
||||
change.add_value(v)
|
||||
|
||||
if command_in == 'create' or command_in == 'delete':
|
||||
change = changes.add_change(command_in.upper(), record_in, type_in, ttl_in)
|
||||
for v in value_list:
|
||||
change.add_value(v)
|
||||
|
||||
try:
|
||||
result = commit(changes, retry_interval_in)
|
||||
except boto.route53.exception.DNSServerError, e:
|
||||
txt = e.body.split("<Message>")[1]
|
||||
txt = txt.split("</Message>")[0]
|
||||
module.fail_json(msg = txt)
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.ec2 import *
|
||||
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue