def post(self): """ --- summary: Create a new System or update an existing System description: | If the System does not exist it will be created. If the System already exists it will be updated (assuming it passes validation). parameters: - name: system in: body description: The System definition to create / update schema: $ref: '#/definitions/System' responses: 200: description: An existing System has been updated schema: $ref: '#/definitions/System' 201: description: A new System has been created schema: $ref: '#/definitions/System' 400: $ref: '#/definitions/400Error' 50x: $ref: '#/definitions/50xError' tags: - Systems """ self.request.event.name = Events.SYSTEM_CREATED.name system_model = self.parser.parse_system(self.request.decoded_body, from_string=True) with (yield self.system_lock.acquire()): # See if we already have a system with this name + version existing_system = System.find_unique(system_model.name, system_model.version) if not existing_system: self.logger.debug("Creating a new system: %s" % system_model.name) saved_system, status_code = self._create_new_system( system_model) else: self.logger.debug("System %s already exists. Updating it." % system_model.name) self.request.event.name = Events.SYSTEM_UPDATED.name saved_system, status_code = self._update_existing_system( existing_system, system_model) saved_system.deep_save() self.request.event_extras = {"system": saved_system} self.set_status(status_code) self.write( self.parser.serialize_system(saved_system, to_string=False, include_commands=True))
def setUp(self): self.default_command = Command(name="name", description="description") self.default_command.save = Mock() self.default_command.validate = Mock() self.default_command.delete = Mock() self.default_instance = Instance(name="default") self.default_instance.save = Mock() self.default_instance.validate = Mock() self.default_instance.delete = Mock() self.default_system = System( id="1234", name="foo", version="1.0.0", instances=[self.default_instance], commands=[self.default_command], ) self.default_system.save = Mock() self.default_system.validate = Mock() self.default_system.delete = Mock()
def setUp(self): self.app = brew_view.app.test_client() self.default_instance = Instance(name="default", status="RUNNING") self.default_command = Command( id="54ac18f778c4b57e963f3c18", name="command", description="foo" ) self.default_system = System( id="54ac18f778c4b57e963f3c18", name="default_system", version="1.0.0", instances=[self.default_instance], commands=[self.default_command], max_instances="1", )
def setUp(self): self.app = brew_view.app.test_client() self.default_instance = Instance(name="default", status="RUNNING") self.default_command = Command(id="54ac18f778c4b57e963f3c18", name="command", description="foo") self.default_system = System( id="54ac18f778c4b57e963f3c18", name="default_system", version="1.0.0", instances=[self.default_instance], commands=[self.default_command], max_instances="1", ) self.client_mock = Mock(name="client_mock") self.fake_context = MagicMock( __enter__=Mock(return_value=self.client_mock), __exit__=Mock(return_value=False), )
def get_and_validate_system(self, request): """Ensure there is a system in the DB that corresponds to this Request. :param request: The request to validate :return: The system corresponding to this Request :raises ModelValidationError: There is no system that corresponds to this Request """ system = System.find_unique(request.system, request.system_version) if system is None: raise ModelValidationError( "Could not find System named '%s' matching version '%s'" % (request.system, request.system_version)) if request.instance_name not in system.instance_names: raise ModelValidationError( "Could not find instance with name '%s' in system '%s'" % (request.instance_name, system.name)) self.logger.debug("Found System %s-%s" % (request.system, request.instance_name)) return system
def load_plugin(self, plugin_path): """Loads a plugin given a path to a plugin directory. It will use the validator to validate the plugin before registering the plugin in the database as well as adding an entry to the plugin map. :param plugin_path: The path of the plugin to load :return: The loaded plugin """ if not self.validator.validate_plugin(plugin_path): self.logger.warning( "Not loading plugin at %s because it was invalid.", plugin_path) return False config = self._load_plugin_config(join(plugin_path, "beer.conf")) plugin_name = config["NAME"] plugin_version = config["VERSION"] plugin_entry = config["PLUGIN_ENTRY"] plugin_instances = config["INSTANCES"] plugin_args = config["PLUGIN_ARGS"] # If this system already exists we need to do some stuff plugin_id = None plugin_commands = [] # TODO: replace this with a call from the EasyClient # plugin_system = self.easy_client.find_unique_system( # name=plugin_name, version=plugin_version) plugin_system = System.find_unique(plugin_name, plugin_version) if plugin_system: # Remove the current instances so they aren't left dangling # TODO: This should be replaced with a network call plugin_system.delete_instances() # Carry these over to the new system plugin_id = plugin_system.id plugin_commands = plugin_system.commands plugin_system = System( id=plugin_id, name=plugin_name, version=plugin_version, commands=plugin_commands, instances=[ Instance(name=instance_name) for instance_name in plugin_instances ], max_instances=len(plugin_instances), description=config.get("DESCRIPTION"), icon_name=config.get("ICON_NAME"), display_name=config.get("DISPLAY_NAME"), metadata=config.get("METADATA"), ) # TODO: Right now, we have to save this system because the LocalPluginRunner # uses the database to determine status, specifically, it calls reload on the # instance object which we need to change to satisfy plugin_system.deep_save() plugin_list = [] plugin_log_directory = bartender.config.plugin.local.log_directory for instance_name in plugin_instances: plugin = LocalPluginRunner( plugin_entry, plugin_system, instance_name, abspath(plugin_path), bartender.config.web.host, bartender.config.web.port, bartender.config.web.ssl_enabled, plugin_args=plugin_args.get(instance_name), environment=config["ENVIRONMENT"], requirements=config["REQUIRES"], plugin_log_directory=plugin_log_directory, url_prefix=bartender.config.web.url_prefix, ca_verify=bartender.config.web.ca_verify, ca_cert=bartender.config.web.ca_cert, username=bartender.config.plugin.local.auth.username, password=bartender.config.plugin.local.auth.password, log_level=config["LOG_LEVEL"], ) self.registry.register_plugin(plugin) plugin_list.append(plugin) return plugin_list
def find_unique_system_none(self): system = System.find_unique("foo", "1.0.0") assert system is None
def find_unique_system(self): system = System.find_unique("foo", "0.0.0") assert system == 1
def tearDown(self): self.default_system = None System.drop_collection()
def setUp(self): self.default_system = System(name="foo", version="1.0.0")
def setup_systems(app, mongo_system): System.drop_collection() mongo_system.deep_save()
def test_find_unique_system_none(self): self.assertIsNone(System.find_unique("foo", "1.0.0"))
def test_find_unique_system(self, objects_mock): objects_mock.get = Mock(return_value=self.default_system) self.assertEqual(self.default_system, System.find_unique("foo", "1.0.0"))
class SystemTest(unittest.TestCase): def setUp(self): self.default_command = Command(name="name", description="description") self.default_command.save = Mock() self.default_command.validate = Mock() self.default_command.delete = Mock() self.default_instance = Instance(name="default") self.default_instance.save = Mock() self.default_instance.validate = Mock() self.default_instance.delete = Mock() self.default_system = System( id="1234", name="foo", version="1.0.0", instances=[self.default_instance], commands=[self.default_command], ) self.default_system.save = Mock() self.default_system.validate = Mock() self.default_system.delete = Mock() def tearDown(self): self.default_system = None def test_str(self): self.assertEqual("foo-1.0.0", str(self.default_system)) def test_repr(self): self.assertNotEqual(-1, repr(self.default_system).find("foo")) self.assertNotEqual(-1, repr(self.default_system).find("1.0.0")) def test_clean(self): self.default_system.clean() def test_clean_fail_max_instances(self): self.default_system.instances.append(Instance(name="default2")) self.assertRaises(ModelValidationError, self.default_system.clean) def test_clean_fail_duplicate_instance_names(self): self.default_system.max_instances = 2 self.default_system.instances.append(Instance(name="default")) self.assertRaises(ModelValidationError, self.default_system.clean) @patch("bg_utils.mongo.models.System.objects") def test_find_unique_system(self, objects_mock): objects_mock.get = Mock(return_value=self.default_system) self.assertEqual(self.default_system, System.find_unique("foo", "1.0.0")) @patch( "bg_utils.mongo.models.System.objects", Mock(get=Mock(side_effect=mongoengine.DoesNotExist)), ) def test_find_unique_system_none(self): self.assertIsNone(System.find_unique("foo", "1.0.0")) def test_deep_save(self): self.default_system.deep_save() self.assertEqual(self.default_system.save.call_count, 2) self.assertEqual(len(self.default_system.commands), 1) self.assertEqual(self.default_command.system, self.default_system) self.assertEqual(self.default_command.save.call_count, 1) self.assertEqual(self.default_instance.save.call_count, 1) def test_deep_save_validate_exception(self): self.default_command.validate = Mock(side_effect=ValueError) self.assertRaises(ValueError, self.default_system.deep_save) self.assertEqual(self.default_system.commands, [self.default_command]) self.assertEqual(self.default_system.instances, [self.default_instance]) self.assertFalse(self.default_command.save.called) self.assertFalse(self.default_instance.save.called) self.assertFalse(self.default_system.delete.called) @patch("bg_utils.mongo.models.Command.validate", Mock()) @patch("bg_utils.mongo.models.Instance.validate", Mock()) def test_deep_save_save_exception(self): self.default_instance.save = Mock(side_effect=ValueError) self.assertRaises(ValueError, self.default_system.deep_save) self.assertEqual(self.default_system.commands, [self.default_command]) self.assertEqual(self.default_system.instances, [self.default_instance]) self.assertTrue(self.default_command.save.called) self.assertTrue(self.default_instance.save.called) self.assertFalse(self.default_system.delete.called) @patch("bg_utils.mongo.models.Command.validate", Mock()) @patch("bg_utils.mongo.models.Instance.validate", Mock()) def test_deep_save_save_exception_not_already_exists(self): self.default_instance.save = Mock(side_effect=ValueError) with patch( "bg_utils.mongo.models.System.id", new_callable=PropertyMock ) as id_mock: id_mock.side_effect = [None, "1234", "1234"] self.assertRaises(ValueError, self.default_system.deep_save) self.assertEqual(self.default_system.commands, [self.default_command]) self.assertEqual(self.default_system.instances, [self.default_instance]) self.assertTrue(self.default_command.save.called) self.assertTrue(self.default_instance.save.called) self.assertTrue(self.default_system.delete.called) def test_deep_delete(self): self.default_system.deep_delete() self.assertEqual(self.default_system.delete.call_count, 1) self.assertEqual(self.default_command.delete.call_count, 1) self.assertEqual(self.default_instance.delete.call_count, 1) # FYI - Have to mock out System.commands here or else MongoEngine # blows up trying to dereference them @patch("bg_utils.mongo.models.System.commands", Mock()) @patch("bg_utils.mongo.models.Command.objects") def test_upsert_commands_new(self, objects_mock): self.default_system.commands = [] objects_mock.return_value = [] new_command = Mock() self.default_system.upsert_commands([new_command]) self.assertTrue(new_command.save.called) self.assertTrue(self.default_system.save.called) self.assertEqual([new_command], self.default_system.commands) @patch("bg_utils.mongo.models.System.commands", Mock()) @patch("bg_utils.mongo.models.Command.objects") def test_upsert_commands_delete(self, objects_mock): old_command = Mock() objects_mock.return_value = [old_command] self.default_system.upsert_commands([]) self.assertTrue(old_command.delete.called) self.assertEqual([], self.default_system.commands) @patch("bg_utils.mongo.models.System.commands", Mock()) @patch("bg_utils.mongo.models.Command.objects") def test_upsert_commands_update(self, objects_mock): new_command = Mock(description="new desc") old_command = Mock(id="123", description="old desc") name_mock = PropertyMock(return_value="name") type(new_command).name = name_mock type(old_command).name = name_mock objects_mock.return_value = [old_command] self.default_system.upsert_commands([new_command]) self.assertTrue(self.default_system.save.called) self.assertTrue(new_command.save.called) self.assertFalse(old_command.delete.called) self.assertEqual([new_command], self.default_system.commands) self.assertEqual(old_command.id, self.default_system.commands[0].id) self.assertEqual( new_command.description, self.default_system.commands[0].description )
def drop_systems(app): System.drop_collection()