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