import os import unittest from ruamel import yaml from fleece.cli.run import run from . import utils from unittest import mock class TestCLIRun(unittest.TestCase): def setUp(self): self.aws_credentials = { "credential": { "accessKeyId": "123456", "secretAccessKey": "987654", "sessionToken": "456789", } } self.account = "123456789012" self.role = "LambdaDeployRole" self.environment = "foo" self.config = 'environments:\n - name: {}\n account: "{}"'.format( self.environment, self.account ) def test_environment_or_account(self): args = ["--account", self.account, "--environment", self.environment, "wat"] with self.assertRaises(SystemExit) as exc: run.main(args) self.assertIn(run.ENV_AND_ACCT_ERROR, str(exc.exception)) def test_no_account_or_environment(self): args = ["wat"] with self.assertRaises(SystemExit) as exc: run.main(args) self.assertIn(run.NO_ACCT_OR_ENV_ERROR, str(exc.exception)) def test_environment_with_role(self): args = ["--environment", "foo", "--role", self.role, "wat"] with self.assertRaises(SystemExit) as exc: run.main(args) self.assertIn(run.ENV_AND_ROLE_ERROR, str(exc.exception)) def test_no_username(self): args = ["--account", self.account, "--apikey", "foo", "wat"] with self.assertRaises(SystemExit) as exc: run.main(args) self.assertIn(run.NO_USER_OR_APIKEY_ERROR, str(exc.exception)) def test_no_apikey(self): args = ["--account", self.account, "--username", "foo", "wat"] with self.assertRaises(SystemExit) as exc: run.main(args) self.assertIn(run.NO_USER_OR_APIKEY_ERROR, str(exc.exception)) def test_good_rackspace_token(self): response_mock = mock.MagicMock() response_mock.ok = True response_mock.json = lambda: utils.USER_DATA with mock.patch( "fleece.cli.run.run.requests.post", return_value=response_mock ) as requests_mock: token, tenant = run.get_rackspace_token("foo", "bar") requests_mock.assert_called_with( "https://identity.api.rackspacecloud.com/v2.0/tokens", json={ "auth": { "RAX-KSKEY:apiKeyCredentials": { "username": "foo", "apiKey": "bar", } } }, ) self.assertEqual(utils.TEST_TOKEN, token) self.assertEqual(utils.USER_DATA["access"]["token"]["tenant"]["id"], tenant) def test_bad_rackspace_token(self): response_mock = mock.MagicMock() response_mock.ok = False response_mock.status_code = 401 response_mock.text = "Narp" with mock.patch("fleece.cli.run.run.requests.post", return_value=response_mock): with self.assertRaises(SystemExit) as exc: run.get_rackspace_token("foo", "bar") self.assertIn( run.RS_AUTH_ERROR.format( response_mock.status_code, response_mock.text ), str(exc.exception), ) def test_get_aws_creds(self): response_mock = mock.MagicMock() response_mock.ok = True response_mock.json = mock.MagicMock(return_value=self.aws_credentials) with mock.patch( "fleece.cli.run.run.requests.post", return_value=response_mock ) as requests_mock: creds = run.get_aws_creds(self.account, "123456", "foo") requests_mock.assert_called_with( run.FAWS_API_URL.format(self.account), headers={"X-Auth-Token": "foo", "X-Tenant-Id": "123456"}, json={"credential": {"duration": "3600"}}, ) self.assertDictEqual(self.aws_credentials["credential"], creds) def test_get_aws_creds_fail(self): response_mock = mock.MagicMock() response_mock.ok = False response_mock.status_code = 404 response_mock.test = "Narp" with mock.patch("fleece.cli.run.run.requests.post", return_value=response_mock): with self.assertRaises(SystemExit) as exc: run.get_aws_creds(self.account, "123456", "foo") self.assertIn( run.FAWS_API_ERROR.format( response_mock.status_code, response_mock.text ), str(exc.exception), ) def test_get_config(self): mock_open = mock.mock_open(read_data=self.config) with mock.patch("fleece.cli.run.run.open", mock_open, create=True): config = run.get_config("./wat") self.assertDictEqual(yaml.safe_load(self.config), config) def test_bad_config_file_path(self): with self.assertRaises(SystemExit) as exc: run.get_config("./nope") self.assertIn("No such file or directory", str(exc.exception)) def test_get_account(self): config = yaml.safe_load(self.config) account, role, username, apikey = run.get_account(config, self.environment) self.assertEqual(account, self.account) self.assertIsNone(role) self.assertIsNone(username) self.assertIsNone(apikey) def test_get_account_with_creds(self): os.environ["MY_USERNAME"] = "foo" os.environ["MY_APIKEY"] = "bar" config = yaml.safe_load( "environments:\n" " - name: {}\n" ' account: "{}"\n' " rs_username_var: MY_USERNAME\n" " rs_apikey_var: MY_APIKEY".format(self.environment, self.account) ) account, role, username, apikey = run.get_account(config, self.environment) del os.environ["MY_USERNAME"] del os.environ["MY_APIKEY"] self.assertEqual(account, self.account) self.assertIsNone(role) self.assertEqual(username, "foo") self.assertEqual(apikey, "bar") def test_get_account_with_stage_creds(self): os.environ["MY_USERNAME"] = "foo" os.environ["MY_APIKEY"] = "bar" config = yaml.safe_load( "stages:\n" " sandwhich:\n" " environment: {env_name}\n" "environments:\n" " - name: {env_name}\n" ' account: "{account}"\n' " rs_username_var: MY_USERNAME\n" " rs_apikey_var: MY_APIKEY".format( env_name=self.environment, account=self.account ) ) account, role, username, apikey = run.get_account(config, None, "sandwhich") del os.environ["MY_USERNAME"] del os.environ["MY_APIKEY"] self.assertEqual(account, self.account) self.assertIsNone(role) self.assertEqual(username, "foo") self.assertEqual(apikey, "bar") def test_get_account_with_stage_creds_2(self): os.environ["MY_USERNAME"] = "foo" os.environ["MY_APIKEY"] = "bar" config = yaml.safe_load( "stages:\n" " /.*/:\n" " environment: {env_name}\n" "environments:\n" " - name: {env_name}\n" ' account: "{account}"\n' " rs_username_var: MY_USERNAME\n" " rs_apikey_var: MY_APIKEY".format( env_name=self.environment, account=self.account ) ) account, role, username, apikey = run.get_account( config, None, "made-up-nonsense" ) del os.environ["MY_USERNAME"] del os.environ["MY_APIKEY"] self.assertEqual(account, self.account) self.assertIsNone(role) self.assertEqual(username, "foo") self.assertEqual(apikey, "bar") def _assert_config_leads_to_msg(self, config_txt, msg): os.environ["MY_USERNAME"] = "foo" os.environ["MY_APIKEY"] = "bar" config = yaml.safe_load(config_txt) try: run.get_account(config, None, "sandwhich") self.fail("Expected SystemExit") except SystemExit as se: self.assertIn(msg, str(se)) def test_get_account_with_stage_creds_but_stages_not_found(self): self._assert_config_leads_to_msg( "environments:\n" " - name: {env_name}\n" ' account: "{account}"\n' " rs_username_var: MY_USERNAME\n" " rs_apikey_var: MY_APIKEY".format( env_name=self.environment, account=self.account ), "No stage named", ) def test_get_account_with_stage_creds_but_specific_stage_not_found(self): self._assert_config_leads_to_msg( "stages:\n" " biscuit:\n" " environment: {env_name}\n" "environments:\n" " - name: {env_name}\n" ' account: "{account}"\n' " rs_username_var: MY_USERNAME\n" " rs_apikey_var: MY_APIKEY".format( env_name=self.environment, account=self.account ), "No stage named", ) def test_get_account_with_stage_creds_but_no_envs_for_stage(self): self._assert_config_leads_to_msg( "stages:\n" " sandwhich:\n" " pie: {env_name}\n" "environments:\n" " - name: {env_name}\n" ' account: "{account}"\n' " rs_username_var: MY_USERNAME\n" " rs_apikey_var: MY_APIKEY".format( env_name=self.environment, account=self.account ), "No default environment defined for stage", ) def test_environment_not_found(self): with self.assertRaises(SystemExit) as exc: run.get_account({}, self.environment) self.assertIn( run.ACCT_NOT_FOUND_ERROR.format(self.environment), str(exc.exception) )