domain_modify 7.22 KB
#!/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: "www.yohotest.xyz,*.yohotest.xyz"
        value: "1.2.3.4"

    - name: "修改域名对应的CNAME"
      domain_modify:
        secretId: "{{ qcloud_key.SecretId }}"
        secretKey: "{{ qcloud_key.SecretKey }}"
        domain_name: "2.yohotest.xyz"
        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 = {}
    URLS_DNS = 'cns.api.qcloud.com/v2/index.php'
    # 通过传入的域名来获取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"
    if recordType == "CNAME":
        if not value.endswith('.'):
            value += '.'
    # 通过调用域名解析接口RecordList来获取待修改的域名解析记录值(调用修改域名解析接口时必须要传入的参数值)
    try:
        domaininfo_query = QcloudApi(secretId=SecretId,secretKey=SecretKey)
        domaininfo = domaininfo_query.do_query(params={'Action': 'RecordList','domain': domain },req_url=URLS_DNS)
        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["value"] = value
                    ret["recordType_old"] = lines["type"]
                    ret["recordType_new"] = recordType
                    ret["recordLine"] = lines["line"]
                    ret["ttl"] = lines["ttl"]
                    #ret["mx"] = lines["mx"]
                    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,ttl):
    ret = {}
    URLS_DNS = 'cns.api.qcloud.com/v2/index.php'
    # 调用域名解析接口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,'ttl':ttl},req_url=URLS_DNS)
        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'].strip()

    domain_name_list = domain_name.split(',')

    rets = {}
    message_list = []
    for domain_name in domain_name_list: 
        domain_name = domain_name.strip()
        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)

        messages = {"需修改解析的DNS":domain_name ,"修改之前的解析地址":ret["value_old"],"修改之前的记录类型":ret["recordType_old"],"修改之后的解析地址":ret["value"] ,"修改之后的记录类型":ret["recordType_new"]}
        message_list.append(messages)
        result['message'] = message_list

        if ret["value_old"] == ret["value"]:
            module.fail_json(msg='Modify Failed: 修改的解析与原解析一致', **result)
        
        rets[domain_name] = ret
        # check模式下只执行查询接口 执行语句:ansible-playbook playbooks/domain.modify.yml -e '{"domain_name":"www.yohotest.xyz","new_record":"1.2.3.4"}' --check -vvv

    if module.check_mode:
        #result['response'] = ret
        module.exit_json(**result)
    # 非check模式下执行修改接口 执行语句:ansible-playbook playbooks/domain.modify.yml -e '{"domain_name":"www.yohotest.xyz","new_record":"1.2.3.4"}'
    else:
        for domain_name in domain_name_list:
            domain_name = domain_name.strip()
            value = rets[domain_name]["value"]
            subDomain = rets[domain_name]["subDomain"]
            domain = rets[domain_name]["domain"]
            recordType = rets[domain_name]["recordType_new"]
            recordId = rets[domain_name]["recordId"]
            recordLine = rets[domain_name]["recordLine"]
            ttl = rets[domain_name]["ttl"]
            modify_result = dns_modify(secretId,secretKey,domain_name,value,subDomain,domain,recordType,recordId,recordLine,ttl)
            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()