xref: /freebsd/libexec/nuageinit/tests/nuageinit.sh (revision 8b70a203be10411c560ed303ab25713d70b316e9)
1#-
2# Copyright (c) 2022-2025 Baptiste Daroussin <bapt@FreeBSD.org>
3# Copyright (c) 2025 Jesús Daniel Colmenares Oviedo <dtxdf@FreeBSD.org>
4#
5# SPDX-License-Identifier: BSD-2-Clause
6#
7
8export NUAGE_FAKE_ROOTDIR="$PWD"
9
10atf_test_case args
11atf_test_case nocloud
12atf_test_case nocloud_userdata_script
13atf_test_case nocloud_user_data_script
14atf_test_case nocloud_userdata_cloudconfig_users
15atf_test_case nocloud_network
16atf_test_case config2
17atf_test_case config2_pubkeys
18atf_test_case config2_pubkeys_user_data
19atf_test_case config2_pubkeys_meta_data
20atf_test_case config2_network
21atf_test_case config2_network_static_v4
22atf_test_case config2_ssh_keys
23atf_test_case nocloud_userdata_cloudconfig_ssh_pwauth
24atf_test_case nocloud_userdata_cloudconfig_chpasswd
25atf_test_case nocloud_userdata_cloudconfig_chpasswd_list_string
26atf_test_case nocloud_userdata_cloudconfig_chpasswd_list_list
27atf_test_case config2_userdata_runcmd
28atf_test_case config2_userdata_packages
29atf_test_case config2_userdata_update_packages
30atf_test_case config2_userdata_upgrade_packages
31atf_test_case config2_userdata_shebang
32atf_test_case config2_userdata_fqdn_and_hostname
33atf_test_case config2_userdata_write_files
34
35setup_test_adduser()
36{
37	here=$(pwd)
38	export NUAGE_FAKE_ROOTDIR=$(pwd)
39	mkdir -p etc/ssh
40	cat > etc/master.passwd << EOF
41root:*:0:0::0:0:Charlie &:/root:/bin/csh
42sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
43EOF
44	pwd_mkdb -d etc ${here}/etc/master.passwd
45	cat > etc/group << EOF
46wheel:*:0:root
47users:*:1:
48EOF
49}
50
51args_body()
52{
53	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit
54	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla
55	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla meh plop
56	atf_check -s exit:1 -e inline:"nuageinit: Unknown cloud init type: meh\n" /usr/libexec/nuageinit bla meh
57}
58
59nocloud_body()
60{
61	mkdir -p media/nuageinit
62	setup_test_adduser
63	atf_check -s exit:1 -e match:"nuageinit: error parsing nocloud.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit/ nocloud
64	printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > "${PWD}"/media/nuageinit/meta-data
65	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
66	atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
67	cat > media/nuageinit/meta-data << EOF
68instance-id: iid-local01
69hostname: myhost
70EOF
71	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
72	atf_check -o inline:"hostname=\"myhost\"\n" cat etc/rc.conf.d/hostname
73}
74
75nocloud_userdata_script_body()
76{
77	mkdir -p media/nuageinit
78	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
79	# ensure this is an invalid when parsed with the yaml parser
80	printf "#!/bin/sh\n: ${test:-yes}\necho $test\n" > "${PWD}"/media/nuageinit/user-data
81	chmod 644 "${PWD}"/media/nuageinit/user-data
82	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
83	atf_check test -x var/cache/nuageinit/user_data
84	atf_check -o inline:"#!/bin/sh\n: ${test:-yes}\necho $test\n" cat var/cache/nuageinit/user_data
85}
86
87nocloud_user_data_script_body()
88{
89	mkdir -p media/nuageinit
90	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
91	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user_data
92	chmod 755 "${PWD}"/media/nuageinit/user_data
93	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
94	atf_check -o inline:"#!/bin/sh\necho yeah\n" cat var/cache/nuageinit/user_data
95}
96
97nocloud_userdata_cloudconfig_users_head()
98{
99	atf_set "require.user" root
100}
101nocloud_userdata_cloudconfig_users_body()
102{
103	mkdir -p media/nuageinit
104	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
105	mkdir -p etc
106	cat > etc/master.passwd << EOF
107root:*:0:0::0:0:Charlie &:/root:/bin/sh
108sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
109EOF
110	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
111	cat > etc/group << EOF
112wheel:*:0:root
113users:*:1:
114EOF
115	cat > media/nuageinit/user-data << 'EOF'
116#cloud-config
117groups:
118  - admingroup: [root,sys]
119  - cloud-users
120users:
121  - default
122  - name: foobar
123    gecos: Foo B. Bar
124    primary_group: foobar
125    sudo: ALL=(ALL) NOPASSWD:ALL
126    doas: permit persist %u as root
127    groups: users
128    passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
129  - name: bla
130    sudo:
131    - "ALL=(ALL) NOPASSWD:/usr/sbin/pw"
132    - "ALL=(ALL) ALL"
133    doas:
134    - "deny %u as foobar"
135    - "permit persist %u as root cmd whoami"
136EOF
137	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
138	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
139	cat > expectedgroup << EOF
140wheel:*:0:root,freebsd
141users:*:1:foobar
142admingroup:*:1001:root,sys
143cloud-users:*:1002:
144freebsd:*:1003:
145foobar:*:1004:
146bla:*:1005:
147EOF
148	cat > expectedpasswd << 'EOF'
149root:*:0:0::0:0:Charlie &:/root:/bin/sh
150sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
151freebsd:freebsd:1001:1003::0:0:FreeBSD User:/home/freebsd:/bin/sh
152foobar:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1002:1004::0:0:Foo B. Bar:/home/foobar:/bin/sh
153bla::1003:1005::0:0:bla User:/home/bla:/bin/sh
154EOF
155	sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" "${PWD}"/etc/master.passwd
156	atf_check -o file:expectedpasswd cat "${PWD}"/etc/master.passwd
157	atf_check -o file:expectedgroup cat "${PWD}"/etc/group
158	localbase=`sysctl -ni user.localbase 2> /dev/null`
159	if [ -z "${localbase}" ]; then
160		# fallback
161		localbase="/usr/local"
162	fi
163	atf_check -o inline:"foobar ALL=(ALL) NOPASSWD:ALL\nbla ALL=(ALL) NOPASSWD:/usr/sbin/pw\nbla ALL=(ALL) ALL\n" cat "${PWD}/${localbase}/etc/sudoers.d/90-nuageinit-users"
164	atf_check -o inline:"permit persist foobar as root\ndeny bla as foobar\npermit persist bla as root cmd whoami\n" cat "${PWD}/${localbase}/etc/doas.conf"
165}
166
167nocloud_network_head()
168{
169	atf_set "require.user" root
170}
171nocloud_network_body()
172{
173	mkdir -p media/nuageinit
174	mkdir -p etc
175	cat > etc/master.passwd << EOF
176root:*:0:0::0:0:Charlie &:/root:/bin/sh
177sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
178EOF
179	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
180	cat > etc/group << EOF
181wheel:*:0:root
182users:*:1:
183EOF
184	mynetworks=$(ifconfig -l ether)
185	if [ -z "$mynetworks" ]; then
186		atf_skip "a network interface is needed"
187	fi
188	set -- $mynetworks
189	myiface=$1
190	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
191	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
192	cat > media/nuageinit/user-data << EOF
193#cloud-config
194network:
195  version: 2
196  ethernets:
197    # opaque ID for physical interfaces, only referred to by other stanzas
198    id0:
199      match:
200        macaddress: "$myaddr"
201      addresses:
202        - 192.0.2.2/24
203        - 2001:db8::2/64
204      gateway4: 192.0.2.1
205      gateway6: 2001:db8::1
206EOF
207	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
208	cat > network << EOF
209ifconfig_${myiface}="inet 192.0.2.2/24"
210ifconfig_${myiface}_ipv6="inet6 2001:db8::2/64"
211ipv6_network_interfaces="${myiface}"
212ipv6_default_interface="${myiface}"
213EOF
214	cat > routing << EOF
215defaultrouter="192.0.2.1"
216ipv6_defaultrouter="2001:db8::1"
217ipv6_route_${myiface}="2001:db8::1 -prefixlen 128 -interface ${myiface}"
218EOF
219	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
220	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
221}
222
223config2_body()
224{
225	mkdir -p media/nuageinit
226	setup_test_adduser
227	atf_check -s exit:1 -e match:"nuageinit: error parsing config-2 meta_data.json:.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
228	printf "{}" > media/nuageinit/meta_data.json
229	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
230	cat > media/nuageinit/meta_data.json << EOF
231{
232    "hostname": "cloudimg"
233}
234EOF
235	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
236	atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
237}
238
239config2_pubkeys_head()
240{
241	atf_set "require.user" root
242}
243config2_pubkeys_body()
244{
245	mkdir -p media/nuageinit
246	touch media/nuageinit/meta_data.json
247	cat > media/nuageinit/user-data << EOF
248#cloud-config
249ssh_authorized_keys:
250  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
251EOF
252	mkdir -p etc
253	cat > etc/master.passwd << EOF
254root:*:0:0::0:0:Charlie &:/root:/bin/sh
255sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
256EOF
257	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
258	cat > etc/group << EOF
259wheel:*:0:root
260users:*:1:
261EOF
262	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
263	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
264}
265
266config2_pubkeys_user_data_head()
267{
268	atf_set "require.user" root
269}
270config2_pubkeys_user_data_body()
271{
272	mkdir -p media/nuageinit
273	touch media/nuageinit/meta_data.json
274	cat > media/nuageinit/user_data << EOF
275#cloud-config
276ssh_authorized_keys:
277  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
278EOF
279	mkdir -p etc
280	cat > etc/master.passwd << EOF
281root:*:0:0::0:0:Charlie &:/root:/bin/sh
282sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
283EOF
284	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
285	cat > etc/group << EOF
286wheel:*:0:root
287users:*:1:
288EOF
289	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
290	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
291}
292
293config2_pubkeys_meta_data_body()
294{
295	here=$(pwd)
296	export NUAGE_FAKE_ROOTDIR=$(pwd)
297	if [ $(id -u) -ne 0 ]; then
298		atf_skip "root required"
299	fi
300	mkdir -p media/nuageinit
301	cat > media/nuageinit/meta_data.json << EOF
302{
303    "uuid": "uuid_for_this_instance",
304    "admin_pass": "a_generated_password",
305    "public_keys": {
306        "tdb": "ssh-ed25519 my_key_id tdb@host"
307    },
308    "keys": [
309        {
310            "name": "tdb",
311            "type": "ssh",
312            "data": "ssh-ed25519 my_key_id tdb@host"
313        }
314    ],
315    "hostname": "freebsd-14-test.novalocal",
316    "name": "freebsd-14-test",
317    "launch_index": 0,
318    "availability_zone": "nova",
319    "random_seed": "long_random_seed",
320    "project_id": "my_project_id",
321    "devices": [],
322    "dedicated_cpus": []
323}
324EOF
325	mkdir -p etc
326	cat > etc/master.passwd << EOF
327root:*:0:0::0:0:Charlie &:/root:/bin/csh
328sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
329EOF
330	pwd_mkdb -d etc ${here}/etc/master.passwd
331	cat > etc/group << EOF
332wheel:*:0:root
333users:*:1:
334EOF
335	atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2
336	atf_check -o inline:"ssh-ed25519 my_key_id tdb@host\n" cat home/freebsd/.ssh/authorized_keys
337}
338
339config2_network_body()
340{
341	mkdir -p media/nuageinit
342	setup_test_adduser
343	printf "{}" > media/nuageinit/meta_data.json
344	mynetworks=$(ifconfig -l ether)
345	if [ -z "$mynetworks" ]; then
346		atf_skip "a network interface is needed"
347	fi
348	set -- $mynetworks
349	myiface=$1
350	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
351cat > media/nuageinit/network_data.json << EOF
352{
353    "links": [
354        {
355            "ethernet_mac_address": "$myaddr",
356            "id": "iface0",
357            "mtu": null
358        }
359    ],
360    "networks": [
361        {
362            "id": "network0",
363            "link": "iface0",
364            "type": "ipv4_dhcp"
365        },
366        { // IPv6
367            "id": "private-ipv4",
368            "type": "ipv6",
369            "link": "iface0",
370            // supports condensed IPv6 with CIDR netmask
371            "ip_address": "2001:db8::3257:9652/64",
372            "gateway": "fd00::1",
373            "routes": [
374                {
375                    "network": "::",
376                    "netmask": "::",
377                    "gateway": "fd00::1"
378                },
379                {
380                    "network": "::",
381                    "netmask": "ffff:ffff:ffff::",
382                    "gateway": "fd00::1:1"
383                }
384            ],
385            "network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d8"
386        }
387    ]
388}
389EOF
390	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
391	cat > network << EOF
392ifconfig_${myiface}="DHCP"
393ifconfig_${myiface}_ipv6="inet6 2001:db8::3257:9652/64"
394ipv6_network_interfaces="${myiface}"
395ipv6_default_interface="${myiface}"
396EOF
397	cat > routing << EOF
398ipv6_defaultrouter="fd00::1"
399ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}"
400ipv6_static_routes="${myiface}"
401EOF
402	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
403	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
404}
405
406config2_network_static_v4_body()
407{
408	mkdir -p media/nuageinit
409	setup_test_adduser
410	printf "{}" > media/nuageinit/meta_data.json
411	mynetworks=$(ifconfig -l ether)
412	if [ -z "$mynetworks" ]; then
413		atf_skip "a network interface is needed"
414	fi
415	set -- $mynetworks
416	myiface=$1
417	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
418cat > media/nuageinit/network_data.json << EOF
419{
420    "links": [
421        {
422            "ethernet_mac_address": "$myaddr",
423            "id": "iface0",
424            "mtu": null
425        }
426    ],
427    "networks": [
428        {
429            "id": "network0",
430            "link": "iface0",
431            "type": "ipv4",
432            "ip_address": "10.184.0.244",
433            "netmask": "255.255.240.0",
434            "routes": [
435                {
436                    "network": "10.0.0.0",
437                    "netmask": "255.0.0.0",
438                    "gateway": "11.0.0.1"
439                },
440                {
441                    "network": "0.0.0.0",
442                    "netmask": "0.0.0.0",
443                    "gateway": "23.253.157.1"
444                }
445            ]
446        }
447    ]
448}
449EOF
450	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
451	cat > network << EOF
452ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0"
453EOF
454	cat > routing << EOF
455route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0"
456defaultrouter="23.253.157.1"
457static_routes="cloudinit1_${myiface}"
458EOF
459	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
460	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
461}
462
463config2_ssh_keys_head()
464{
465	atf_set "require.user" root
466}
467config2_ssh_keys_body()
468{
469	here=$(pwd)
470	export NUAGE_FAKE_ROOTDIR=$(pwd)
471	mkdir -p media/nuageinit
472	touch media/nuageinit/meta_data.json
473	cat > media/nuageinit/user-data << EOF
474#cloud-config
475ssh_keys:
476  rsa_private: |
477    -----BEGIN RSA PRIVATE KEY-----
478    MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
479    ...
480    -----END RSA PRIVATE KEY-----
481  rsa_public: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...
482  ed25519_private: |
483    -----BEGIN OPENSSH PRIVATE KEY-----
484    blabla
485    ...
486    -----END OPENSSH PRIVATE KEY-----
487  ed25519_public: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+MH4E8KO32N5CXRvXVqvyZVl0+6ue4DobdhU0FqFd+
488EOF
489	mkdir -p etc/ssh
490	cat > etc/master.passwd << EOF
491root:*:0:0::0:0:Charlie &:/root:/bin/csh
492sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
493EOF
494	pwd_mkdb -d etc ${here}/etc/master.passwd
495	cat > etc/group << EOF
496wheel:*:0:root
497users:*:1:
498EOF
499	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
500	_expected="-----BEGIN RSA PRIVATE KEY-----
501MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
502...
503-----END RSA PRIVATE KEY-----
504
505"
506	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_rsa_key
507	_expected="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...\n"
508	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_rsa_key.pub
509	_expected="-----BEGIN OPENSSH PRIVATE KEY-----
510blabla
511...
512-----END OPENSSH PRIVATE KEY-----
513
514"
515	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_ed25519_key
516	_expected="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+MH4E8KO32N5CXRvXVqvyZVl0+6ue4DobdhU0FqFd+\n"
517	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_ed25519_key.pub
518}
519
520
521nocloud_userdata_cloudconfig_ssh_pwauth_head()
522{
523	atf_set "require.user" root
524}
525nocloud_userdata_cloudconfig_ssh_pwauth_body()
526{
527	mkdir -p etc
528	cat > etc/master.passwd << EOF
529root:*:0:0::0:0:Charlie &:/root:/bin/sh
530sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
531EOF
532	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
533	cat > etc/group << EOF
534wheel:*:0:root
535users:*:1:
536EOF
537	mkdir -p media/nuageinit
538	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
539	cat > media/nuageinit/user-data << 'EOF'
540#cloud-config
541ssh_pwauth: true
542EOF
543	mkdir -p etc/ssh/
544	touch etc/ssh/sshd_config
545
546	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
547	atf_check -o inline:"PasswordAuthentication yes\n" cat etc/ssh/sshd_config
548
549	# Same value we don't touch anything
550	printf "   PasswordAuthentication yes # I want password\n" > etc/ssh/sshd_config
551	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
552	atf_check -o inline:"   PasswordAuthentication yes # I want password\n" cat etc/ssh/sshd_config
553
554	printf "   PasswordAuthentication no # Should change\n" > etc/ssh/sshd_config
555	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
556	atf_check -o inline:"PasswordAuthentication yes\n" cat etc/ssh/sshd_config
557
558	cat > media/nuageinit/user-data << 'EOF'
559#cloud-config
560ssh_pwauth: false
561EOF
562
563	printf "   PasswordAuthentication no # no passwords\n" > etc/ssh/sshd_config
564	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
565	atf_check -o inline:"   PasswordAuthentication no # no passwords\n" cat etc/ssh/sshd_config
566
567	printf "   PasswordAuthentication yes # Should change\n" > etc/ssh/sshd_config
568	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
569	atf_check -o inline:"PasswordAuthentication no\n" cat etc/ssh/sshd_config
570}
571
572nocloud_userdata_cloudconfig_chpasswd_head()
573{
574	atf_set "require.user" root
575}
576nocloud_userdata_cloudconfig_chpasswd_body()
577{
578	mkdir -p etc
579	cat > etc/master.passwd << EOF
580root:*:0:0::0:0:Charlie &:/root:/bin/sh
581sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
582user:*:1:0::0:0:Sys:/home/sys:/bin/sh
583EOF
584	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
585	cat > etc/group << EOF
586wheel:*:0:root
587users:*:1:
588EOF
589	mkdir -p media/nuageinit
590	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
591	cat > media/nuageinit/user-data << 'EOF'
592#cloud-config
593chpasswd:
594  expire: true
595  users:
596  - { user: "sys", password: RANDOM }
597EOF
598
599	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
600	atf_check -o empty -e inline:"nuageinit: Invalid entry for chpasswd.users: missing 'name'\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
601	# nothing modified
602	atf_check -o inline:"sys:*:1:0::0:0:Sys:/home/sys:/bin/sh\n" pw -R $(pwd) usershow sys
603
604	cat > media/nuageinit/user-data << 'EOF'
605#cloud-config
606chpasswd:
607  expire: true
608  users:
609  - { name: "sys", pwd: RANDOM }
610EOF
611	atf_check -o empty -e inline:"nuageinit: Invalid entry for chpasswd.users: missing 'password'\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
612	# nothing modified
613	atf_check -o inline:"sys:*:1:0::0:0:Sys:/home/sys:/bin/sh\n" pw -R $(pwd) usershow sys
614
615	cat > media/nuageinit/user-data << 'EOF'
616#cloud-config
617chpasswd:
618  expire: false
619  users:
620  - { name: "sys", password: RANDOM }
621EOF
622	# not empty because the password is printed to stdout
623	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
624	atf_check -o match:'sys:\$.*:1:0::0:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
625
626	cat > media/nuageinit/user-data << 'EOF'
627#cloud-config
628chpasswd:
629  expire: true
630  users:
631  - { name: "sys", password: RANDOM }
632EOF
633	# not empty because the password is printed to stdout
634	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
635	atf_check -o match:'sys:\$.*:1:0::1:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
636
637	cat > media/nuageinit/user-data << 'EOF'
638#cloud-config
639chpasswd:
640  expire: true
641  users:
642  - { name: "user", password: "$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/" }
643EOF
644	# not empty because the password is printed to stdout
645	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
646	atf_check -o inline:'user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1:0::1:0:Sys:/home/sys:/bin/sh\n' pw -R $(pwd) usershow user
647}
648
649
650nocloud_userdata_cloudconfig_chpasswd_list_string_head()
651{
652	atf_set "require.user" root
653}
654nocloud_userdata_cloudconfig_chpasswd_list_string_body()
655{
656	mkdir -p etc
657	cat > etc/master.passwd << EOF
658root:*:0:0::0:0:Charlie &:/root:/bin/sh
659sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
660user:*:1:0::0:0:Sys:/home/sys:/bin/sh
661EOF
662	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
663	cat > etc/group << EOF
664wheel:*:0:root
665users:*:1:
666EOF
667	mkdir -p media/nuageinit
668	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
669	cat > media/nuageinit/user-data << 'EOF'
670#cloud-config
671chpasswd:
672  expire: true
673  list: |
674     sys:RANDOM
675EOF
676
677	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
678	atf_check -o empty -e inline:"nuageinit: chpasswd.list is deprecated consider using chpasswd.users\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
679	atf_check -o match:'sys:\$.*:1:0::1:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
680
681	cat > media/nuageinit/user-data << 'EOF'
682#cloud-config
683chpasswd:
684  expire: false
685  list: |
686     sys:plop
687     user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
688     root:R
689EOF
690
691	atf_check -o empty -e ignore /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
692	atf_check -o match:'sys:\$.*:1:0::0:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
693	atf_check -o inline:'user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1:0::0:0:Sys:/home/sys:/bin/sh\n' pw -R $(pwd) usershow user
694	atf_check -o match:'root:\$.*:0:0::0:0:Charlie &:/root:/bin/sh$' pw -R $(pwd) usershow root
695}
696
697nocloud_userdata_cloudconfig_chpasswd_list_list_head()
698{
699	atf_set "require.user" root
700}
701nocloud_userdata_cloudconfig_chpasswd_list_list_body()
702{
703	mkdir -p etc
704	cat > etc/master.passwd << EOF
705root:*:0:0::0:0:Charlie &:/root:/bin/sh
706sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
707user:*:1:0::0:0:Sys:/home/sys:/bin/sh
708EOF
709	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
710	cat > etc/group << EOF
711wheel:*:0:root
712users:*:1:
713EOF
714	mkdir -p media/nuageinit
715	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
716	cat > media/nuageinit/user-data << 'EOF'
717#cloud-config
718chpasswd:
719  expire: true
720  list:
721  - sys:RANDOM
722EOF
723
724	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
725	atf_check -o empty -e inline:"nuageinit: chpasswd.list is deprecated consider using chpasswd.users\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
726	atf_check -o match:'sys:\$.*:1:0::1:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
727
728	cat > media/nuageinit/user-data << 'EOF'
729#cloud-config
730chpasswd:
731  expire: false
732  list:
733  - sys:plop
734  - user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
735  - root:R
736EOF
737
738	atf_check -o empty -e ignore /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
739	atf_check -o match:'sys:\$.*:1:0::0:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
740	atf_check -o inline:'user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1:0::0:0:Sys:/home/sys:/bin/sh\n' pw -R $(pwd) usershow user
741	atf_check -o match:'root:\$.*:0:0::0:0:Charlie &:/root:/bin/sh$' pw -R $(pwd) usershow root
742}
743
744config2_userdata_runcmd_head()
745{
746	atf_set "require.user" root
747}
748config2_userdata_runcmd_body()
749{
750	mkdir -p media/nuageinit
751	setup_test_adduser
752	printf "{}" > media/nuageinit/meta_data.json
753	cat > media/nuageinit/user_data << 'EOF'
754#cloud-config
755runcmd:
756EOF
757	chmod 755 "${PWD}"/media/nuageinit/user_data
758	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
759	cat > media/nuageinit/user_data << 'EOF'
760#cloud-config
761runcmd:
762  - plop
763EOF
764	chmod 755 "${PWD}"/media/nuageinit/user_data
765	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
766	test -f var/cache/nuageinit/runcmds || atf_fail "File not created"
767	test -x var/cache/nuageinit/runcmds || atf_fail "Missing execution permission"
768	atf_check -o inline:"#!/bin/sh\nplop\n" cat var/cache/nuageinit/runcmds
769
770	cat > media/nuageinit/user_data << 'EOF'
771#cloud-config
772runcmd:
773  - echo "yeah!"
774  - uname -s
775EOF
776	chmod 755 "${PWD}"/media/nuageinit/user_data
777	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
778	atf_check -o inline:"#!/bin/sh\necho \"yeah!\"\nuname -s\n" cat var/cache/nuageinit/runcmds
779}
780
781config2_userdata_packages_head()
782{
783	atf_set "require.user" root
784}
785
786config2_userdata_packages_body()
787{
788	mkdir -p media/nuageinit
789	setup_test_adduser
790	export NUAGE_RUN_TESTS=1
791	printf "{}" > media/nuageinit/meta_data.json
792	cat > media/nuageinit/user_data << 'EOF'
793#cloud-config
794packages:
795EOF
796	chmod 755 "${PWD}"/media/nuageinit/user_data
797	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
798	cat > media/nuageinit/user_data << 'EOF'
799#cloud-config
800packages:
801  - yeah/plop
802EOF
803	chmod 755 "${PWD}"/media/nuageinit/user_data
804	atf_check -s exit:0 -o inline:"pkg install -y 'yeah/plop'\npkg info -q 'yeah/plop'\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
805
806	cat > media/nuageinit/user_data << 'EOF'
807#cloud-config
808packages:
809  - curl
810EOF
811	chmod 755 "${PWD}"/media/nuageinit/user_data
812	atf_check -o inline:"pkg install -y 'curl'\npkg info -q 'curl'\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
813
814	cat > media/nuageinit/user_data << 'EOF'
815#cloud-config
816packages:
817  - curl
818  - meh: bla
819EOF
820	chmod 755 "${PWD}"/media/nuageinit/user_data
821	atf_check -o inline:"pkg install -y 'curl'\npkg info -q 'curl'\n" -e inline:"nuageinit: Invalid type: table for packages entry number 2\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
822}
823
824config2_userdata_update_packages_body()
825{
826	mkdir -p media/nuageinit
827	setup_test_adduser
828	export NUAGE_RUN_TESTS=1
829	printf "{}" > media/nuageinit/meta_data.json
830	cat > media/nuageinit/user_data << 'EOF'
831#cloud-config
832package_update: true
833EOF
834	chmod 755 "${PWD}"/media/nuageinit/user_data
835	atf_check -o inline:"env ASSUME_ALWAYS_YES=yes pkg update\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
836}
837
838config2_userdata_upgrade_packages_body()
839{
840	mkdir -p media/nuageinit
841	setup_test_adduser
842	export NUAGE_RUN_TESTS=1
843	printf "{}" > media/nuageinit/meta_data.json
844	cat > media/nuageinit/user_data << 'EOF'
845#cloud-config
846package_upgrade: true
847EOF
848	chmod 755 "${PWD}"/media/nuageinit/user_data
849	atf_check -o inline:"env ASSUME_ALWAYS_YES=yes pkg upgrade\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
850}
851
852config2_userdata_shebang_body()
853{
854	mkdir -p media/nuageinit
855	setup_test_adduser
856	printf "{}" > media/nuageinit/meta_data.json
857	cat > media/nuageinit/user_data <<EOF
858#!/we/dont/care
859anything
860EOF
861	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
862	test -f var/cache/nuageinit/user_data || atf_fail "File not created"
863	test -x var/cache/nuageinit/user_data || atf_fail "Missing execution permission"
864	atf_check -o inline:"#!/we/dont/care\nanything\n" cat var/cache/nuageinit/user_data
865	cat > media/nuageinit/user_data <<EOF
866/we/dont/care
867EOF
868	rm var/cache/nuageinit/user_data
869	if [ -f var/cache/nuageinit/user_data ]; then
870		atf_fail "File should not have been created"
871	fi
872}
873
874config2_userdata_write_files_body()
875{
876	mkdir -p media/nuageinit
877	setup_test_adduser
878	printf "{}" > media/nuageinit/meta_data.json
879	cat > media/nuageinit/user_data <<EOF
880#cloud-config
881write_files:
882- content: "plop"
883  path: /file1
884- path: /emptyfile
885- content: !!binary |
886    YmxhCg==
887  path: /file_base64
888  encoding: b64
889  permissions: '0755'
890  owner: nobody
891- content: "bob"
892  path: "/foo"
893  defer: true
894EOF
895	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
896	atf_check -o inline:"plop" cat file1
897	atf_check -o inline:"" cat emptyfile
898	atf_check -o inline:"bla\n" cat file_base64
899	test -f foo && atf_fail "foo creation should have been deferred"
900	atf_check -o match:"^-rwxr-xr-x.*nobody" ls -l file_base64
901	rm file1 emptyfile file_base64
902	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
903	test -f file1 -o -f emptyfile -o -f file_base64 && atf_fail "defer not working properly"
904	atf_check -o inline:"bob" cat foo
905}
906
907config2_userdata_fqdn_and_hostname_body()
908{
909	mkdir -p media/nuageinit
910	setup_test_adduser
911	printf "{}" > media/nuageinit/meta_data.json
912	cat > media/nuageinit/user_data <<EOF
913#cloud-config
914fqdn: host.domain.tld
915hostname: host
916EOF
917	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
918	atf_check -o inline:"hostname=\"host.domain.tld\"\n" cat ${PWD}/etc/rc.conf.d/hostname
919	cat > media/nuageinit/user_data <<EOF
920#cloud-config
921hostname: host
922EOF
923	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
924	atf_check -o inline:"hostname=\"host\"\n" cat ${PWD}/etc/rc.conf.d/hostname
925}
926
927atf_init_test_cases()
928{
929	atf_add_test_case args
930	atf_add_test_case nocloud
931	atf_add_test_case nocloud_userdata_script
932	atf_add_test_case nocloud_user_data_script
933	atf_add_test_case nocloud_userdata_cloudconfig_users
934	atf_add_test_case nocloud_network
935	atf_add_test_case config2
936	atf_add_test_case config2_pubkeys
937	atf_add_test_case config2_pubkeys_user_data
938	atf_add_test_case config2_pubkeys_meta_data
939	atf_add_test_case config2_network
940	atf_add_test_case config2_network_static_v4
941	atf_add_test_case config2_ssh_keys
942	atf_add_test_case nocloud_userdata_cloudconfig_ssh_pwauth
943	atf_add_test_case nocloud_userdata_cloudconfig_chpasswd
944	atf_add_test_case nocloud_userdata_cloudconfig_chpasswd_list_string
945	atf_add_test_case nocloud_userdata_cloudconfig_chpasswd_list_list
946	atf_add_test_case config2_userdata_runcmd
947	atf_add_test_case config2_userdata_packages
948	atf_add_test_case config2_userdata_update_packages
949	atf_add_test_case config2_userdata_upgrade_packages
950	atf_add_test_case config2_userdata_shebang
951	atf_add_test_case config2_userdata_fqdn_and_hostname
952	atf_add_test_case config2_userdata_write_files
953}
954