Commit 1a030947 authored by Geoff Simmons's avatar Geoff Simmons

Add support for custom VCL.

parent 8c70952e
...@@ -151,6 +151,9 @@ spec: ...@@ -151,6 +151,9 @@ spec:
value: value:
type: string type: string
minLength: 1 minLength: 1
vcl:
type: string
minLength: 1
status: status:
acceptedNames: acceptedNames:
kind: VarnishConfig kind: VarnishConfig
......
...@@ -51,6 +51,7 @@ type VarnishConfig struct { ...@@ -51,6 +51,7 @@ type VarnishConfig struct {
type VarnishConfigSpec struct { type VarnishConfigSpec struct {
Services []string `json:"services,omitempty"` Services []string `json:"services,omitempty"`
SelfSharding *SelfShardSpec `json:"self-sharding,omitempty"` SelfSharding *SelfShardSpec `json:"self-sharding,omitempty"`
VCL string `json:"vcl,omitempty"`
Auth []AuthSpec `json:"auth,omitempty"` Auth []AuthSpec `json:"auth,omitempty"`
ACLs []ACLSpec `json:"acl,omitempty"` ACLs []ACLSpec `json:"acl,omitempty"`
} }
......
...@@ -439,6 +439,7 @@ func (worker *NamespaceWorker) addOrUpdateIng(ing *extensions.Ingress) error { ...@@ -439,6 +439,7 @@ func (worker *NamespaceWorker) addOrUpdateIng(ing *extensions.Ingress) error {
if err = worker.configACL(&vclSpec, vcfg); err != nil { if err = worker.configACL(&vclSpec, vcfg); err != nil {
return err return err
} }
vclSpec.VCL = vcfg.Spec.VCL
} else { } else {
worker.log.Infof("Found no VarnishConfigs for Varnish Service "+ worker.log.Infof("Found no VarnishConfigs for Varnish Service "+
"%s/%s", svc.Namespace, svc.Name) "%s/%s", svc.Namespace, svc.Name)
......
...@@ -322,9 +322,11 @@ type Spec struct { ...@@ -322,9 +322,11 @@ type Spec struct {
// Authentication, derived from the Auth section of a // Authentication, derived from the Auth section of a
// VarnishConfig. // VarnishConfig.
Auths []Auth Auths []Auth
// VCL is custom VCL, derived from VarnishConfig.Spec.VCL.
VCL string
// ACLs is a list of specifications for whitelisting or // ACLs is a list of specifications for whitelisting or
// blacklisting IPs with access control lists, derived from // blacklisting IPs with access control lists, derived from
// VarnishConfig.ACLs. // VarnishConfig.Spec.ACLs.
ACLs []ACL ACLs []ACL
} }
...@@ -348,6 +350,7 @@ func (spec Spec) DeepHash() uint64 { ...@@ -348,6 +350,7 @@ func (spec Spec) DeepHash() uint64 {
spec.AllServices[svc].hash(hash) spec.AllServices[svc].hash(hash)
} }
spec.ShardCluster.hash(hash) spec.ShardCluster.hash(hash)
hash.Write([]byte(spec.VCL))
for _, auth := range spec.Auths { for _, auth := range spec.Auths {
auth.hash(hash) auth.hash(hash)
} }
...@@ -367,6 +370,7 @@ func (spec Spec) Canonical() Spec { ...@@ -367,6 +370,7 @@ func (spec Spec) Canonical() Spec {
Rules: make([]Rule, len(spec.Rules)), Rules: make([]Rule, len(spec.Rules)),
AllServices: make(map[string]Service, len(spec.AllServices)), AllServices: make(map[string]Service, len(spec.AllServices)),
ShardCluster: spec.ShardCluster, ShardCluster: spec.ShardCluster,
VCL: spec.VCL,
Auths: make([]Auth, len(spec.Auths)), Auths: make([]Auth, len(spec.Auths)),
ACLs: make([]ACL, len(spec.ACLs)), ACLs: make([]ACL, len(spec.ACLs)),
} }
......
...@@ -134,6 +134,9 @@ func (spec Spec) GetSrc() (string, error) { ...@@ -134,6 +134,9 @@ func (spec Spec) GetSrc() (string, error) {
return "", err return "", err
} }
} }
if spec.VCL != "" {
buf.WriteString(spec.VCL)
}
return buf.String(), nil return buf.String(), nil
} }
......
vcl 4.0;
import std;
import directors;
import re2;
backend vk8s_notfound {
# 192.0.2.0/24 reserved for docs & examples (RFC5737).
.host = "192.0.2.255";
.port = "80";
}
backend vk8s_coffee-svc_192_0_2_4 {
.host = "192.0.2.4";
.port = "80";
}
backend vk8s_coffee-svc_192_0_2_5 {
.host = "192.0.2.5";
.port = "80";
}
backend vk8s_tea-svc_192_0_2_1 {
.host = "192.0.2.1";
.port = "80";
}
backend vk8s_tea-svc_192_0_2_2 {
.host = "192.0.2.2";
.port = "80";
}
backend vk8s_tea-svc_192_0_2_3 {
.host = "192.0.2.3";
.port = "80";
}
sub vcl_init {
new vk8s_hosts = re2.set(posix_syntax=true, literal=true, anchor=both);
vk8s_hosts.add("cafe.example.com");
vk8s_hosts.compile();
new vk8s_coffee-svc_director = directors.round_robin();
vk8s_coffee-svc_director.add_backend(vk8s_coffee-svc_192_0_2_4);
vk8s_coffee-svc_director.add_backend(vk8s_coffee-svc_192_0_2_5);
new vk8s_tea-svc_director = directors.round_robin();
vk8s_tea-svc_director.add_backend(vk8s_tea-svc_192_0_2_1);
vk8s_tea-svc_director.add_backend(vk8s_tea-svc_192_0_2_2);
vk8s_tea-svc_director.add_backend(vk8s_tea-svc_192_0_2_3);
new vk8s_cafe_example_com_url = re2.set(posix_syntax=true, anchor=start);
vk8s_cafe_example_com_url.add("/coffee",
backend=vk8s_coffee-svc_director.backend());
vk8s_cafe_example_com_url.add("/tea",
backend=vk8s_tea-svc_director.backend());
vk8s_cafe_example_com_url.compile();
}
sub vk8s_set_backend {
set req.backend_hint = vk8s_notfound;
if (vk8s_hosts.match(req.http.Host)) {
if (vk8s_hosts.nmatches() != 1) {
# Fail fast when the match was not unique.
return (fail);
}
if (0 != 0) {
#
}
elsif (vk8s_hosts.which() == 1) {
if (vk8s_cafe_example_com_url.match(req.url)) {
set req.backend_hint = vk8s_cafe_example_com_url.backend(select=FIRST);
}
}
}
if (req.backend_hint == vk8s_notfound) {
return (synth(404));
}
}
sub vcl_miss {
call vk8s_set_backend;
}
sub vcl_pass {
call vk8s_set_backend;
}
sub vcl_deliver {
set resp.http.Hello = "world";
}
\ No newline at end of file
...@@ -566,3 +566,42 @@ func TestAclTemplate(t *testing.T) { ...@@ -566,3 +566,42 @@ func TestAclTemplate(t *testing.T) {
} }
} }
} }
var customVCLSpec = Spec{
DefaultService: Service{},
Rules: []Rule{{
Host: "cafe.example.com",
PathMap: map[string]Service{
"/tea": teaSvc,
"/coffee": coffeeSvc,
},
}},
AllServices: map[string]Service{
"tea-svc": teaSvc,
"coffee-svc": coffeeSvc,
},
VCL: `sub vcl_deliver {
set resp.http.Hello = "world";
}`,
}
func TestCustomVCL(t *testing.T) {
gold := "custom_vcl.golden"
vcl, err := customVCLSpec.GetSrc()
if err != nil {
t.Fatal("GetSrc():", err)
}
ok, err := cmpGold([]byte(vcl), gold)
if err != nil {
t.Fatalf("Reading %s: %v", gold, err)
}
if !ok {
t.Errorf("Generated VCL for custom VCL does not match gold "+
"file: %s", gold)
if testing.Verbose() {
t.Log("Generated: ", vcl)
}
}
}
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