Puppet Class: profile::services_proxy::envoy

Defined in:
modules/profile/manifests/services_proxy/envoy.pp

Overview

Class profile::services_proxy::envoy

This class sets up a simple nginx proxy to remote services.

Parameters

ensure

Whether the proxy should be present or not. We don't use it in deployment-prep.

listeners

A hash of listener definitions.

Each listener should have the following structure: name - the name of the listener port - the local port to listen on timeout - the time after which we timeout on a call service - The label for the service we're connecting to in service::catalog in hiera http_host - optional http Host: header to add to the request upstream - upstream host to contact. If unspecified, <service>.discovery.wmnet will be assumed. retry - The retry policy, if any. See the envoy docs for RetryPolicy for details. keepalive - keepalive timeout. If not specified, the default envoy value will be used.

For nodejs applications assume the right value is 5 seconds (see T247484)

xfp - Set an explicit value for X-Forwarded-Proto, instead of letting envoy inject it (see T249535)

Parameters:

  • ensure (Wmflib::Ensure) (defaults to: lookup('profile::envoy::ensure', {'default_value' => 'present'}))
  • listeners (Array[Struct[{ 'name' => String, 'port' => Stdlib::Port::Unprivileged, 'timeout' => String, 'service' => String, 'http_host' => Optional[Stdlib::Fqdn], 'xfp' => Optional[Enum['http', 'https']], 'upstream' => Optional[Stdlib::Fqdn], 'retry' => Optional[Hash], 'keepalive' => Optional[String], }]]) (defaults to: lookup('profile::services_proxy::envoy::listeners', {'default_value' => []}))


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'modules/profile/manifests/services_proxy/envoy.pp', line 22

class profile::services_proxy::envoy(
    Wmflib::Ensure $ensure = lookup('profile::envoy::ensure', {'default_value' => 'present'}),
    Array[Struct[{
        'name'      => String,
        'port'      => Stdlib::Port::Unprivileged,
        'timeout'   => String,
        'service'   => String,
        'http_host' => Optional[Stdlib::Fqdn],
        'xfp'       => Optional[Enum['http', 'https']],
        'upstream'  => Optional[Stdlib::Fqdn],
        'retry'     => Optional[Hash],
        'keepalive' => Optional[String],
    }]] $listeners = lookup('profile::services_proxy::envoy::listeners', {'default_value' => []}),
) {
    if $ensure == 'present' {
        if $listeners == undef {
            fail('You must declare services if the proxy is to be present')
        }
        require ::profile::envoy
    }
    $all_services = wmflib::service::fetch()

    $listeners.each |$listener| {
        $cluster_label = $listener['service']
        $svc = $all_services[$cluster_label]
        if $svc == undef {
            fail("Could not find service ${cluster_label} in service::catalog")
        }
        # Service name is:
        # - foo if upstream is foo.discovery.wmnet
        # - $listener['service']_eqiad if upstream is foo.eqiad.wikimedia.org
        #   or foo.svc.eqiad.wmnet
        # - $listener['service'] otherwise
        if $listener['upstream'] {
            $address = $listener['upstream']
            if $address =~ /^([^.]+)\.discovery\.wmnet$/ {
                $svc_name = $1
            }
            elsif $address =~ /^[^.]+\.svc\.([^.]+)\.wmnet$/ {
                $svc_name = "${listener['service']}_${1}"
            }
            elsif $address =~ /^[^.]+\.([^.]+)\.wikimedia\.org$/ {
                $svc_name = "${listener['service']}_${1}"
            }
            else {
                $svc_name = $address
            }
        } else {
            $svc_name = $listener['service']
            $address = "${svc_name}.discovery.wmnet"
        }
        if !defined(Envoyproxy::Cluster["${svc_name}_cluster"]) {
            envoyproxy::cluster { "${svc_name}_cluster":
                content => template('profile/services_proxy/envoy_service_cluster.yaml.erb')
            }
        }

        # Now define the listener
        if $listener['retry'] == undef {
            $retry_policy = {'num_retries' => 0}
        } else {
            $retry_policy = $listener['retry']
        }
        envoyproxy::listener { $listener['name']:
            content => template('profile/services_proxy/envoy_service_listener.yaml.erb')
        }
    }
}