---
node:
  id: downstream-node
  cluster: downstream-cluster

# Enable reverse connection bootstrap extension which registers the custom resolver
bootstrap_extensions:
- name: envoy.bootstrap.reverse_tunnel.downstream_socket_interface
  typed_config:
    "@type": >-
      type.googleapis.com/envoy.extensions.bootstrap.reverse_tunnel.downstream_socket_interface.v3.DownstreamReverseConnectionSocketInterface
    stat_prefix: "downstream_reverse_connection"
    access_log:
    - name: envoy.access_loggers.stdout
      typed_config:
        "@type": >-
          type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
        log_format:
          text_format_source:
            inline_string: >-
              [%START_TIME%] reverse_tunnel_initiator
              event=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:event)%
              node=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:node_id)%
              cluster=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:cluster_id)%
              tenant=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:tenant_id)%
              upstream_cluster=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:upstream_cluster)%
              host=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:host_address)%
              error=%DYNAMIC_METADATA(envoy.reverse_tunnel.initiator:error)%

static_resources:
  listeners:
  # Initiates reverse connections to upstream using custom resolver
  - name: reverse_conn_listener
    listener_filters_timeout: 0s
    listener_filters: []
    # Use custom address with reverse connection metadata encoded in URL format
    address:
      socket_address:
        # This encodes: src_node_id, src_cluster_id, src_tenant_id
        # and remote clusters: upstream-cluster with 1 connection
        address: "rc://downstream-node:downstream-cluster:downstream-tenant@upstream-cluster:1"
        port_value: 0
        # Use custom resolver that can parse reverse connection metadata
        resolver_name: "envoy.resolvers.reverse_connection"
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": >-
            type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: reverse_conn_listener
          route_config:
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: '/downstream_service'
                route:
                  cluster: downstream-service
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": >-
                type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  # Cluster designating upstream-envoy
  clusters:
  - name: upstream-cluster
    type: STRICT_DNS
    connect_timeout: 30s
    load_assignment:
      cluster_name: upstream-cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1  # Address of upstream-envoy
                port_value: 9000  # Port for rev_conn_api_listener

  # Backend HTTP service behind downstream which
  # we will access via reverse connections
  - name: downstream-service
    type: STRICT_DNS
    connect_timeout: 30s
    load_assignment:
      cluster_name: downstream-service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8080
