domain_modify 6.23 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: "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()