Source

Implementation

Provisioner Type

Resource Type

Flavor

Tool

route

The default route provisioner sets up an nginx service with an HTTP service that can route on our prefix paths. It assumes the hostnames and routes provided have no overlaps. Weird behavior may happen if there are overlaps.

Provisions a ingress route on a shared Nginx instance.

type: route
supported_params:
  - host
  - port
  - path

provisioners.yaml (view on GitHub) :

- uri: template://default-provisioners/route
  type: route
  description: Provisions a ingress route on a shared Nginx instance.
  init: |
    randomServiceName: routing-{{ randAlphaNum 6 }}
    sk: default-provisioners-routing-instance
    {{ if not (regexMatch "^/|(/([^/]+))+$" .Params.path) }}{{ fail "params.path start with a / but cannot end with /" }}{{ end }}
    {{ if not (regexMatch "^[a-z0-9_.-]{1,253}$" .Params.host) }}{{ fail (cat "params.host must be a valid hostname but was" .Params.host) }}{{ end }}
    {{ $ports := (index .WorkloadServices .SourceWorkload).Ports }}
    {{ if not $ports }}{{ fail "no service ports exist" }}{{ end }}
    {{ $port := index $ports (print .Params.port) }}
    {{ if not $port.TargetPort }}{{ fail "params.port is not a named service port" }}{{ end }}    

  shared: |
    {{ .Init.sk }}:
      instancePort: {{ dig .Init.sk "instancePort" 8080 .Shared }}
      instanceServiceName: {{ dig .Init.sk "instanceServiceName" .Init.randomServiceName .Shared | quote }}
      {{ $targetHost := (index .WorkloadServices .SourceWorkload).ServiceName }}
      {{ $ports := (index .WorkloadServices .SourceWorkload).Ports }}
      {{ $port := index $ports (print .Params.port) }}
      {{ $targetPort := $port.TargetPort }}
      {{ $target := (printf "%s:%d" $targetHost $targetPort) }}
      {{ $hBefore := dig .Init.sk "hosts" (dict) .Shared }}
      {{ $rBefore := dig .Params.host (dict) $hBefore }}
      {{ $pathType := dig "compose.score.dev/route-provisioner-path-type" "Prefix" (dig "annotations" (dict) (.Metadata | default (dict))) }}
      {{ $inner := dict "path" .Params.path "target" $target "port" $targetPort "path_type" $pathType }}
      {{ $rAfter := (merge $rBefore (dict .Uid $inner)) }}
      {{ $hAfter := (merge $hBefore (dict .Params.host $rAfter)) }}
      hosts: {{ $hAfter | toRawJson }}    
  files: |
    {{ dig .Init.sk "instanceServiceName" "" .Shared }}/nginx.conf: |
      worker_processes 1;
      worker_rlimit_nofile 8192;
      events {
        worker_connections 4096;
      }
      http {
        resolver 127.0.0.11;

        {{ range $h, $r := (dig .Init.sk "hosts" "" .Shared) }}
        server {
          listen 80;
          listen [::]:80;
          server_name {{ $h }};

          proxy_set_header X-Real-IP              $remote_addr;
          proxy_set_header X-Forwarded-For        $remote_addr;
          proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
          proxy_set_header Proxy                  "";
          proxy_connect_timeout                   5s;
          proxy_send_timeout                      60s;
          proxy_read_timeout                      60s;
          proxy_buffers                           16 4k;
          proxy_buffer_size                       2k;
          client_max_body_size                    10m;
      {{ dig "compose.score.dev/route-provisioner-server-snippet" "" (dig "annotations" (dict) ($.Metadata | default (dict))) | indent 4 }}

          location = /favicon.ico {
            return 204;
            access_log     off;
            log_not_found  off;
          }

          {{ range $k, $v := $r }}
          # the basic path variant, "/" or "/one/two"
          location ~ ^{{ index $v "path" }}$ {
            set $backend {{ index $v "target" }};
            proxy_pass http://$backend;
      {{ dig "compose.score.dev/route-provisioner-location-snippet" "" (dig "annotations" (dict) ($.Metadata | default (dict))) | indent 6 }}
          }

          # The prefix match variants are included by default but can be excluded via 'compose.score.dev/route-provisioner-path-type' annotation
          {{ if eq (index $v "path_type") "Prefix" }}
          location ~ ^{{ index $v "path" | trimSuffix "/" }}/.* {
            set $backend {{ index $v "target" }};
            proxy_pass http://$backend;
      {{ dig "compose.score.dev/route-provisioner-location-snippet" "" (dig "annotations" (dict) ($.Metadata | default (dict))) | indent 6 }}
          }
          {{ end }}
          {{ end }}
        }
        {{ end }}
      }    

  services: |
    {{ $p := (dig .Init.sk "instancePort" 0 .Shared) }}
    {{ dig .Init.sk "instanceServiceName" "" .Shared }}:
      image: mirror.gcr.io/nginx:1-alpine
      restart: always
      ports:
        - published: {{ $p }}
          target: 80
      volumes:
        - type: bind
          source: {{ .MountsDirectory }}/{{ dig .Init.sk "instanceServiceName" "" .Shared }}/nginx.conf
          target: /etc/nginx/nginx.conf
          readOnly: true    
  info_logs: |
    {{ $p := (dig .Init.sk "instancePort" 0 .Shared) }}
    - "{{.Uid}}: To connect to this route, http://{{ .Params.host }}:{{ $p }}{{ .Params.path }} (make sure {{ .Params.host }} resolves to localhost)"    
  supported_params:
    - host
    - port
    - path