def test_get_slice_status_returns_populated_dictionary_when_it_gets_valid_statuses_and_one_whitespace_sliver_status(
            self):
        self.mock_urlopen_response.read.return_value = """
mock.mlab1.xyz01.measurement-lab.org/ndt 0 1 mock tool extra
\t\t
mock.mlab3.xyz01.measurement-lab.org/ndt 2 1 mock tool extra
""".lstrip()
        nagios_status.parse_sliver_tool_status.side_effect = [
            ('mock.mlab1.xyz01.measurement-lab.org', '0', 'mock tool extra'),
            ('mock.mlab3.xyz01.measurement-lab.org', '2', 'mock tool extra')
        ]

        expected_status = {
            'mock.mlab1.xyz01.measurement-lab.org': {
                'status': message.STATUS_ONLINE,
                'tool_extra': 'mock tool extra'
            },
            'mock.mlab3.xyz01.measurement-lab.org': {
                'status': message.STATUS_OFFLINE,
                'tool_extra': 'mock tool extra'
            }
        }

        actual_status = nagios_status.get_slice_status(
            'nagios.measurementlab.mock.net', self.opener)
        nagios_status.urllib2.OpenerDirector.open.assert_called_once_with(
            self.opener, 'nagios.measurementlab.mock.net')
        self.assertDictEqual(actual_status, expected_status)
    def test_get_slice_status_handles_NagiosStatusUnparseableError_from_one_status_in_parse_sliver_tool_status(
            self):
        self.mock_urlopen_response.read.return_value = """
mock.mlab1.xyz01.measurement-lab.org/ndt 0 1 mock tool extra
unparseable status
mock.mlab3.xyz01.measurement-lab.org/ndt 2 1 mock tool extra
""".lstrip()
        nagios_status.parse_sliver_tool_status.side_effect = [
            ('mock.mlab1.xyz01.measurement-lab.org', '0', 'mock tool extra'),
            nagios_status.NagiosStatusUnparseableError('mock error'),
            ('mock.mlab3.xyz01.measurement-lab.org', '2', 'mock tool extra')
        ]

        expected_status = {
            'mock.mlab1.xyz01.measurement-lab.org': {
                'status': message.STATUS_ONLINE,
                'tool_extra': 'mock tool extra'
            },
            'mock.mlab3.xyz01.measurement-lab.org': {
                'status': message.STATUS_OFFLINE,
                'tool_extra': 'mock tool extra'
            }
        }

        actual_status = nagios_status.get_slice_status(
            'nagios.measurementlab.mock.net')
        self.assertDictEqual(actual_status, expected_status)
    def test_get_slice_status_returns_populated_dictionary_when_it_gets_valid_statuses_and_one_whitespace_sliver_status(
            self):
        self.mock_urlopen_response.read.return_value = """
mock.mlab1.xyz01.measurement-lab.org/ndt 0 1 mock tool extra
\t\t
mock.mlab3.xyz01.measurement-lab.org/ndt 2 1 mock tool extra
""".lstrip()
        nagios_status.parse_sliver_tool_status.side_effect = [
            ('mock.mlab1.xyz01.measurement-lab.org', '0', 'mock tool extra'),
            ('mock.mlab3.xyz01.measurement-lab.org', '2', 'mock tool extra')
        ]

        expected_status = {
            'mock.mlab1.xyz01.measurement-lab.org': {
                'status': message.STATUS_ONLINE,
                'tool_extra': 'mock tool extra'
            },
            'mock.mlab3.xyz01.measurement-lab.org': {
                'status': message.STATUS_OFFLINE,
                'tool_extra': 'mock tool extra'
            }
        }

        actual_status = nagios_status.get_slice_status(
            'nagios.measurementlab.mock.net')
        nagios_status.urllib2.urlopen.assert_called_once_with(
            'nagios.measurementlab.mock.net')
        self.assertDictEqual(actual_status, expected_status)
    def test_get_slice_status_handles_NagiosStatusUnparseableError_from_one_status_in_parse_sliver_tool_status(
            self):
        self.mock_urlopen_response.read.return_value = """
mock.mlab1.xyz01.measurement-lab.org/ndt 0 1 mock tool extra
unparseable status
mock.mlab3.xyz01.measurement-lab.org/ndt 2 1 mock tool extra
""".lstrip()
        nagios_status.parse_sliver_tool_status.side_effect = [
            ('mock.mlab1.xyz01.measurement-lab.org', '0', 'mock tool extra'),
            nagios_status.NagiosStatusUnparseableError('mock error'),
            ('mock.mlab3.xyz01.measurement-lab.org', '2', 'mock tool extra')
        ]

        expected_status = {
            'mock.mlab1.xyz01.measurement-lab.org': {
                'status': message.STATUS_ONLINE,
                'tool_extra': 'mock tool extra'
            },
            'mock.mlab3.xyz01.measurement-lab.org': {
                'status': message.STATUS_OFFLINE,
                'tool_extra': 'mock tool extra'
            }
        }

        actual_status = nagios_status.get_slice_status(
            'nagios.measurementlab.mock.net', self.opener)
        self.assertDictEqual(actual_status, expected_status)
Exemple #5
0
    def test_get_slice_status_returns_none_when_a_HTTPError_is_raised_by_urlopen(
            self):
        class MockHttpError(urllib2.HTTPError):
            def __init__(self, cause):
                self.cause = cause

        self.mock_urlopen_response.read.side_effect = MockHttpError(
            'mock http error')
        self.assertIsNone(
            nagios_status.get_slice_status('nagios.measurementlab.mock.net'))
    def test_get_slice_status_returns_none_when_a_HTTPError_is_raised_by_urlopen(
            self):

        class MockHttpError(urllib2.HTTPError):

            def __init__(self, cause):
                self.cause = cause

        self.mock_urlopen_response.read.side_effect = MockHttpError(
            'mock http error')
        self.assertIsNone(nagios_status.get_slice_status(
            'nagios.measurementlab.mock.net'))
Exemple #7
0
    def get(self):
        """Triggers the update handler.

        Updates sliver status with information from Nagios. The Nagios URL
        containing the information is stored in the Nagios db along with
        the credentials necessary to access the data.
        """
        nagios = nagios_config_wrapper.get_nagios_config()
        if nagios is None:
            logging.error('Datastore does not have the Nagios credentials.')
            return util.send_not_found(self)

        nagios_status.authenticate_nagios(nagios)

        for slice_info in nagios_status.get_slice_info(nagios.url):

            slice_status = nagios_status.get_slice_status(slice_info.slice_url)
            if slice_status:
                self.update_sliver_tools_status(
                    slice_status, slice_info.tool_id, slice_info.address_family)
        return util.send_success(self)
Exemple #8
0
    def get(self):
        """Triggers the update handler.

        Updates sliver status with information from Nagios. The Nagios URL
        containing the information is stored in the Nagios db along with
        the credentials necessary to access the data.
        """
        nagios = nagios_config_wrapper.get_nagios_config()
        if nagios is None:
            logging.error('Datastore does not have the Nagios credentials.')
            return util.send_not_found(self)

        nagios_status.authenticate_nagios(nagios)

        for slice_info in nagios_status.get_slice_info(nagios.url):

            slice_status = nagios_status.get_slice_status(slice_info.slice_url)
            if slice_status:
                self.update_sliver_tools_status(
                    slice_status, slice_info.tool_id, slice_info.address_family)
        return util.send_success(self)
 def test_get_slice_status_returns_none_when_Nagios_response_is_tab_whitespace(
         self):
     self.mock_urlopen_response.read.return_value = '\t\t\t\n'
     actual_status = nagios_status.get_slice_status(
         'nagios.measurementlab.mock.net')
     self.assertIsNone(actual_status)
Exemple #10
0
    def get(self):
        """Triggers the update handler.

        Updates sliver status with information from either Nagios or Prometheus.
        The base URLs for accessing status information are stored in the
        datastore along with the credentials necessary to access the data.
        """
        # Determine if there are any dependencies on Prometheus.
        prometheus_deps = model.get_status_source_deps('prometheus')
        # Get Prometheus configs, and authenticate.
        prometheus_config = prometheus_config_wrapper.get_prometheus_config()
        if prometheus_config is None:
            logging.error('Datastore does not have the Prometheus configs.')
        else:
            prometheus_opener = prometheus_status.authenticate_prometheus(
                prometheus_config)

        # Determine if there are any dependencies on Nagios.
        nagios_deps = model.get_status_source_deps('nagios')
        # Get Nagios configs, and authenticate.
        nagios_config = nagios_config_wrapper.get_nagios_config()
        if nagios_config is None:
            logging.error('Datastore does not have the Nagios configs.')
        else:
            nagios_opener = nagios_status.authenticate_nagios(nagios_config)

        # If we have dependencies on both Prometheus and Nagios, and neither one
        # of the configs is available, then abort, because we can't fetch status
        # from either. However, if we have one or the other, then continue,
        # because it may be preferable to update _some_ statuses than none.
        if (prometheus_deps and not prometheus_config) and (nagios_deps and
                                                            not nagios_config):
            logging.error(
                'Neither Nagios nor Prometheus configs are available.')
            return util.send_not_found(self)

        for tool_id in model.get_all_tool_ids():
            tool = model.get_tool_from_tool_id(tool_id)
            for address_family in ['', '_ipv6']:
                if tool.status_source == 'prometheus':
                    logging.info('Status source for %s%s is: prometheus',
                                 tool_id, address_family)
                    # Only proceed if prometheus_config exists, and hence
                    # prometheus_opener should also exist.
                    if prometheus_config:
                        slice_info = prometheus_status.get_slice_info(
                            prometheus_config.url, tool_id, address_family)
                        if not slice_info:
                            continue
                        slice_status = prometheus_status.get_slice_status(
                            slice_info.slice_url, prometheus_opener)
                    else:
                        logging.error(
                            'Prometheus config unavailable. Skipping %s%s',
                            tool_id, address_family)
                        continue
                elif tool.status_source == 'nagios':
                    logging.info('Status source for %s%s is: nagios', tool_id,
                                 address_family)
                    # Only proceed if nagios_config exists, and hence
                    # nagios_opener should also exist.
                    if nagios_config:
                        slice_info = nagios_status.get_slice_info(
                            nagios_config.url, tool_id, address_family)
                        slice_status = nagios_status.get_slice_status(
                            slice_info.slice_url, nagios_opener)
                    else:
                        logging.error(
                            'Nagios config unavailable. Skipping %s%s', tool_id,
                            address_family)
                        continue
                else:
                    logging.error('Unknown tool status_source: %s.',
                                  tool.status_source)
                    continue

                if slice_status:
                    self.update_sliver_tools_status(slice_status,
                                                    slice_info.tool_id,
                                                    slice_info.address_family)

        return util.send_success(self)
 def test_get_slice_status_returns_none_when_Nagios_response_is_tab_whitespace(
         self):
     self.mock_urlopen_response.read.return_value = '\t\t\t\n'
     actual_status = nagios_status.get_slice_status(
         'nagios.measurementlab.mock.net', self.opener)
     self.assertIsNone(actual_status)
Exemple #12
0
 def test_get_slice_status_returns_none_when_Nagios_response_is_whitespace_and_no_newline(
         self):
     self.mock_urlopen_response.read.return_value = '  '
     actual_status = nagios_status.get_slice_status(
         'nagios.measurementlab.mock.net', self.opener)
     self.assertIsNone(actual_status)
Exemple #13
0
 def test_get_slice_status_returns_none_when_Nagios_response_is_whitespace_and_no_newline(
         self):
     self.mock_urlopen_response.read.return_value = '  '
     actual_status = nagios_status.get_slice_status(
         'nagios.measurementlab.mock.net')
     self.assertIsNone(actual_status)
Exemple #14
0
    def get(self):
        """Triggers the update handler.

        Updates sliver status with information from either Nagios or Prometheus.
        The base URLs for accessing status information are stored in the
        datastore along with the credentials necessary to access the data.
        """
        # Determine if there are any dependencies on Prometheus.
        prometheus_deps = model.get_status_source_deps('prometheus')
        # Get Prometheus configs, and authenticate.
        prometheus_config = prometheus_config_wrapper.get_prometheus_config()
        if prometheus_config is None:
            logging.error('Datastore does not have the Prometheus configs.')
        else:
            prometheus_opener = prometheus_status.authenticate_prometheus(
                prometheus_config)

        # Determine if there are any dependencies on Nagios.
        nagios_deps = model.get_status_source_deps('nagios')
        # Get Nagios configs, and authenticate.
        nagios_config = nagios_config_wrapper.get_nagios_config()
        if nagios_config is None:
            logging.error('Datastore does not have the Nagios configs.')
        else:
            nagios_opener = nagios_status.authenticate_nagios(nagios_config)

        # If we have dependencies on both Prometheus and Nagios, and neither one
        # of the configs is available, then abort, because we can't fetch status
        # from either. However, if we have one or the other, then continue,
        # because it may be preferable to update _some_ statuses than none.
        if (prometheus_deps and not prometheus_config) and (nagios_deps and
                                                            not nagios_config):
            logging.error(
                'Neither Nagios nor Prometheus configs are available.')
            return util.send_not_found(self)

        for tool_id in model.get_all_tool_ids():
            tool = model.get_tool_from_tool_id(tool_id)
            for address_family in ['', '_ipv6']:
                if tool.status_source == 'prometheus':
                    logging.info('Status source for %s%s is: prometheus',
                                 tool_id, address_family)
                    # Only proceed if prometheus_config exists, and hence
                    # prometheus_opener should also exist.
                    if prometheus_config:
                        slice_info = prometheus_status.get_slice_info(
                            prometheus_config.url, tool_id, address_family)
                        if not slice_info:
                            continue
                        slice_status = prometheus_status.get_slice_status(
                            slice_info.slice_url, prometheus_opener)
                    else:
                        logging.error(
                            'Prometheus config unavailable. Skipping %s%s',
                            tool_id, address_family)
                        continue
                elif tool.status_source == 'nagios':
                    logging.info('Status source for %s%s is: nagios', tool_id,
                                 address_family)
                    # Only proceed if nagios_config exists, and hence
                    # nagios_opener should also exist.
                    if nagios_config:
                        slice_info = nagios_status.get_slice_info(
                            nagios_config.url, tool_id, address_family)
                        slice_status = nagios_status.get_slice_status(
                            slice_info.slice_url, nagios_opener)
                    else:
                        logging.error(
                            'Nagios config unavailable. Skipping %s%s', tool_id,
                            address_family)
                        continue
                else:
                    logging.error('Unknown tool status_source: %s.',
                                  tool.status_source)
                    continue

                if slice_status:
                    self.update_sliver_tools_status(slice_status,
                                                    slice_info.tool_id,
                                                    slice_info.address_family)

        return util.send_success(self)