Ctrl K
ComunidadGuías…

sample.config.yaml

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Aastro - example configuration showcasing every available option.
#
# This file is meant as a reference, not a copy-paste production config.
# Most blocks are optional; uncomment and adjust what you actually need.
#
# Required top-level sections: schema, gateway.server, gateway.admin, gateway.routing.
# Everything else has sensible defaults.

schema: v1
debug: false   # verbose logging across router, scatter, and upstream components

gateway:
  # ── Service identity ─────────────────────────────────────────────────────
  # Appears as service.name in OpenTelemetry resource attributes.

  service:
    name: aastro

  # ── Data port ────────────────────────────────────────────────────────────
  # Serves API traffic. Optionally protected by TLS or mTLS.

  server:
    port: 7805
    timeout: 20s             # read + write timeout per request
    header_timeout: 5s       # Slowloris defence - caps header read time
    http2: auto               # auto | on | off - auto negotiates HTTP/2 over TLS, nothing without it.
                               # "on" requires tls.enabled (no cleartext HTTP/2 / h2c support).
                               # "off" pins the data port to HTTP/1.1 even over TLS.

    # TLS / mTLS on the data port.
    # Remove the tls block entirely for plain HTTP.
    tls:
      enabled: true
      cert_file: /etc/aastro/server.crt
      key_file: /etc/aastro/server.key
      min_version: "1.2"     # 1.2 or 1.3 - older versions are not selectable
      client_auth: require   # none | optional | require
      client_ca_file: /etc/aastro/client-ca.crt   # required unless client_auth=none

  # ── Admin port ───────────────────────────────────────────────────────────
  # Health probes, metrics, pprof. Bound to localhost by default.
  # Never TLS-terminated - kubelet probes and Prometheus scrape over plain HTTP
  # even when the data port enforces mTLS.

  admin:
    port: 9090
    bind_addr: 127.0.0.1     # set to 0.0.0.0 only if Prometheus runs outside the pod
    timeout: 5m              # generous to accommodate long pprof captures
    header_timeout: 5s
    enable_pprof: true       # exposes /debug/pprof/ on the admin port

  # ── Observability ────────────────────────────────────────────────────────
  # Push-based instrumentation. Metrics in prometheus mode also exposes
  # /metrics on the admin port; OTLP mode is purely push.

  observability:
    metrics:
      enabled: true
      exporter: prometheus   # prometheus | otlp
      # OTLP config is used only when exporter=otlp:
      otlp:
        endpoint: otel-collector:4318
        insecure: true
        interval: 10s

    tracing:
      enabled: true
      exporter: otlp
      sampling_ratio: 1.0    # 0.0–1.0 (1.0 = sample every trace)
      otlp:
        endpoint: otel-collector:4318
        insecure: true
        interval: 10s

  # ── Routing ──────────────────────────────────────────────────────────────

  routing:
    # CIDR ranges whose X-Forwarded-* headers are appended to rather than overwritten.
    # Leave empty if Aastro is your outermost edge.
    trusted_proxies:
      - 127.0.0.1/32
      - 10.0.0.0/8

    # Per-IP rate limiter. The IP is the one extracted via trusted-proxy resolution.
    rate_limiter:
      enabled: true
      config:
        limit: 100
        window: 1s

    # ── Flow examples ──────────────────────────────────────────────────────
    # A flow defines: how a request is matched, which upstreams it scatters to,
    # how their responses are aggregated, and which plugins/middlewares run.

    flows:
      # ── Example 1: merge aggregation across two upstreams ────────────────
      # Combines responses from `users` and `orders` services into a single
      # JSON object. Returns 206 Partial Content if one fails and best_effort
      # is enabled.

      - path: /api/v1/customers/{customer_id}
        method: GET

        aggregation:
          strategy: merge        # merge | array | namespace
          best_effort: true      # return partial data on upstream failures
          on_conflict:
            policy: prefer       # overwrite | first | error | prefer
            prefer_upstream: users   # this upstream wins on key collision

        # Cross-cutting middlewares wrap the entire flow handler.
        # First in the list = outermost wrapper.
        middlewares:
          - name: recoverer
            source: builtin
          - name: logger
            source: builtin
          - name: auth
            source: builtin
            config:
              alg: HS256
              issuer: https://auth.example.com
              audience: api
              hmac_secret: "base64secret"

        # Plugins run at specific lifecycle phases (request / response).
        plugins:
          - name: snakeify
            source: builtin
          - name: tenant_resolver
            source: file
            path: /etc/aastro/plugins/
            config:
              header: X-Tenant-Id

        upstreams:
          - name: users
            hosts:
              - https://users-1.internal
              - https://users-2.internal
            path: /v1/users/{customer_id}
            method: GET
            timeout: 3s

            forward_headers: [ "Authorization", "X-Tenant-Id", "X-Request-Id" ]
            forward_queries: [ "expand", "fields" ]
            forward_params: [ "customer_id" ]

            transport:
              max_idle_conns: 100
              max_idle_conns_per_host: 50
              idle_conn_timeout: 90s
              http2: auto     # auto | on | off - same semantics as gateway.server.http2, scoped to
                              # this upstream. "off" is the escape hatch for a backend with a flaky
                              # HTTP/2 implementation; "on" requires this upstream's tls.enabled.

            # Outbound mTLS to the upstream.
            # Omit the tls block entirely for plain HTTPS - Go uses system roots.
            tls:
              enabled: true
              cert_file: /etc/aastro/clients/users.crt
              key_file: /etc/aastro/clients/users.key
              ca_file: /etc/aastro/internal-ca.crt
              server_name: users.internal   # SNI / hostname verification
              min_version: "1.2"

            policy:
              require_body: true
              max_response_body_size: 1048576   # 1 MiB

              header_blacklist:
                - X-Internal-Token

              retry:
                max_retries: 3
                retry_on_statuses: [ 500, 502, 503, 504 ]
                backoff_delay: 200ms

              circuit_breaker:
                enabled: true
                max_failures: 5
                reset_timeout: 10s

              load_balancing:
                mode: least_conns   # round_robin | least_conns

          - name: orders
            hosts: https://orders.internal   # single host - string is fine
            path: /v1/customers/{customer_id}/orders
            timeout: 2s
            forward_params: [ "customer_id" ]
            # No upstream tls block → public-ish HTTPS via system root CAs
            policy:
              retry:
                max_retries: 2
                retry_on_statuses: [ 503 ]
                backoff_delay: 100ms

      # ── Example 2: namespace aggregation ─────────────────────────────────
      # Each upstream's response lives under a key named after the upstream:
      # {"profile": {...}, "preferences": {...}}

      - path: /api/v1/me
        method: GET
        aggregation:
          strategy: namespace
          best_effort: false   # any upstream failure fails the whole request

        middlewares:
          - name: auth
            source: builtin
            config:
              alg: HS256
              hmac_secret: "base64secret"

        upstreams:
          - name: profile
            hosts: https://profile.internal
            path: /v1/profile
            forward_headers: [ "Authorization" ]
          - name: preferences
            hosts: https://prefs.internal
            path: /v1/prefs
            forward_headers: [ "Authorization" ]

      # ── Example 3: array aggregation, POST with body ─────────────────────
      # Each upstream response becomes an element of a JSON array.
      # POST/PUT/PATCH bodies are forwarded; other methods discard the body.

      - path: /api/v1/search
        method: POST
        aggregation:
          strategy: array
          best_effort: true

        upstreams:
          - name: catalog
            hosts: https://catalog.internal
            path: /v1/search
            method: POST
            timeout: 5s
            forward_headers: [ "Content-Type", "Authorization", "X-*" ]
          - name: docs
            hosts: https://docs.internal
            path: /v2/query
            method: POST
            timeout: 5s
            forward_headers: [ "Content-Type", "Authorization" ]

      # ── Example 4: streaming (SSE / chunked) ──────────────────────────────
      # Bypasses aggregation entirely. Body streams chunk-by-chunk to the
      # client. Requires exactly one upstream. Response-phase plugins do not
      # run (body is already streaming by the time they'd execute).

      - path: /api/v1/events/{user_id}
        method: GET
        streaming: true

        # Request-phase plugins still run before the upstream call.
        plugins:
          - name: tenant_resolver
            source: file
            path: /etc/aastro/plugins/
            config:
              header: X-Tenant-Id

        upstreams:
          - name: events
            hosts: https://events.internal
            path: /v1/users/{user_id}/events
            timeout: 60s   # long-lived; remember server.timeout caps this
            forward_headers: [ "Authorization", "Accept", "Last-Event-Id" ]
            forward_params: [ "user_id" ]

      # ── Example 5: bare minimum ──────────────────────────────────────────
      # Single upstream, simplest possible flow.

      - path: /api/v1/health-check
        method: GET
        aggregation:
          strategy: array
        upstreams:
          - name: noop
            hosts: https://example.com
            path: /