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