{Core} Migrate generate_ssh_keys from paramiko to cryptography#30063
{Core} Migrate generate_ssh_keys from paramiko to cryptography#30063
generate_ssh_keys from paramiko to cryptography#30063Conversation
️✔️AzureCLI-FullTest
|
️✔️AzureCLI-BreakingChangeTest
|
|
Core |
|
|
paramiko dependency from coregenerate_ssh_keys from paramiko to cryptography
|
|
||
|
|
||
| def _open(filename, mode): | ||
| return os.open(filename, flags=os.O_WRONLY | os.O_TRUNC | os.O_CREAT, mode=mode) |
There was a problem hiding this comment.
Setting file mode at creation time avoids the time gap between open and chmod. See #21719
| except (PasswordRequiredException, SSHException, IOError) as e: | ||
| raise CLIError(e) |
There was a problem hiding this comment.
I don't feel the necessity of converting these errors to a CLIError. They should be propagated as it.
This also aligns with azure.cli.command_modules.vm._vm_utils.generate_ssh_keys_ed25519 (#30077):
azure-cli/src/azure-cli/azure/cli/command_modules/vm/_vm_utils.py
Lines 724 to 731 in 8b90393
| def test_error_raised_when_private_key_file_exists_IOError(self): | ||
| # Create private key file | ||
| private_key_path = self._create_new_temp_key_file(self.private_key) | ||
|
|
||
| with mock.patch('paramiko.RSAKey') as mocked_RSAKey: | ||
| # mock failed RSAKey generation | ||
| mocked_RSAKey.side_effect = IOError("Mocked IOError") | ||
|
|
||
| # assert that CLIError raised when generate_ssh_keys is called | ||
| with self.assertRaises(CLIError): | ||
| public_key_path = private_key_path + ".pub" | ||
| generate_ssh_keys(private_key_path, public_key_path) | ||
|
|
||
| # assert that CLIError raised because of attempt to generate key from private key file. | ||
| mocked_RSAKey.assert_called_once_with(filename=private_key_path) | ||
|
|
There was a problem hiding this comment.
As IOError is no longer caught, this test is meaningless.
| # -----END RSA PRIVATE KEY----- | ||
| private_bytes = private_key.private_bytes( | ||
| encoding=serialization.Encoding.PEM, | ||
| format=serialization.PrivateFormat.TraditionalOpenSSL, |
There was a problem hiding this comment.
May I ask why we are using PrivateFormat.TraditionalOpenSSL instead of PrivateFormat.OpenSSH?
There was a problem hiding this comment.
Good question!
PrivateFormat.TraditionalOpenSSL will generate a private key file like:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
while PrivateFormat.OpenSSH will generate a private key file like
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Using PrivateFormat.TraditionalOpenSSL makes sure there is no breaking change.
|
@yanzhudd Could you please help review it as well and do some simple tests? |
yanzhudd
left a comment
There was a problem hiding this comment.
I used "az vm create" command to verify this command, and it did not generate any unexpected results.
Description
Migrate
generate_ssh_keysfromparamikotocryptography.https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/ contains some useful examples for working with RSA keys.