def start_tcp_proxy(src, dst, handler, **kwargs): """Run a simple TCP proxy (tunneling raw connections from src to dst), using a message handler that can be used to intercept messages and return predefined responses for certain requests. Arguments: src -- Source IP address and port string. I.e.: '127.0.0.1:8000' dst -- Destination IP address and port. I.e.: '127.0.0.1:8888' handler -- a handler function to intercept requests (returns tuple (forward_value, response_value)) """ src = "%s:%s" % (BIND_HOST, src) if is_number(src) else src dst = "%s:%s" % (LOCALHOST_IP, dst) if is_number(dst) else dst thread = kwargs.get("_thread") def ip_to_tuple(ip): ip, port = ip.split(":") return ip, int(port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(ip_to_tuple(src)) s.listen(1) s.settimeout(10) def handle_request(s_src, thread): s_dst = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s_dst.connect(ip_to_tuple(dst)) sockets = [s_src, s_dst] try: while thread.running: s_read, _, _ = select.select(sockets, [], []) for s in s_read: data = s.recv(BUFFER_SIZE) if data in [b"", "", None]: return if s == s_src: forward, response = data, None if handler: forward, response = handler(data) if forward is not None: s_dst.sendall(forward) elif response is not None: s_src.sendall(response) return elif s == s_dst: s_src.sendall(data) finally: run_safe(s_src.close) run_safe(s_dst.close) while thread.running: try: src_socket, _ = s.accept() start_worker_thread( lambda *args, _thread: handle_request(src_socket, _thread)) except socket.timeout: pass
def _create_response(result, status_code=200): """ Create the final response for the given invocation result """ if isinstance(result, Response): return result details = { 'StatusCode': status_code, 'Payload': result, 'Headers': {} } if isinstance(result, dict): for key in ('StatusCode', 'Payload', 'FunctionError'): if result.get(key): details[key] = result[key] # Try to parse parse payload as JSON payload = details['Payload'] if payload and isinstance(payload, (str, bytes)) and payload[0] in ('[', '{'): try: details['Payload'] = json.loads(details['Payload']) except Exception: pass # Set error headers if details.get('FunctionError'): details['Headers']['X-Amz-Function-Error'] = str(details['FunctionError']) # Construct response object response_obj = details['Payload'] if isinstance(response_obj, (dict, list, bool)) or is_number(response_obj): # Assume this is a JSON response response_obj = jsonify(response_obj) else: response_obj = str(response_obj) details['Headers']['Content-Type'] = 'text/plain' return response_obj, details['StatusCode'], details['Headers']
def publish_log_metrics_for_events(data): """Filter and publish log metrics for matching events""" from moto.logs.models import ( # TODO: create separate RegionBackend class to store state logs_backends, ) data = data if isinstance(data, dict) else json.loads(data) log_events = data.get("logEvents") or [] logs_backend = logs_backends[aws_stack.get_region()] metric_filters = logs_backend.filters.metric_filters client = aws_stack.connect_to_service("cloudwatch") for metric_filter in metric_filters: pattern = metric_filter.get("filterPattern", "") if log_events_match_filter_pattern(pattern, log_events): for tf in metric_filter.get("metricTransformations", []): value = tf.get("metricValue") or "1" if "$size" in value: LOG.info( "Expression not yet supported for log filter metricValue: %s" % value) value = float(value) if is_number(value) else 1 data = [{"MetricName": tf["metricName"], "Value": value}] try: client.put_metric_data(Namespace=tf["metricNamespace"], MetricData=data) except Exception as e: LOG.info( "Unable to put metric data for matching CloudWatch log events: %s" % e)
def publish_log_metrics_for_events(data): """ Filter and publish log metrics for matching events """ from moto.logs.models import logs_backends # TODO: create separate RegionBackend class to store state data = data if isinstance(data, dict) else json.loads(data) log_events = data.get('logEvents') or [] logs_backend = logs_backends[aws_stack.get_region()] metric_filters = logs_backend.metric_filters = getattr( logs_backend, 'metric_filters', []) client = aws_stack.connect_to_service('cloudwatch') for metric_filter in metric_filters: pattern = metric_filter.get('filterPattern', '') if log_events_match_filter_pattern(pattern, log_events): for tf in metric_filter.get('metricTransformations', []): value = tf.get('metricValue') or '1' if '$size' in value: LOG.info( 'Expression not yet supported for log filter metricValue: %s' % value) value = float(value) if is_number(value) else 1 data = [{'MetricName': tf['metricName'], 'Value': value}] try: client.put_metric_data(Namespace=tf['metricNamespace'], MetricData=data) except Exception as e: LOG.info( 'Unable to put metric data for matching CloudWatch log events: %s' % e)
def put_log_events( self, context: RequestContext, log_group_name: LogGroupName, log_stream_name: LogStreamName, log_events: InputLogEvents, sequence_token: SequenceToken = None, ) -> PutLogEventsResponse: logs_backend = logs_backends[aws_stack.get_region()] metric_filters = logs_backend.filters.metric_filters for metric_filter in metric_filters: pattern = metric_filter.get("filterPattern", "") transformations = metric_filter.get("metricTransformations", []) matches = get_pattern_matcher(pattern) for log_event in log_events: if matches(pattern, log_event): for tf in transformations: value = tf.get("metricValue") or "1" if "$size" in value: LOG.info( "Expression not yet supported for log filter metricValue", value ) value = float(value) if is_number(value) else 1 data = [{"MetricName": tf["metricName"], "Value": value}] try: self.cw_client.put_metric_data( Namespace=tf["metricNamespace"], MetricData=data ) except Exception as e: LOG.info( "Unable to put metric data for matching CloudWatch log events", e ) return call_moto(context)
def escapeJavaScript(self, s): try: return json.dumps(json.loads(s)) except Exception: primitive_types = (str, int, bool, float, type(None)) s = s if isinstance(s, primitive_types) else str(s) if str(s).strip() in ["true", "false"]: s = bool(s) elif s not in [True, False] and is_number(s): s = to_number(s) return json.dumps(s)
def test_is_number(self): env = common.is_number(5) self.assertEqual(env, True)
def test_is_number(self): assert common.is_number(5)
def test_is_number(self): env = common.is_number(5) self.assertTrue(env)