1{ lib, pkgs, ... }:
2let
3 hosts = ''
4 192.168.2.101 example.com
5 192.168.2.101 api.example.com
6 192.168.2.101 backend.example.com
7 '';
8
9in
10{
11 name = "angie-api";
12 meta.maintainers = with pkgs.lib.maintainers; [ izorkin ];
13
14 nodes = {
15 server =
16 { pkgs, ... }:
17 {
18 networking = {
19 interfaces.eth1 = {
20 ipv4.addresses = [
21 {
22 address = "192.168.2.101";
23 prefixLength = 24;
24 }
25 ];
26 };
27 extraHosts = hosts;
28 firewall.allowedTCPPorts = [ 80 ];
29 };
30
31 services.nginx = {
32 enable = true;
33 package = pkgs.angie;
34
35 upstreams = {
36 "backend-http" = {
37 servers = {
38 "backend.example.com:8080" = {
39 fail_timeout = "0";
40 };
41 };
42 extraConfig = ''
43 zone upstream 256k;
44 '';
45 };
46 "backend-socket" = {
47 servers = {
48 "unix:/run/example.sock" = {
49 fail_timeout = "0";
50 };
51 };
52 extraConfig = ''
53 zone upstream 256k;
54 '';
55 };
56 };
57
58 virtualHosts."api.example.com" = {
59 locations."/console/" = {
60 extraConfig = ''
61 api /status/;
62
63 allow 192.168.2.201;
64 deny all;
65 '';
66 };
67 };
68
69 virtualHosts."example.com" = {
70 locations."/test/" = {
71 root = lib.mkForce (
72 pkgs.runCommandLocal "testdir" { } ''
73 mkdir -p "$out/test"
74 cat > "$out/test/index.html" <<EOF
75 <html><body>Hello World!</body></html>
76 EOF
77 ''
78 );
79 extraConfig = ''
80 status_zone test_zone;
81
82 allow 192.168.2.201;
83 deny all;
84 '';
85 };
86 locations."/test/locked/" = {
87 extraConfig = ''
88 status_zone test_zone;
89
90 deny all;
91 '';
92 };
93 locations."/test/error/" = {
94 extraConfig = ''
95 status_zone test_zone;
96
97 allow all;
98 '';
99 };
100 locations."/upstream-http/" = {
101 proxyPass = "http://backend-http";
102 };
103 locations."/upstream-socket/" = {
104 proxyPass = "http://backend-socket";
105 };
106 };
107 };
108 };
109
110 client =
111 { pkgs, ... }:
112 {
113 environment.systemPackages = [ pkgs.jq ];
114 networking = {
115 interfaces.eth1 = {
116 ipv4.addresses = [
117 {
118 address = "192.168.2.201";
119 prefixLength = 24;
120 }
121 ];
122 };
123 extraHosts = hosts;
124 };
125 };
126 };
127
128 testScript = ''
129 start_all()
130
131 server.wait_for_unit("nginx")
132 server.wait_for_open_port(80)
133
134 # Check Angie version
135 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.angie.version' | grep '${pkgs.angie.version}'")
136
137 # Check access
138 client.succeed("curl --verbose --head http://api.example.com/console/ | grep 'HTTP/1.1 200'")
139 server.succeed("curl --verbose --head http://api.example.com/console/ | grep 'HTTP/1.1 403 Forbidden'")
140
141 # Check responses and requests
142 client.succeed("curl --verbose http://example.com/test/")
143 client.succeed("curl --verbose http://example.com/test/locked/")
144 client.succeed("curl --verbose http://example.com/test/locked/")
145 client.succeed("curl --verbose http://example.com/test/error/")
146 client.succeed("curl --verbose http://example.com/test/error/")
147 client.succeed("curl --verbose http://example.com/test/error/")
148 server.succeed("curl --verbose http://example.com/test/")
149 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.location_zones.test_zone.responses.\"200\"' | grep '1'")
150 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.location_zones.test_zone.responses.\"403\"' | grep '3'")
151 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.location_zones.test_zone.responses.\"404\"' | grep '3'")
152 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.location_zones.test_zone.requests.total' | grep '7'")
153
154 # Check upstreams
155 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.upstreams.\"backend-http\".peers.\"192.168.2.101:8080\".state' | grep 'up'")
156 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.upstreams.\"backend-http\".peers.\"192.168.2.101:8080\".health.fails' | grep '0'")
157 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.upstreams.\"backend-socket\".peers.\"unix:/run/example.sock\".state' | grep 'up'")
158 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.upstreams.\"backend-socket\".peers.\"unix:/run/example.sock\".health.fails' | grep '0'")
159 client.succeed("curl --verbose http://example.com/upstream-http/")
160 client.succeed("curl --verbose http://example.com/upstream-socket/")
161 client.succeed("curl --verbose http://example.com/upstream-socket/")
162 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.upstreams.\"backend-http\".peers.\"192.168.2.101:8080\".health.fails' | grep '1'")
163 client.succeed("curl --verbose http://api.example.com/console/ | jq -e '.http.upstreams.\"backend-socket\".peers.\"unix:/run/example.sock\".health.fails' | grep '2'")
164
165 server.shutdown()
166 client.shutdown()
167 '';
168}