def test_fetch_objs_internal_error(self):
        """Test whether a log error message is thrown when an internal error occurs with the method fetch_objs"""

        saved_objs_error = read_file('data/objects_error')
        saved_objs_empty = read_file('data/objects_empty')

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=2',
                               body=saved_objs_empty,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=1',
                               body=saved_objs_error,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger, level='ERROR') as cm:
            _ = [
                obj for page_objs in client.fetch_objs(SAVED_OBJECTS_URL)
                for obj in page_objs
            ]
            self.assertEqual(
                cm.output[0],
                'ERROR:archimedes.clients.saved_objects:Impossible to retrieve objects at page 1, '
                'url http://example.com/api/saved_objects, An internal server error occurred'
            )
    def test_fetch_objs_http_error_500(self):
        """Test whether a warning is logged when a 500 HTTP error occurs"""

        saved_objs_page_1 = read_file('data/objects_1')
        saved_objs_page_2 = read_file('data/objects_2')
        saved_objs_page_3 = read_file('data/objects_empty')

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=3',
                               body=saved_objs_page_3,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=2',
                               body=saved_objs_page_2,
                               status=500)

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=1',
                               body=saved_objs_page_1,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger) as cm:
            _ = [
                obj for page_objs in client.fetch_objs(SAVED_OBJECTS_URL)
                for obj in page_objs
            ]

        self.assertEqual(
            cm.output[0],
            'WARNING:archimedes.clients.saved_objects:Impossible to retrieve objects at page 2, '
            'url http://example.com/api/saved_objects')
    def test_create_object_http_error(self):
        """Test whether an exception is thrown if create_object fails"""

        obj_data = read_file('data/object_index-pattern')
        attributes = json.loads(obj_data)['attributes']
        httpretty.register_uri(httpretty.POST,
                               OBJECT_URL,
                               body=obj_data,
                               status=500)

        client = SavedObjects(KIBANA_URL)
        with self.assertRaises(requests.exceptions.HTTPError):
            _ = client.create_object(OBJECT_TYPE, OBJECT_ID, attributes)
    def test_delete_object_http_error(self):
        """Test whether an exception is thrown when the HTTP error is not 404"""

        obj_data = read_file('data/object_index-pattern')

        httpretty.register_uri(httpretty.DELETE,
                               OBJECT_URL,
                               body=obj_data,
                               status=500)

        client = SavedObjects(KIBANA_URL)
        with self.assertRaises(requests.exceptions.HTTPError):
            _ = client.delete_object(OBJECT_TYPE, OBJECT_ID)
    def test_get_object(self):
        """Test the method get_object"""

        obj_data = read_file('data/object_index-pattern')

        httpretty.register_uri(httpretty.GET,
                               OBJECT_URL,
                               body=obj_data,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        obj = client.get_object(OBJECT_TYPE, OBJECT_ID)
        self.assertDictEqual(obj, json.loads(obj_data))
    def test_delete_object(self):
        """Test the method delete_object"""

        httpretty.register_uri(httpretty.DELETE,
                               OBJECT_URL,
                               body="{}",
                               status=200)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger, level='INFO') as cm:
            _ = client.delete_object(OBJECT_TYPE, OBJECT_ID)
            self.assertEqual(
                cm.output[0], 'INFO:archimedes.clients.saved_objects:'
                'Object ' + OBJECT_TYPE + ' with id ' + OBJECT_ID + ' deleted')
    def test_update_object_http_error(self):
        """Test whether an exception is thrown when the HTTP error is not 404 or 400"""

        obj_data = read_file('data/object_index-pattern')
        attributes = {"version": "2"}

        httpretty.register_uri(httpretty.PUT,
                               OBJECT_URL,
                               body=obj_data,
                               status=500)

        client = SavedObjects(KIBANA_URL)
        with self.assertRaises(requests.exceptions.HTTPError):
            _ = client.update_object(OBJECT_TYPE, OBJECT_ID, attributes)
    def test_fetch_objs(self):
        """Test whether objects are correctly returned by the method fetch_objs"""

        saved_objs_page_1 = read_file('data/objects_1')
        saved_objs_page_2 = read_file('data/objects_2')
        saved_objs_page_3 = read_file('data/objects_empty')

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=3',
                               body=saved_objs_page_3,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=2',
                               body=saved_objs_page_2,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=1',
                               body=saved_objs_page_1,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        fetched_objs = [
            obj for page_objs in client.fetch_objs(SAVED_OBJECTS_URL)
            for obj in page_objs
        ]
        self.assertEqual(len(fetched_objs), 4)

        obj = fetched_objs[0]
        self.assertEqual(obj['id'], "0b84fff0-b1b6-11e8-8aac-ef7fd4d8cbad")
        self.assertEqual(obj['type'], "visualization")
        self.assertEqual(obj["version"], 1)

        obj = fetched_objs[1]
        self.assertEqual(obj['id'], "00cf9cf0-d074-11e8-8aac-ef7fd4d8cbad")
        self.assertEqual(obj['type'], "visualization")
        self.assertEqual(obj["version"], 1)

        obj = fetched_objs[2]
        self.assertEqual(obj['id'], "1a23fbd0-bc0e-11e8-8aac-ef7fd4d8cbad")
        self.assertEqual(obj['type'], "visualization")
        self.assertEqual(obj["version"], 2)

        obj = fetched_objs[3]
        self.assertEqual(obj['id'], "00fee5a0-7eb7-11e8-a4e7-6b1c6a13c58d")
        self.assertEqual(obj['type'], "visualization")
        self.assertEqual(obj["version"], 1)
    def test_fetch_objs_http_error(self):
        """Test whether an exception is thrown when the HTTP error is not 500"""

        saved_objs_page = read_file('data/objects_1')

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL,
                               body=saved_objs_page,
                               status=404)

        client = SavedObjects(KIBANA_URL)
        with self.assertRaises(requests.exceptions.HTTPError):
            _ = [
                obj for page_objs in client.fetch_objs(SAVED_OBJECTS_URL)
                for obj in page_objs
            ]
Esempio n. 10
0
    def test_fetch_objs_empty(self):
        """Test whether no objects are returned by the method fetch_objs"""

        saved_objs_empty = read_file('data/objects_empty')

        httpretty.register_uri(httpretty.GET,
                               SAVED_OBJECTS_URL + '?page=1',
                               body=saved_objs_empty,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        fetched_objs = [
            obj for page_objs in client.fetch_objs(SAVED_OBJECTS_URL)
            for obj in page_objs
        ]
        self.assertEqual(len(fetched_objs), 0)
Esempio n. 11
0
    def test_delete_object_not_found(self):
        """Test whether a warning is logged when the object is not found"""

        obj_data = read_file('data/object_index-pattern')

        httpretty.register_uri(httpretty.DELETE,
                               OBJECT_URL,
                               body=obj_data,
                               status=404)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger, level='WARNING') as cm:
            obj = client.delete_object(OBJECT_TYPE, OBJECT_ID)
            self.assertEqual(
                cm.output[0], 'WARNING:archimedes.clients.saved_objects:'
                'No ' + OBJECT_TYPE + ' found with id: ' + OBJECT_ID)
            self.assertIsNone(obj)
Esempio n. 12
0
    def test_create_object(self):
        """Test the method create_object"""

        obj_data = read_file('data/object_index-pattern')
        attributes = json.loads(obj_data)['attributes']
        httpretty.register_uri(httpretty.POST,
                               OBJECT_URL,
                               body=obj_data,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger, level='INFO') as cm:
            obj = client.create_object(OBJECT_TYPE, OBJECT_ID, attributes)
            self.assertEqual(
                cm.output[0], 'INFO:archimedes.clients.saved_objects:'
                'Object ' + OBJECT_TYPE + ' with id ' + OBJECT_ID + ' create')
            self.assertDictEqual(obj, json.loads(obj_data))
Esempio n. 13
0
    def test_update_object_not_updated(self):
        """Test whether a warning is logged when the object is not updated"""

        obj_data = read_file('data/object_index-pattern')
        attributes = {"version": "2"}

        httpretty.register_uri(httpretty.PUT,
                               OBJECT_URL,
                               body=obj_data,
                               status=400)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger, level='WARNING') as cm:
            obj = client.update_object(OBJECT_TYPE, OBJECT_ID, attributes)
            self.assertEqual(
                cm.output[0],
                'WARNING:archimedes.clients.saved_objects:Impossible to update '
                'the object ' + OBJECT_TYPE + ' with id ' + OBJECT_ID)
            self.assertIsNone(obj)
Esempio n. 14
0
    def test_initialization(self):
        """Test whether attributes are initialized"""

        client = SavedObjects(KIBANA_URL)

        self.assertEqual(client.base_url, KIBANA_URL)
        self.assertIsNotNone(client.session)
        self.assertEqual(client.session.headers['kbn-xsrf'],
                         HEADERS.get('kbn-xsrf'))
        self.assertEqual(client.session.headers['Content-Type'],
                         HEADERS.get('Content-Type'))
Esempio n. 15
0
    def test_update_object(self):
        """Test the method update_object"""

        obj_data = read_file('data/object_index-pattern')
        obj_attr = "version"
        obj_new_value = "2"

        httpretty.register_uri(httpretty.PUT,
                               OBJECT_URL,
                               body=obj_data,
                               status=200)

        client = SavedObjects(KIBANA_URL)
        with self.assertLogs(logger, level='INFO') as cm:
            obj = client.update_object(OBJECT_TYPE, OBJECT_ID, obj_attr,
                                       obj_new_value)
            self.assertEqual(
                cm.output[0], 'INFO:archimedes.clients.saved_objects:'
                'Object ' + OBJECT_TYPE + ' with id ' + OBJECT_ID + ' updated')
            self.assertDictEqual(obj, json.loads(obj_data))
Esempio n. 16
0
def set_kibiter_config(kibiter_url,
                       kibiter_time_from='now-90d',
                       kibiter_index_pattern='git',
                       kibiter_version='6.8.6',
                       overwrite=True):
    """Set the configuration of the Kibiter instance via the Kibana API

    :param kibiter_url: Kibiter URL
    :param kibiter_time_from: The value of the time picker
    :param kibiter_index_pattern: The value of the default index pattern
    :param kibiter_version: The value of the Kibiter version
    :param overwrite: If True, force the overwrite of existing dashboards
    """
    attributes = {}
    time_picker = {"from": kibiter_time_from, "to": "now", "mode": "quick"}
    attributes["timepicker:timeDefaults"] = json.dumps(time_picker)
    attributes["defaultIndex"] = kibiter_index_pattern

    saved_objects = SavedObjects(kibiter_url)
    saved_objects.create_object('config',
                                kibiter_version,
                                attributes,
                                overwrite=overwrite)
Esempio n. 17
0
 def __init__(self, base_url):
     self.base_url = base_url
     self.dashboard = Dashboard(base_url)
     self.saved_objects = SavedObjects(base_url)
Esempio n. 18
0
class Kibana:
    """Kibana class.

    This class defines operations performed against the Dashboard and
    the SavedObjects APIs, such as exporting and importing objects as well
    as searching objects by ID or title.

    :param base_url: the Kibana URL
    """
    def __init__(self, base_url):
        self.base_url = base_url
        self.dashboard = Dashboard(base_url)
        self.saved_objects = SavedObjects(base_url)

    def export_by_id(self, obj_type, obj_id):
        """Export an object identified by its ID.

        This method returns an object saved in Kibana based on its type and ID.

        An `ObjectTypeError` is thrown if the type of the object is not one of
        the following: dashboard, index pattern, search, visualization.

        A `NotFoundError` is thrown if the object is not found in the Kibana instance.

        :param obj_type: type of the target object
        :param obj_id: ID of the target object

        :returns the target Kibana object
        """
        if obj_type == DASHBOARD:
            obj = self.dashboard.export_dashboard(obj_id)
        elif obj_type in [INDEX_PATTERN, SEARCH, VISUALIZATION]:
            obj = self.saved_objects.get_object(obj_type, obj_id)
        else:
            cause = "Unknown type %s" % obj_type
            logger.error(cause)
            raise ObjectTypeError(cause=cause)

        if not obj:
            cause = "Impossible to export %s with id %s, not found" % (
                obj_type, obj_id)
            logger.error(cause)
            raise NotFoundError(cause=cause)

        return obj

    def export_by_title(self, obj_type, obj_title):
        """Export an object identified by its title.

        This method returns an object saved in Kibana based on its type and title.

        An `ObjectTypeError` is thrown if the type of the object is not one of
        the following: dashboard, index pattern, search, visualization.

        A `NotFoundError` is thrown if the object is not found in the Kibana instance.

        :param obj_type: type of the target object
        :param obj_title: title of the target object

        :returns the target Kibana object
        """
        if obj_type not in [DASHBOARD, INDEX_PATTERN, SEARCH, VISUALIZATION]:
            cause = "Unknown type %s" % obj_type
            logger.error(cause)
            raise ObjectTypeError(cause=cause)

        obj = self.find_by_title(obj_type, obj_title)

        if obj_type == DASHBOARD:
            obj_id = obj['id']
            obj = self.dashboard.export_dashboard(obj_id)

        if not obj:
            cause = "Impossible to export %s with title %s, not found" % (
                obj_type, obj_title)
            logger.error(cause)
            raise NotFoundError(cause=cause)

        return obj

    def import_objects(self, objects, force=False):
        """Import a list of objects to Kibana.

        This method imports a list of Kibana objects to Kibana by using the Dashboard API.

        :param objects: list of objects to import
        :param force: overwrite any existing objects on ID conflict
        """
        self.dashboard.import_objects(objects, force=force)

    def find_by_title(self, obj_type, obj_title):
        """Find an object by its type and title.

        This methods returns a Kibana object based on its type and title.

        A `NotFoundError` is thrown if the object is not found in the Kibana instance.

        :param obj_type: type of the target object
        :param obj_title: title of the target object

        :returns the target object or None if not found
        """
        url = urijoin(self.base_url, self.saved_objects.API_SAVED_OBJECTS_URL)
        found_obj = None

        for page_objs in self.saved_objects.fetch_objs(url):
            for obj in page_objs:
                if obj['type'] == obj_type and obj['attributes'][
                        'title'] == obj_title:
                    found_obj = obj
                    break

        if not found_obj:
            cause = "No %s found with title: %s" % (obj_type, obj_title)
            logger.error(cause)
            raise NotFoundError(cause=cause)

        return found_obj

    def find_by_id(self, obj_type, obj_id):
        """Find an object by its type and ID.

        This methods returns a Kibana object based on its type and ID.

        A `NotFoundError` is thrown if the object is not found in the Kibana instance.

        :param obj_type: type of the target object
        :param obj_id: ID of the target object

        :returns the target object or None if not found
        """
        url = urijoin(self.base_url, self.saved_objects.API_SAVED_OBJECTS_URL)
        found_obj = None

        for page_objs in self.saved_objects.fetch_objs(url):
            for obj in page_objs:
                if obj['type'] == obj_type and obj['id'] == obj_id:
                    found_obj = obj
                    break

        if not found_obj:
            cause = "No %s found with ID: %s" % (obj_type, obj_id)
            logger.error(cause)
            raise NotFoundError(cause=cause)

        return found_obj

    def find_all(self):
        """Find all objects stored in Kibana.

        This method returns all remote Kibana objects using the SavedObject API.

        :returns a generator of Kibana objects
        """
        url = urijoin(self.base_url, self.saved_objects.API_SAVED_OBJECTS_URL)

        for page_objs in self.saved_objects.fetch_objs(url):
            for obj in page_objs:
                yield obj