Commit ae7f797c authored by Geoff Simmons's avatar Geoff Simmons

Implement TemplateConfig sync for all template types.

parent dce8d546
......@@ -47,6 +47,18 @@ func (worker *NamespaceWorker) syncTcfg(key string) update.Status {
tcfg.Name, tcfg)
updates := make([]string, 0, ntmpls)
if tcfg.Spec.Ingress != "" {
if err = vcl.SetIngressTmpl(tcfg.Spec.Ingress); err != nil {
return update.MakeFatal(
"TemplateConfig %s/%s: Cannot parse ingress "+
"template: %v", tcfg.Namespace,
tcfg.Name, err)
}
worker.log.Infof(
"TemplateConfig %s/%s: updated ingress template",
tcfg.Namespace, tcfg.Name)
updates = append(updates, "ingress")
}
if tcfg.Spec.ACL != "" {
if err = vcl.SetACLTmpl(tcfg.Spec.ACL); err != nil {
return update.MakeFatal(
......@@ -58,6 +70,53 @@ func (worker *NamespaceWorker) syncTcfg(key string) update.Status {
tcfg.Namespace, tcfg.Name)
updates = append(updates, "acl")
}
if tcfg.Spec.Auth != "" {
if err = vcl.SetAuthTmpl(tcfg.Spec.Auth); err != nil {
return update.MakeFatal(
"TemplateConfig %s/%s: Cannot parse auth "+
"template: %v", tcfg.Namespace,
tcfg.Name, err)
}
worker.log.Infof("TemplateConfig %s/%s: updated auth template",
tcfg.Namespace, tcfg.Name)
updates = append(updates, "auth")
}
if tcfg.Spec.ReqDisp != "" {
if err = vcl.SetReqDispTmpl(tcfg.Spec.ReqDisp); err != nil {
return update.MakeFatal(
"TemplateConfig %s/%s: Cannot parse reqDisp "+
"template: %v", tcfg.Namespace,
tcfg.Name, err)
}
worker.log.Infof(
"TemplateConfig %s/%s: updated reqDisp template",
tcfg.Namespace, tcfg.Name)
updates = append(updates, "reqDisp")
}
if tcfg.Spec.Rewrite != "" {
if err = vcl.SetRewriteTmpl(tcfg.Spec.Rewrite); err != nil {
return update.MakeFatal(
"TemplateConfig %s/%s: Cannot parse rewrite "+
"template: %v", tcfg.Namespace,
tcfg.Name, err)
}
worker.log.Infof(
"TemplateConfig %s/%s: updated rewrite template",
tcfg.Namespace, tcfg.Name)
updates = append(updates, "rewrite")
}
if tcfg.Spec.Shard != "" {
if err = vcl.SetShardTmpl(tcfg.Spec.Shard); err != nil {
return update.MakeFatal(
"TemplateConfig %s/%s: Cannot parse shard "+
"template: %v", tcfg.Namespace,
tcfg.Name, err)
}
worker.log.Infof(
"TemplateConfig %s/%s: updated shard template",
tcfg.Namespace, tcfg.Name)
updates = append(updates, "shard")
}
return update.MakeSuccess(
"TemplateConfig %s/%s: updated templates: %v", tcfg.Namespace,
......@@ -76,7 +135,12 @@ func (worker *NamespaceWorker) deleteTcfg(obj interface{}) update.Status {
tcfg, ok := obj.(*vcr_v1alpha1.TemplateConfig)
if !ok || tcfg == nil {
worker.log.Warnf("Delete TemplateConfig: not found: %v", obj)
vcl.ResetIngressTmpl()
vcl.ResetACLTmpl()
vcl.ResetAuthTmpl()
vcl.ResetReqDispTmpl()
vcl.ResetRewriteTmpl()
vcl.ResetShardTmpl()
return update.MakeSuccess("TemplateConfig: all templates reset")
}
......@@ -84,12 +148,42 @@ func (worker *NamespaceWorker) deleteTcfg(obj interface{}) update.Status {
tcfg.Name)
resets := make([]string, 0, ntmpls)
if tcfg.Spec.Ingress != "" {
vcl.ResetIngressTmpl()
worker.log.Infof("TemplateConfig %s/%s: reset ingress template",
tcfg.Namespace, tcfg.Name)
resets = append(resets, "ingress")
}
if tcfg.Spec.ACL != "" {
vcl.ResetACLTmpl()
worker.log.Infof("TemplateConfig %s/%s: reset ACL template",
tcfg.Namespace, tcfg.Name)
resets = append(resets, "acl")
}
if tcfg.Spec.Auth != "" {
vcl.ResetAuthTmpl()
worker.log.Infof("TemplateConfig %s/%s: reset auth template",
tcfg.Namespace, tcfg.Name)
resets = append(resets, "auth")
}
if tcfg.Spec.ReqDisp != "" {
vcl.ResetReqDispTmpl()
worker.log.Infof("TemplateConfig %s/%s: reset reqDisp template",
tcfg.Namespace, tcfg.Name)
resets = append(resets, "reqDisp")
}
if tcfg.Spec.Rewrite != "" {
vcl.ResetRewriteTmpl()
worker.log.Infof("TemplateConfig %s/%s: reset rewrite template",
tcfg.Namespace, tcfg.Name)
resets = append(resets, "rewrite")
}
if tcfg.Spec.Shard != "" {
vcl.ResetShardTmpl()
worker.log.Infof("TemplateConfig %s/%s: reset shard template",
tcfg.Namespace, tcfg.Name)
resets = append(resets, "shard")
}
return update.MakeSuccess(
"TemplateConfig %s/%s: reset templates: %v", tcfg.Namespace,
......
......@@ -91,3 +91,27 @@ var authFuncs = template.FuncMap{
var authTmpl = template.Must(template.New(authTmplName).Funcs(authFuncs).
Parse(authTmplSrc))
// ResetAuthTmpl sets the VCL template for the VarnishConfig auth
// feature to its current "official" value. Invoked on TemplateConfig
// deletion, only needed when devmode is activated for the controller.
func ResetAuthTmpl() {
authTmpl = template.Must(template.New(authTmplName).Funcs(authFuncs).
Parse(authTmplSrc))
}
// SetAuthTmpl parses src as a text/template, using the FuncMap
// defined for the auth template, which is used to generate VCL for
// the VarnishConfig auth feature. On success, the auth template is
// replaced. If the parse fails, then the error is returned and the
// auth template is unchanged.
//
// Only used when devmode is activated for the controller.
func SetAuthTmpl(src string) error {
newTmpl, err := template.New(authTmplName).Funcs(authFuncs).Parse(src)
if err != nil {
return err
}
authTmpl = newTmpl
return nil
}
......@@ -126,3 +126,29 @@ var reqDispFuncs = template.FuncMap{
var reqDispTmpl = template.Must(template.New(reqDispTmplName).
Funcs(reqDispFuncs).Parse(reqDispTmplSrc))
// ResetReqDispTmpl sets the VCL template for the VarnishConfig
// reqDisp feature to its current "official" value. Invoked on
// TemplateConfig deletion, only needed when devmode is activated for
// the controller.
func ResetReqDispTmpl() {
reqDispTmpl = template.Must(template.New(reqDispTmplName).
Funcs(reqDispFuncs).Parse(reqDispTmplSrc))
}
// SetReqDispTmpl parses src as a text/template, using the FuncMap
// defined for the reqDisp template, which is used to generate VCL for
// the VarnishConfig reqDisp feature. On success, the reqDisp template
// is replaced. If the parse fails, then the error is returned and the
// reqDisp template is unchanged.
//
// Only used when devmode is activated for the controller.
func SetReqDispTmpl(src string) error {
newTmpl, err := template.New(reqDispTmplName).Funcs(reqDispFuncs).
Parse(src)
if err != nil {
return err
}
reqDispTmpl = newTmpl
return nil
}
......@@ -272,3 +272,29 @@ var rewriteFuncs = template.FuncMap{
var rewriteTmpl = template.Must(template.New(rewriteTmplName).
Funcs(rewriteFuncs).Parse(rewriteTmplSrc))
// ResetRewriteTmpl sets the VCL template for the VarnishConfig
// rewrite feature to its current "official" value. Invoked on
// TemplateConfig deletion, only needed when devmode is activated for
// the controller.
func ResetRewriteTmpl() {
rewriteTmpl = template.Must(template.New(rewriteTmplName).
Funcs(rewriteFuncs).Parse(rewriteTmplSrc))
}
// SetRewriteTmpl parses src as a text/template, using the FuncMap
// defined for the rewrite template, which is used to generate VCL for
// the VarnishConfig rewrite feature. On success, the rewrite template
// is replaced. If the parse fails, then the error is returned and the
// rewrite template is unchanged.
//
// Only used when devmode is activated for the controller.
func SetRewriteTmpl(src string) error {
newTmpl, err := template.New(rewriteTmplName).Funcs(rewriteFuncs).
Parse(src)
if err != nil {
return err
}
rewriteTmpl = newTmpl
return nil
}
......@@ -241,3 +241,29 @@ var shardFuncMap = template.FuncMap{
var shardTmpl = template.Must(template.New(selfShardName).Funcs(shardFuncMap).
Parse(selfShardTmplSrc))
// ResetShardTmpl sets the VCL template for the VarnishConfig
// shard feature to its current "official" value. Invoked on
// TemplateConfig deletion, only needed when devmode is activated for
// the controller.
func ResetShardTmpl() {
shardTmpl = template.Must(template.New(selfShardName).
Funcs(shardFuncMap).Parse(selfShardTmplSrc))
}
// SetShardTmpl parses src as a text/template, using the FuncMap
// defined for the shard template, which is used to generate VCL for
// the VarnishConfig shard feature. On success, the shard template
// is replaced. If the parse fails, then the error is returned and the
// shard template is unchanged.
//
// Only used when devmode is activated for the controller.
func SetShardTmpl(src string) error {
newTmpl, err := template.New(selfShardName).Funcs(shardFuncMap).
Parse(src)
if err != nil {
return err
}
shardTmpl = newTmpl
return nil
}
......@@ -284,3 +284,30 @@ var vclFuncs = template.FuncMap{
var ingressTmpl = template.Must(template.New(ingTmplName).
Funcs(vclFuncs).Parse(ingTmplSrc))
// ResetIngressTmpl sets the VCL template for Ingress implementation
// (routing rules and bakend configuration) to its current "official"
// value. Invoked on TemplateConfig deletion, only needed when devmode
// is activated for the controller.
func ResetIngressTmpl() {
ingressTmpl = template.Must(template.New(ingTmplName).Funcs(vclFuncs).
Parse(ingTmplSrc))
}
// SetIngressTmpl parses src as a text/template, using the FuncMap
// defined for the ingress template, which is used to generate VCL for
// Ingress implementaion -- routing rules and backend configuration,
// including configuration set for the BackendConfig custom
// resource. On success, the ingress template is replaced. If the
// parse fails, then the error is returned and the shard template is
// unchanged.
//
// Only used when devmode is activated for the controller.
func SetIngressTmpl(src string) error {
newTmpl, err := template.New(ingTmplName).Funcs(vclFuncs).Parse(src)
if err != nil {
return err
}
ingressTmpl = newTmpl
return nil
}
......@@ -104,7 +104,8 @@ deploy-kubectl:
@kubectl apply -f varnish.yaml
@kubectl apply -f controller.yaml
@kubectl apply -f tmplcfg.yaml
@kubectl apply -f acl.yaml
@kubectl apply -f auth-secrets.yaml
@kubectl apply -f vcfg.yaml
@kubectl apply -f cafe.yaml
@kubectl apply -f cafe-ingress.yaml
......@@ -129,7 +130,8 @@ undeploy-helm:
undeploy-kubectl:
@kubectl delete -f cafe-ingress.yaml
@kubectl delete -f cafe.yaml
@kubectl delete -f acl.yaml
@kubectl delete -f vcfg.yaml
@kubectl delete -f auth-secrets.yaml
@kubectl delete -f tmplcfg.yaml
@kubectl delete -f controller.yaml
@kubectl delete -f varnish.yaml
......
apiVersion: "ingress.varnish-cache.org/v1alpha1"
kind: VarnishConfig
metadata:
namespace: dev
name: acl-example-cfg
spec:
services:
- varnish-ingress-admin
acl:
- name: local-private-ip4
addrs:
- addr: 127.0.0.0
mask-bits: 8
- addr: 10.0.0.0
mask-bits: 24
- addr: 172.16.0.0
mask-bits: 12
- addr: 192.168.0.0
mask-bits: 16
result-header:
header: req.http.X-ACL-Match
success: "matched"
failure: "failed"
apiVersion: v1
kind: Secret
metadata:
namespace: dev
name: coffee-creds
labels:
viking.uplex.de/secret: auth
type: Opaque
stringData:
coffee-admin: superpowers
foo: bar
baz: quux
Aladdin: open sesame
# looks like -*- vcl -*-
varnishtest "cafe example, ACLs with modified VCL template"
varnishtest "cafe example with modified VCL templates"
client c1 -connect "${localhost} ${localport}" {
txreq -url /tea -hdr "Host: cafe.example.com"
rxresp
expect resp.status == 200
expect resp.http.X-Backend ~ "^vk8s_dev_"
expect resp.http.Ingress-Template == "override"
expect resp.http.X-ACL-Match == "matched"
expect resp.http.Template == "acl"
expect resp.http.ACL-Template == "override"
expect resp.http.Auth-Template == "override"
expect resp.http.ReqDisp-Template == "override"
expect resp.http.X-Cache ~ "HIT|MISS"
expect resp.http.Rewrite-Template == "override"
expect resp.http.Shard-Template == "override"
txreq -url /coffee/black -hdr "Host: cafe.example.com"
rxresp
expect resp.status == 200
expect resp.http.X-ACL-Match == "matched"
expect resp.http.Template == "acl"
expect resp.http.X-Auth-Status == 60401
expect resp.http.WWW-Authenticate == {Basic realm="coffee", charset="UTF-8"}
txreq -url /coffee -hdr "Host: cafe.example.com"
# credentials foo:bar
txreq -url /coffee -hdr "Host: cafe.example.com" \
-hdr "Authorization: Basic Zm9vOmJhcg=="
rxresp
expect resp.status == 200
expect resp.http.X-Backend ~ "^vk8s_dev_"
expect resp.http.Ingress-Template == "override"
expect resp.http.X-ACL-Match == "matched"
expect resp.http.Template == "acl"
expect resp.http.ACL-Template == "override"
expect resp.http.Auth-Template == "override"
expect resp.http.ReqDisp-Template == "override"
expect resp.http.X-Cache ~ "HIT|MISS"
expect resp.http.Rewrite-Template == "override"
expect resp.http.Shard-Template == "override"
txreq -req PURGE -url /tea -hdr "Host: cafe.example.com"
rxresp
expect resp.status == 200
expect resp.reason == "Purged"
} -run
......@@ -4,6 +4,215 @@ metadata:
namespace: dev
name: tmplcfg
spec:
ingress: |
vcl 4.1;
import std;
import directors;
import re2;
import dynamic;
include "bogo_backend.vcl";
{{- define "ProbeDef"}}
{{- range $name, $svc := .}}
{{- if $svc.Probe}}
{{with $svc.Probe}}
probe {{probeName $name}} {
{{- if ne .URL ""}}
.url = "{{.URL}}";
{{- else if .Request}}
.request =
{{- range $reqLine := .Request}}
"{{$reqLine}}"
{{- end}}
;
{{- end}}
{{- if .ExpResponse}}
.expected_response = {{.ExpResponse}};
{{- end}}
{{- if .Timeout}}
.timeout = {{.Timeout}};
{{- end}}
{{- if .Interval}}
.interval = {{.Interval}};
{{- end}}
{{- if .Initial}}
.initial = {{.Initial}};
{{- end}}
{{- if .Window}}
.window = {{.Window}};
{{- end}}
{{- if .Threshold}}
.threshold = {{.Threshold}};
{{- end}}
}
{{- end}}
{{- end}}
{{- end}}
{{- end}}
{{- template "ProbeDef" .IntSvcs -}}
{{- template "ProbeDef" .ExtSvcs}}
{{range $name, $svc := .IntSvcs -}}
{{range $addr := $svc.Addresses -}}
backend {{backendName $svc $addr}} {
.host = "{{$addr.IP}}";
.port = "{{$addr.Port}}";
{{- with $svc}}
{{- if .HostHeader}}
.host_header = "{{.HostHeader}}";
{{- end}}
{{- if .ConnectTimeout}}
.connect_timeout = {{.ConnectTimeout}};
{{- end}}
{{- if .FirstByteTimeout}}
.first_byte_timeout = {{.FirstByteTimeout}};
{{- end}}
{{- if .BetweenBytesTimeout}}
.between_bytes_timeout = {{.BetweenBytesTimeout}};
{{- end}}
{{- if .ProxyHeader}}
.proxy_header = {{.ProxyHeader}};
{{- end}}
{{- if .MaxConnections}}
.max_connections = {{.MaxConnections}};
{{- end}}
{{- if .Probe}}
.probe = {{probeName $name}};
{{- end}}
{{- end}}
}
{{end -}}
{{end}}
sub vcl_init {
{{- if .Rules}}
new vk8s_hosts = re2.set(anchor=both);
{{- range $rule := .Rules}}
vk8s_hosts.add("{{hostRegex $rule.Host}}(:\d+)?");
{{- end}}
vk8s_hosts.compile();
{{end}}
{{- range $name, $svc := .IntSvcs}}
{{- $dirType := dirType $svc}}
new {{dirName $svc}} = directors.{{$dirType}}();
{{- range $addr := $svc.Addresses}}
{{dirName $svc}}.add_backend({{backendName $svc $addr}}
{{- if eq $dirType "random"}}
, 1.0
{{- end}}
);
{{- end}}
{{- if eq $dirType "shard"}}
{{- if $svc.Director.Warmup}}
{{dirName $svc}}.set_warmup({{$svc.Director.Warmup}});
{{- end}}
{{- if $svc.Director.Rampup}}
{{dirName $svc}}.set_rampup({{$svc.Director.Rampup}});
{{- end}}
{{dirName $svc}}.reconfigure();
{{- end}}
{{end}}
{{- range $name, $svc := .ExtSvcs}}
new {{resolverName $svc}} = dynamic.resolver();
{{resolverName $svc}}.set_resolution_type(STUB);
new {{dirName $svc}} = dynamic.director(
ttl_from = dns,
ttl = {{.DNSRetryDelay}},
resolver = {{resolverName $svc}}.use()
{{- with $svc}}
{{- if .ExternalPort}}
, port = "{{.ExternalPort}}"
{{- end}}
{{- if .HostHeader}}
, host_header = "{{.HostHeader}}"
{{- end}}
{{- if .ConnectTimeout}}
, connect_timeout = {{.ConnectTimeout}}
{{- end}}
{{- if .FirstByteTimeout}}
, first_byte_timeout = {{.FirstByteTimeout}}
{{- end}}
{{- if .BetweenBytesTimeout}}
, between_bytes_timeout = {{.BetweenBytesTimeout}}
{{- end}}
{{- if .DomainUsageTimeout}}
, domain_usage_timeout = {{.DomainUsageTimeout}}
{{- end}}
{{- if .FirstLookupTimeout}}
, first_lookup_timeout = {{.FirstLookupTimeout}}
{{- end}}
{{- if .ProxyHeader}}
, proxy_header = {{.ProxyHeader}}
{{- end}}
{{- if .MaxConnections}}
, max_connections = {{.MaxConnections}}
{{- end}}
{{- if .Probe}}
, probe = {{probeName $name}}
{{- end}}
{{- end}}
);
{{- if .ResolverIdleTimeout}}
{{resolverName $svc}}.set_idle_timeout({{.ResolverIdleTimeout}});
{{- end }}
{{- if .ResolverTimeout}}
{{resolverName $svc}}.set_timeout({{.ResolverTimeout}});
{{- end }}
{{- if .MaxDNSQueries}}
{{resolverName $svc}}.set_limit_outstanding_queries({{.MaxDNSQueries}});
{{- end }}
{{- if not .FollowDNSRedirects}}
{{resolverName $svc}}.set_follow_redirects(REDIRECTS_DO_NOT_FOLLOW);
{{- end }}
{{end}}
{{- range $rule := .Rules}}
new {{urlMatcher $rule}} = re2.set(posix_syntax=true, anchor=start);
{{- range $path, $svc := $rule.PathMap}}
{{urlMatcher $rule}}.add("{{$path}}",
{{- if $svc.ExternalName}}
backend={{dirName $svc}}.backend("{{$svc.ExternalName}}"));
{{- else}}
backend={{dirName $svc}}.backend());
{{- end}}
{{- end}}
{{urlMatcher $rule}}.compile();
{{end -}}
}
sub vcl_backend_fetch {
set bereq.backend = vk8s_notfound;
{{- if .Rules}}
if (vk8s_hosts.match(bereq.http.Host)) {
{{- range $i, $rule := .Rules}}
{{ifelse $i}} (vk8s_hosts.which(select=FIRST) == {{plusOne $i}}) {
if ({{urlMatcher $rule}}.match(bereq.url)) {
set bereq.backend = {{urlMatcher $rule}}.backend(select=FIRST);
}
}
{{- end}}
}
{{- end}}
if (bereq.backend == vk8s_notfound) {
{{- if .DefaultService.Name}}
set bereq.backend = {{dirName .DefaultService}}.backend();
{{- else}}
return (error(404));
{{- end}}
}
}
sub vcl_backend_response {
set beresp.http.X-Backend = beresp.backend;
}
sub vcl_deliver {
set resp.http.Ingress-Template = "override";
}
acl: |
import std;
......@@ -17,7 +226,7 @@ spec:
sub vcl_deliver {
set resp.http.X-ACL-Match = req.http.X-ACL-Match;
set resp.http.Template = "acl";
set resp.http.ACL-Template = "override";
}
sub vcl_recv {
......@@ -45,3 +254,322 @@ spec:
{{- end}}
{{- end}}
}
auth: |
import re2;
sub vcl_init {
{{- range $auth := .Auths}}
new {{credsMatcher .Realm}} = re2.set(anchor=both);
{{- range $cred := .Credentials}}
{{credsMatcher $auth.Realm}}.add("Basic\s+\Q{{$cred}}\E\s*");
{{- end}}
{{credsMatcher .Realm}}.compile();
{{end -}}
}
sub vcl_deliver {
set resp.http.Auth-Template = "override";
}
sub vcl_recv {
{{- range .Auths}}
if (
{{- range .Conditions}}
{{.Comparand}} {{cmpRelation .Compare .Negate}} "{{.Value}}" &&
{{- end}}
{{- if eq .Status 401}}
!{{credsMatcher .Realm}}.match(req.http.Authorization)
{{- else}}
!{{credsMatcher .Realm}}.match(req.http.Proxy-Authorization)
{{- end}}
) {
{{- if .UTF8 }}
set req.http.VK8S-Authenticate =
{"Basic realm="{{.Realm}}", charset="UTF-8""};
{{- else}}
set req.http.VK8S-Authenticate = {"Basic realm="{{.Realm}}""};
{{- end}}
return(synth(60000 + {{.Status}}));
}
{{- end}}
}
sub vcl_synth {
if (resp.status == 60401) {
set resp.http.WWW-Authenticate = req.http.VK8S-Authenticate;
}
if (resp.status == 60407) {
set resp.http.Proxy-Authenticate = req.http.VK8S-Authenticate;
}
if (resp.status > 60000) {
set resp.http.X-Auth-Status = resp.status;
set resp.status = 200;
}
return(deliver);
}
reqDisp: |
import re2;
import selector;
{{range $didx, $d := .Dispositions -}}
{{range $cidx, $c := .Conditions -}}
{{if reqNeedsMatcher $c -}}
sub vcl_init {
new {{reqObj $didx $cidx}} = {{vmod $c.Compare}}.set({{reqFlags $c}});
{{- range $val := $c.Values}}
{{reqObj $didx $cidx}}.add("{{$val}}");
{{- end}}
{{reqObj $didx $cidx}}.compile();
}
{{end -}}
{{- end}}
{{- end}}
sub vcl_recv {
{{- range $didx, $d := .Dispositions}}
if (
{{- range $cidx, $cond := .Conditions}}
{{- if ne $cidx 0}} &&
{{end}}
{{- if .Negate}}! {{end}}
{{- if reqNeedsMatcher $cond}}
{{- reqObj $didx $cidx}}.{{match .Compare}}({{.Comparand}})
{{- else if exists .Compare}}
{{- .Comparand}}
{{- else}}
{{- .Comparand}} {{cmpRelation .Compare .Negate}} {{value $cond}}
{{- end}}
{{- end -}}
) {
return (
{{- with .Disposition}}
{{- if eq .Action "synth"}}synth({{.Status}}
{{- if .Reason}}, "{{.Reason}}"{{end -}})
{{- else}}{{.Action}}
{{- end}}
{{- end -}}
);
}
{{- end}}
return (hash);
}
sub vcl_deliver {
set resp.http.ReqDisp-Template = "override";
}
rewrite: |
import re2;
import selector;
{{range $i, $r := .Rewrites -}}
{{if needsMatcher $r -}}
sub vcl_init {
new {{rewrName $i}} = {{vmod $r.Compare}}.set({{rewrFlags $r}});
{{- range $rule := $r.Rules}}
{{rewrName $i}}.add("{{$rule.Value}}", string="{{$rule.Rewrite}}"
{{- if needsSave $r}}, save=true{{end -}}
{{- if needsRegex $r}}, regex="{{saveRegex $r $rule}}"{{end -}}
{{- if needsNeverCapture $r}}, never_capture=true{{end -}}
);
{{- end}}
{{rewrName $i}}.compile();
}
{{- end}}
sub vcl_{{rewrSub $r}} {
{{- if needsMatcher $r}}
if ({{rewrName $i}}.{{match $r.Compare}}({{$r.Source}})) {
{{- if needsUniqueCheck $r}}
if ({{rewrName $i}}.nmatches() != 1) {
std.log({{$r.Source}} + " had " +
{{rewrName $i}}.nmatches() + " matches");
return(fail);
}
{{- end}}
{{- end}}
{{- if rewrMethodDelete $r}}
unset {{$r.Target}};
{{- else if rewrMethodAppend $r}}
set {{$r.Target}} = {{rewrOperand1 $r}} + {{rewrOperand2 $r $i}};
{{- else if rewrMethodPrepend $r}}
set {{$r.Target}} = {{rewrOperand2 $r $i}} + {{rewrOperand1 $r}};
{{- else if rewrMethodReplace $r}}
set {{$r.Target}} = {{rewrOperand2 $r $i}};
{{- else}}
set {{$r.Target}} =
{{rewrName $i}}.{{rewrOp $r}}({{$r.Source}},
{{rewrName $i}}.string({{rewrSelect $r}})
{{- if needsAll $r}}, all=true{{end -}}
{{- if needsSelectEnum $r -}}
, {{rewrSelect $r}}{{end -}}
);
{{- end}}
{{- if needsMatcher $r}}
}
{{- end}}
}
{{- end}}
sub vcl_deliver {
set resp.http.Rewrite-Template = "override";
}
shard: |
import std;
import directors;
import blob;
import blobdigest;
probe vk8s_probe_varnish {
.request = "HEAD /vk8s_cluster_health HTTP/1.1"
"Host: vk8s_cluster"
"Connection: close";
{{- if .Probe.Timeout}}
.timeout = {{.Probe.Timeout}};
{{- end}}
{{- if .Probe.Interval}}
.interval = {{.Probe.Interval}};
{{- end}}
{{- if .Probe.Initial}}
.initial = {{.Probe.Initial}};
{{- end}}
{{- if .Probe.Window}}
.window = {{.Probe.Window}};
{{- end}}
{{- if .Probe.Threshold}}
.threshold = {{.Probe.Threshold}};
{{- end}}
}
{{range $node := .Nodes -}}
backend {{backendName $node}} {
.host = "{{(index $node.Addresses 0).IP}}";
.port = "{{(index $node.Addresses 0).Port}}";
.probe = vk8s_probe_varnish;
}
{{end -}}
acl vk8s_cluster_acl {
{{- range $node := .Nodes}}
"{{(index $node.Addresses 0).IP}}";
{{- end}}
}
sub vcl_init {
new vk8s_cluster_param = directors.shard_param();
new vk8s_cluster = directors.shard();
vk8s_cluster.associate(vk8s_cluster_param.use());
{{range $node := .Nodes -}}
vk8s_cluster.add_backend({{backendName $node}});
{{end -}}
vk8s_cluster.reconfigure();
{{- digest_init . }}
}
sub vcl_recv {
{{ if .PrimaryOnly -}}
unset req.http.VK8S-Shard-Primary-Only;
{{- digest_update 'c' . }}
if (remote.ip !~ vk8s_cluster_acl
&& "" + vk8s_cluster.backend(resolve=NOW
{{- key 'c' .}}) != server.identity) {
set req.http.VK8S-Shard-Primary-Only = "true";
set req.backend_hint = vk8s_cluster.backend(resolve=NOW
{{- key 'c' .}});
return (pass);
}
else {{ end }}if (remote.ip ~ vk8s_cluster_acl) {
if (req.http.Host == "vk8s_cluster") {
if (req.url == "/vk8s_cluster_health") {
return (synth(200));
}
return (synth(404));
}
# prevent deadlock for accidental cyclic requests
set req.hash_ignore_busy = true;
# if we're async, don't deliver stale
if (req.http.VK8S-Is-Bgfetch == "true") {
set req.grace = 0s;
}
return (hash);
}
}
{{ if .PrimaryOnly }}
sub vcl_pass {
if (req.http.VK8S-Shard-Primary-Only) {
return (fetch);
}
}
{{ end }}
sub vcl_backend_fetch {
{{- if .PrimaryOnly }}
if (bereq.http.VK8S-Shard-Primary-Only) {
return (fetch);
}
{{- end }}
{{- digest_update 'b' . }}
vk8s_cluster_param.set({{ key 'b' .}});
if (bereq.retries == 0
&& !bereq.uncacheable
&& remote.ip !~ vk8s_cluster_acl
&& "" + vk8s_cluster.backend(resolve=NOW) != server.identity) {
set bereq.backend = vk8s_cluster.backend(resolve=LAZY);
set bereq.http.VK8S-Is-Bgfetch = bereq.is_bgfetch;
return (fetch);
}
}
sub vcl_backend_response {
{{- if .PrimaryOnly }}
if (bereq.http.VK8S-Shard-Primary-Only) {
return (deliver);
}
{{- end }}
if (bereq.backend == vk8s_cluster.backend(resolve=LAZY)) {
if (beresp.http.VK8S-Cluster-TTL) {
set beresp.ttl = std.duration(
beresp.http.VK8S-Cluster-TTL + "s", 1s);
if (beresp.ttl > {{.MaxSecondaryTTL}}) {
set beresp.ttl = {{.MaxSecondaryTTL}};
}
unset beresp.http.VK8S-Cluster-TTL;
}
else {
set beresp.uncacheable = true;
}
return (deliver);
}
}
sub vcl_backend_error {
if (bereq.backend == vk8s_cluster.backend(resolve=LAZY)) {
return (deliver);
}
}
sub vcl_deliver {
set resp.http.Shard-Template = "override";
{{- if .PrimaryOnly }}
if (req.http.VK8S-Shard-Primary-Only) {
return (deliver);
}
{{- end }}
unset resp.http.VK8S-Cluster-TTL;
if (remote.ip ~ vk8s_cluster_acl) {
if (! obj.uncacheable) {
set resp.http.VK8S-Cluster-TTL = obj.ttl;
}
return (deliver);
}
}
......@@ -37,7 +37,302 @@ acls:
success: "matched"
failure: "failed"
auth:
- realm: coffee
type: basic
utf8: true
conditions:
- comparand: req.http.Host
value: cafe.example.com
compare: equal
- comparand: req.url
value: ^/coffee($|/)
compare: match
creds:
coffee-admin: superpowers
foo: bar
baz: quux
Aladdin: open sesame
reqDisposition:
- conditions:
- comparand: req.http.Host
compare: not-exists
- comparand: req.esi_level
count: 0
- comparand: req.proto
compare: prefix
values:
- HTTP/1.1
match-flags:
case-insensitive: true
disposition:
action: synth
status: 400
- conditions:
- comparand: req.method
compare: equal
values:
- PURGE
disposition:
action: purge
- conditions:
- comparand: req.method
compare: not-equal
values:
- GET
- HEAD
- PUT
- POST
- TRACE
- OPTIONS
- DELETE
- PATCH
- CONNECT
disposition:
action: synth
status: 405
- conditions:
- comparand: req.method
compare: not-equal
values:
- GET
- HEAD
disposition:
action: pass
rewrites:
- target: req.http.X-Cache
vcl-sub: hit
rules:
- rewrite: HIT
method: replace
- target: req.http.X-Cache
vcl-sub: miss
rules:
- rewrite: MISS
method: replace
- target: req.http.X-Cache
vcl-sub: pass
rules:
- rewrite: PASS
method: replace
- target: resp.http.X-Cache
source: req.http.X-Cache
method: replace
selfSharding: {}
templates:
ingress: |
vcl 4.1;
import std;
import directors;
import re2;
import dynamic;
include "bogo_backend.vcl";
{{- define "ProbeDef"}}
{{- range $name, $svc := .}}
{{- if $svc.Probe}}
{{with $svc.Probe}}
probe {{probeName $name}} {
{{- if ne .URL ""}}
.url = "{{.URL}}";
{{- else if .Request}}
.request =
{{- range $reqLine := .Request}}
"{{$reqLine}}"
{{- end}}
;
{{- end}}
{{- if .ExpResponse}}
.expected_response = {{.ExpResponse}};
{{- end}}
{{- if .Timeout}}
.timeout = {{.Timeout}};
{{- end}}
{{- if .Interval}}
.interval = {{.Interval}};
{{- end}}
{{- if .Initial}}
.initial = {{.Initial}};
{{- end}}
{{- if .Window}}
.window = {{.Window}};
{{- end}}
{{- if .Threshold}}
.threshold = {{.Threshold}};
{{- end}}
}
{{- end}}
{{- end}}
{{- end}}
{{- end}}
{{- template "ProbeDef" .IntSvcs -}}
{{- template "ProbeDef" .ExtSvcs}}
{{range $name, $svc := .IntSvcs -}}
{{range $addr := $svc.Addresses -}}
backend {{backendName $svc $addr}} {
.host = "{{$addr.IP}}";
.port = "{{$addr.Port}}";
{{- with $svc}}
{{- if .HostHeader}}
.host_header = "{{.HostHeader}}";
{{- end}}
{{- if .ConnectTimeout}}
.connect_timeout = {{.ConnectTimeout}};
{{- end}}
{{- if .FirstByteTimeout}}
.first_byte_timeout = {{.FirstByteTimeout}};
{{- end}}
{{- if .BetweenBytesTimeout}}
.between_bytes_timeout = {{.BetweenBytesTimeout}};
{{- end}}
{{- if .ProxyHeader}}
.proxy_header = {{.ProxyHeader}};
{{- end}}
{{- if .MaxConnections}}
.max_connections = {{.MaxConnections}};
{{- end}}
{{- if .Probe}}
.probe = {{probeName $name}};
{{- end}}
{{- end}}
}
{{end -}}
{{end}}
sub vcl_init {
{{- if .Rules}}
new vk8s_hosts = re2.set(anchor=both);
{{- range $rule := .Rules}}
vk8s_hosts.add("{{hostRegex $rule.Host}}(:\d+)?");
{{- end}}
vk8s_hosts.compile();
{{end}}
{{- range $name, $svc := .IntSvcs}}
{{- $dirType := dirType $svc}}
new {{dirName $svc}} = directors.{{$dirType}}();
{{- range $addr := $svc.Addresses}}
{{dirName $svc}}.add_backend({{backendName $svc $addr}}
{{- if eq $dirType "random"}}
, 1.0
{{- end}}
);
{{- end}}
{{- if eq $dirType "shard"}}
{{- if $svc.Director.Warmup}}
{{dirName $svc}}.set_warmup({{$svc.Director.Warmup}});
{{- end}}
{{- if $svc.Director.Rampup}}
{{dirName $svc}}.set_rampup({{$svc.Director.Rampup}});
{{- end}}
{{dirName $svc}}.reconfigure();
{{- end}}
{{end}}
{{- range $name, $svc := .ExtSvcs}}
new {{resolverName $svc}} = dynamic.resolver();
{{resolverName $svc}}.set_resolution_type(STUB);
new {{dirName $svc}} = dynamic.director(
ttl_from = dns,
ttl = {{.DNSRetryDelay}},
resolver = {{resolverName $svc}}.use()
{{- with $svc}}
{{- if .ExternalPort}}
, port = "{{.ExternalPort}}"
{{- end}}
{{- if .HostHeader}}
, host_header = "{{.HostHeader}}"
{{- end}}
{{- if .ConnectTimeout}}
, connect_timeout = {{.ConnectTimeout}}
{{- end}}
{{- if .FirstByteTimeout}}
, first_byte_timeout = {{.FirstByteTimeout}}
{{- end}}
{{- if .BetweenBytesTimeout}}
, between_bytes_timeout = {{.BetweenBytesTimeout}}
{{- end}}
{{- if .DomainUsageTimeout}}
, domain_usage_timeout = {{.DomainUsageTimeout}}
{{- end}}
{{- if .FirstLookupTimeout}}
, first_lookup_timeout = {{.FirstLookupTimeout}}
{{- end}}
{{- if .ProxyHeader}}
, proxy_header = {{.ProxyHeader}}
{{- end}}
{{- if .MaxConnections}}
, max_connections = {{.MaxConnections}}
{{- end}}
{{- if .Probe}}
, probe = {{probeName $name}}
{{- end}}
{{- end}}
);
{{- if .ResolverIdleTimeout}}
{{resolverName $svc}}.set_idle_timeout({{.ResolverIdleTimeout}});
{{- end }}
{{- if .ResolverTimeout}}
{{resolverName $svc}}.set_timeout({{.ResolverTimeout}});
{{- end }}
{{- if .MaxDNSQueries}}
{{resolverName $svc}}.set_limit_outstanding_queries({{.MaxDNSQueries}});
{{- end }}
{{- if not .FollowDNSRedirects}}
{{resolverName $svc}}.set_follow_redirects(REDIRECTS_DO_NOT_FOLLOW);
{{- end }}
{{end}}
{{- range $rule := .Rules}}
new {{urlMatcher $rule}} = re2.set(posix_syntax=true, anchor=start);
{{- range $path, $svc := $rule.PathMap}}
{{urlMatcher $rule}}.add("{{$path}}",
{{- if $svc.ExternalName}}
backend={{dirName $svc}}.backend("{{$svc.ExternalName}}"));
{{- else}}
backend={{dirName $svc}}.backend());
{{- end}}
{{- end}}
{{urlMatcher $rule}}.compile();
{{end -}}
}
sub vcl_backend_fetch {
set bereq.backend = vk8s_notfound;
{{- if .Rules}}
if (vk8s_hosts.match(bereq.http.Host)) {
{{- range $i, $rule := .Rules}}
{{ifelse $i}} (vk8s_hosts.which(select=FIRST) == {{plusOne $i}}) {
if ({{urlMatcher $rule}}.match(bereq.url)) {
set bereq.backend = {{urlMatcher $rule}}.backend(select=FIRST);
}
}
{{- end}}
}
{{- end}}
if (bereq.backend == vk8s_notfound) {
{{- if .DefaultService.Name}}
set bereq.backend = {{dirName .DefaultService}}.backend();
{{- else}}
return (error(404));
{{- end}}
}
}
sub vcl_backend_response {
set beresp.http.X-Backend = beresp.backend;
}
sub vcl_deliver {
set resp.http.Ingress-Template = "override";
}
acl: |
import std;
......@@ -51,7 +346,7 @@ templates:
sub vcl_deliver {
set resp.http.X-ACL-Match = req.http.X-ACL-Match;
set resp.http.Template = "acl";
set resp.http.ACL-Template = "override";
}
sub vcl_recv {
......@@ -79,3 +374,322 @@ templates:
{{- end}}
{{- end}}
}
auth: |
import re2;
sub vcl_init {
{{- range $auth := .Auths}}
new {{credsMatcher .Realm}} = re2.set(anchor=both);
{{- range $cred := .Credentials}}
{{credsMatcher $auth.Realm}}.add("Basic\s+\Q{{$cred}}\E\s*");
{{- end}}
{{credsMatcher .Realm}}.compile();
{{end -}}
}
sub vcl_deliver {
set resp.http.Auth-Template = "override";
}
sub vcl_recv {
{{- range .Auths}}
if (
{{- range .Conditions}}
{{.Comparand}} {{cmpRelation .Compare .Negate}} "{{.Value}}" &&
{{- end}}
{{- if eq .Status 401}}
!{{credsMatcher .Realm}}.match(req.http.Authorization)
{{- else}}
!{{credsMatcher .Realm}}.match(req.http.Proxy-Authorization)
{{- end}}
) {
{{- if .UTF8 }}
set req.http.VK8S-Authenticate =
{"Basic realm="{{.Realm}}", charset="UTF-8""};
{{- else}}
set req.http.VK8S-Authenticate = {"Basic realm="{{.Realm}}""};
{{- end}}
return(synth(60000 + {{.Status}}));
}
{{- end}}
}
sub vcl_synth {
if (resp.status == 60401) {
set resp.http.WWW-Authenticate = req.http.VK8S-Authenticate;
}
if (resp.status == 60407) {
set resp.http.Proxy-Authenticate = req.http.VK8S-Authenticate;
}
if (resp.status > 60000) {
set resp.http.X-Auth-Status = resp.status;
set resp.status = 200;
}
return(deliver);
}
reqDisp: |
import re2;
import selector;
{{range $didx, $d := .Dispositions -}}
{{range $cidx, $c := .Conditions -}}
{{if reqNeedsMatcher $c -}}
sub vcl_init {
new {{reqObj $didx $cidx}} = {{vmod $c.Compare}}.set({{reqFlags $c}});
{{- range $val := $c.Values}}
{{reqObj $didx $cidx}}.add("{{$val}}");
{{- end}}
{{reqObj $didx $cidx}}.compile();
}
{{end -}}
{{- end}}
{{- end}}
sub vcl_recv {
{{- range $didx, $d := .Dispositions}}
if (
{{- range $cidx, $cond := .Conditions}}
{{- if ne $cidx 0}} &&
{{end}}
{{- if .Negate}}! {{end}}
{{- if reqNeedsMatcher $cond}}
{{- reqObj $didx $cidx}}.{{match .Compare}}({{.Comparand}})
{{- else if exists .Compare}}
{{- .Comparand}}
{{- else}}
{{- .Comparand}} {{cmpRelation .Compare .Negate}} {{value $cond}}
{{- end}}
{{- end -}}
) {
return (
{{- with .Disposition}}
{{- if eq .Action "synth"}}synth({{.Status}}
{{- if .Reason}}, "{{.Reason}}"{{end -}})
{{- else}}{{.Action}}
{{- end}}
{{- end -}}
);
}
{{- end}}
return (hash);
}
sub vcl_deliver {
set resp.http.ReqDisp-Template = "override";
}
rewrite: |
import re2;
import selector;
{{range $i, $r := .Rewrites -}}
{{if needsMatcher $r -}}
sub vcl_init {
new {{rewrName $i}} = {{vmod $r.Compare}}.set({{rewrFlags $r}});
{{- range $rule := $r.Rules}}
{{rewrName $i}}.add("{{$rule.Value}}", string="{{$rule.Rewrite}}"
{{- if needsSave $r}}, save=true{{end -}}
{{- if needsRegex $r}}, regex="{{saveRegex $r $rule}}"{{end -}}
{{- if needsNeverCapture $r}}, never_capture=true{{end -}}
);
{{- end}}
{{rewrName $i}}.compile();
}
{{- end}}
sub vcl_{{rewrSub $r}} {
{{- if needsMatcher $r}}
if ({{rewrName $i}}.{{match $r.Compare}}({{$r.Source}})) {
{{- if needsUniqueCheck $r}}
if ({{rewrName $i}}.nmatches() != 1) {
std.log({{$r.Source}} + " had " +
{{rewrName $i}}.nmatches() + " matches");
return(fail);
}
{{- end}}
{{- end}}
{{- if rewrMethodDelete $r}}
unset {{$r.Target}};
{{- else if rewrMethodAppend $r}}
set {{$r.Target}} = {{rewrOperand1 $r}} + {{rewrOperand2 $r $i}};
{{- else if rewrMethodPrepend $r}}
set {{$r.Target}} = {{rewrOperand2 $r $i}} + {{rewrOperand1 $r}};
{{- else if rewrMethodReplace $r}}
set {{$r.Target}} = {{rewrOperand2 $r $i}};
{{- else}}
set {{$r.Target}} =
{{rewrName $i}}.{{rewrOp $r}}({{$r.Source}},
{{rewrName $i}}.string({{rewrSelect $r}})
{{- if needsAll $r}}, all=true{{end -}}
{{- if needsSelectEnum $r -}}
, {{rewrSelect $r}}{{end -}}
);
{{- end}}
{{- if needsMatcher $r}}
}
{{- end}}
}
{{- end}}
sub vcl_deliver {
set resp.http.Rewrite-Template = "override";
}
shard: |
import std;
import directors;
import blob;
import blobdigest;
probe vk8s_probe_varnish {
.request = "HEAD /vk8s_cluster_health HTTP/1.1"
"Host: vk8s_cluster"
"Connection: close";
{{- if .Probe.Timeout}}
.timeout = {{.Probe.Timeout}};
{{- end}}
{{- if .Probe.Interval}}
.interval = {{.Probe.Interval}};
{{- end}}
{{- if .Probe.Initial}}
.initial = {{.Probe.Initial}};
{{- end}}
{{- if .Probe.Window}}
.window = {{.Probe.Window}};
{{- end}}
{{- if .Probe.Threshold}}
.threshold = {{.Probe.Threshold}};
{{- end}}
}
{{range $node := .Nodes -}}
backend {{backendName $node}} {
.host = "{{(index $node.Addresses 0).IP}}";
.port = "{{(index $node.Addresses 0).Port}}";
.probe = vk8s_probe_varnish;
}
{{end -}}
acl vk8s_cluster_acl {
{{- range $node := .Nodes}}
"{{(index $node.Addresses 0).IP}}";
{{- end}}
}
sub vcl_init {
new vk8s_cluster_param = directors.shard_param();
new vk8s_cluster = directors.shard();
vk8s_cluster.associate(vk8s_cluster_param.use());
{{range $node := .Nodes -}}
vk8s_cluster.add_backend({{backendName $node}});
{{end -}}
vk8s_cluster.reconfigure();
{{- digest_init . }}
}
sub vcl_recv {
{{ if .PrimaryOnly -}}
unset req.http.VK8S-Shard-Primary-Only;
{{- digest_update 'c' . }}
if (remote.ip !~ vk8s_cluster_acl
&& "" + vk8s_cluster.backend(resolve=NOW
{{- key 'c' .}}) != server.identity) {
set req.http.VK8S-Shard-Primary-Only = "true";
set req.backend_hint = vk8s_cluster.backend(resolve=NOW
{{- key 'c' .}});
return (pass);
}
else {{ end }}if (remote.ip ~ vk8s_cluster_acl) {
if (req.http.Host == "vk8s_cluster") {
if (req.url == "/vk8s_cluster_health") {
return (synth(200));
}
return (synth(404));
}
# prevent deadlock for accidental cyclic requests
set req.hash_ignore_busy = true;
# if we're async, don't deliver stale
if (req.http.VK8S-Is-Bgfetch == "true") {
set req.grace = 0s;
}
return (hash);
}
}
{{ if .PrimaryOnly }}
sub vcl_pass {
if (req.http.VK8S-Shard-Primary-Only) {
return (fetch);
}
}
{{ end }}
sub vcl_backend_fetch {
{{- if .PrimaryOnly }}
if (bereq.http.VK8S-Shard-Primary-Only) {
return (fetch);
}
{{- end }}
{{- digest_update 'b' . }}
vk8s_cluster_param.set({{ key 'b' .}});
if (bereq.retries == 0
&& !bereq.uncacheable
&& remote.ip !~ vk8s_cluster_acl
&& "" + vk8s_cluster.backend(resolve=NOW) != server.identity) {
set bereq.backend = vk8s_cluster.backend(resolve=LAZY);
set bereq.http.VK8S-Is-Bgfetch = bereq.is_bgfetch;
return (fetch);
}
}
sub vcl_backend_response {
{{- if .PrimaryOnly }}
if (bereq.http.VK8S-Shard-Primary-Only) {
return (deliver);
}
{{- end }}
if (bereq.backend == vk8s_cluster.backend(resolve=LAZY)) {
if (beresp.http.VK8S-Cluster-TTL) {
set beresp.ttl = std.duration(
beresp.http.VK8S-Cluster-TTL + "s", 1s);
if (beresp.ttl > {{.MaxSecondaryTTL}}) {
set beresp.ttl = {{.MaxSecondaryTTL}};
}
unset beresp.http.VK8S-Cluster-TTL;
}
else {
set beresp.uncacheable = true;
}
return (deliver);
}
}
sub vcl_backend_error {
if (bereq.backend == vk8s_cluster.backend(resolve=LAZY)) {
return (deliver);
}
}
sub vcl_deliver {
set resp.http.Shard-Template = "override";
{{- if .PrimaryOnly }}
if (req.http.VK8S-Shard-Primary-Only) {
return (deliver);
}
{{- end }}
unset resp.http.VK8S-Cluster-TTL;
if (remote.ip ~ vk8s_cluster_acl) {
if (! obj.uncacheable) {
set resp.http.VK8S-Cluster-TTL = obj.ttl;
}
return (deliver);
}
}
apiVersion: "ingress.varnish-cache.org/v1alpha1"
kind: VarnishConfig
metadata:
namespace: dev
name: acl-example-cfg
spec:
services:
- varnish-ingress-admin
acl:
- name: local-private-ip4
addrs:
- addr: 127.0.0.0
mask-bits: 8
- addr: 10.0.0.0
mask-bits: 24
- addr: 172.16.0.0
mask-bits: 12
- addr: 192.168.0.0
mask-bits: 16
result-header:
header: req.http.X-ACL-Match
success: "matched"
failure: "failed"
auth:
- realm: coffee
secretName: coffee-creds
type: basic
utf8: true
conditions:
- comparand: req.http.Host
value: cafe.example.com
compare: equal
- comparand: req.url
value: ^/coffee($|/)
compare: match
req-disposition:
- conditions:
- comparand: req.http.Host
compare: not-exists
- comparand: req.esi_level
count: 0
- comparand: req.proto
compare: prefix
values:
- HTTP/1.1
match-flags:
case-insensitive: true
disposition:
action: synth
status: 400
- conditions:
- comparand: req.method
compare: equal
values:
- PURGE
disposition:
action: purge
- conditions:
- comparand: req.method
compare: not-equal
values:
- GET
- HEAD
- PUT
- POST
- TRACE
- OPTIONS
- DELETE
- PATCH
- CONNECT
disposition:
action: synth
status: 405
- conditions:
- comparand: req.method
compare: not-equal
values:
- GET
- HEAD
disposition:
action: pass
rewrites:
- target: req.http.X-Cache
vcl-sub: hit
rules:
- rewrite: HIT
method: replace
- target: req.http.X-Cache
vcl-sub: miss
rules:
- rewrite: MISS
method: replace
- target: req.http.X-Cache
vcl-sub: pass
rules:
- rewrite: PASS
method: replace
- target: resp.http.X-Cache
source: req.http.X-Cache
method: replace
self-sharding: {}
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