Commit e55aa899 authored by Geoff Simmons's avatar Geoff Simmons

WIP: initial, limited implementation of TLS onload.

This uses haproxy for TLS connections to IngressBackends, and the
via feature of the klarlack implementation of Varnish. See:

https://github.com/varnishcache/varnish-cache/pull/3128

Adds the spec.tls object to the BackendConfig CRD, which configures
TLS onload for a backend.

Limitations: currently only verify:false and the maxConn settings
are implemented. Specification of CA certificates and the stick
table configuration for haproxy are not yet implemented. Currently
TLS onload may be only specified for one backend (no more than one
BackendConfig).

Adds the CLI option -varnishImpl to the controller. TLS onload is
only supported if this option is set to "klarlack". Otherwise, the
presence of the tls object in a BackendConfig leads to a SyncFatalError,
with a message that it's only supported for klarlack, and the
BackendConfig is not synced.

If the backend Service specified for TLS onload has type ExternalName,
then 3 server instances are configured for the haproxy backend. This
value is currently hard-wired, and may be made configurable in a future
iteration. For any other Service type, there are as many haproxy server
instances as there are Endpoints (Pods) in the k8s cluster.

If maxConn is not specified in the BackendConfig, it defaults to
2000 (the haproxy default).
parent 9e962196
......@@ -120,6 +120,30 @@ spec:
rampup:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
tls:
type: object
properties:
verify:
type: boolean
authority:
type: string
caSecret:
type: string
minLength: 1
caCrt:
type: string
minLength: 1
caIssuer:
type: string
minLength: 1
maxConn:
type: integer
minimum: 1
maximum: 2147483647
stickTableSize:
type: integer
minimum: 1
maximum: 2147483647
status:
acceptedNames:
kind: BackendConfig
......
......@@ -56,6 +56,9 @@ spec:
{{- if .Values.vikingController.namespace }}
- -namespace={{ .Values.vikingController.namespace }}
{{- end }}
{{- if .Values.vikingController.varnishImpl }}
- -varnishImpl={{ .Values.vikingController.varnishImpl }}
{{- end }}
{{- if .Values.vikingController.extraArgs }}
{{ toYaml .Values.vikingController.extraArgs | nindent 12 }}
{{- end }}
......
......@@ -15,6 +15,11 @@ vikingController:
## Only listen for resources in this namespace (default all)
# namespace:
## Set this value to klarlack to enable features that are only
## supported by the klarlack implementation of Varnish (default any
## implementation).
# varnishImpl:
# labels to add to the pod container metadata
podLabels: {}
# key: value
......
......@@ -89,7 +89,11 @@ var (
"re-queue delay when the controller does not have all of the\n"+
"information required for a necessary cluster change\n"+
"must be > 0s")
devModeF = flag.Bool("devmode", false, "enable development mode")
devModeF = flag.Bool("devmode", false, "enable development mode")
varnishImplF = flag.String("varnishImpl", "",
"set to 'klarlack' to enable features only implemented by\n"+
"the klarlack image for Varnish Ingress")
logFormat = logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
......@@ -232,9 +236,10 @@ func main() {
informers.WithTweakListOptions(ingressTLSSecrets))
ingController, err := controller.NewIngressController(log,
*ingressClassF, *namespaceF, *devModeF, kubeClient, vController,
hController, informerFactory, vcrInformerFactory,
vsecrInformerFactory, tsecrInformerFactory, *incomplRetryDelayF)
*ingressClassF, *namespaceF, *devModeF, *varnishImplF,
kubeClient, vController, hController, informerFactory,
vcrInformerFactory, vsecrInformerFactory, tsecrInformerFactory,
*incomplRetryDelayF)
if err != nil {
log.Fatalf("Could not initialize controller: %v", err)
os.Exit(-1)
......
......@@ -87,7 +87,8 @@ deploy-controller-helm:
@helm install viking-controller $(mkdir)/../charts/viking-controller \
--values values-controller.yaml --namespace kube-system \
--set vikingController.image.repository=$(CONTROLLER_IMAGE) \
--set vikingController.image.tag=$(CONTROLLER_TAG)
--set vikingController.image.tag=$(CONTROLLER_TAG) \
--set vikingController.varnishImpl=$(VARNISH)
deploy-controller-kubectl:
@kubectl apply -f serviceaccount-controller.yaml
......@@ -95,7 +96,11 @@ deploy-controller-kubectl:
@kubectl apply -f varnishcfg-crd.yaml
@kubectl apply -f backendcfg-crd.yaml
@kubectl apply -f templatecfg-crd.yaml
ifeq ($(VARNISH),klarlack)
@kubectl apply -f controller_klarlack.yaml
else
@kubectl apply -f controller.yaml
endif
deploy-controller:
......@@ -119,7 +124,11 @@ deploy-service-kubectl:
@kubectl apply -f serviceaccount-varnish.yaml
@kubectl apply -f rbac-varnish.yaml
@kubectl apply -f adm-secret.yaml
ifeq ($(VARNISH),klarlack)
@kubectl apply -f varnish_klarlack.yaml
else
@kubectl apply -f varnish.yaml
endif
@kubectl apply -f admin-svc.yaml
@kubectl apply -f service.yaml
......@@ -146,7 +155,11 @@ undeploy-service-kubectl:
@kubectl delete -f serviceaccount-varnish.yaml
@kubectl delete -f service.yaml
@kubectl delete -f admin-svc.yaml
ifeq ($(VARNISH),klarlack)
@kubectl delete -f varnish_klarlack.yaml
else
@kubectl delete -f varnish.yaml
endif
@kubectl delete -f adm-secret.yaml
@echo Waiting for viking-service Pods to be deleted
@kubectl wait pod --timeout=$(WAIT_TIMEOUT) \
......@@ -170,7 +183,11 @@ undeploy-controller-helm:
-l app.kubernetes.io/name=viking-controller --for=delete
undeploy-controller-kubectl:
ifeq ($(VARNISH),klarlack)
@kubectl delete -f controller_klarlack.yaml
else
@kubectl delete -f controller.yaml
endif
@kubectl delete -f templatecfg-crd.yaml
@kubectl delete -f backendcfg-crd.yaml
@kubectl delete -f varnishcfg-crd.yaml
......
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: backendconfigs.ingress.varnish-cache.org
spec:
group: ingress.varnish-cache.org
names:
kind: BackendConfig
listKind: BackendConfigList
plural: backendconfigs
singular: backendconfig
shortNames:
- becfg
scope: Namespaced
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
validation:
openAPIV3Schema:
required:
- spec
properties:
spec:
required:
- services
properties:
services:
type: array
minItems: 1
items:
type: string
minLength: 1
host-header:
type: string
minLength: 1
connect-timeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
first-byte-timeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
between-bytes-timeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
dnsRetryDelay:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
domainUsageTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
firstLookupTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
resolverIdleTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
resolverTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
proxy-header:
type: integer
minimum: 1
maximum: 2
max-connections:
type: integer
minimum: 1
maxDNSQueries:
type: integer
minimum: 0
maximum: 65535
followDNSRedirects:
type: boolean
probe:
type: object
properties:
url:
type: string
pattern: ^/
request:
type: array
minItems: 1
items:
type: string
expected-response:
type: integer
minimum: 100
maximum: 599
timeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
interval:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
initial:
type: integer
minimum: 0
window:
type: integer
minimum: 0
maximum: 64
threshold:
type: integer
minimum: 0
maximum: 64
director:
type: object
properties:
type:
enum:
- round-robin
- random
- shard
type: string
warmup:
type: integer
minimum: 0
maximum: 100
rampup:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
status:
acceptedNames:
kind: BackendConfig
listKind: BackendConfigList
plural: backendconfigs
singular: backendconfig
shortNames:
- becfg
storedVersions:
- v1alphav1
conditions: []
../charts/viking-controller/crds/backendcfg-crd.yaml
\ No newline at end of file
apiVersion: apps/v1
kind: Deployment
metadata:
name: varnish-ingress-controller
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: varnish-ingress-controller
template:
metadata:
labels:
app: varnish-ingress-controller
spec:
serviceAccountName: varnish-ingress-controller
containers:
- image: varnish-ingress/controller
imagePullPolicy: IfNotPresent
name: varnish-ingress-controller
ports:
- name: http
containerPort: 8080
volumeMounts:
- name: run
mountPath: "/run"
livenessProbe:
exec:
command:
- /usr/bin/pgrep
- -P
- "0"
- k8s-ingress
readinessProbe:
exec:
command:
- /usr/bin/test
- -e
- /run/controller-ready
args:
- -readyfile=/run/controller-ready
- -varnishImpl=klarlack
volumes:
- name: run
emptyDir:
medium: "Memory"
apiVersion: apps/v1
kind: Deployment
metadata:
name: varnish
spec:
replicas: 2
selector:
matchLabels:
app: varnish-ingress
template:
metadata:
labels:
app: varnish-ingress
spec:
serviceAccountName: varnish-ingress
securityContext:
# group varnish in the varnish and haproxy containers
# The varnish and haproxy users belong to this group.
fsGroup: 998
containers:
- image: varnish-ingress/klarlack
imagePullPolicy: IfNotPresent
name: varnish-ingress
ports:
- name: http
containerPort: 80
- name: k8s
containerPort: 8080
volumeMounts:
- name: adm-secret
mountPath: "/var/run/varnish"
readOnly: true
- name: varnish-home
mountPath: "/var/run/varnish-home"
- name: offload
mountPath: "/var/run/offload"
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
livenessProbe:
exec:
command:
- /usr/bin/pgrep
- -P
- "0"
- varnishd
readinessProbe:
httpGet:
path: /ready
port: k8s
args:
- -n
- /var/run/varnish-home
- image: varnish-ingress/haproxy
imagePullPolicy: IfNotPresent
name: varnish-ingress-offloader
ports:
- name: tls
containerPort: 443
- name: k8s
containerPort: 8443
volumeMounts:
- name: tls-cert
mountPath: "/etc/ssl/private"
- name: offload
mountPath: "/var/run/offload"
env:
- name: SECRET_DATAPLANEAPI
valueFrom:
secretKeyRef:
name: adm-secret
key: dataplaneapi
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
livenessProbe:
exec:
command:
- /usr/bin/pgrep
- -P
- "0"
- haproxy
readinessProbe:
httpGet:
path: /healthz
port: k8s
volumes:
- name: adm-secret
secret:
secretName: adm-secret
items:
- key: admin
path: _.secret
- name: tls-cert
emptyDir: {}
- name: varnish-home
emptyDir:
medium: "Memory"
- name: offload
emptyDir: {}
# Copyright (c) 2021 UPLEX Nils Goroll Systemoptimierung
# All rights reserved
#
# Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# GNU make is required.
mkpath := $(abspath $(lastword $(MAKEFILE_LIST)))
mkdir := $(dir $(mkpath))
CHARTDIR=$(mkdir)/../../../charts
TESTDIR=$(mkdir)/../../../test
ifneq ($(VARNISH),klarlack)
all deploy deploy-helm deploy-kubectl verify wait uninstall-kubectl \
uninstall-helm undeploy-kubectl undeploy-helm:
@echo TLS onload only supported for the klarlack implementation
else
all: deploy
deploy-helm:
@helm install viking-ingress-tls-onload $(CHARTDIR)/viking-test-app \
--values values.yaml
deploy-kubectl:
@kubectl apply -f cafe.yaml
@kubectl apply -f ext-svcs.yaml
@kubectl apply -f cafe-ingress.yaml
@kubectl apply -f backend-cfg.yaml
# TESTOPTS are passed to varnishtest, e.g.: make TESTOPTS=-v verify
verify:
$(mkdir)/verify.sh
wait:
$(TESTDIR)/wait.sh app=varnish-ingress
uninstall-kubectl:
@kubectl delete -f backend-cfg.yaml
@kubectl delete -f cafe-ingress.yaml
@kubectl delete -f ext-svcs.yaml
@kubectl delete -f cafe.yaml
uninstall-helm:
@helm uninstall viking-ingress-tls-onload
undeploy-kubectl: uninstall-kubectl wait
undeploy-helm: uninstall-helm wait
endif
ifeq ($(DEPLOY),kubectl)
deploy: deploy-kubectl
undeploy: undeploy-kubectl
else
deploy: deploy-helm
undeploy: undeploy-helm
endif
.PHONY: all $(MAKECMDGOALS)
# Sample backend configurations
apiVersion: "ingress.varnish-cache.org/v1alpha1"
kind: BackendConfig
metadata:
name: cafe-onload-cfg
spec:
services:
- coffee-external-svc
tls:
verify: false
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress-varnish
annotations:
kubernetes.io/ingress.class: "varnish"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee
backend:
serviceName: coffee-external-svc
servicePort: 4443
# looks like -*- vcl -*-
varnishtest "cafe example with TLS onload for a backend"
# Expectations for the https-echo test backend
client c1 -connect "${localhost} ${localport}" {
txreq -url /coffee/foo/bar -hdr "Host: cafe.example.com"
rxresp
expect resp.status == 200
expect resp.http.X-Host ~ "^coffee-[a-z0-9]+-[a-z0-9]+$"
expect resp.http.X-URI == "/coffee/foo/bar"
expect resp.body == "GET /coffee/foo/bar HTTP/1.1"
} -run
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
spec:
replicas: 2
selector:
matchLabels:
app: coffee
example: onload
template:
metadata:
labels:
app: coffee
example: onload
spec:
containers:
- name: coffee
image: uplex/https-echo
ports:
- containerPort: 4443
---
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
spec:
ports:
- port: 443
targetPort: 4443
protocol: TCP
name: https
selector:
app: coffee
example: onload
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
spec:
replicas: 3
selector:
matchLabels:
app: tea
example: onload
template:
metadata:
labels:
app: tea
example: onload
spec:
containers:
- name: tea
image: uplex/http-echo
ports:
- containerPort: 7357
---
apiVersion: v1
kind: Service
metadata:
name: tea-svc
spec:
ports:
- port: 80
targetPort: 7357
protocol: TCP
name: http
selector:
app: tea
example: onload
apiVersion: v1
kind: Service
metadata:
name: coffee-external-svc
spec:
type: ExternalName
externalName: coffee-svc.default.svc.cluster.local
ports:
- port: 443
protocol: TCP
name: https
apps:
coffee-external:
externalName: coffee-svc.default.svc.cluster.local
labels:
app: coffee-external
example: onload
config:
tls:
verify: false
coffee:
image: uplex/https-echo
replicas: 2
servicePort: 443
containerPort: 4443
targetPort: 4443
labels:
app: coffee
example: onload
tea:
image: uplex/http-echo
replicas: 3
servicePort: 80
containerPort: 7357
targetPort: 7357
labels:
app: tea
example: onload
ingress:
name: cafe-ingress
rules:
- host: cafe.example.com
paths:
- path: /tea
app: tea
servicePort: 80
- path: /coffee
app: coffee-external
servicePort: 4443
#! /bin/bash -ex
MYDIR=$(dirname ${BASH_SOURCE[0]})
source ${MYDIR}/../../../test/utils.sh
LOCALPORT=${LOCALPORT:-8888}
wait_until_ready app=varnish-ingress
wait_until_configured app=varnish-ingress
kubectl port-forward svc/varnish-ingress ${LOCALPORT}:80 >/dev/null &
trap 'kill $(jobs -p)' EXIT
wait_for_port ${LOCALPORT}
varnishtest ${TESTOPTS} -Dlocalport=${LOCALPORT} cafe.vtc
......@@ -5,21 +5,27 @@ go 1.15
require (
code.uplex.de/uplex-varnish/varnishapi v0.0.0-20191205154529-31e610a4139d
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
github.com/go-openapi/errors v0.19.4 // indirect
github.com/go-openapi/strfmt v0.19.5
github.com/go-openapi/swag v0.19.9 // indirect
github.com/go-openapi/validate v0.19.8 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/go-openapi/analysis v0.20.1 // indirect
github.com/go-openapi/errors v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/runtime v0.19.29 // indirect
github.com/go-openapi/strfmt v0.20.1
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-openapi/validate v0.20.2 // indirect
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff // indirect
github.com/google/go-cmp v0.3.0
github.com/google/go-cmp v0.5.2
github.com/googleapis/gnostic v0.2.0 // indirect
github.com/haproxytech/models v1.2.4
github.com/haproxytech/models/v2 v2.2.0
github.com/imdario/mergo v0.3.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/prometheus/client_golang v0.9.2
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sirupsen/logrus v1.2.0
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/api v0.16.4
k8s.io/apimachinery v0.16.4
k8s.io/client-go v0.16.4
github.com/sirupsen/logrus v1.6.0
go.mongodb.org/mongo-driver v1.5.3 // indirect
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
k8s.io/api v0.16.15
k8s.io/apimachinery v0.16.15
k8s.io/client-go v0.16.15
k8s.io/code-generator v0.16.5-beta.1 // indirect
)
......@@ -28,9 +28,16 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzs
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
......@@ -42,8 +49,8 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
......@@ -56,15 +63,26 @@ github.com/go-openapi/analysis v0.17.0 h1:8JV+dzJJiK46XqGLqqLav8ZfEiJECp8jlOFhpi
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI=
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ=
github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk=
github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
github.com/go-openapi/analysis v0.20.1 h1:zdVbw8yoD4SWZeq+cWdGgquaB0W4VrsJvDJHJND/Ktc=
github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.19.0 h1:guf3T2lnCBKlODmERt4T9GtMWRpJOikgKGyIvi0xcb8=
github.com/go-openapi/errors v0.19.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/errors v0.19.4 h1:fSGwO1tSYHFu70NKaWJt5Qh0qoBRtCm/mXS1yhf+0W0=
github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.0 h1:Sxpo9PjEHDzhs3FbnGNonvDgWcMW2U7wGTcDDSFSceM=
github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
......@@ -73,6 +91,8 @@ github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
......@@ -81,18 +101,33 @@ github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/loads v0.17.0 h1:H22nMs3GDQk4SwAaFQ+jLNw+0xoFeCueawhZlv8MBYs=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
github.com/go-openapi/loads v0.19.4 h1:5I4CCSqoWzT+82bBkNIvmLc0UOsoKKQ4Fz+3VxOB7SY=
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY=
github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9 h1:zXd+rkzHwMIYVTJ/j/v8zUQ9j3Ir32gC5Dn9DzZVvCk=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI=
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
github.com/go-openapi/runtime v0.19.29 h1:5IIvCaIDbxetN674vX9eOxvoZ9mYGQ16fV1Q0VSG+NA=
github.com/go-openapi/runtime v0.19.29/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.17.0 h1:XNvrt8FlSVP8T1WuhbAFF6QDhJc0zsoWzX4wXARhhpE=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
......@@ -101,31 +136,78 @@ github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCr
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ=
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.19.0 h1:0Dn9qy1G9+UJfRU7TR8bmdGxb4uifB7HNrJjOnV0yPk=
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM=
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.20.1 h1:1VgxvehFne1mbChGeCmZ5pc0LxUf6yaACVSIYAR91Xc=
github.com/go-openapi/strfmt v0.20.1/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.0 h1:Kg7Wl7LkTPlmc393QZQ/5rQadPhi7pBVEMZxyTi0Ii8=
github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE=
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.0 h1:SF5vyj6PBFM6D1cw2NJIFrlS8Su2YKk6ADPPjAH70Bw=
github.com/go-openapi/validate v0.19.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8=
github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4=
github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI=
github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0=
github.com/go-openapi/validate v0.20.2 h1:AhqDegYV3J3iQkMPJSXkvzymHKMTw0BST3RK3hTT4ts=
github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZIVCbJBpTUoY0=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
......@@ -140,12 +222,15 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
......@@ -159,9 +244,9 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/haproxytech/models v1.2.4 h1:KYWMzEVVRxAPI6F64xF6oISY10TGm6VWvo/T2rXp4x4=
github.com/haproxytech/models v1.2.4/go.mod h1:UXZVErm/XN6z10sM/enmxrdeEnwo7vz1JI+a8ycEvOQ=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/haproxytech/models/v2 v2.2.0 h1:2eBxpioPujHsZ0lMI6IN61V3PfcoNjy254FKnBk4NHs=
github.com/haproxytech/models/v2 v2.2.0/go.mod h1:HjM8x+j1/j4nHUA5lqh159OPZ3zQ5iGz13vHo9xeEk0=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
......@@ -171,20 +256,35 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
......@@ -194,10 +294,21 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
......@@ -205,8 +316,13 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
......@@ -214,9 +330,16 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
......@@ -229,15 +352,25 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7q
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
......@@ -248,23 +381,46 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
go.mongodb.org/mongo-driver v1.5.3 h1:wWbFB6zaGHpzguF3f7tW94sVE8sFl3lHx8OZx/4OuFI=
go.mongodb.org/mongo-driver v1.5.3/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56 h1:ZpKuNIejY8P0ExLOVyKhb0WsgG8UdvHXe6TWjY7eL6k=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
......@@ -286,10 +442,20 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
......@@ -299,7 +465,9 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
......@@ -309,17 +477,36 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
......@@ -329,10 +516,16 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
......@@ -351,9 +544,11 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
......@@ -363,14 +558,23 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.16.4 h1:O06Ed/hgLiCrzW1SHp6HAhqcTnYHtK80bP5rXoHakpM=
k8s.io/api v0.16.4/go.mod h1:AtzMnsR45tccQss5q8RnF+W8L81DH6XwXwo/joEx9u0=
k8s.io/apimachinery v0.16.4 h1:+VNiyTcctUvBBRUxfulwL2I6TGratkR1oAoULuas/HI=
k8s.io/apimachinery v0.16.4/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ=
k8s.io/client-go v0.16.4 h1:sf+FEZXYhJNjpTZapQDLvvN+0kBeUTxCYxlXcVdhv2E=
k8s.io/client-go v0.16.4/go.mod h1:ZgxhFDxSnoKY0J0U2/Y1C8obKDdlhGPZwA7oHH863Ok=
k8s.io/api v0.16.15 h1:6yvV9YNGwnebDAsA4Sfj+1b1S9j5OYfmckjTdc9b1bI=
k8s.io/api v0.16.15/go.mod h1:8z880CLtpCJqHWe9vmBkZMQeMKHNvdTQuqLW2QUefUA=
k8s.io/apimachinery v0.16.15 h1:4cmEfuRsKuV8pMpaQ6z0AKEUXZ3r+u/NKaz5dvIjySk=
k8s.io/apimachinery v0.16.15/go.mod h1:xAtIC8Gj83Pn2OCs2g57wZpZembRhJhiXIlQIqanwas=
k8s.io/client-go v0.16.15 h1:cuSmM5begnN77V0beNgmhQ9yob6TFUnN+YaqAfRBD40=
k8s.io/client-go v0.16.15/go.mod h1:onpbkg9XeonG579HOlK9RS56ixfOJdbBM5dKluyFM8c=
k8s.io/code-generator v0.16.5-beta.1 h1:+zWxMQH3a6fd8lZe6utWyW/V7nmG2ZMXwtovSJI2p+0=
k8s.io/code-generator v0.16.5-beta.1/go.mod h1:mJUgkl06XV4kstAnLHAIzJPVCOzVR+ZcfPIv4fUsFCY=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
......@@ -378,10 +582,12 @@ k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKO
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ=
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200410163147-594e756bea31 h1:PsbYeEz2x7ll6JYUzBEG+DT78910DDTlvn5Ma10F5/E=
k8s.io/kube-openapi v0.0.0-20200410163147-594e756bea31/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
......
......@@ -449,6 +449,7 @@ type BackendConfigSpec struct {
Services []string `json:"services,omitempty"`
Probe *ProbeSpec `json:"probe,omitempty"`
Director *DirectorSpec `json:"director,omitempty"`
TLS *TLSSpec `json:"tls,omitempty"`
HostHeader string `json:"host-header,omitempty"`
ConnectTimeout string `json:"connect-timeout,omitempty"`
FirstByteTimeout string `json:"first-byte-timeout,omitempty"`
......@@ -485,6 +486,20 @@ type DirectorSpec struct {
Rampup string `json:"rampup,omitempty"`
}
// TLSSpec corresponds to spec.tls in a BackendConfig, to configure
// TLS onload -- TLS connections to IngressBackends using haproxy and
// the via feature of the klarlack implementation of Varnish. Only
// supported for klarlack.
type TLSSpec struct {
Authority *string `json:"authority,omitempty"`
MaxConn *int32 `json:"maxConn,omitempty"`
StickTblSz *int32 `json:"stickTableSize,omitempty"`
Verify *bool `json:"verify,omitempty"`
CACrt string `json:"caCrt,omitempty"`
CAIssuer string `json:"caIssuer,omitempty"`
CASecret string `json:"caSecret,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BackendConfigList is a list of BackendConfig Custom Resources.
......
......@@ -192,6 +192,11 @@ func (in *BackendConfigSpec) DeepCopyInto(out *BackendConfigSpec) {
*out = new(DirectorSpec)
(*in).DeepCopyInto(*out)
}
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(TLSSpec)
(*in).DeepCopyInto(*out)
}
if in.MaxConnections != nil {
in, out := &in.MaxConnections, &out.MaxConnections
*out = new(int32)
......@@ -531,6 +536,42 @@ func (in *ShardSpec) DeepCopy() *ShardSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSSpec) DeepCopyInto(out *TLSSpec) {
*out = *in
if in.Authority != nil {
in, out := &in.Authority, &out.Authority
*out = new(string)
**out = **in
}
if in.MaxConn != nil {
in, out := &in.MaxConn, &out.MaxConn
*out = new(int32)
**out = **in
}
if in.StickTblSz != nil {
in, out := &in.StickTblSz, &out.StickTblSz
*out = new(int32)
**out = **in
}
if in.Verify != nil {
in, out := &in.Verify, &out.Verify
*out = new(bool)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSSpec.
func (in *TLSSpec) DeepCopy() *TLSSpec {
if in == nil {
return nil
}
out := new(TLSSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TemplateConfig) DeepCopyInto(out *TemplateConfig) {
*out = *in
......
......@@ -148,6 +148,7 @@ func NewIngressController(
ingClass string,
namespace string,
devMode bool,
varnishImpl string,
kubeClient kubernetes.Interface,
vc *varnish.Controller,
hc *haproxy.Controller,
......@@ -243,7 +244,8 @@ func NewIngressController(
}
ingc.nsQs = NewNamespaceQueues(ingc.log, ingClass, vc, hc, ingc.listers,
ingc.client, ingc.recorder, incomplRetryDelay, devMode)
ingc.client, ingc.recorder, incomplRetryDelay, devMode,
varnishImpl)
return &ingc, nil
}
......
......@@ -59,6 +59,9 @@ const (
defACLfailStatus = uint16(403)
defDNSRetryDelay = "30s"
defMax2ndTTL = "5m"
defStickTblSz = 128
defMaxConn = 2000
extOnldInstances = 3
vikingPubSvcKey = vikingLabelPfx + "svc"
vikingPubSvcVal = "public"
)
......@@ -335,7 +338,12 @@ func (worker *NamespaceWorker) getVCLSvc(
addrs []vcl.Address,
extName string,
extPort string,
) (vcl.Service, *vcr_v1alpha1.BackendConfig, update.Status) {
) (
vcl.Service,
*vcr_v1alpha1.BackendConfig,
*haproxy.OnloadSpec,
update.Status,
) {
if svcNamespace == "" {
svcNamespace = "default"
}
......@@ -354,9 +362,9 @@ func (worker *NamespaceWorker) getVCLSvc(
status := update.MakeNoop(
"No BackendConfig in namespace %s",
svcNamespace)
return vclSvc, nil, status
return vclSvc, nil, nil, status
}
return vclSvc, nil, update.MakeRecoverable("%v", err)
return vclSvc, nil, nil, update.MakeRecoverable("%v", err)
}
var bcfg *vcr_v1alpha1.BackendConfig
BCfgs:
......@@ -370,13 +378,13 @@ BCfgs:
}
}
if bcfg == nil {
return vclSvc, nil,
return vclSvc, nil, nil,
update.MakeNoop("Service %s/%s: no BackendConfig "+
"specified", svcNamespace, svcName)
}
if bcfg.Spec.Director != nil {
if extName != "" {
return vclSvc, nil,
return vclSvc, nil, nil,
update.MakeFatal(
"Service %s/%s, BackendConfig %s/%s: "+
"director may not be set for "+
......@@ -420,16 +428,88 @@ BCfgs:
if bcfg.Spec.FollowDNSRedirects != nil {
vclSvc.FollowDNSRedirects = *bcfg.Spec.FollowDNSRedirects
}
return vclSvc, bcfg, update.MakeSuccess("")
var onload *haproxy.OnloadSpec
if bcfg.Spec.TLS != nil {
if worker.varnishImpl != "klarlack" {
return vclSvc, nil, nil, update.MakeFatal(
"Service %s/%s, BackendConfig %s/%s: "+
"TLS onload only enabled for the "+
"klarlack implementation "+
"(varnishImpl: %s)",
svcNamespace, svcName, bcfg.Namespace,
bcfg.Name, worker.varnishImpl)
}
vclSvc.Via = true
onload = &haproxy.OnloadSpec{
Verify: true,
StickTblSz: defStickTblSz,
MaxConn: defMaxConn,
}
if bcfg.Spec.TLS.MaxConn != nil {
onload.MaxConn = int(*bcfg.Spec.TLS.MaxConn)
}
if bcfg.Spec.TLS.StickTblSz != nil {
onload.StickTblSz = int(*bcfg.Spec.TLS.StickTblSz)
}
if bcfg.Spec.TLS.Authority != nil {
authority := *bcfg.Spec.TLS.Authority
vclSvc.Authority = &authority
onload.Authority = true
} else {
vclSvc.Authority = nil
onload.Authority = false
}
if bcfg.Spec.TLS.Verify != nil && !*bcfg.Spec.TLS.Verify {
onload.Verify = false
} else if bcfg.Spec.TLS.CACrt != "" {
// XXX
// - find CACrt in cert-manager.io/v1, same ns
// - Sync Incomplete if not found
// - else check isCA field
// - SyncFatal if false
// - else find Secret in secretName field, same ns
// - Sync Incomplete if not found
// 3. else add to haproxySpec
// will have to send to crt-dnldr
if bcfg.Spec.TLS.CAIssuer != "" {
// XXX
// 1. find in cert-manager, may be a cluster
// issuer if ns/name is specified
// 2. SyncIncomplete if not found
// 3. otherwise attempt verification
// 4. SyncFatal if verfication fails
// - not added to any config
}
} else if bcfg.Spec.TLS.CASecret != "" {
// XXX
// 1. Find in the same ns
// 2. SyncIncomplete if not found
// 3. otherwise update haproxy spec
// will have to send to crt-dnldr
} else {
// SyncFatal, Verify true but no crt
}
}
return vclSvc, bcfg, onload, update.MakeSuccess("")
}
func (worker *NamespaceWorker) ings2VCLSpec(
ings []*extensions.Ingress) (vcl.Spec,
map[string]*vcr_v1alpha1.BackendConfig, update.Status) {
func (worker *NamespaceWorker) ings2VCLSpec(ings []*extensions.Ingress) (
vcl.Spec,
map[string]*vcr_v1alpha1.BackendConfig,
map[string]*haproxy.OnloadSpec,
update.Status,
) {
vclSpec := vcl.Spec{}
vclSpec.IntSvcs = make(map[string]vcl.Service)
vclSpec.ExtSvcs = make(map[string]vcl.Service)
bcfgs := make(map[string]*vcr_v1alpha1.BackendConfig)
onlds := make(map[string]*haproxy.OnloadSpec)
for _, ing := range ings {
namespace := ing.Namespace
if namespace == "" {
......@@ -443,23 +523,33 @@ func (worker *NamespaceWorker) ings2VCLSpec(
addrs, extName, extPort, status := worker.
ingBackend2Addrs(namespace, *backend)
if status.IsError() {
return vclSpec, bcfgs, status
return vclSpec, bcfgs, onlds, status
}
vclSvc, bcfg, status := worker.getVCLSvc(namespace,
backend.ServiceName, addrs, extName, extPort)
vclSvc, bcfg, onload, status := worker.
getVCLSvc(namespace, backend.ServiceName, addrs,
extName, extPort)
if status.IsError() {
return vclSpec, bcfgs, status
return vclSpec, bcfgs, onlds, status
}
vclSpec.DefaultService = vclSvc
key := namespace + "/" + backend.ServiceName
if extName == "" {
vclSpec.IntSvcs[key] = vclSvc
if onload != nil {
onload.Instances = len(addrs)
}
} else {
vclSpec.ExtSvcs[key] = vclSvc
if onload != nil {
onload.Instances = extOnldInstances
}
}
if bcfg != nil {
bcfgs[vclSvc.Name] = bcfg
}
if onload != nil {
onlds[vclSvc.Name] = onload
}
}
for _, rule := range ing.Spec.Rules {
vclRule := vcl.Rule{Host: rule.Host}
......@@ -473,7 +563,7 @@ func (worker *NamespaceWorker) ings2VCLSpec(
ingBackend2Addrs(namespace,
path.Backend)
if status.IsError() {
return vclSpec, bcfgs, status
return vclSpec, bcfgs, onlds, status
}
if extName == "" &&
(addrs == nil || len(addrs) == 0) {
......@@ -481,29 +571,39 @@ func (worker *NamespaceWorker) ings2VCLSpec(
namespace + " IngressBackend=" +
path.Backend.String())
}
vclSvc, bcfg, status := worker.
vclSvc, bcfg, onload, status := worker.
getVCLSvc(namespace,
path.Backend.ServiceName, addrs,
extName, extPort)
if status.IsError() {
return vclSpec, bcfgs, status
return vclSpec, bcfgs, onlds, status
}
vclRule.PathMap[path.Path] = vclSvc
key := namespace + "/" +
path.Backend.ServiceName
if extName == "" {
vclSpec.IntSvcs[key] = vclSvc
if onload != nil {
onload.Instances = len(addrs)
}
} else {
vclSpec.ExtSvcs[key] = vclSvc
if onload != nil {
onload.Instances =
extOnldInstances
}
}
if bcfg != nil {
bcfgs[vclSvc.Name] = bcfg
}
if onload != nil {
onlds[vclSvc.Name] = onload
}
}
vclSpec.Rules = append(vclSpec.Rules, vclRule)
}
}
return vclSpec, bcfgs, update.MakeSuccess("")
return vclSpec, bcfgs, onlds, update.MakeSuccess("")
}
func configConditions(vclConds []vcl.MatchTerm,
......@@ -995,7 +1095,7 @@ func (worker *NamespaceWorker) addOrUpdateIng(
}
worker.log.Infof("Ingresses implemented by Varnish Service %s: %v",
svcKey, ingNames)
vclSpec, bcfgs, status := worker.ings2VCLSpec(ings)
vclSpec, bcfgs, onlds, status := worker.ings2VCLSpec(ings)
if status.IsError() {
return status
}
......@@ -1051,7 +1151,18 @@ func (worker *NamespaceWorker) addOrUpdateIng(
if err != nil {
return update.MakeFatal("%v", err)
}
if offldrSpec.Name == "" {
if len(onlds) > 0 {
if len(onlds) > 1 {
// XXX
return update.MakeFatal(
"Multiple TLS onload configs currently not " +
"supported")
} // else {
for _, v := range onlds {
offldrSpec.Onload = v
}
}
if offldrSpec.Name == "" && len(onlds) == 0 {
worker.log.Infof("No TLS config found for Ingresses: %v",
ingNames)
} else {
......@@ -1073,10 +1184,7 @@ func (worker *NamespaceWorker) addOrUpdateIng(
return status
}
if len(offldrSpec.Secrets) == 0 {
worker.log.Infof("Service %s: no TLS certificates specified",
svcKey)
} else {
if len(offldrSpec.Secrets) != 0 || len(onlds) != 0 {
if status := worker.hController.Update(svcKey, offldAddrs,
offldrSpec); status.IsError() {
return status
......
......@@ -62,6 +62,7 @@ import (
type NamespaceWorker struct {
namespace string
ingClass string
varnishImpl string
log *logrus.Logger
vController *varnish.Controller
hController *haproxy.Controller
......@@ -296,6 +297,7 @@ func (worker *NamespaceWorker) work() {
type NamespaceQueues struct {
Queue workqueue.RateLimitingInterface
ingClass string
varnishImpl string
log *logrus.Logger
vController *varnish.Controller
hController *haproxy.Controller
......@@ -326,6 +328,7 @@ func NewNamespaceQueues(
recorder record.EventRecorder,
incomplRetryDelay time.Duration,
devMode bool,
varnishImpl string,
) *NamespaceQueues {
q := workqueue.NewNamedRateLimitingQueue(
......@@ -334,6 +337,7 @@ func NewNamespaceQueues(
Queue: q,
log: log,
ingClass: ingClass,
varnishImpl: varnishImpl,
vController: vController,
hController: hController,
workers: make(map[string]*NamespaceWorker),
......@@ -379,6 +383,7 @@ func (qs *NamespaceQueues) next() {
worker = &NamespaceWorker{
namespace: ns,
ingClass: qs.ingClass,
varnishImpl: qs.varnishImpl,
log: qs.log,
vController: qs.vController,
hController: qs.hController,
......
......@@ -31,6 +31,7 @@ package haproxy
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
......@@ -40,7 +41,7 @@ import (
"time"
"github.com/go-openapi/strfmt"
"github.com/haproxytech/models"
models "github.com/haproxytech/models/v2"
)
var fmts = strfmt.NewFormats()
......@@ -53,14 +54,23 @@ const (
versionHdr = "Configuration-Version"
reloadIDHdr = "Reload-ID"
varnishSock = "unix@/varnish.sock"
backendSock = "unix@/run/offload/onload.sock"
frontend = "offloader"
backend = "varnish"
server = backend
onloader = "onloader"
varnish = "varnish"
server = varnish
ingBackends = "ingressBackends"
frontendSitePath = sitesPath + "/" + frontend
backendSitePath = sitesPath + "/" + onloader
crtPath = "/etc/ssl/private"
caBundlePath = "/run/haproxy/ca-bundle.crt"
)
var port = int64(4443)
var (
port = int64(4443)
sslPort = int64(443)
roundRobin = "roundrobin"
)
// ReloadStatus classifies the current state of a dataplane reload.
type ReloadStatus uint8
......@@ -197,7 +207,7 @@ var offldSite = &models.Site{
},
Farms: []*models.SiteFarm{
{
Name: backend,
Name: varnish,
UseAs: "default",
Servers: []*models.Server{
{
......@@ -215,6 +225,58 @@ func getSite() ([]byte, error) {
return offldSite.MarshalBinary()
}
func getOnldSite(spec *OnloadSpec) ([]byte, error) {
// XXX: stick-table configuration
maxConn := int64(spec.MaxConn)
site := &models.Site{
Name: onloader,
Service: &models.SiteService{
Listeners: []*models.Bind{
{
Name: onloader,
Address: backendSock,
Mode: "660",
AcceptProxy: true,
},
},
Mode: "tcp",
Maxconn: &maxConn,
},
Farms: []*models.SiteFarm{
{
Name: ingBackends,
UseAs: "default",
Mode: "tcp",
Balance: &models.Balance{
Algorithm: &roundRobin,
},
Servers: []*models.Server{},
},
},
}
for s := 0; s < spec.Instances; s++ {
server := &models.Server{
Name: fmt.Sprintf("s%02d", s),
Address: "0.0.0.0",
Port: &sslPort,
Ssl: "enabled",
Alpn: "http/1.1",
Stick: "enabled",
}
if spec.Verify {
server.Verify = "required"
server.SslCafile = caBundlePath
if spec.Authority {
server.Sni = "fc_pp_authority"
}
} else {
server.Verify = "none"
}
site.Farms[0].Servers = append(site.Farms[0].Servers, server)
}
return site.MarshalBinary()
}
func drainAndClose(body io.ReadCloser) {
io.Copy(ioutil.Discard, body)
body.Close()
......@@ -355,14 +417,24 @@ func (client *DataplaneClient) FinishTx(
}
func (client *DataplaneClient) configTLS(
tx *models.Transaction, spec Spec, path, method string) error {
tx *models.Transaction,
path, method string,
onldSpec *OnloadSpec,
) error {
var rdr *bytes.Reader
if method != http.MethodDelete {
site, err := getSite()
var siteBytes []byte
var err error
if onldSpec == nil {
siteBytes, err = getSite()
} else {
siteBytes, err = getOnldSite(onldSpec)
}
if err != nil {
return err
}
rdr = bytes.NewReader(site)
rdr = bytes.NewReader(siteBytes)
}
req, err := client.getReq(path, method, rdr,
......@@ -407,39 +479,72 @@ func (client *DataplaneClient) configTLS(
}
}
// AddTLS adds the offloader configuration for haproxy, as specified
// by spec, in the dataplane transaction tx.
// AddOffldr adds the offloader configuration for haproxy, in the
// dataplane transaction tx.
//
// AddTLS MUST be used if the offloader was not configured previously
// AddOffldr MUST be used if the offloader was not configured previously
// since the haproxy container was started, or after deletion.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) AddTLS(
tx *models.Transaction, spec Spec) error {
func (client *DataplaneClient) AddOffldr(tx *models.Transaction) error {
return client.configTLS(tx, sitesPath, http.MethodPost, nil)
}
return client.configTLS(tx, spec, sitesPath, http.MethodPost)
// UpdateOffldr modifies the offloader configuration for haproxy, in
// the dataplane transaction tx.
//
// UpdateOffldr MUST be used if the offloader was previously added with
// AddOffldr, and not removed with DeleteOffldr.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) UpdateOffldr(tx *models.Transaction) error {
return client.configTLS(tx, frontendSitePath, http.MethodPut, nil)
}
// DeleteOffldr removes the haproxy offloader configuration, in the
// dataplane transaction tx.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) DeleteOffldr(tx *models.Transaction) error {
return client.configTLS(tx, frontendSitePath, http.MethodDelete, nil)
}
// UpdateTLS modifies the offloader configuration for haproxy to the
// specification in spec, in the dataplane transaction tx.
// AddOnldr adds the onloader configuration for haproxy, in the
// dataplane transaction tx. instances specifies the number of servers
// in the haproxy backend.
//
// UpdateTLS MUST be used if the offloader was previously added with
// AddTLS, and not removed with DeleteTLS.
// AddOnldr MUST be used if the onloader was not configured previously
// since the haproxy container was started, or after deletion.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) UpdateTLS(
tx *models.Transaction, spec Spec) error {
func (client *DataplaneClient) AddOnldr(
tx *models.Transaction,
onldSpec *OnloadSpec,
) error {
return client.configTLS(tx, sitesPath, http.MethodPost, onldSpec)
}
return client.configTLS(tx, spec, frontendSitePath, http.MethodPut)
// UpdateOnldr modifies the onloader configuration for haproxy, in the
// dataplane transaction tx. instances specifies the number of servers
// in the haproxy backend.
//
// UpdateOnldr MUST be used if the onloader was previously added with
// AddOnldr, and not removed with DeleteOnldr.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) UpdateOnldr(
tx *models.Transaction,
onldSpec *OnloadSpec,
) error {
return client.configTLS(tx, backendSitePath, http.MethodPut, onldSpec)
}
// DeleteTLS removes the haproxy offloader configuration, in the
// DeleteOnldr removes the haproxy onloader configuration, in the
// dataplane transaction tx.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) DeleteTLS(tx *models.Transaction) error {
return client.configTLS(tx, Spec{}, frontendSitePath, http.MethodDelete)
func (client *DataplaneClient) DeleteOnldr(tx *models.Transaction) error {
return client.configTLS(tx, backendSitePath, http.MethodDelete, nil)
}
// DeleteTx removes the dataplane transaction tx. This should be
......@@ -500,12 +605,13 @@ type sitesBody struct {
Sites models.Sites `json:"data"`
}
// OffldrStatus returns true iff the offloader site has been loaded by
// the dataplane API, and returns the current configuration version.
// LoaderStatus returns booleans for whether the off- and onloader
// sites have been loaded by the dataplane API, and returns the
// current configuration version.
//
// A non-nil error return may wrap a DataplaneError.
func (client *DataplaneClient) OffldrStatus() (
loaded bool, version int, err error) {
func (client *DataplaneClient) LoaderStatus() (
offLoaded, onLoaded bool, version int, err error) {
req, err := client.getReq(sitesPath, http.MethodGet, nil, false)
if err != nil {
......@@ -544,7 +650,11 @@ func (client *DataplaneClient) OffldrStatus() (
// XXX what if version from body & the header don't match?
for _, site := range []*models.Site(sb.Sites) {
if site.Name == frontend {
loaded = true
offLoaded = true
} else if site.Name == onloader {
onLoaded = true
}
if offLoaded && onLoaded {
break
}
}
......
......@@ -62,6 +62,18 @@ func (spec SecretSpec) String() string {
return spec.Namespace + "/" + spec.Name
}
// OnloadSpec specifies the configuration of TLS onload for haproxy.
// The haproxy configuration specifically works together with the
// via feature of the klarlack implementation of Varnish. See:
// https://github.com/varnishcache/varnish-cache/pull/3128
type OnloadSpec struct {
Verify bool
Authority bool
Instances int
StickTblSz int
MaxConn int
}
// Spec specifies the configuration of TLS offload for haproxy. It
// includes the namespace and name of the Varnish admin Service (the
// headless k8s Service specifying ports for remote administration),
......@@ -70,6 +82,7 @@ type Spec struct {
Namespace string
Name string
Secrets []SecretSpec
Onload *OnloadSpec
}
func (spec Spec) String() string {
......@@ -177,7 +190,8 @@ type configStatus struct {
dplaneState ReloadState
version int64
pemExists map[SecretSpec]bool
loaded bool
offLoaded bool
onLoaded bool
}
type haproxyInst struct {
......@@ -270,7 +284,7 @@ func decodeCrtError(secret SecretSpec, inst *haproxyInst, err error) error {
// XXX eliminate repetition in updateLoadStatus() & updateInstance()
func (hc *Controller) updateLoadStatus(inst *haproxyInst) error {
hc.log.Debugf("Offloader instance %s, checking load status, spec: %+v",
hc.log.Debugf("haproxy instance %s, checking load status, spec: %+v",
inst.name, inst.spec)
inst.admMtx.Lock()
defer inst.admMtx.Unlock()
......@@ -285,23 +299,23 @@ func (hc *Controller) updateLoadStatus(inst *haproxyInst) error {
if !ok {
inst.status.pemExists[s] = false
}
hc.log.Debugf("Offloader instance %s, "+
hc.log.Debugf("haproxy instance %s, "+
"checking certificate for Secret %s", inst.name, s)
if err := inst.crtDnldr.Put(s); err != nil {
return decodeCrtError(s, inst, err)
}
inst.status.pemExists[s] = true
hc.log.Infof("Offloader instance %s: certificate for Secret "+
hc.log.Infof("haproxy instance %s: certificate for Secret "+
"%s exists", inst.name, s)
}
if inst.status.dplaneState.ID == "" {
hc.log.Infof("Offloader instance %s: no known TLS config "+
hc.log.Infof("haproxy instance %s: no known TLS config "+
"reload state", inst.name)
return nil
}
hc.log.Debugf("Offloader instance %s: checking reload state: %s",
hc.log.Debugf("haproxy instance %s: checking reload state: %s",
inst.name, inst.status.dplaneState.ID)
reloaded, state, err := inst.dplane.Reloaded(inst.status.dplaneState.ID)
if err != nil {
......@@ -310,11 +324,11 @@ func (hc *Controller) updateLoadStatus(inst *haproxyInst) error {
inst.status.dplaneState = state
if !reloaded {
return update.MakeIncomplete(
"Offloader instance %s: TLS config %s not "+
"haproxy instance %s: TLS config %s not "+
"loaded, status: %s", inst.name, inst.spec,
state.Status)
}
hc.log.Infof("Offloader instance %s: TLS config %s successfully "+
hc.log.Infof("haproxy instance %s: TLS config %s successfully "+
"loaded at %s", inst.name, inst.spec,
state.Timestamp.Format(time.RFC3339))
return nil
......@@ -323,15 +337,15 @@ func (hc *Controller) updateLoadStatus(inst *haproxyInst) error {
func (hc *Controller) updateInstance(inst *haproxyInst, spec *Spec) error {
var err error
hc.log.Infof("Update offloader instance %s to TLS config: %s",
hc.log.Infof("Update haproxy instance %s to TLS config: %s",
inst.name, spec)
hc.log.Debugf("Offloader instance: %+v", inst)
hc.log.Debugf("haproxy instance: %+v", inst)
if reflect.DeepEqual(spec, inst.spec) {
hc.log.Infof("Offloader instance %s: TLS config %s was "+
hc.log.Infof("haproxy instance %s: TLS config %s was "+
"accepted for load", inst.name, spec)
return hc.updateLoadStatus(inst)
}
hc.log.Debugf("Offloader instance %s, old spec: %+v, new spec: %+v",
hc.log.Debugf("haproxy instance %s, old spec: %+v, new spec: %+v",
inst.name, inst.spec, spec)
inst.admMtx.Lock()
......@@ -339,10 +353,10 @@ func (hc *Controller) updateInstance(inst *haproxyInst, spec *Spec) error {
hc.wg.Add(1)
defer hc.wg.Done()
if len(spec.Secrets) == 0 {
if len(spec.Secrets) == 0 && spec.Onload == nil {
return update.MakeIncomplete(
"Offloader instance %s: no certificates specified",
inst.name)
"haproxy instance %s: no offload certificates or "+
"onload config specified", inst.name)
}
for _, s := range spec.Secrets {
hc.log.Debugf("Offloader instance %s, checking certificate "+
......@@ -369,17 +383,37 @@ func (hc *Controller) updateInstance(inst *haproxyInst, spec *Spec) error {
hc.log.Debugf("Offloader instance %s: started transaction: %+v",
inst.name, tx)
if tx.Version <= 1 {
hc.log.Debugf("Offloader instance %s: adding TLS config %s",
inst.name, spec)
err = inst.dplane.AddTLS(tx, *spec)
} else {
hc.log.Debugf("Offloader instance %s: updating TLS config %s",
inst.name, spec)
err = inst.dplane.UpdateTLS(tx, *spec)
if len(spec.Secrets) > 0 && !inst.status.offLoaded {
if tx.Version <= 1 || inst.spec == nil ||
len(inst.spec.Secrets) == 0 {
hc.log.Debugf("Offloader instance %s: "+
"adding TLS config", inst.name)
err = inst.dplane.AddOffldr(tx)
} else {
hc.log.Debugf("Offloader instance %s: "+
"updating TLS config", inst.name)
err = inst.dplane.UpdateOffldr(tx)
}
if err != nil {
return err
}
}
if err != nil {
return err
if spec.Onload != nil && !inst.status.onLoaded {
if tx.Version <= 1 || inst.spec == nil ||
inst.spec.Onload == nil {
hc.log.Debugf("Onloader instance %s: "+
"adding TLS config %+v", inst.name,
*spec.Onload)
err = inst.dplane.AddOnldr(tx, spec.Onload)
} else {
hc.log.Debugf("Onloader instance %s: "+
"updating TLS config %+v", inst.name,
*spec.Onload)
err = inst.dplane.UpdateOnldr(tx, spec.Onload)
}
if err != nil {
return err
}
}
hc.log.Debugf("Offloader instance %s: finishing tx for version %d: %+v",
......@@ -398,10 +432,20 @@ func (hc *Controller) updateInstance(inst *haproxyInst, spec *Spec) error {
Namespace: spec.Namespace,
Name: spec.Name,
Secrets: make([]SecretSpec, len(spec.Secrets)),
Onload: nil,
}
for i, s := range spec.Secrets {
inst.spec.Secrets[i] = s
}
if spec.Onload != nil {
inst.spec.Onload = &OnloadSpec{
Verify: spec.Onload.Verify,
Authority: spec.Onload.Authority,
Instances: spec.Onload.Instances,
StickTblSz: spec.Onload.StickTblSz,
MaxConn: spec.Onload.MaxConn,
}
}
// XXX where does this go?
// defer hc.dataplane.DeleteTx(tx)
......@@ -409,10 +453,15 @@ func (hc *Controller) updateInstance(inst *haproxyInst, spec *Spec) error {
switch state.Status {
case Succeeded:
inst.status.dplaneState = state
hc.log.Infof("Offloader instance %s: TLS config %s sucessfully"+
hc.log.Infof("haproxy instance %s: TLS config %s sucessfully"+
"loaded at %s", inst.name, spec,
state.Timestamp.Format(time.RFC3339))
inst.status.loaded = true
if len(spec.Secrets) > 0 {
inst.status.offLoaded = true
}
if spec.Onload != nil {
inst.status.onLoaded = true
}
return nil
case Failed, Unknown:
return fmt.Errorf("Offloader instance %s: TLS config %s load "+
......@@ -428,16 +477,20 @@ func (hc *Controller) updateInstance(inst *haproxyInst, spec *Spec) error {
}
inst.status.dplaneState = state
if reloaded {
hc.log.Infof("Offloader instance %s: TLS config %s "+
hc.log.Infof("haproxy instance %s: TLS config %s "+
"successfully loaded at %s", inst.name, spec,
state.Timestamp.Format(time.RFC3339))
inst.status.loaded = true
if len(spec.Secrets) > 0 {
inst.status.offLoaded = true
}
if spec.Onload != nil {
inst.status.onLoaded = true
}
return nil
}
return update.MakeIncomplete(
"Offloader instance %s: TLS config %s not "+
"loaded, status: %s",
inst.name, spec, state.Status)
"haproxy instance %s: TLS config %s not loaded, "+
"status: %s", inst.name, spec, state.Status)
default:
panic("Illegal reload status")
}
......@@ -456,26 +509,26 @@ func (hc *Controller) updateOffldSvc(svcKey string) error {
svc, exists := hc.svcs[svcKey]
if !exists || svc == nil {
return update.MakeIncomplete(
"No known offloader service for %s", svcKey)
"No known haproxy service for %s", svcKey)
}
if svc.secrName == "" {
return update.MakeIncomplete(
"No known admin secret for offloader service %s",
"No known admin secret for haproxy service %s",
svcKey)
}
if svc.spec == nil {
return update.MakeNoop(
"Offloader service %s: no current spec", svcKey)
"haproxy service %s: no current spec", svcKey)
}
hc.log.Info("Updating offloader instances for ", svcKey)
hc.log.Info("Updating haproxy instances for ", svcKey)
for _, inst := range svc.instances {
if inst == nil {
hc.log.Errorf("Instance object is nil")
continue
}
// XXX metrics
hc.log.Debugf("offloader svc %s: get current status", inst.name)
hc.log.Debugf("haproxy svc %s: get current status", inst.name)
if err := hc.getOffldStatus(inst); err != nil {
offldrErr := inst.mkError(err)
errs = append(errs, offldrErr)
......@@ -497,25 +550,26 @@ func (hc *Controller) removeOffldrInstances(
for _, inst := range insts {
version := inst.status.version + 1
hc.log.Debugf("Offloader instance %s: starting tx for version "+
hc.log.Debugf("haproxy instance %s: starting tx for version "+
"%d", inst.name, version)
tx, err := inst.dplane.StartTx(version)
if err != nil {
errs = append(errs, inst.mkError(err))
continue
}
hc.log.Debugf("Offloader instance %s: started transaction: %+v",
hc.log.Debugf("haproxy instance %s: started transaction: %+v",
inst.name, tx)
hc.log.Debugf("Offloader instance %s: deleting TLS config",
// XXX either offload or onload or both
hc.log.Debugf("haproxy instance %s: deleting offload config",
inst.name)
err = inst.dplane.DeleteTLS(tx)
err = inst.dplane.DeleteOffldr(tx)
if err != nil {
errs = append(errs, inst.mkError(err))
continue
}
hc.log.Debugf("Offloader instance %s: finishing tx for "+
hc.log.Debugf("haproxy instance %s: finishing tx for "+
"version %d: %+v", inst.name, tx.Version, tx)
state, err := inst.dplane.FinishTx(tx)
if err != nil {
......@@ -523,25 +577,25 @@ func (hc *Controller) removeOffldrInstances(
continue
}
defer inst.dplane.DeleteTx(tx)
hc.log.Infof("Offloader instance %s: transaction accepted for "+
hc.log.Infof("haproxy instance %s: transaction accepted for "+
"delete", inst.name)
inst.status.version = tx.Version
inst.status.dplaneState = state
switch state.Status {
case Succeeded:
hc.log.Infof("Offloader instance %s: TLS config "+
hc.log.Infof("haproxy instance %s: TLS config "+
"sucessfully deleted at %s", inst.name,
state.Timestamp.Format(time.RFC3339))
continue
case Failed, Unknown:
err = fmt.Errorf("Offloader instance %s: TLS config "+
err = fmt.Errorf("haproxy instance %s: TLS config "+
"delete failed or status unknown: %v",
inst.name, state)
errs = append(errs, inst.mkError(err))
continue
case InProgress:
hc.log.Debugf("Offloader instance %s: checking reload "+
hc.log.Debugf("haproxy instance %s: checking reload "+
"state: %s", inst.name,
inst.status.dplaneState.ID)
reloaded, state, err := inst.dplane.Reloaded(
......@@ -552,7 +606,7 @@ func (hc *Controller) removeOffldrInstances(
}
inst.status.dplaneState = state
if reloaded {
hc.log.Infof("Offloader instance %s: TLS "+
hc.log.Infof("haproxy instance %s: TLS "+
"config successfully deleted at %s",
inst.name,
state.Timestamp.Format(time.RFC3339))
......@@ -560,7 +614,7 @@ func (hc *Controller) removeOffldrInstances(
continue
}
err = update.MakeIncomplete(
"Offloader instance %s: TLS config "+
"haproxy instance %s: TLS config "+
"not deleted, status: %s", inst.name,
state.Status)
errs = append(errs, inst.mkError(err))
......@@ -667,26 +721,33 @@ func (hc *Controller) updateOffldrAddrs(key string, addrs []OffldAddr,
}
func (hc *Controller) getOffldStatus(inst *haproxyInst) error {
hc.log.Debugf("Offloader instance %s, checking offloader config",
inst.name)
hc.log.Debugf("haproxy instance %s, checking config", inst.name)
inst.admMtx.Lock()
defer inst.admMtx.Unlock()
hc.wg.Add(1)
defer hc.wg.Done()
loaded, version, err := inst.dplane.OffldrStatus()
offLoaded, onLoaded, version, err := inst.dplane.LoaderStatus()
if err != nil {
return err
}
inst.status.version = int64(version)
inst.status.loaded = loaded
if loaded {
inst.status.offLoaded = offLoaded
inst.status.onLoaded = onLoaded
if offLoaded {
hc.log.Infof("Offloader instance %s: offloader configured, "+
"version=%d", inst.name, version)
} else {
hc.log.Infof("Offloader instance %s: offloader not configured,"+
" current version=%d", inst.name, version)
}
if onLoaded {
hc.log.Infof("Onloader instance %s: onloader configured, "+
"version=%d", inst.name, version)
} else {
hc.log.Infof("Onloader instance %s: onloader not configured,"+
" current version=%d", inst.name, version)
}
return nil
}
......
......@@ -190,6 +190,9 @@ sub vcl_init {
{{- if .Probe}}
, probe = {{probeName $name}}
{{- end}}
{{- if .Via}}
, via = vk8s_via
{{- end}}
{{- end}}
);
{{- if .ResolverIdleTimeout}}
......
......@@ -27,6 +27,10 @@ echo TLS offload example with multiple certificates distinguished by SNI
cd ${MYPATH}/../examples/tls/sni
make deploy verify undeploy
echo TLS onload
cd ${MYPATH}/../examples/tls/onload
make deploy verify undeploy
echo Single namespace example
cd ${MYPATH}/../examples/namespace/
make deploy verify undeploy
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment