|
|
#!/usr/bin/env python
|
|
|
# -*- coding: UTF-8 -*-
|
|
|
# ansible module for domain modify
|
|
|
ANSIBLE_METADATA = {
|
|
|
'metadata_version': '1.0',
|
|
|
'status': ['preview'],
|
|
|
'supported_by': 'hua.qu@yoho.cn'
|
|
|
}
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
|
---
|
|
|
module: domain_modify
|
|
|
short_description: 修改域名解析
|
|
|
'''
|
|
|
|
|
|
EXAMPLES = '''
|
|
|
|
|
|
- hosts: 127.0.0.1
|
|
|
tasks:
|
|
|
- name: "修改域名对应的IP"
|
|
|
domain_modify:
|
|
|
secretId: "{{ qcloud_key.SecretId }}"
|
|
|
secretKey: "{{ qcloud_key.SecretKey }}"
|
|
|
domain_name: "switch.test.yohops.com"
|
|
|
value: "1.2.3.4"
|
|
|
|
|
|
- name: "修改域名对应的CNAME"
|
|
|
domain_modify:
|
|
|
secretId: "{{ qcloud_key.SecretId }}"
|
|
|
secretKey: "{{ qcloud_key.SecretKey }}"
|
|
|
domain_name: "switch.test.yohops.com"
|
|
|
value: "cname.dnspod.com."
|
|
|
|
|
|
'''
|
|
|
|
|
|
from ansible.module_utils.basic import *
|
|
|
from ansible.module_utils.qcloud_api import QcloudApi
|
|
|
import json
|
|
|
import sys
|
|
|
reload(sys)
|
|
|
sys.setdefaultencoding('utf8')
|
|
|
|
|
|
'''
|
|
|
通过调用接口RecordList获取待修改的域名解析记录列表
|
|
|
'''
|
|
|
def dns_inqure(SecretId,SecretKey,domain_name,value):
|
|
|
ret = {}
|
|
|
# 通过传入的域名参数简单判断域名格式是否正确
|
|
|
domain_regex = re.compile(r'(?:[A-Z0-9_](?:[A-Z0-9-_]{0,247}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?<!-))\Z',re.IGNORECASE)
|
|
|
if not domain_regex.match(domain_name):
|
|
|
ret["code"] = 2
|
|
|
ret["err"] = "域名格式不对"
|
|
|
return ret
|
|
|
# 通过传入的域名来获取domain和subDomain值
|
|
|
domain = '.'.join(domain_name.split('.')[-2:])
|
|
|
subDomain = '.'.join(domain_name.split('.')[:-2])
|
|
|
# Comment: 目前仅支持IP和CNAME的修改
|
|
|
pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')
|
|
|
recordType = "A" if pattern.match(value) else "CNAME"
|
|
|
# 通过调用域名解析接口RecordList来获取待修改的域名解析记录值(调用修改域名解析接口时必须要传入的参数值)
|
|
|
try:
|
|
|
domaininfo_query = QcloudApi(secretId=SecretId,secretKey=SecretKey)
|
|
|
domaininfo = domaininfo_query.do_query(params={'Action': 'RecordList','domain': domain })
|
|
|
if domaininfo["code"] == 0:
|
|
|
domaininfo = domaininfo["data"]["records"]
|
|
|
# 循环获取到的domain下的所有域名解析值,提取待修改的域名对应的所有的参数值,子域名, 当解析值匹配时ret["code"] = 0
|
|
|
for lines in domaininfo:
|
|
|
if subDomain == lines["name"]:
|
|
|
ret["recordId"] = lines["id"]
|
|
|
ret["subDomain"] = subDomain
|
|
|
ret["domain"] = domain
|
|
|
ret["value_old"] = lines["value"]
|
|
|
ret["recordType_old"] = lines["type"]
|
|
|
ret["recordType_new"] = recordType
|
|
|
ret["recordLine"] = lines["line"]
|
|
|
ret["code"] = 0
|
|
|
break
|
|
|
else:
|
|
|
ret["code"] = 1
|
|
|
else:
|
|
|
ret["code"] = domaininfo["code"]
|
|
|
ret["err"] = domaininfo["message"]
|
|
|
except Exception,e:
|
|
|
ret["code"] = 500
|
|
|
ret["err"] = e.message
|
|
|
# 给子域名不存在情况下加错误信息
|
|
|
if ret["code"] == 1:
|
|
|
ret["err"] = "子域名subDomain: %s 不存在"%subDomain
|
|
|
#elif ret["code"] == 5100:
|
|
|
# ret["err"] = "domain: %s 不存在"%domain
|
|
|
return ret
|
|
|
'''
|
|
|
通过调用接口RecordModify修改域名解析记录
|
|
|
'''
|
|
|
def dns_modify(SecretId,SecretKey,domain_name,value,subDomain,domain,recordType,recordId,recordLine):
|
|
|
ret = {}
|
|
|
# 调用域名解析接口RecordModify修改域名解析记录
|
|
|
try:
|
|
|
domain_modify_api = QcloudApi(secretId=SecretId,secretKey=SecretKey)
|
|
|
dns_info = domain_modify_api.do_query(params={'Action':'RecordModify','domain':domain,'recordId':recordId,'subDomain':subDomain,'recordType':recordType,'recordLine':recordLine,'value':value})
|
|
|
ret["code"] = dns_info["code"]
|
|
|
ret["err"] = dns_info['message']
|
|
|
except Exception,e:
|
|
|
ret["code"] = 500
|
|
|
ret["err"] = e.message
|
|
|
return ret
|
|
|
|
|
|
def run_module():
|
|
|
|
|
|
# 定义参数
|
|
|
module_args = dict(
|
|
|
secretId=dict(type='str', required=True),
|
|
|
secretKey=dict(type='str', required=True),
|
|
|
domain_name=dict(type='str', required=True),
|
|
|
value=dict(type='str', required=True),
|
|
|
)
|
|
|
|
|
|
# seed the result dict in the object
|
|
|
# we primarily care about changed and state
|
|
|
# change is if this module effectively modified the target
|
|
|
# state will include any data that you want your module to pass back
|
|
|
# for consumption, for example, in a subsequent task
|
|
|
result = dict(
|
|
|
changed=False,
|
|
|
original_message='',
|
|
|
message=''
|
|
|
)
|
|
|
|
|
|
module = AnsibleModule(
|
|
|
argument_spec=module_args,
|
|
|
supports_check_mode=True
|
|
|
)
|
|
|
|
|
|
secretId = module.params['secretId']
|
|
|
secretKey = module.params['secretKey']
|
|
|
domain_name = module.params['domain_name']
|
|
|
value = module.params['value']
|
|
|
|
|
|
ret = dns_inqure(secretId,secretKey,domain_name,value)
|
|
|
if ret['code'] != 0:
|
|
|
module.fail_json(msg='查询失败: code: %s err: %s' % (ret["code"],ret['err']), **result)
|
|
|
|
|
|
result['message'] = {"需修改解析的DNS":domain_name ,"修改之前的解析地址":ret["value_old"],"修改之前的记录类型":ret["recordType_old"],"修改之后的解析地址":value ,"修改之后的记录类型":ret["recordType_new"]}
|
|
|
if ret["value_old"] == value:
|
|
|
module.fail_json(msg='Modify Failed: 修改的解析与原解析一致', **result)
|
|
|
|
|
|
# check模式下只执行查询接口 执行语句:ansible-playbook playbooks/domain.modify.yml --check -vvv
|
|
|
if module.check_mode:
|
|
|
#result['response'] = ret
|
|
|
module.exit_json(**result)
|
|
|
# 非check模式下执行修改接口 执行语句:ansible-playbook playbooks/domain.modify.yml
|
|
|
else:
|
|
|
modify_result = dns_modify(secretId,secretKey,domain_name, value,ret["subDomain"],ret["domain"],ret["recordType_new"],ret["recordId"],ret["recordLine"])
|
|
|
if modify_result['code'] != 0:
|
|
|
module.fail_json(msg='Modify Failed: code: %i, err: %s' % (modify_result['code'], modify_result['err']), **result)
|
|
|
result['changed'] = True
|
|
|
#result['response'] = modify_result
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
def main():
|
|
|
run_module()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
main()
|
|
|
|
...
|
...
|
|