|
| 1 | +"""Integration test for LP: #1910835. |
| 2 | +
|
| 3 | +If users do not provide an SSH key and instead ask Azure to generate a key for |
| 4 | +them, the key material available in the IMDS may include CRLF sequences. Prior |
| 5 | +to e56b55452549cb037da0a4165154ffa494e9678a, the Azure datasource handled keys |
| 6 | +via a certificate, the tooling for which removed these sequences. This test |
| 7 | +ensures that cloud-init does not regress support for this Azure behaviour. |
| 8 | +
|
| 9 | +This test provides the SSH key configured for tests to the instance in two |
| 10 | +ways: firstly, with CRLFs to mimic the generated keys, via the Azure API; |
| 11 | +secondly, as user-data in unmodified form. This means that even on systems |
| 12 | +which exhibit the bug fetching the platform's metadata, we can SSH into the SUT |
| 13 | +to confirm this (instead of having to assert SSH failure; there are lots of |
| 14 | +reasons SSH might fail). |
| 15 | +
|
| 16 | +Once SSH'd in, we check that the two keys in .ssh/authorized_keys have the same |
| 17 | +material: if the Azure datasource has removed the CRLFs correctly, then they |
| 18 | +will match. |
| 19 | +""" |
| 20 | +import pytest |
| 21 | + |
| 22 | + |
| 23 | +USER_DATA_TMPL = """\ |
| 24 | +#cloud-config |
| 25 | +ssh_authorized_keys: |
| 26 | + - {}""" |
| 27 | + |
| 28 | + |
| 29 | +@pytest.mark.sru_2021_01 |
| 30 | +@pytest.mark.azure |
| 31 | +def test_crlf_in_azure_metadata_ssh_keys(session_cloud, setup_image): |
| 32 | + authorized_keys_path = "/home/{}/.ssh/authorized_keys".format( |
| 33 | + session_cloud.cloud_instance.username |
| 34 | + ) |
| 35 | + # Pass in user-data to allow us to access the instance when the normal |
| 36 | + # path fails |
| 37 | + key_data = session_cloud.cloud_instance.key_pair.public_key_content |
| 38 | + user_data = USER_DATA_TMPL.format(key_data) |
| 39 | + # Throw a CRLF into the otherwise good key data, to emulate Azure's |
| 40 | + # behaviour for generated keys |
| 41 | + key_data = key_data[:20] + "\r\n" + key_data[20:] |
| 42 | + vm_params = { |
| 43 | + "os_profile": { |
| 44 | + "linux_configuration": { |
| 45 | + "ssh": { |
| 46 | + "public_keys": [ |
| 47 | + {"path": authorized_keys_path, "key_data": key_data} |
| 48 | + ] |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + with session_cloud.launch( |
| 54 | + launch_kwargs={"vm_params": vm_params, "user_data": user_data} |
| 55 | + ) as client: |
| 56 | + authorized_keys = ( |
| 57 | + client.read_from_file(authorized_keys_path).strip().splitlines() |
| 58 | + ) |
| 59 | + # We expect one key from the cloud, one from user-data |
| 60 | + assert 2 == len(authorized_keys) |
| 61 | + # And those two keys should be the same, except for a possible key |
| 62 | + # comment, which Azure strips out |
| 63 | + assert ( |
| 64 | + authorized_keys[0].rsplit(" ")[:2] |
| 65 | + == authorized_keys[1].split(" ")[:2] |
| 66 | + ) |
0 commit comments