TypeCodes

脚本自动切换博客图片域名在阿里云的DNS解析

自从七牛开放了自定义SSL证书服务后,博主就通过CNAME方式把博客图片对应的域名cdn.typecodes.com解析到了七牛,然后把Let's Encrypt申请的SSL证书上传到七牛服务器。

但是Let's Encrypt的证书有效期只有3个月,所以到期后需要先把域名重新解析到原来的主机服务器,然后重新申请证书。申请通过后再把域名解析到七牛,同时上传并启用新SSL证书。

1 阿里云DNS相关

博客根域名是在阿里云购买的,所以用的DNS解析服务也是阿里云的。目前整个阿里云控制台的相关功能都可以通过在RAM访问控制申请用户AccessKey和AccessKeySecret后调用相关的API实现。

阿里云开放的API接口对应的SDK库已经在GitHub了,对应的python版本地址是: https://github.com/aliyun/aliyun-openapi-python-sdk

2 要实现的功能

根据业务需求,博客在申请Let's Encrypt证书时,需要使用A方式把cdn.typecodes.com解析到主机服务器(111.231.246.29)。

当证书申请通过后,需要使用CNAME方式把cdn.typecodes.com解析到七牛云存储服务器(cdn.typecodes.com.qiniudns.com)。

3 实现程序

根据阿里云的SDK python版本的说明,下面是具体的实现程序。最后传入的参数1表示把域名解析到七牛,其它值则表示把域名解析到原主机服务器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/python
# -*- coding: UTF-8 -*-

# FileName:      aliyun_dns_modify.py
# (c) 2019.6.1 vfhky https://typecodes.com/python/aliyundnsanalysis1.html
# https://github.com/vfhky/shell-tools/blob/master/dns/aliyun_dns_modify.py
# 脚本功能:修改 cdn.typecodes.com 在阿里云DNS的解析(七牛和源主机之间的切换)。
# 使用方法: python aliyun_dns_modify.py cdn 1/2
#
# 必须安装的核心包:             pip install aliyun-python-sdk-core
# 根据功能选装dns相关的包:       pip install aliyun-python-sdk-alidns

import sys
import json
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest


# constant statics.
aliyun_accesskey = "key"
aliyun_accesskeysecret = "secret"
domain_pre = "cdn"
# must be the root domain other than the second or third level domain.
domain = "typecodes.com"
# the dns record type which is defined 1 meaning qiniu defaultly.
record_type = 1
# qiniu.
qiniu_cname = ("CNAME", "cdn.typecodes.com.qiniudns.com")
# host ip.
original_host = ("A", "111.231.246.29")


# create aliyun api object.
client = AcsClient(
  aliyun_accesskey,
  aliyun_accesskeysecret
);


if __name__ == '__main__':
    if len(sys.argv) == 3:
        domain_pre = sys.argv[1]
        record_type = int(sys.argv[2])
    else:
        print("==== usage: python %s %s %d ====" % (sys.argv[0], domain_pre, record_type) )
        sys.exit(1)

    # first step: call aliyun api to get dns record lists.
    try:
        # domain act.
        request = DescribeDomainRecordsRequest()
        request.set_accept_format('json')
        request.set_DomainName( domain )
        response = client.do_action_with_exception(request)
    except ServerException as srv_ex:
    # if response.has_key('Code') or response.has_key('Message'):
        print("Error: Code=[%s] Message=[%s], exit." % (srv_ex.error_code, srv_ex.message) )
        sys.exit(1)
    except:
        print( "unexcepted error, exit." )
        sys.exit(1)

    # parse response:
    data = json.loads(response)
    record = data["DomainRecords"]["Record"];

    # recrucive all dns record and find the RecordId of target pre-domain.
    for single_record in record:
        if ( single_record["RR"] == domain_pre ):
            print( "==== get domain=[%s] RR=[%s] RecordId=[%s] Type=[%s] Value=[%s]." % (domain, single_record["RR"], single_record["RecordId"], single_record["Type"], single_record["Value"] ) )
            # second step: call aliyun api to update the target record.
            request = UpdateDomainRecordRequest()
            request.set_accept_format('json')
            request.set_RR( domain_pre )
            request.set_RecordId( single_record["RecordId"] )

            if record_type == 1:
                request.set_Type( qiniu_cname[0] )
                request.set_Value( qiniu_cname[1] )
            else:
                request.set_Type( original_host[0] )
                request.set_Value( original_host[1] )

            try:
                response = client.do_action_with_exception(request)
            except ServerException as srv_ex:
            # if response.has_key('Code') or response.has_key('Message'):
                print("Error: Code=[%s] Message=[%s], exit." % (srv_ex.error_code, srv_ex.message) )
                sys.exit(1)
            except:
                print( "unexcepted error, exit." )
                sys.exit(1)

            print("==== success.")
        else:
            continue

4 执行效果

执行python aliyun_dns_modify.py cdn 2将域名DNS解析到原主机。

执行python aliyun_dns_modify.py cdn 1将域名DNS解析到七牛。

在阿里云的域名解析日志上可以看到效果,如下图所示:

阿里云DNS的解析记录

5 脚本管理

目前已经把这个脚本放在Github了,地址是https://github.com/vfhky/shell-tools,以后脚本的更新或者更多好用的脚本也都会加入到这个工程中。

6 其它说明

阿里云相关的API是可以在线调试的,非常方便!例如,查看所有的DNS解析记录可以点这里进入调试。

打赏支持

Comments »