Пример #1
0
    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))
Пример #2
0
    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()
Пример #3
0
    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",
        )
Пример #4
0
    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),
        )
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
 def find_unique_system_none(self):
     system = System.find_unique("foo", "1.0.0")
     assert system is None
Пример #8
0
 def find_unique_system(self):
     system = System.find_unique("foo", "0.0.0")
     assert system == 1
Пример #9
0
 def tearDown(self):
     self.default_system = None
     System.drop_collection()
Пример #10
0
 def setUp(self):
     self.default_system = System(name="foo", version="1.0.0")
Пример #11
0
def setup_systems(app, mongo_system):
    System.drop_collection()
    mongo_system.deep_save()
Пример #12
0
 def test_find_unique_system_none(self):
     self.assertIsNone(System.find_unique("foo", "1.0.0"))
Пример #13
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"))
Пример #14
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
        )
Пример #15
0
def drop_systems(app):
    System.drop_collection()