def test_keypair_exists(self): with mock_ec2(): logger = "stacker.hooks.keypair" client = boto3.client("ec2", region_name=REGION) client.create_key_pair(KeyName=KEY_PAIR_NAME) response = client.describe_key_pairs() # check that one keypair was created self.assertEqual(len(response["KeyPairs"]), 1) keypair = find(response["KeyPairs"], "KeyName", KEY_PAIR_NAME) with LogCapture(logger) as logs: value = ensure_keypair_exists(provider=self.provider, context=self.context, keypair=KEY_PAIR_NAME) message = "keypair: " + KEY_PAIR_NAME + \ " (" + keypair["KeyFingerprint"] + ") exists" logs.check( ( logger, "INFO", message ) ) self.assertEqual(value["status"], "exists") self.assertEqual(value["key_name"], KEY_PAIR_NAME) self.assertEqual(value["fingerprint"], keypair["KeyFingerprint"])
def test_keypair_missing_create(self, mocked_input): mocked_input.side_effect = ["create", "./"] with mock_ec2(): logger = "stacker.hooks.keypair" client = boto3.client("ec2", region_name=REGION) with LogCapture(logger) as logs: value = ensure_keypair_exists(provider=self.provider, context=self.context, keypair=KEY_PAIR_NAME) response = client.describe_key_pairs() print(response) keypair = find(response["KeyPairs"], "KeyName", KEY_PAIR_NAME) message = "keypair: " + KEY_PAIR_NAME + \ " (" + keypair["KeyFingerprint"] + ") created" logs.check( ( logger, "INFO", "keypair: \"%s\" not found" % KEY_PAIR_NAME ), ( logger, "INFO", message ) ) tmp_file_path = "/home/circleci/project/" + KEY_PAIR_NAME + ".pem" self.assertEqual(value["status"], "created") self.assertEqual(value["key_name"], KEY_PAIR_NAME) self.assertEqual(value["file_path"], tmp_file_path)
def test_param_validation(provider, context): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, ssm_parameter_name='test', public_key_path='test') assert result is False
def test_import_bad_key_data(tmpdir, provider, context): pkey = tmpdir.join("id_rsa.pub") pkey.write('garbage') result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, public_key_path=str(pkey)) assert result is False
def test_keypair_missing_cancel_input(self, mocked_input): mocked_input.side_effect = ["Cancel"] with mock_ec2(): logger = "stacker.hooks.keypair" client = boto3.client("ec2", region_name=REGION) response = client.describe_key_pairs() # initially no key pairs created self.assertEqual(len(response["KeyPairs"]), 0) with LogCapture(logger) as logs: self.assertFalse(ensure_keypair_exists(provider=self.provider, context=self.context, keypair=KEY_PAIR_NAME)) logs.check( ( logger, "INFO", "keypair: \"%s\" not found" % KEY_PAIR_NAME ), ( logger, "WARNING", "no action to find keypair, failing" ) )
def test_interactive_retry_cancel(provider, context): lines = ['garbage', 'cancel'] with mock_input(lines) as input: result = ensure_keypair_exists( provider, context, keypair=KEY_PAIR_NAME) assert input.call_count == 2 assert result is False
def test_import_file(tmpdir, provider, context, ssh_key): pkey = tmpdir.join("id_rsa.pub") pkey.write(ssh_key.public_key) result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, public_key_path=str(pkey)) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'imported'
def test_keypair_exists(provider, context): ec2 = boto3.client('ec2') keypair = ec2.create_key_pair(KeyName=KEY_PAIR_NAME) result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) expected = dict(status='exists', key_name=KEY_PAIR_NAME, fingerprint=keypair['KeyFingerprint']) assert result == expected
def test_interactive_create_bad_dir(tmpdir, provider, context): key_dir = tmpdir.join('missing') lines = ['create', str(key_dir)] with mock_input(lines): result = ensure_keypair_exists( provider, context, keypair=KEY_PAIR_NAME) assert result is False
def test_interactive_retry_cancel(provider, context): lines = ['garbage', 'cancel'] with mock_input(lines) as input: result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) assert input.call_count == 2 assert result is False
def test_import_bad_key_data(tmpdir, provider, context): pkey = tmpdir.join("id_rsa.pub") pkey.write('garbage') result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, public_key_path=str(pkey)) assert result is False
def test_import_file(tmpdir, provider, context, ssh_key): pkey = tmpdir.join("id_rsa.pub") pkey.write(ssh_key.public_key) result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, public_key_path=str(pkey)) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'imported'
def test_interactive_create_bad_dir(tmpdir, provider, context): key_dir = tmpdir.join('missing') lines = ['create', str(key_dir)] with mock_input(lines): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) assert result is False
def test_interactive_non_terminal_input(capsys, provider, context): with mock_input(isatty=False) as input: result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) input.assert_not_called() assert result is False output = capsys.readouterr() assert len(output.out) == 0 assert len(output.err) == 0
def test_keypair_exists(provider, context): ec2 = boto3.client('ec2') keypair = ec2.create_key_pair(KeyName=KEY_PAIR_NAME) result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) expected = dict( status='exists', key_name=KEY_PAIR_NAME, fingerprint=keypair['KeyFingerprint']) assert result == expected
def test_interactive_non_terminal_input(capsys, provider, context): with mock_input(isatty=False) as input: result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) input.assert_not_called() assert result is False output = capsys.readouterr() assert len(output.out) == 0 assert len(output.err) == 0
def test_interactive_import(tmpdir, provider, context, ssh_key): key_file = tmpdir.join("id_rsa.pub") key_file.write(ssh_key.public_key) lines = ['import', str(key_file)] with mock_input(lines): result = ensure_keypair_exists( provider, context, keypair=KEY_PAIR_NAME) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'imported'
def test_interactive_import(tmpdir, provider, context, ssh_key): key_file = tmpdir.join("id_rsa.pub") key_file.write(ssh_key.public_key) lines = ['import', str(key_file)] with mock_input(lines): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'imported'
def test_interactive_create_existing_file(tmpdir, provider, context): key_dir = tmpdir.join('keys') key_dir.ensure_dir() key_file = key_dir.join('{}.pem'.format(KEY_PAIR_NAME)) key_file.ensure() lines = ['create', str(key_dir)] with mock_input(lines): result = ensure_keypair_exists( provider, context, keypair=KEY_PAIR_NAME) assert result is False
def test_interactive_create_existing_file(tmpdir, provider, context): key_dir = tmpdir.join('keys') key_dir.ensure_dir() key_file = key_dir.join('{}.pem'.format(KEY_PAIR_NAME)) key_file.ensure() lines = ['create', str(key_dir)] with mock_input(lines): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) assert result is False
def test_interactive_create(tmpdir, provider, context, ssh_key): key_dir = tmpdir.join('keys') key_dir.ensure_dir() key_file = key_dir.join('{}.pem'.format(KEY_PAIR_NAME)) lines = ['create', str(key_dir)] with mock_input(lines): result = ensure_keypair_exists( provider, context, keypair=KEY_PAIR_NAME) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'created' assert key_file.samefile(result['file_path']) assert key_file.read_binary() == ssh_key.private_key
def test_interactive_create(tmpdir, provider, context, ssh_key): key_dir = tmpdir.join('keys') key_dir.ensure_dir() key_file = key_dir.join('{}.pem'.format(KEY_PAIR_NAME)) lines = ['create', str(key_dir)] with mock_input(lines): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'created' assert key_file.samefile(result['file_path']) assert key_file.read_binary() == ssh_key.private_key
def test_create_in_ssm(provider, context, ssh_key, ssm_key_id): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, ssm_parameter_name='param', ssm_key_id=ssm_key_id) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'created' ssm = boto3.client('ssm') param = ssm.get_parameter(Name='param', WithDecryption=True)['Parameter'] assert param['Value'] == ssh_key.private_key.decode('ascii') assert param['Type'] == 'SecureString' params = ssm.describe_parameters()['Parameters'] param_details = next(p for p in params if p['Name'] == 'param') assert param_details['Description'] == \ 'SSH private key for KeyPair "{}" (generated by Stacker)'.format( KEY_PAIR_NAME) assert param_details.get('KeyId') == ssm_key_id
def test_create_in_ssm(provider, context, ssh_key, ssm_key_id): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, ssm_parameter_name='param', ssm_key_id=ssm_key_id) assert_key_present(result, KEY_PAIR_NAME, ssh_key.fingerprint) assert result['status'] == 'created' ssm = boto3.client('ssm') param = ssm.get_parameter(Name='param', WithDecryption=True)['Parameter'] assert param['Value'] == ssh_key.private_key.decode('ascii') assert param['Type'] == 'SecureString' params = ssm.describe_parameters()['Parameters'] param_details = next(p for p in params if p['Name'] == 'param') assert param_details['Description'] == \ 'SSH private key for KeyPair "{}" (generated by Stacker)'.format( KEY_PAIR_NAME) assert param_details.get('KeyId') == ssm_key_id
def test_keypair_missing_create_invalid_path(self, mocked_input): mocked_input.side_effect = ["create", "$"] with mock_ec2(): logger = "stacker.hooks.keypair" with LogCapture(logger) as logs: value = ensure_keypair_exists(provider=self.provider, context=self.context, keypair=KEY_PAIR_NAME) message = "\"/home/circleci/project/" + \ "$" + "\" is not a valid directory" logs.check( ( logger, "INFO", "keypair: \"%s\" not found" % KEY_PAIR_NAME ), ( logger, "ERROR", message ) ) self.assertFalse(value)
def test_keypair_missing_import_invalid_path(self, mocked_input): mocked_input.side_effect = ["import", "$"] with mock_ec2(): logger = "stacker.hooks.keypair" with LogCapture(logger) as logs: value = ensure_keypair_exists(provider=self.provider, context=self.context, keypair=KEY_PAIR_NAME) er_message = "Failed to find keypair at path: " + \ "/home/circleci/project/$" logs.check( ( logger, "INFO", "keypair: \"%s\" not found" % KEY_PAIR_NAME ), ( logger, "ERROR", er_message ) ) self.assertFalse(value)
def test_param_validation(provider, context): result = ensure_keypair_exists(provider, context, keypair=KEY_PAIR_NAME, ssm_parameter_name='test', public_key_path='test') assert result is False