Skip to content

Commit 119cfd6

Browse files
authored
Test admin endpoint (#198)
* Add tests for admin endpoint and fix bugs * Patch DNSSEC enabled zones in the admin API * Fix double inet start for metrics
1 parent 7c92180 commit 119cfd6

6 files changed

+377
-39
lines changed

priv/zones-example.json

+66
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,71 @@
103103
}
104104
}
105105
]
106+
},
107+
{
108+
"name": "example-dnssec0.com",
109+
"records": [
110+
{
111+
"name": "example-dnssec0.com",
112+
"type": "SOA",
113+
"data": {
114+
"mname": "ns1.example-dnssec0.com",
115+
"rname": "ahu.example-dnssec0.com",
116+
"serial": 2000081501,
117+
"refresh": 28800,
118+
"retry": 7200,
119+
"expire": 604800,
120+
"minimum": 86400
121+
},
122+
"ttl": 100000
123+
},
124+
{
125+
"name": "example-dnssec0.com",
126+
"type": "CDS",
127+
"ttl": 120,
128+
"data": {
129+
"alg": 0,
130+
"digest": "00",
131+
"digest_type": 0,
132+
"keytag": 0
133+
}
134+
},
135+
{
136+
"name": "example-dnssec0.com",
137+
"type": "CDNSKEY",
138+
"ttl": 120,
139+
"data": {
140+
"flags": 0,
141+
"protocol": 3,
142+
"alg": 0,
143+
"public_key": "AA==",
144+
"key_tag": 0
145+
}
146+
},
147+
{
148+
"name": "example-dnssec0.com",
149+
"type": "DNSKEY",
150+
"ttl": 120,
151+
"data": {
152+
"flags": 257,
153+
"protocol": 3,
154+
"alg": 8,
155+
"public_key": "MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgQCn9Iv82vkFiv8ts8K9jzUzfp3UEZx+76r+X9A4GOFfYbx3USChEW0fLYT/QkAM8/SiTkEXzZPqhrV083mp5VLYNLxic2ii6DrwvyGpENVPJnDQMu+CfKMyb9IWcm9MkeHh8t/ovsCQAEJWIPTnzv8rlQcDU44c3qgTpHSU8htjdwICBAE=",
156+
"key_tag": 0
157+
}
158+
}
159+
],
160+
"keys": [
161+
{
162+
"ksk": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCn9Iv82vkFiv8ts8K9jzUzfp3UEZx+76r+X9A4GOFfYbx3USCh\nEW0fLYT/QkAM8/SiTkEXzZPqhrV083mp5VLYNLxic2ii6DrwvyGpENVPJnDQMu+C\nfKMyb9IWcm9MkeHh8t/ovsCQAEJWIPTnzv8rlQcDU44c3qgTpHSU8htjdwICBAEC\ngYEAlpYTHWYrcd0HQXO3F9lPqwwfHUt7VBaSEUYrk3N3ZYCWvmV1qyKbB/kb1SBs\n4GfW1vP966HXCffnX92LDXYxi7It3TJaKmo8aF/leN7w8WLNJXUayEoQKUfKLprj\nN14Jx/tgMu7I/BOoHId8b7e57pBKtDiSF6WWn3K7tNPbfmkCQQDST41m62mC4MAa\nDsUdyM0Vg/tjduGqnygryCDEXDabdg95a3wMk0SQCQzZFHGNYnsXcffTqGs/y+5w\nQWxyOGSNAkEAzHFkDJla30NiiKvhu7dY+0+dGrfMA7pNUh+LGdXe5QFdjwwxqPbF\n7NMGXKMdB8agSCxGZC3bxdvYNF9LULzhEwJABpDYNSoQx+UMvaEN5XTpLmCHuS1r\nsmhfKZPcDx8Z7mAYda3wZEuHQq+cf6i5XhOO9P5QKpKeslHLAMHa7NaNgQJBAI03\nGGacYLwui32fbzb8BYRg82Kga/OW6btY+O6hNs6iSR2gBlQ9j3Tgrzo+N4R/NQSl\nc05wGO2RnBUwlu0XUckCQHfHsWHVrrADTpalbv+FTDyWd0ouHXBmDecVZh3e7/ue\ncdMoblzeasvgp8CjFa9U+uDozY+aL6TNIpG++nn4lNw=\n-----END RSA PRIVATE KEY-----\n",
163+
"ksk_keytag": 37440,
164+
"ksk_alg": 8,
165+
"zsk": "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAK8YnU+YqBxD/EDwVeHZsJillAJ80PCnLU+/rlGrlzgw+eabF8jT\nCaEwnpE74YHCLegKAAn+efeZrT/EBBrzlacCAgIBAkBh9VGFW2SJk1I9SBQaDIA9\nchdrrx+PHibSyozwT4eAPmd6OFoLausc7ls6v9evPeb+Yj3g0JXvTGp6BgNhFqLR\nAiEA1+ievAEBVM6IlOmpiTwlaWe/HV6MokBBq1G/tvJS0M8CIQDPm/DUsoTEv/Jj\n6O3U9hNcPLbvKMMGld2wbf7nrQmzqQIhAJrhwTaFdjnXhmfUB9a33vRIbSaIsLxA\nDyuM+03XP+YhAiEAmJIJz7WX9uPkCIy8wO655Hh4dt4UkBFRE98OqkHIwGkCIFFv\nN8rJojI+oEiJyNjEjWZD4qoUMUp3+YBl0htAJUE2\n-----END RSA PRIVATE KEY-----\n",
166+
"zsk_keytag": 49016,
167+
"zsk_alg": 8,
168+
"inception": "2016-11-14T11:36:58.851612Z",
169+
"until": "2017-02-12T11:36:58.849384Z"
170+
}
171+
]
106172
}
107173
]

src/admin/erldns_admin.erl

+7-7
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ start(#{port := Port, username := Username, password := Password}) ->
7777
{'_', [
7878
{"/", erldns_admin_root_handler, State},
7979
{"/zones/:zone_name", erldns_admin_zone_resource_handler, State},
80-
{"/zones/:zone_name/:action", erldns_admin_zone_control_handler, State},
81-
{"/zones/:zone_name/records[/:record_name]", erldns_admin_zone_records_resource_handler, State}
80+
{"/zones/:zone_name/records[/:record_name]", erldns_admin_zone_records_resource_handler, State},
81+
{"/zones/:zone_name/:action", erldns_admin_zone_control_handler, State}
8282
]}
8383
]
8484
),
@@ -93,8 +93,8 @@ start(#{port := Port, username := Username, password := Password}) ->
9393
is_authorized(Req, #{username := ValidUsername, password := ValidPassword} = State) ->
9494
maybe
9595
{basic, GivenUsername, GivenPassword} ?= cowboy_req:parse_header(<<"authorization">>, Req),
96-
true ?= is_binary_of_equal_size(GivenUsername),
97-
true ?= is_binary_of_equal_size(GivenPassword),
96+
true ?= is_binary_of_equal_size(GivenUsername, ValidUsername),
97+
true ?= is_binary_of_equal_size(GivenPassword, ValidPassword),
9898
true ?= crypto:hash_equals(GivenUsername, ValidUsername) andalso
9999
crypto:hash_equals(GivenPassword, ValidPassword),
100100
{true, Req, State}
@@ -103,9 +103,9 @@ is_authorized(Req, #{username := ValidUsername, password := ValidPassword} = Sta
103103
{{false, <<"Basic realm=\"erldns admin\"">>}, Req, State}
104104
end.
105105

106-
-spec is_binary_of_equal_size(term()) -> boolean().
107-
is_binary_of_equal_size(Bin) ->
108-
is_binary(Bin) andalso byte_size(Bin) =:= byte_size(Bin).
106+
-spec is_binary_of_equal_size(term(), term()) -> boolean().
107+
is_binary_of_equal_size(Bin1, Bin2) ->
108+
is_binary(Bin1) andalso is_binary(Bin2) andalso byte_size(Bin1) =:= byte_size(Bin2).
109109

110110
-spec ensure_valid_config() -> false | disabled | config().
111111
ensure_valid_config() ->

src/admin/erldns_admin_zone_records_resource_handler.erl

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ to_text(Req, State) ->
8080
{stop | cowboy_req:resp_body(), cowboy_req:req(), erldns_admin:handler_state()}.
8181
to_json(Req, State) ->
8282
ZoneName = cowboy_req:binding(zone_name, Req),
83-
RecordName = cowboy_req:binding(record_name, Req, <<"">>),
83+
RecordName = cowboy_req:binding(record_name, Req, <<>>),
8484
Params = cowboy_req:parse_qs(Req),
8585
case lists:keyfind(<<"type">>, 1, Params) of
8686
false ->

src/erldns_zone_encoder.erl

+32-30
Original file line numberDiff line numberDiff line change
@@ -171,53 +171,53 @@ encode_record(Record, Encoders) ->
171171
EncodedRecord
172172
end.
173173

174-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_SOA, Ttl, Data}) ->
174+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_SOA, ttl = Ttl, data = Data}) ->
175175
encode_record(Name, Type, Ttl, Data);
176-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_NS, Ttl, Data}) ->
176+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_NS, ttl = Ttl, data = Data}) ->
177177
encode_record(Name, Type, Ttl, Data);
178-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_A, Ttl, Data}) ->
178+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_A, ttl = Ttl, data = Data}) ->
179179
encode_record(Name, Type, Ttl, Data);
180-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_AAAA, Ttl, Data}) ->
180+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_AAAA, ttl = Ttl, data = Data}) ->
181181
encode_record(Name, Type, Ttl, Data);
182-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_CNAME, Ttl, Data}) ->
182+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_CNAME, ttl = Ttl, data = Data}) ->
183183
encode_record(Name, Type, Ttl, Data);
184-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_MX, Ttl, Data}) ->
184+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_MX, ttl = Ttl, data = Data}) ->
185185
encode_record(Name, Type, Ttl, Data);
186-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_HINFO, Ttl, Data}) ->
186+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_HINFO, ttl = Ttl, data = Data}) ->
187187
encode_record(Name, Type, Ttl, Data);
188-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_TXT, Ttl, Data}) ->
188+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_TXT, ttl = Ttl, data = Data}) ->
189189
encode_record(Name, Type, Ttl, Data);
190-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_SPF, Ttl, Data}) ->
190+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_SPF, ttl = Ttl, data = Data}) ->
191191
encode_record(Name, Type, Ttl, Data);
192-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_SSHFP, Ttl, Data}) ->
192+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_SSHFP, ttl = Ttl, data = Data}) ->
193193
encode_record(Name, Type, Ttl, Data);
194-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_SRV, Ttl, Data}) ->
194+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_SRV, ttl = Ttl, data = Data}) ->
195195
encode_record(Name, Type, Ttl, Data);
196-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_NAPTR, Ttl, Data}) ->
196+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_NAPTR, ttl = Ttl, data = Data}) ->
197197
encode_record(Name, Type, Ttl, Data);
198-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_CAA, Ttl, Data}) ->
198+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_CAA, ttl = Ttl, data = Data}) ->
199199
encode_record(Name, Type, Ttl, Data);
200-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_DS, Ttl, Data}) ->
200+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_DS, ttl = Ttl, data = Data}) ->
201201
encode_record(Name, Type, Ttl, Data);
202-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_CDS, Ttl, Data}) ->
202+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_CDS, ttl = Ttl, data = Data}) ->
203203
encode_record(Name, Type, Ttl, Data);
204-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_DNSKEY, Ttl, Data}) ->
204+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_DNSKEY, ttl = Ttl, data = Data}) ->
205205
encode_record(Name, Type, Ttl, Data);
206-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_CDNSKEY, Ttl, Data}) ->
206+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_CDNSKEY, ttl = Ttl, data = Data}) ->
207207
encode_record(Name, Type, Ttl, Data);
208-
encode_record({dns_rr, Name, _, Type = ?DNS_TYPE_RRSIG, Ttl, Data}) ->
208+
encode_record(#dns_rr{name = Name, type = Type = ?DNS_TYPE_RRSIG, ttl = Ttl, data = Data}) ->
209209
encode_record(Name, Type, Ttl, Data);
210210
encode_record(Record) ->
211211
lager:warning("Unable to encode record (record: ~p)", [Record]),
212212
[].
213213

214214
encode_record(Name, Type, Ttl, Data) ->
215-
[
216-
{<<"name">>, erlang:iolist_to_binary(io_lib:format("~s.", [Name]))},
217-
{<<"type">>, dns:type_name(Type)},
218-
{<<"ttl">>, Ttl},
219-
{<<"content">>, encode_data(Data)}
220-
].
215+
#{
216+
<<"name">> => erlang:iolist_to_binary(io_lib:format("~s.", [Name])),
217+
<<"type">> => dns:type_name(Type),
218+
<<"ttl">> => Ttl,
219+
<<"content">> => encode_data(Data)
220+
}.
221221

222222
try_custom_encoders(_Record, []) ->
223223
{};
@@ -262,14 +262,16 @@ encode_data({dns_rrdata_ds, Keytag, Alg, DigestType, Digest}) ->
262262
encode_data({dns_rrdata_cds, Keytag, Alg, DigestType, Digest}) ->
263263
erlang:iolist_to_binary(io_lib:format("~w ~w ~w ~s", [Keytag, Alg, DigestType, Digest]));
264264
encode_data({dns_rrdata_dnskey, Flags, Protocol, Alg, Key, KeyTag}) ->
265-
erlang:iolist_to_binary(io_lib:format("~w ~w ~w ~w ~w", [Flags, Protocol, Alg, Key, KeyTag]));
265+
binary:encode_hex(erlang:iolist_to_binary(io_lib:format("~w ~w ~w ~w ~w", [Flags, Protocol, Alg, Key, KeyTag])));
266266
encode_data({dns_rrdata_cdnskey, Flags, Protocol, Alg, Key, KeyTag}) ->
267-
erlang:iolist_to_binary(io_lib:format("~w ~w ~w ~w ~w", [Flags, Protocol, Alg, Key, KeyTag]));
267+
binary:encode_hex(erlang:iolist_to_binary(io_lib:format("~w ~w ~w ~w ~w", [Flags, Protocol, Alg, Key, KeyTag])));
268268
encode_data({dns_rrdata_rrsig, TypeCovered, Alg, Labels, OriginalTtl, Expiration, Inception, KeyTag, SignersName, Signature}) ->
269-
erlang:iolist_to_binary(
270-
io_lib:format(
271-
"~w ~w ~w ~w ~w ~w ~w ~w ~s",
272-
[TypeCovered, Alg, Labels, OriginalTtl, Expiration, Inception, KeyTag, SignersName, Signature]
269+
binary:encode_hex(
270+
erlang:iolist_to_binary(
271+
io_lib:format(
272+
"~w ~w ~w ~w ~w ~w ~w ~w ~s",
273+
[TypeCovered, Alg, Labels, OriginalTtl, Expiration, Inception, KeyTag, SignersName, Signature]
274+
)
273275
)
274276
);
275277
encode_data(Data) ->

src/metrics/erldns_metrics.erl

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ start(#{port := Port}) ->
6363
]}
6464
]
6565
),
66-
TransportOpts = #{socket_opts => [inet, inet6, {ip, {0, 0, 0, 0}}, {port, Port}]},
66+
TransportOpts = #{socket_opts => [inet, inet6, {ip, any}, {port, Port}]},
6767
ProtocolOpts = #{env => #{dispatch => Dispatch}},
6868
cowboy:start_clear(?MODULE, TransportOpts, ProtocolOpts).
6969

0 commit comments

Comments
 (0)