Exemplo n.º 1
0
 def test_params(self):
     """Verify that our server breaks out query parameters."""
     self.handler_a.side_effect = (
         lambda request, *args, **kwargs: request.send_response(200))
     response = urllibUrlopen(
         'http://localhost:{0}/path/a?p1=1&p2=test'.format(self.port))
     self.assertEqual(200, response.code)
     self.handler_a.assert_called_with(mock.ANY, '/path/a', {
         'p1': '1',
         'p2': 'test'
     }, None)
def get_aws_identity_document():
    url = 'http://169.254.169.254/latest/dynamic/instance-identity/document'
    request = urllibRequest(url)
    try:
        response = urllibUrlopen(request)
    except IOError as ioex:
        logging.info(
            'Cannot read AWS Identity Document,'
            ' probably not on Amazon Web Services.'
            ' url=%s: %s', url, ioex)
        raise ioex
    return json.JSONDecoder().decode(response.read().decode('utf-8'))
def get_google_metadata(attribute):
    url = 'http://169.254.169.254/computeMetadata/v1/' + attribute
    request = urllibRequest(url)
    request.add_header('Metadata-Flavor', 'Google')
    try:
        response = urllibUrlopen(request)
    except IOError as ioex:
        logging.info(
            'Cannot read google metadata,'
            ' probably not on Google Cloud Platform.'
            ' url=%s: %s', url, ioex)
        raise ioex

    return response.read().decode('utf-8')
Exemplo n.º 4
0
    def test_delegation(self):
        """Verify that our server delegates to commands."""
        def xxx(request, *args, **kwargs):
            print('*** XXX %r | %r | %r\n' % (request, args, kwargs))
            request.send_response(212)
            print('*** YYY sent')

        self.handler_b.side_effect = (
            lambda request, *args, **kwargs: xxx(request, *args, **kwargs))
        response = urllibUrlopen('http://localhost:{0}/path/b'.format(
            self.port))
        self.assertEqual(212, response.code)

        self.assertEqual(0, self.handler_a.call_count)
        self.assertEqual(1, self.handler_b.call_count)
        self.handler_b.assert_called_with(mock.ANY, '/path/b', {}, None)
Exemplo n.º 5
0
 def test_not_found(self):
     """Verify that our server delegates to commands."""
     with self.assertRaises(HTTPError) as context:
         urllibUrlopen('http://localhost:{0}/unknown_path'.format(
             self.port))
     self.assertEqual(404, context.exception.code)
    def collect_metrics(self, service, base_url, params=None):
        """Return JSON metrics from the given server."""
        info = urlsplit(base_url)
        host = info.hostname
        port = info.port or 80
        netloc = host

        if info.port:
            netloc += ':{0}'.format(info.port)
        base_url = '{scheme}://{netloc}{path}'.format(scheme=info.scheme,
                                                      netloc=netloc,
                                                      path=info.path)

        authorization = None
        if info.username or info.password:
            text = '%s:%s' % (info.username, info.password)
            authorization = base64.encodestring(text.encode('utf-8')).replace(
                b'\n', b'')

        query = '?' + info.query if info.query else ''
        sep = '&' if info.query else '?'
        query_params = dict(self.__default_scan_params)
        if params is None:
            params = {}
        keys_to_copy = [
            key for key in ['tagNameRegex', 'tagValueRegex', 'meterNameRegex']
            if key in params
        ]
        for key in keys_to_copy:
            query_params[key] = params[key]

        for key, value in query_params.items():
            query += sep + key + "=" + urllibQuote(value)
            sep = "&"

        url = '{base_url}{query}'.format(base_url=base_url, query=query)
        collect_start_time = time.time()
        response = urllibUrlopen(self.create_request(url, authorization))
        collect_end_time = time.time()

        json_text = response.read().decode('utf-8')
        try:
            spectator_response = json.JSONDecoder().decode(json_text)
            spectator_response['__collectStartTime'] = int(collect_start_time *
                                                           1000)
            spectator_response['__collectEndTime'] = int(collect_end_time *
                                                         1000)
        except ValueError:
            if len(json_text) > 200:
                snippet = '%s ... %s' % (json_text[:100], json_text[:-100])
            else:
                snippet = json_text
            logging.error('Invalid JSON len=%d excerpt:\n%s', len(json_text),
                          snippet)
            raise

        try:
            self.__log_scan_diff(host, port + 1012,
                                 spectator_response.get('metrics', {}))
        except:
            extype, exvalue, _ = sys.exc_info()
            logging.error(traceback.format_exception_only(extype, exvalue))

        spectator_response['__port'] = port
        spectator_response['__host'] = (socket.getfqdn() if host in [
            'localhost', '127.0.0.1', None, ''
        ] else host)

        available_metrics = (
            self.__response_processor.extract_spectator_response_metrics(
                params, service, spectator_response))

        # NOTE: 20180614
        # There have been occasional bugs in spinnaker
        # where gauges are returned as 'NaN'.
        #
        # This string value is causing prometheus errors
        # which prevent any metrics from being stored.
        num_metrics = 0
        for metric_name, metric_data in available_metrics.items():
            meter_values = metric_data.get('values', [])
            num_metrics += len(meter_values)
            empty_value_list_indexes = []
            for index, values_list in enumerate(meter_values):
                # Ensure the value of each measurement is a float
                # If jackson encountered NaN or Inf values then
                # it will make them strings by default.
                # These should probably not be present, but if they are
                # This will convert NaN or Inf into a float
                for elem in values_list['values']:
                    if elem['v'] == 'NaN':
                        logging.warn('Removing illegal NaN from "%s.%s"',
                                     service, metric_name)
                        values_list['values'] = [
                            e for e in values_list['values'] if e['v'] != 'NaN'
                        ]
                        if not values_list['values']:
                            empty_value_list_indexes.append(index)
                        break

            # If there are metrics that only had NaN values,
            # delete them in reverse order so list indexes are still valid.
            # This could still leave meters with no metrics.
            while empty_value_list_indexes:
                del meter_values[empty_value_list_indexes.pop()]

        spectator_response['metrics'] = available_metrics
        return spectator_response