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