class TestConfigureAuthentication(MAASTestCase): def setUp(self): super().setUp() self.maas_bin_path = "snap-path/bin/maas-region" self.mock_subprocess = self.patch(init, "subprocess") self.mock_environ = patch.dict(init.os.environ, {"SNAP": "snap-path"}, clear=True) self.mock_environ.start() self.parser = ArgumentParser() init.add_rbac_options(self.parser) init.add_candid_options(self.parser) def tearDown(self): self.mock_subprocess.stop() self.mock_environ.stop() super().tearDown() def test_no_options(self): options = self.parser.parse_args([]) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual(([self.maas_bin_path, "configauth"], ), args) self.assertEqual({}, kwargs) def test_rbac_url(self): config_auth_args = ["--rbac-url", "http://rrbac.example.com/"] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual( ([self.maas_bin_path, "configauth"] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_rbac_service_name(self): config_auth_args = ["--rbac-service-name", "mymaas"] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual( ([self.maas_bin_path, "configauth"] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_candid_agent_file(self): _, agent_file_path = tempfile.mkstemp() self.addCleanup(os.remove, agent_file_path) config_auth_args = ["--candid-agent-file", agent_file_path] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual("call", method) self.assertEqual( ([self.maas_bin_path, "configauth"] + config_auth_args, ), args) self.assertEqual({}, kwargs)
class TestCreateAdminOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_create_admin_options(self.parser) def test_create_admin_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.admin_username) self.assertIsNone(options.admin_password) self.assertIsNone(options.admin_email) self.assertIsNone(options.admin_ssh_import) def test_create_admin_options_username(self): options = self.parser.parse_args( ['--admin-username', 'my-username']) self.assertEqual('my-username', options.admin_username) def test_create_admin_options_password(self): options = self.parser.parse_args(['--admin-password', 'my-password']) self.assertEqual('my-password', options.admin_password) def test_create_admin_options_email(self): options = self.parser.parse_args(['--admin-email', '*****@*****.**']) self.assertEqual('*****@*****.**', options.admin_email) def test_create_admin_options_ssh_import(self): options = self.parser.parse_args(['--admin-ssh-import', 'lp:me']) self.assertEqual('lp:me', options.admin_ssh_import)
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = cli.cmd_init(self.parser) self.maas_region_path = init.get_maas_region_bin_path() self.call_mock = self.patch(init.subprocess, "call") self.check_output_mock = self.patch(init.subprocess, "check_output") self.check_output_mock.return_value = json.dumps( {"external_auth_url": ""}) # avoid printouts self.mock_stdout = self.patch(init.sys, "stdout", StringIO()) self.mock_stderr = self.patch(init.sys, "stderr", StringIO()) def test_defaults(self): options = self.parser.parse_args([]) self.assertFalse(options.skip_admin) self.assertIsNone(options.admin_username) self.assertIsNone(options.admin_password) self.assertIsNone(options.admin_email) self.assertIsNone(options.admin_ssh_import) self.assertIsNone(options.candid_agent_file) self.assertIsNone(options.rbac_url) def test_init_maas_calls_subcommands(self): options = self.parser.parse_args([]) self.cmd(options) configauth_call, createadmin_call = self.call_mock.mock_calls _, args1, kwargs1 = configauth_call _, args2, kwargs2 = createadmin_call self.assertEqual(([self.maas_region_path, "configauth"], ), args1) self.assertEqual({}, kwargs1) self.assertEqual(([self.maas_region_path, "createadmin"], ), args2) self.assertEqual({}, kwargs2)
class TestAddCandidOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_candid_options(self.parser) self.mock_stderr = self.patch(init.sys, "stderr", StringIO()) def test_add_candid_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.candid_agent_file) def test_add_candid_options_candid_domain(self): options = self.parser.parse_args( ['--candid-domain', 'mydomain']) self.assertEqual('mydomain', options.candid_domain) def test_add_candid_options_candid_agent_file(self): options = self.parser.parse_args(['--candid-agent-file', 'agent.file']) self.assertEqual(options.candid_agent_file, 'agent.file') def test_add_candid_options_candid_admin_group(self): options = self.parser.parse_args( ['--candid-admin-group', 'admins']) self.assertEqual('admins', options.candid_admin_group)
class TestAddIdmOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_idm_options(self.parser) def test_add_idm_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.idm_url) self.assertIsNone(options.idm_user) self.assertIsNone(options.idm_key) self.assertIsNone(options.idm_agent_file) def test_add_idm_options_idm_url(self): options = self.parser.parse_args( ['--idm-url', 'http://idm.example.com/']) self.assertEqual('http://idm.example.com/', options.idm_url) def test_add_idm_options_idm_user(self): options = self.parser.parse_args(['--idm-user', 'my-user']) self.assertEqual('my-user', options.idm_user) def test_add_idm_options_idm_key(self): options = self.parser.parse_args(['--idm-key', 'my-key']) self.assertEqual('my-key', options.idm_key) def test_add_idm_options_idm_agent_file(self): fd, agent_file_name = tempfile.mkstemp() self.addCleanup(os.remove, agent_file_name) os.write(fd, b'my-agent-file-content') os.close(fd) options = self.parser.parse_args(['--idm-agent-file', agent_file_name]) self.assertEqual('my-agent-file-content', options.idm_agent_file.read())
class TestAddRBACOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_rbac_options(self.parser) def test_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.rbac_url) def test_rbac_url(self): options = self.parser.parse_args( ['--rbac-url', 'http://rbac.example.com/']) self.assertEqual('http://rbac.example.com/', options.rbac_url)
class TestCmdConfig(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_config(self.parser) self.patch(os, "getuid").return_value = 0 snap_common = self.make_dir() snap_data = self.make_dir() self.useFixture(EnvironmentVariableFixture("SNAP_COMMON", snap_common)) self.useFixture(EnvironmentVariableFixture("SNAP_DATA", snap_data)) def test_show(self): # Regression test for LP:1892868 stdout = io.StringIO() self.patch(sys, "stdout", stdout) options = self.parser.parse_args([]) self.assertIsNone(self.cmd(options)) self.assertEqual(stdout.getvalue(), "Mode: none\n") def test_enable_debugging(self): mock_maas_configuration = self.patch(snappy, "MAASConfiguration") mock_sighup_supervisord = self.patch(snappy, "sighup_supervisord") options = self.parser.parse_args(["--enable-debug"]) stdout = io.StringIO() self.patch(sys, "stdout", stdout) self.cmd(options) mock_maas_configuration().update.assert_called_once_with( {"debug": True} ) # After config is changed, services are restarted self.assertEqual(stdout.getvalue(), "Stopping services\n") mock_sighup_supervisord.assert_called_once_with() def test_reenable_debugging(self): mock_maas_configuration = self.patch(snappy, "MAASConfiguration") config_manager = mock_maas_configuration() mock_sighup_supervisord = self.patch(snappy, "sighup_supervisord") options = self.parser.parse_args(["--enable-debug"]) stdout = io.StringIO() self.patch(sys, "stdout", stdout) # Simulate the value already being enabled current_config = config_manager.get() current_config.get.side_effect = {"debug": True}.__getitem__ self.cmd(options) config_manager.update.assert_not_called() self.assertEqual(stdout.getvalue(), "") mock_sighup_supervisord.assert_not_called()
def test_requires_root(self): parser = ArgumentParser() cmd = snappy.cmd_status(parser) self.patch(os, "getuid").return_value = 1000 error = self.assertRaises(SystemExit, cmd, parser.parse_args([])) self.assertEqual(str(error), "The 'status' command must be run by root.")
def test_cmd_configure_supervisord(self): self.patch(snappy, "get_current_mode").return_value = "region+rack" mock_render_supervisord = self.patch(snappy, "render_supervisord") mock_sighup_supervisord = self.patch(snappy, "sighup_supervisord") parser = ArgumentParser() cmd = snappy.cmd_reconfigure_supervisord(parser) cmd(parser.parse_args([])) mock_render_supervisord.assert_called_once_with("region+rack") mock_sighup_supervisord.assert_called_once()
class TestAddRBACOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_rbac_options(self.parser) def test_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.rbac_url) def test_rbac_url(self): options = self.parser.parse_args( ["--rbac-url", "http://rbac.example.com/"]) self.assertEqual("http://rbac.example.com/", options.rbac_url) def test_rbac_service_name(self): options = self.parser.parse_args(["--rbac-service-name", "mymaas"]) self.assertEqual(options.rbac_service_name, "mymaas")
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = cli.cmd_init(self.parser) self.maas_region_path = init.get_maas_region_bin_path() self.call_mock = self.patch(init.subprocess, 'call') self.check_output_mock = self.patch(init.subprocess, 'check_output') self.check_output_mock.return_value = json.dumps( {'external_auth_url': ''}) # avoid printouts self.patch(sys, "stdout", StringIO()) def test_defaults(self): options = self.parser.parse_args([]) self.assertFalse(options.skip_admin) self.assertIsNone(options.admin_username) self.assertIsNone(options.admin_password) self.assertIsNone(options.admin_email) self.assertIsNone(options.admin_ssh_import) self.assertFalse(options.enable_idm) self.assertIsNone(options.idm_url) self.assertIsNone(options.idm_user) self.assertIsNone(options.idm_key) self.assertIsNone(options.idm_agent_file) def test_init_maas_no_idm(self): options = self.parser.parse_args([]) self.cmd(options) [createadmin_call] = self.call_mock.mock_calls _, args, kwargs = createadmin_call self.assertEqual(([self.maas_region_path, 'createadmin'], ), args) self.assertEqual({}, kwargs) def test_init_maas_with_idm(self): options = self.parser.parse_args(['--enable-idm']) self.cmd(options) configauth_call, createadmin_call = self.call_mock.mock_calls _, args1, kwargs1 = configauth_call _, args2, kwargs2 = createadmin_call self.assertEqual(([self.maas_region_path, 'configauth'], ), args1) self.assertEqual({}, kwargs1) self.assertEqual(([self.maas_region_path, 'createadmin'], ), args2) self.assertEqual({}, kwargs2)
class TestAddCandidOptions(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_candid_options(self.parser) self.mock_stderr = self.patch(init.sys, "stderr", StringIO()) def test_add_candid_options_empty(self): options = self.parser.parse_args([]) self.assertIsNone(options.candid_url) self.assertIsNone(options.candid_user) self.assertIsNone(options.candid_key) self.assertIsNone(options.candid_agent_file) def test_add_candid_options_candid_url(self): options = self.parser.parse_args( ['--idm-url', 'http://candid.example.com/']) self.assertEqual( 'http://candid.example.com/', options.candid_url) def test_add_candid_options_candid_domain(self): options = self.parser.parse_args( ['--candid-domain', 'mydomain']) self.assertEqual('mydomain', options.candid_domain) def test_add_candid_options_candid_user(self): options = self.parser.parse_args(['--idm-user', 'my-user']) self.assertEqual('my-user', options.candid_user) def test_add_candid_options_candid_key(self): options = self.parser.parse_args(['--idm-key', 'my-key']) self.assertEqual('my-key', options.candid_key) def test_add_candid_options_candid_agent_file(self): options = self.parser.parse_args(['--candid-agent-file', 'agent.file']) self.assertEqual(options.candid_agent_file, 'agent.file') def test_add_candid_options_deprecated_idm_agent_file(self): options = self.parser.parse_args(['--idm-agent-file', 'agent.file']) self.assertEqual(options.candid_agent_file, 'agent.file') self.assertIn( 'Note: "--idm-agent-file" is deprecated and will be removed, ' 'please use "--candid-agent-file" instead', self.mock_stderr.getvalue()) def test_add_candid_options_candid_admin_group(self): options = self.parser.parse_args( ['--candid-admin-group', 'admins']) self.assertEqual('admins', options.candid_admin_group)
class TestCreateAdminAccount(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_create_admin_options(self.parser) self.mock_call = self.patch(init.subprocess, "call") self.mock_print_msg = self.patch(init, "print_msg") self.maas_region_path = init.get_maas_region_bin_path() def test_no_options(self): options = self.parser.parse_args([]) init.create_admin_account(options) self.mock_print_msg.assert_called_with("Create first admin account") self.mock_call.assert_called_with( [self.maas_region_path, "createadmin"]) def test_username(self): options = self.parser.parse_args(["--admin-username", "my-user"]) init.create_admin_account(options) self.mock_print_msg.assert_called_with("Create first admin account") self.mock_call.assert_called_with( [self.maas_region_path, "createadmin", "--username", "my-user"]) def test_password(self): options = self.parser.parse_args(["--admin-password", "my-pass"]) init.create_admin_account(options) self.mock_print_msg.assert_called_with("Create first admin account") self.mock_call.assert_called_with( [self.maas_region_path, "createadmin", "--password", "my-pass"]) def test_email(self): options = self.parser.parse_args(["--admin-email", "*****@*****.**"]) init.create_admin_account(options) self.mock_print_msg.assert_called_with("Create first admin account") self.mock_call.assert_called_with([ self.maas_region_path, "createadmin", "--email", "*****@*****.**" ]) def test_ssh_import(self): options = self.parser.parse_args(["--admin-ssh-import", "lp:me"]) init.create_admin_account(options) self.mock_print_msg.assert_called_with("Create first admin account") self.mock_call.assert_called_with( [self.maas_region_path, "createadmin", "--ssh-import", "lp:me"]) def test_no_print_header(self): options = self.parser.parse_args([ "--admin-username", "my-user", "--admin-password", "my-pass", "--admin-email", "*****@*****.**", ]) init.create_admin_account(options) self.mock_print_msg.assert_not_called()
class TestCreateAdminAccount(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() init.add_create_admin_options(self.parser) self.mock_call = self.patch(init.subprocess, 'call') self.mock_print_msg = self.patch(init, 'print_msg') self.maas_region_path = init.get_maas_region_bin_path() def test_no_options(self): options = self.parser.parse_args([]) init.create_admin_account(options) self.mock_print_msg.assert_called_with('Create first admin account') self.mock_call.assert_called_with( [self.maas_region_path, 'createadmin']) def test_username(self): options = self.parser.parse_args(['--admin-username', 'my-user']) init.create_admin_account(options) self.mock_print_msg.assert_called_with('Create first admin account') self.mock_call.assert_called_with( [self.maas_region_path, 'createadmin', '--username', 'my-user']) def test_password(self): options = self.parser.parse_args(['--admin-password', 'my-pass']) init.create_admin_account(options) self.mock_print_msg.assert_called_with('Create first admin account') self.mock_call.assert_called_with( [self.maas_region_path, 'createadmin', '--password', 'my-pass']) def test_email(self): options = self.parser.parse_args(['--admin-email', '*****@*****.**']) init.create_admin_account(options) self.mock_print_msg.assert_called_with('Create first admin account') self.mock_call.assert_called_with( [self.maas_region_path, 'createadmin', '--email', '*****@*****.**']) def test_ssh_import(self): options = self.parser.parse_args(['--admin-ssh-import', 'lp:me']) init.create_admin_account(options) self.mock_print_msg.assert_called_with('Create first admin account') self.mock_call.assert_called_with( [self.maas_region_path, 'createadmin', '--ssh-import', 'lp:me']) def test_no_print_header(self): options = self.parser.parse_args( ['--admin-username', 'my-user', '--admin-password', 'my-pass', '--admin-email', '*****@*****.**']) init.create_admin_account(options) self.mock_print_msg.assert_not_called()
class TestCmdConfig(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_config(self.parser) self.patch(os, "getuid").return_value = 0 snap_common = self.make_dir() snap_data = self.make_dir() self.useFixture(EnvironmentVariableFixture("SNAP_COMMON", snap_common)) self.useFixture(EnvironmentVariableFixture("SNAP_DATA", snap_data)) def test_show(self): # Regression test for LP:1892868 stdout = io.StringIO() self.patch(sys, "stdout", stdout) options = self.parser.parse_args([]) self.assertIsNone(self.cmd(options)) self.assertEqual(stdout.getvalue(), "Mode: none\n")
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_init(self.parser) self.patch(os, "getuid").return_value = 0 self.patch( os, "environ", { "SNAP": "/snap/maas", "SNAP_COMMON": "/snap/maas/common", "SNAP_DATA": "/snap/maas/data", }, ) self.mock_read_input = self.patch(snappy, "read_input") def test_init_snap_db_options_prompt(self): self.mock_maas_configuration = self.patch(snappy, "MAASConfiguration") self.patch(snappy, "set_rpc_secret") self.patch(snappy.cmd_init, "_finalize_init") self.mock_read_input.side_effect = [ "http://localhost:5240/MAAS", "localhost", "db", "maas", "pwd", ] options = self.parser.parse_args(["--mode=region+rack"]) self.cmd(options) self.mock_maas_configuration().update.assert_called_once_with({ "maas_url": "http://localhost:5240/MAAS", "database_host": "localhost", "database_name": "db", "database_user": "******", "database_pass": "******", })
def test_handlers_registered_using_correct_names(self): profile = self.make_profile() parser = ArgumentParser() api.register_api_commands(parser) for resource in profile.values()[0]["description"]["resources"]: for action in resource["auth"]["actions"]: # Profile names are matched as-is. profile_name = profile.keys()[0] # Handler names are processed with handler_command_name before # being added to the argument parser tree. handler_name = handler_command_name(resource["name"]) # Action names are processed with safe_name before being added # to the argument parser tree. action_name = safe_name(action["name"]) # Parsing these names as command-line arguments yields an # options object. Its execute attribute is an instance of # Action (or a subclass thereof). options = parser.parse_args( (profile_name, handler_name, action_name)) self.assertIsInstance(options.execute, api.Action)
def test_handlers_registered_using_correct_names(self): profile = self.make_profile() parser = ArgumentParser() api.register_api_commands(parser) for resource in list(profile.values())[0]["description"]["resources"]: for action in resource["auth"]["actions"]: # Profile names are matched as-is. [profile_name] = profile # Handler names are processed with handler_command_name before # being added to the argument parser tree. handler_name = handler_command_name(resource["name"]) # Action names are processed with safe_name before being added # to the argument parser tree. action_name = safe_name(action["name"]) # Parsing these names as command-line arguments yields an # options object. Its execute attribute is an instance of # Action (or a subclass thereof). options = parser.parse_args( (profile_name, handler_name, action_name)) self.assertIsInstance(options.execute, api.Action)
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_init(self.parser) self.patch(os, 'getuid').return_value = 0 self.patch( os, 'environ', { 'SNAP': '/snap/maas', 'SNAP_COMMON': '/snap/maas/common', 'SNAP_DATA': '/snap/maas/data' }) self.mock_read_input = self.patch(snappy, 'read_input') def test_init_snap_db_options_prompt(self): self.mock_maas_configuration = self.patch(snappy, 'MAASConfiguration') self.patch(snappy, 'set_rpc_secret') self.patch(snappy.cmd_init, '_finalize_init') self.mock_read_input.side_effect = [ 'http://localhost:5240/MAAS', 'localhost', 'db', 'maas', 'pwd' ] options = self.parser.parse_args(['--mode=region+rack']) self.cmd(options) self.mock_maas_configuration().update.assert_called_once_with({ 'maas_url': 'http://localhost:5240/MAAS', 'database_host': 'localhost', 'database_name': 'db', 'database_user': '******', 'database_pass': '******' })
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = cli.cmd_init(self.parser) self.maas_region_path = init.get_maas_region_bin_path() self.call_mock = self.patch(init.subprocess, 'call') self.check_output_mock = self.patch(init.subprocess, 'check_output') self.check_output_mock.return_value = json.dumps( {'external_auth_url': ''}) # avoid printouts self.mock_stdout = self.patch(init.sys, "stdout", StringIO()) self.mock_stderr = self.patch(init.sys, "stderr", StringIO()) def test_defaults(self): options = self.parser.parse_args([]) self.assertFalse(options.skip_admin) self.assertIsNone(options.admin_username) self.assertIsNone(options.admin_password) self.assertIsNone(options.admin_email) self.assertIsNone(options.admin_ssh_import) self.assertFalse(options.enable_candid) self.assertIsNone(options.candid_url) self.assertIsNone(options.candid_user) self.assertIsNone(options.candid_key) self.assertIsNone(options.candid_agent_file) self.assertIsNone(options.rbac_url) def test_init_maas_no_candid(self): options = self.parser.parse_args([]) self.cmd(options) [createadmin_call] = self.call_mock.mock_calls _, args, kwargs = createadmin_call self.assertEqual(([self.maas_region_path, 'createadmin'], ), args) self.assertEqual({}, kwargs) def test_init_maas_with_candid(self): options = self.parser.parse_args(['--enable-candid']) self.cmd(options) configauth_call, createadmin_call = self.call_mock.mock_calls _, args1, kwargs1 = configauth_call _, args2, kwargs2 = createadmin_call self.assertEqual(([self.maas_region_path, 'configauth'], ), args1) self.assertEqual({}, kwargs1) self.assertEqual(([self.maas_region_path, 'createadmin'], ), args2) self.assertEqual({}, kwargs2) def test_init_maas_with_legacy_idm_option(self): options = self.parser.parse_args(['--enable-idm']) self.cmd(options) configauth_call, createadmin_call = self.call_mock.mock_calls _, args1, kwargs1 = configauth_call _, args2, kwargs2 = createadmin_call self.assertEqual(([self.maas_region_path, 'configauth'], ), args1) self.assertEqual({}, kwargs1) self.assertEqual(([self.maas_region_path, 'createadmin'], ), args2) self.assertEqual({}, kwargs2) self.assertIn( 'Note: "--enable-idm" is deprecated and will be removed, ' 'please use "--enable-candid" instead', self.mock_stderr.getvalue())
class TestCmdInit(MAASTestCase): def setUp(self): super().setUp() self.parser = ArgumentParser() self.cmd = snappy.cmd_init(self.parser) self.patch(os, "getuid").return_value = 0 self.snap_common = self.make_dir() self.patch( os, "environ", { "SNAP": "/snap/maas", "SNAP_COMMON": self.snap_common, "SNAP_DATA": "/snap/maas/data", }, ) self.mock_read_input = self.patch(snappy, "read_input") def test_init_snap_db_options_prompt(self): self.mock_maas_configuration = self.patch(snappy, "MAASConfiguration") self.patch(snappy, "set_rpc_secret") self.patch(snappy.cmd_init, "_finalize_init") self.mock_read_input.side_effect = [ "postgres://*****:*****@localhost/db", "http://*****:*****@dbhost/dbname", ] ) settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": "dbhost", "database_name": "dbname", "database_user": "******", "database_pass": "******", }, settings, ) def test_get_database_settings_prompt_dsn(self): self.mock_read_input.side_effect = [ "postgres://*****:*****@dbhost/dbname" ] options = self.parser.parse_args(["region+rack"]) settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": "dbhost", "database_name": "dbname", "database_user": "******", "database_pass": "******", }, settings, ) def test_get_database_settings_maas_test_db_prompt_default(self): options = self.parser.parse_args(["region+rack"]) os.mkdir(os.path.join(self.snap_common, "test-db-socket")) self.mock_read_input.side_effect = [""] settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": f"{self.snap_common}/test-db-socket", "database_name": "maasdb", "database_user": "******", "database_pass": None, }, settings, ) def test_get_database_settings_maas_test_db_prompt_no_default(self): options = self.parser.parse_args(["region+rack"]) self.mock_read_input.side_effect = ["", "postgres:///?user=foo"] settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": "localhost", "database_name": "foo", "database_user": "******", "database_pass": None, }, settings, ) def test_get_database_settings_maas_test_db(self): options = self.parser.parse_args( ["region+rack", "--database-uri", "maas-test-db:///"] ) settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": f"{self.snap_common}/test-db-socket", "database_name": "maasdb", "database_user": "******", "database_pass": None, }, settings, ) def test_get_database_settings_minimal_postgres(self): options = self.parser.parse_args( ["region+rack", "--database-uri", "postgres:///?user=myuser"] ) settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": "localhost", "database_name": "myuser", "database_user": "******", "database_pass": None, }, settings, ) def test_get_database_settings_full_postgres(self): options = self.parser.parse_args( [ "region+rack", "--database-uri", "postgres://*****:*****@myhost:1234/mydb", ] ) settings = snappy.get_database_settings(options) self.assertEqual( { "database_host": "myhost", "database_name": "mydb", "database_user": "******", "database_pass": "******", "database_port": 1234, }, settings, ) def test_get_database_settings_invalid_parameters(self): options = self.parser.parse_args( [ "region+rack", "--database-uri", "postgres://*****:*****@myhost:1234/mydb?foo=bar", ] ) error = self.assertRaises( snappy.DatabaseSettingsError, snappy.get_database_settings, options ) self.assertEqual( "Error parsing database URI: " 'invalid dsn: invalid URI query parameter: "foo"', str(error), ) def test_get_database_settings_unsupported_parameters(self): options = self.parser.parse_args( [ "region+rack", "--database-uri", "postgres://*****:*****@myhost/?passfile=foo&options=bar", ] ) error = self.assertRaises( snappy.DatabaseSettingsError, snappy.get_database_settings, options ) self.assertEqual( "Error parsing database URI: " "Unsupported parameters: options, passfile", str(error), ) def test_get_database_settings_missing_user(self): options = self.parser.parse_args( ["region+rack", "--database-uri", "postgres://myhost/"] ) error = self.assertRaises( snappy.DatabaseSettingsError, snappy.get_database_settings, options ) self.assertEqual( "No user found in URI: postgres://myhost/", str(error) ) def test_get_database_settings_invalid_maas_test_db(self): options = self.parser.parse_args( ["region+rack", "--database-uri", "maas-test-db:///foo"] ) error = self.assertRaises( snappy.DatabaseSettingsError, snappy.get_database_settings, options ) self.assertEqual( "Database URI needs to be either 'maas-test-db:///' or start with " "'postgres://'", str(error), ) def test_get_database_settings_incomplete_postgres_uri(self): # The URI needs to start with at least postgres:// before we # even try to parse it. options = self.parser.parse_args( ["region+rack", "--database-uri", "postgres:/"] ) error = self.assertRaises( snappy.DatabaseSettingsError, snappy.get_database_settings, options ) self.assertEqual( "Database URI needs to be either 'maas-test-db:///' or start with " "'postgres://'", str(error), )
class TestConfigureAuthentication(MAASTestCase): def setUp(self): super().setUp() self.maas_bin_path = 'snap-path/bin/maas-region' self.mock_subprocess = self.patch(init, 'subprocess') self.mock_environ = patch.dict(init.os.environ, {'SNAP': 'snap-path'}, clear=True) self.mock_environ.start() self.parser = ArgumentParser() init.add_rbac_options(self.parser) init.add_candid_options(self.parser) def tearDown(self): self.mock_subprocess.stop() self.mock_environ.stop() super().tearDown() def test_no_options(self): options = self.parser.parse_args([]) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual(([self.maas_bin_path, 'configauth'], ), args) self.assertEqual({}, kwargs) def test_rbac_url(self): config_auth_args = ['--rbac-url', 'http://rrbac.example.com/'] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual( ([self.maas_bin_path, 'configauth'] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_idm_url(self): config_auth_args = ['--idm-url', 'http://candid.example.com/'] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual( ([self.maas_bin_path, 'configauth'] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_idm_user(self): config_auth_args = ['--idm-user', 'some-user'] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual( ([self.maas_bin_path, 'configauth'] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_idm_key(self): config_auth_args = ['--idm-key', 'some-key'] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual( ([self.maas_bin_path, 'configauth'] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_candid_agent_file(self): _, agent_file_path = tempfile.mkstemp() self.addCleanup(os.remove, agent_file_path) config_auth_args = ['--candid-agent-file', agent_file_path] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual( ([self.maas_bin_path, 'configauth'] + config_auth_args, ), args) self.assertEqual({}, kwargs) def test_full(self): _, agent_file = tempfile.mkstemp() self.addCleanup(os.remove, agent_file) config_auth_args = [ '--idm-url', 'http://candid.example.com/', '--idm-user', 'candid-user', '--idm-key', 'candid-key', '--candid-agent-file', agent_file ] options = self.parser.parse_args(config_auth_args) init.configure_authentication(options) [config_call] = self.mock_subprocess.mock_calls method, args, kwargs = config_call self.assertEqual('call', method) self.assertEqual( ([self.maas_bin_path, 'configauth'] + config_auth_args, ), args) self.assertEqual({}, kwargs)