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
# See https://doc.powerdns.com/authoritative/backends/geoip.html
{%- set slave_instance_list = json_module.loads(slapparameter_dict.get('extra_slave_instance_list', '[]')) %}
{%- set zone = slapparameter_dict.get('zone', 'example.com') %}
{%- macro disambiguate_domain_name(a, b) %}
{#- See http://www.dns-sd.org/trailingdotsindomainnames.html #}
{%- if a.endswith('.') %}
{{- a[:-1] }}
{%- else %}
{{- a }}.{{ b }}
{%- endif %}
{%- endmacro %}
domains:
- domain: {{ zone }}
# TODO: what value for ttl?
ttl: 300
# Note: For each domain, one record of the domain name MUST exist with a soa record.
records:
{{ zone }}:
- soa: {{ slapparameter_dict.get('soa', 'ns0.example.com,admin@example.com').replace(',', ' ') }}
{%- for ns in slapparameter_dict.get('ns-record', 'ns0.example.com,ns1.example.com').split(',') %}
- ns: {{ ns }}
{%- endfor %}
{#- Split the world the way we prefer. 'GeoLite2-Country.mmdb' divides the
world into 7 continents: Oceania, Asia, Europe, South America,
North America, Africa and Antarctica. However, we also want a more
fine-grained division for Asia, i.e. West/East, China, Hong-Kong and
Japan. #}
{%- set world_split = {
"continent": {
"eu": "europe",
"af": "africa",
"sa": "south-america",
"na": "north-america",
"oc": "oceania",
},
"country": {}} %}
{%- for region, codes in asia.items() %}
{%- for country_code in codes.split() %}
{%- do world_split["country"].__setitem__(country_code, region) %}
{%- endfor %}
{%- endfor %}
{%- for slave in slave_instance_list %}
{#- Set the RR to use for each region, as described in
'slave-instance-powerdns-input-schema.json' #}
{%- set rr_dict = {} %}
{%- for region, default_rr in {"europe": "eu",
"africa": "af",
"south-america": "sa",
"north-america": "na",
"china-telecom": "cn-t",
"china-unicom": "cn-u",
"china-mobile": "cn-m",
"japan": "jp",
"hong-kong": "hk",
"east-asia": "as",
"west-asia": "eu",
"oceania": "oc"}.items() %}
{%- do rr_dict.__setitem__(region, slave.get(region, default_rr)) %}
{%- endfor %}
{#- 'code2region' maps an ISO3166 country/continent code (i.e. the client
origin) to a geographical region. The latter is then used to find the
right RR (thanks to 'rr_dict') #}
{%- for placeholder, code2region in world_split.items() %}
{%- for code, region in code2region.items() %}
{%- set origin = slave['origin'] %}
{{ code }}.{{ placeholder }}.{{ origin }}:
- cname: {{ disambiguate_domain_name(rr_dict[region], origin) }}
{%- endfor %}
{%- endfor %}
{%- endfor %}
services:
{%- for slave in slave_instance_list %}
{%- set origin = slave['origin'] %}
{{ disambiguate_domain_name(slave['record'], zone) }}:
{#- Note: Placeholders (i.e. "country." and "continent.") are used to avoid
possible name collisions, e.g.:
- %cc for American Samoa is 'as'
- %cn for Asia is also 'as' #}
default: ['%cc.country.{{ origin }}', '%cn.continent.{{ origin }}', '{{ disambiguate_domain_name(slave['default'], origin) }}']
# Split China's ip addresses according to ISP
{%- for ip_range, country_code in china %}
{{ ip_range }}: {{ country_code }}.country.{{ origin }}
{%- endfor %}
{%- endfor %}