---
name: route_registrar

description: "Used for registering routes"

packages:
- routing_utils
- route_registrar

consumes:
- name: nats
  type: nats
  optional: true
- name: nats-tls
  type: nats-tls
  optional: true
- name: routing_api
  type: routing_api
  optional: true

templates:
  registrar_settings.json.erb: config/registrar_settings.json
  bpm.yml.erb: config/bpm.yml
  ca.crt.erb: config/certs/ca.crt

  client.crt.erb: config/routing_api/certs/client.crt
  client_private.key.erb: config/routing_api/keys/client_private.key
  server_ca.crt.erb: config/routing_api/certs/server_ca.crt

  nats_client.crt.erb: config/nats/certs/client.crt
  nats_client_private.key.erb: config/nats/certs/client_private.key
  nats_server_ca.crt.erb: config/nats/certs/server_ca.crt

properties:
  nats.machines:
    description: IPs of each NATS cluster member
    example: |
      - 192.168.50.123
      - 192.168.52.123
  nats.port:
    description: TCP port of NATS servers
    example: 4222
  nats.user:
    description: User name for NATS authentication
    example: nats
  nats.password:
    description: Password for NATS authentication
    example: natSpa55w0rd
  nats.tls.enabled:
    description: Enable connecting to NATS server via TLS.
    default: false
  nats.tls.client_cert:
    description: "PEM-encoded certificate for the route-registrar to present to NATS for verification when connecting via TLS."
  nats.tls.client_key:
    description: "PEM-encoded private key for the route-registrar to present to NATS for verification when connecting via TLS."
  nats.tls.ca_cert:
    description: "The certificate authority certificate used for the route registrar"
  nats.fail_if_using_nats_without_tls:
    description: |
        Connecting to nats (instead of nats-tls) is deprecated. The nats
        process will be removed soon. Please migrate to using nats-tls as soon
        as possible. If you must continue using nats for a short time you can
        set this flag to false.
    default: true

  host:
    description: (string, optional) By default, route_registrar will detect the IP of the VM and use it, in combination with port as the backend destination for each uri being registered. This property enables overriding the destination hostname or IP.
    example: 192.168.60.25

  route_registrar.logging_level:
    description: "Log level for route_registrar"
    default: "info"
  route_registrar.routing_api.api_url:
    description: (optional, string) The routing API's URL. This is required to register any TCP routes. If not provided here or via link, this defaults to 'https://routing-api.service.cf.internal:3001'
  route_registrar.routing_api.oauth_url:
    description: (optional, string) The OAuth server's URL. This is required to register any TCP routes. If not provided here or via link, this defaults to 'https://uaa.service.cf.internal:8443'
  route_registrar.routing_api.client_id:
    description: (optional, string) An OAuth client ID for a client that is permitted to add new TCP routes. This is required to register any TCP routes. If set, overrides values provided via routing_api's link. If not provided via link or property, defaults to 'routing_api_client'.
  route_registrar.routing_api.client_secret:
    description: (optional, string) The OAuth client secret for the above client. This is required to register any TCP routes. If set, overrides values provided via routing_api's link. If not provided via link, this must be set when registering TCP routes.
  route_registrar.routing_api.ca_certs:
    description: (optional, array of strings) The certificate authority certificates for any APIs that the route registrar is communicating with over HTTPS, e.g., the OAuth server. This is required to register any TCP routes.
  route_registrar.routing_api.skip_ssl_validation:
    description: (optional, boolean) Option to skip TLS validation.
    default: false

  route_registrar.routing_api.client_cert:
    description: "Routing API Client Certificate"
  route_registrar.routing_api.client_private_key:
    description: "Routing API Client Private Key"
  route_registrar.routing_api.server_ca_cert:
    description: "Routing API Certificate Authority"

  route_registrar.dynamic_config_globs:
    description: "Files matching the globs contain routes configuration that will be loaded dynamically. Parent directory must exist for bpm to mount it."
    default: [/var/vcap/jobs/*/config/route_registrar/config.yml]

  route_registrar.routes:
    description: |
      (required, array of objects): Routes that will be registered

      route object
        name (required, string, for all routes): Human-readable reference for the route
        type (optional, string, for all routes): Defaults to http, can specify http, sni, or tcp.
        uris (required, array, for http routes): When Gorouter receives a request that matches one of these URIs,
          it will forward them to the IP of the host on which route_registrar runs, and either port or tls_port.
        sni_port (required, integer, for sni rotues): When sni type provided, this is the downstream port to route to
        port (required, integer, for all routes): Either `port` or `tls_port` are required; if both are provided, Gorouter will prefer tls_port.
          Requests for associated URIs will be forwarded unencypted by the router to this port.
          The IP is determined automatically from the host on which route-registrar is run.
        tls_port (required, integer, for http routes): Either `port` or `tls_port` are required; if both are provided, Gorouter will prefer tls_port.
          Requests for associated URIs will be forwarded over TLS by the router to this port.
          The IP is determined automatically from the host on which route-registrar is run.
        protocol (optional, string): 'http1' or 'http2'. If not provided, Gorouter uses 'http1' as default.
        route_service_url (optional, string, for http routes): When valid route service URL is provided, Gorouter will proxy requests received for the uris above to the specified route service URL.
        server_cert_domain_san (conditional, string, for http routes): Required if tls_port is present.
          Gorouter will validate that the TLS certificate presented by the destination host contains this as a Subject Alternative Name (SAN).
        registration_interval (required, string, for all routes): Interval between heartbeated route registrations
          (e.g. 10s). It must parse to a positive time duration i.e. "-5s" is not permitted.
        tags (optional, array of objects, for http routes): Arbitrary key-value pairs emitted with metrics to support
          filtering of metrics
        prepend_instance_index (optional, boolean, for http routes): When set to true the values in `uris` will be
          prepended with the instance index. e.g. 'some-uri.system-domain.com' will become '0-some-uri.system-domain.com' on the instance with index 0, and '2-some-url.system-domain.com' on the instance with index 2. When this value is enabled, each instance will register its own, unique, set of uris. To additionally continue to register these original uris, create another route with the same uris and set 'prepend_instance_index' to false (or omit the key entirely).
        health_check (optional, object, for all routes): Script executed on frequency of `registration_interval`. If
          healthcheck script exits with success, route registration heartbeat is sent. If script exits
          with error, the route is unregistered.
        router_group (required, string, for tcp routes): Name of the router group to which the TCP route should be added.
        external_port (required, string, for tcp routes): Port that the TCP router will listen on.
        server_cert_domain_name_modifier (optional, string, for sni routes): a regex replace to help with complicated hostnames.
        options (optional, object, for http routes): Custom per-route options

      health_check object
        name (required, string): Human-readable reference for the healthcheck
        script_path (required, string): Path to script that will be run periodically to determine
          service health
        unrestricted_volumes (optional, array of unrestricted_volumes): Additional directories to be mounted in the bpm config for the route_registrar job.
        privileged: (optional, boolean): Sets bpm privileged flag. defaults to false
        timeout (optional, string): The healthcheck script must exit within this timeout, otherwise
          the script is terminated with `SIGKILL` and the route is unregistered. Value is a string (e.g. "10s") and must parse to a positive time duration i.e. "-5s" is not permitted. Must be less than the value of `registration_interval`.
          Default: Half of the value of `registration_interval`

      unrestricted_volume object
        path (required, string): the path to be mounted
        writable (optional, boolean): sets the writable flag. defaults to false

      options object
        lb_algo (optional, string): Load balancing algorithm for routing incoming requests to the backend: 'round-robin' or 'least-connection'. In cases where this option is not specified, the algorithm defined in gorouter spec is applied.

    example: |
      - name: my-service
        uris:
          - my-service.system-domain.com
          - *.my-service.system-domain.com
        port: 12345
        registration_interval: 20s
        tags:
          component: my-service
          env: production
        health_check:
          name: my-service-health_check
          script_path: /path/to/script
          timeout: 5s
        route_service_url: https://my-oauth-proxy-route-service.example.com
        options:
          lb_algo: least-connection
      - name: my-tls-endpoint
        tls_port: 12346
        server_cert_domain_san: "my-tls-endpoint.internal.com"
        uris:
          - my-service.system-domain.com
      - name: my-debug-endpoint
        uris:
          - my-service.system-domain.com/debug
        port: 12346
      - name: cf-mysql-proxy-api-per-instance
        uris:
        - proxy-cf-mysql.system.domain
        port: 8080
        prepend_instance_index: true
      - name: cf-mysql-proxy-api
        uris:
        - proxy-cf-mysql.system.domain
        port: 8081
      - name: my-tcp-route
        type: tcp
        port: 6263
        router_group: my-router-group
        external_port: 1234
        registration_interval: 10s
