xref: /freebsd/libexec/nuageinit/tests/nuageinit.sh (revision 87b759f0fa1f7554d50ce640c40138512bbded44)
1#-
2# Copyright (c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6
7export NUAGE_FAKE_ROOTDIR="$PWD"
8
9atf_test_case args
10atf_test_case nocloud
11atf_test_case nocloud_userdata_script
12atf_test_case nocloud_user_data_script
13atf_test_case nocloud_userdata_cloudconfig_users
14atf_test_case nocloud_network
15atf_test_case config2
16atf_test_case config2_pubkeys
17atf_test_case config2_pubkeys_user_data
18atf_test_case config2_pubkeys_meta_data
19atf_test_case config2_network
20atf_test_case config2_network_static_v4
21
22args_body()
23{
24	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit
25	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla
26	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla meh plop
27	atf_check -s exit:1 -e inline:"nuageinit: Unknown cloud init type: meh\n" /usr/libexec/nuageinit bla meh
28}
29
30nocloud_body()
31{
32	mkdir -p media/nuageinit
33	atf_check -s exit:1 -e match:"nuageinit: error parsing nocloud.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit/ nocloud
34	printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > "${PWD}"/media/nuageinit/meta-data
35	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
36	atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
37	cat > media/nuageinit/meta-data << EOF
38instance-id: iid-local01
39hostname: myhost
40EOF
41	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
42	atf_check -o inline:"hostname=\"myhost\"\n" cat etc/rc.conf.d/hostname
43}
44
45nocloud_userdata_script_body()
46{
47	mkdir -p media/nuageinit
48	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
49	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user-data
50	chmod 755 "${PWD}"/media/nuageinit/user-data
51	atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
52}
53
54nocloud_user_data_script_body()
55{
56	mkdir -p media/nuageinit
57	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
58	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user_data
59	chmod 755 "${PWD}"/media/nuageinit/user_data
60	atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
61}
62
63nocloud_userdata_cloudconfig_users_head()
64{
65	atf_set "require.user" root
66}
67nocloud_userdata_cloudconfig_users_body()
68{
69	mkdir -p media/nuageinit
70	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
71	mkdir -p etc
72	cat > etc/master.passwd << EOF
73root:*:0:0::0:0:Charlie &:/root:/bin/sh
74sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
75EOF
76	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
77	cat > etc/group << EOF
78wheel:*:0:root
79users:*:1:
80EOF
81	cat > media/nuageinit/user-data << 'EOF'
82#cloud-config
83groups:
84  - admingroup: [root,sys]
85  - cloud-users
86users:
87  - default
88  - name: foobar
89    gecos: Foo B. Bar
90    primary_group: foobar
91    groups: users
92    passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
93EOF
94	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
95	cat > expectedgroup << EOF
96wheel:*:0:root,freebsd
97users:*:1:foobar
98admingroup:*:1001:root,sys
99cloud-users:*:1002:
100freebsd:*:1003:
101foobar:*:1004:
102EOF
103	cat > expectedpasswd << 'EOF'
104root:*:0:0::0:0:Charlie &:/root:/bin/sh
105sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
106freebsd:freebsd:1001:1003::0:0:FreeBSD User:/home/freebsd:/bin/sh
107foobar:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1002:1004::0:0:Foo B. Bar:/home/foobar:/bin/sh
108EOF
109	sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" "${PWD}"/etc/master.passwd
110	atf_check -o file:expectedpasswd cat "${PWD}"/etc/master.passwd
111	atf_check -o file:expectedgroup cat "${PWD}"/etc/group
112}
113
114nocloud_network_head()
115{
116	atf_set "require.user" root
117}
118nocloud_network_body()
119{
120	mkdir -p media/nuageinit
121	mkdir -p etc
122	cat > etc/master.passwd << EOF
123root:*:0:0::0:0:Charlie &:/root:/bin/sh
124sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
125EOF
126	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
127	cat > etc/group << EOF
128wheel:*:0:root
129users:*:1:
130EOF
131	mynetworks=$(ifconfig -l ether)
132	if [ -z "$mynetworks" ]; then
133		atf_skip "a network interface is needed"
134	fi
135	set -- $mynetworks
136	myiface=$1
137	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
138	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
139	cat > media/nuageinit/user-data << EOF
140#cloud-config
141network:
142  version: 2
143  ethernets:
144    # opaque ID for physical interfaces, only referred to by other stanzas
145    id0:
146      match:
147        macaddress: "$myaddr"
148      addresses:
149        - 192.0.2.2/24
150        - 2001:db8::2/64
151      gateway4: 192.0.2.1
152      gateway6: 2001:db8::1
153EOF
154	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
155	cat > network << EOF
156ifconfig_${myiface}="inet 192.0.2.2/24"
157ifconfig_${myiface}_ipv6="inet6 2001:db8::2/64"
158ipv6_network_interfaces="${myiface}"
159ipv6_default_interface="${myiface}"
160EOF
161	cat > routing << EOF
162defaultrouter="192.0.2.1"
163ipv6_defaultrouter="2001:db8::1"
164ipv6_route_${myiface}="2001:db8::1 -prefixlen 128 -interface ${myiface}"
165EOF
166	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
167	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
168}
169
170config2_body()
171{
172	mkdir -p media/nuageinit
173	atf_check -s exit:1 -e match:"nuageinit: error parsing config-2 meta_data.json:.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
174	printf "{}" > media/nuageinit/meta_data.json
175	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
176	cat > media/nuageinit/meta_data.json << EOF
177{
178    "hostname": "cloudimg"
179}
180EOF
181	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
182	atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
183}
184
185config2_pubkeys_head()
186{
187	atf_set "require.user" root
188}
189config2_pubkeys_body()
190{
191	mkdir -p media/nuageinit
192	touch media/nuageinit/meta_data.json
193	cat > media/nuageinit/user-data << EOF
194#cloud-config
195ssh_authorized_keys:
196  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
197EOF
198	mkdir -p etc
199	cat > etc/master.passwd << EOF
200root:*:0:0::0:0:Charlie &:/root:/bin/sh
201sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
202EOF
203	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
204	cat > etc/group << EOF
205wheel:*:0:root
206users:*:1:
207EOF
208	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
209	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
210}
211
212config2_pubkeys_user_data_head()
213{
214	atf_set "require.user" root
215}
216config2_pubkeys_user_data_body()
217{
218	mkdir -p media/nuageinit
219	touch media/nuageinit/meta_data.json
220	cat > media/nuageinit/user_data << EOF
221#cloud-config
222ssh_authorized_keys:
223  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
224EOF
225	mkdir -p etc
226	cat > etc/master.passwd << EOF
227root:*:0:0::0:0:Charlie &:/root:/bin/sh
228sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
229EOF
230	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
231	cat > etc/group << EOF
232wheel:*:0:root
233users:*:1:
234EOF
235	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
236	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
237}
238
239config2_pubkeys_meta_data_body()
240{
241	here=$(pwd)
242	export NUAGE_FAKE_ROOTDIR=$(pwd)
243	if [ $(id -u) -ne 0 ]; then
244		atf_skip "root required"
245	fi
246	mkdir -p media/nuageinit
247	cat > media/nuageinit/meta_data.json << EOF
248{
249    "uuid": "uuid_for_this_instance",
250    "admin_pass": "a_generated_password",
251    "public_keys": {
252        "tdb": "ssh-ed25519 my_key_id tdb@host"
253    },
254    "keys": [
255        {
256            "name": "tdb",
257            "type": "ssh",
258            "data": "ssh-ed25519 my_key_id tdb@host"
259        }
260    ],
261    "hostname": "freebsd-14-test.novalocal",
262    "name": "freebsd-14-test",
263    "launch_index": 0,
264    "availability_zone": "nova",
265    "random_seed": "long_random_seed",
266    "project_id": "my_project_id",
267    "devices": [],
268    "dedicated_cpus": []
269}
270EOF
271	mkdir -p etc
272	cat > etc/master.passwd << EOF
273root:*:0:0::0:0:Charlie &:/root:/bin/csh
274sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
275EOF
276	pwd_mkdb -d etc ${here}/etc/master.passwd
277	cat > etc/group << EOF
278wheel:*:0:root
279users:*:1:
280EOF
281	atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2
282	atf_check -o inline:"ssh-ed25519 my_key_id tdb@host\n" cat home/freebsd/.ssh/authorized_keys
283}
284
285config2_network_body()
286{
287	mkdir -p media/nuageinit
288	printf "{}" > media/nuageinit/meta_data.json
289	mynetworks=$(ifconfig -l ether)
290	if [ -z "$mynetworks" ]; then
291		atf_skip "a network interface is needed"
292	fi
293	set -- $mynetworks
294	myiface=$1
295	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
296cat > media/nuageinit/network_data.json << EOF
297{
298    "links": [
299        {
300            "ethernet_mac_address": "$myaddr",
301            "id": "iface0",
302            "mtu": null
303        }
304    ],
305    "networks": [
306        {
307            "id": "network0",
308            "link": "iface0",
309            "type": "ipv4_dhcp"
310        },
311        { // IPv6
312            "id": "private-ipv4",
313            "type": "ipv6",
314            "link": "iface0",
315            // supports condensed IPv6 with CIDR netmask
316            "ip_address": "2001:db8::3257:9652/64",
317            "gateway": "fd00::1",
318            "routes": [
319                {
320                    "network": "::",
321                    "netmask": "::",
322                    "gateway": "fd00::1"
323                },
324                {
325                    "network": "::",
326                    "netmask": "ffff:ffff:ffff::",
327                    "gateway": "fd00::1:1"
328                }
329            ],
330            "network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d8"
331        }
332    ]
333}
334EOF
335	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
336	cat > network << EOF
337ifconfig_${myiface}="DHCP"
338ifconfig_${myiface}_ipv6="inet6 2001:db8::3257:9652/64"
339ipv6_network_interfaces="${myiface}"
340ipv6_default_interface="${myiface}"
341EOF
342	cat > routing << EOF
343ipv6_defaultrouter="fd00::1"
344ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}"
345ipv6_static_routes="${myiface}"
346EOF
347	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
348	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
349}
350
351config2_network_static_v4_body()
352{
353	mkdir -p media/nuageinit
354	printf "{}" > media/nuageinit/meta_data.json
355	mynetworks=$(ifconfig -l ether)
356	if [ -z "$mynetworks" ]; then
357		atf_skip "a network interface is needed"
358	fi
359	set -- $mynetworks
360	myiface=$1
361	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
362cat > media/nuageinit/network_data.json << EOF
363{
364    "links": [
365        {
366            "ethernet_mac_address": "$myaddr",
367            "id": "iface0",
368            "mtu": null
369        }
370    ],
371    "networks": [
372        {
373            "id": "network0",
374            "link": "iface0",
375            "type": "ipv4",
376            "ip_address": "10.184.0.244",
377            "netmask": "255.255.240.0",
378            "routes": [
379                {
380                    "network": "10.0.0.0",
381                    "netmask": "255.0.0.0",
382                    "gateway": "11.0.0.1"
383                },
384                {
385                    "network": "0.0.0.0",
386                    "netmask": "0.0.0.0",
387                    "gateway": "23.253.157.1"
388                }
389            ]
390        }
391    ]
392}
393EOF
394	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
395	cat > network << EOF
396ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0"
397EOF
398	cat > routing << EOF
399route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0"
400defaultrouter="23.253.157.1"
401static_routes="cloudinit1_${myiface}"
402EOF
403	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
404	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
405}
406
407atf_init_test_cases()
408{
409	atf_add_test_case args
410	atf_add_test_case nocloud
411	atf_add_test_case nocloud_userdata_script
412	atf_add_test_case nocloud_user_data_script
413	atf_add_test_case nocloud_userdata_cloudconfig_users
414	atf_add_test_case nocloud_network
415	atf_add_test_case config2
416	atf_add_test_case config2_pubkeys
417	atf_add_test_case config2_pubkeys_user_data
418	atf_add_test_case config2_pubkeys_meta_data
419	atf_add_test_case config2_network
420	atf_add_test_case config2_network_static_v4
421}
422