Commit a68082d8 authored by Geoff Simmons's avatar Geoff Simmons

DeepHash for a VCL Spec is base62-encoded SHA512/224.

Almost certainly, two Specs are equivalent iff their DeepHashes
are equal (unless we've discovered a SHA512 collision).

Base62 encoding is strictly alphanumeric, so VCL config names (which
include the hash) are very likely safe in any context.

With the "vk8s_ing_" prefix, VCL config names are 47 bytes long.

Closes #14
parent 4f5ee750
......@@ -851,13 +851,13 @@ func (worker *NamespaceWorker) addOrUpdateIng(ing *extensions.Ingress) error {
Ver: bcfg.ResourceVersion,
}
}
worker.log.Debugf("Check if config is loaded: hash=%0x "+
worker.log.Debugf("Check if config is loaded: hash=%s "+
"ingressMetaData=%+v vcfgMetaData=%+v bcfgMetaData=%+v",
vclSpec.Canonical().DeepHash(), ingsMeta, vcfgMeta, bcfgMeta)
if worker.vController.HasConfig(svcKey, vclSpec, ingsMeta, vcfgMeta,
bcfgMeta) {
worker.log.Infof("Varnish Service %s: config already "+
"loaded: hash=%0x", svcKey,
"loaded: hash=%s", svcKey,
vclSpec.Canonical().DeepHash())
return nil
}
......
......@@ -125,8 +125,7 @@ type vclSpec struct {
}
func (spec vclSpec) configName() string {
name := fmt.Sprintf("%s%0x", ingressPrefix,
spec.spec.Canonical().DeepHash())
name := fmt.Sprint(ingressPrefix, spec.spec.Canonical().DeepHash())
return nonAlNum.ReplaceAllLiteralString(name, "_")
}
......
......@@ -54,7 +54,7 @@ func TestDeepHash(t *testing.T) {
if testing.Verbose() {
t.Logf("spec1: %+v", cafeSpec)
t.Logf("spec2: %+v", cafeSpec2)
t.Logf("hash: %0x", cafeSpec.DeepHash())
t.Logf("hash: %s", cafeSpec.DeepHash())
}
}
}
......@@ -120,9 +120,9 @@ func TestCanoncial(t *testing.T) {
t.Error("Canonical(): Unequal hashes for equivalent specs")
if testing.Verbose() {
t.Logf("spec1 canonical: %+v", canonCafe)
t.Logf("spec1 hash: %0x", canonCafe.DeepHash())
t.Logf("spec1 hash: %s", canonCafe.DeepHash())
t.Logf("spec2 canonical: %+v", canonShuf)
t.Logf("spec2 hash: %0x", canonShuf.DeepHash())
t.Logf("spec2 hash: %s", canonShuf.DeepHash())
}
}
}
......
......@@ -29,10 +29,11 @@
package vcl
import (
"crypto/sha512"
"encoding/binary"
"hash"
"hash/fnv"
"math"
"math/big"
"sort"
)
......@@ -680,10 +681,11 @@ type Spec struct {
Rewrites []Rewrite
}
// DeepHash computes a 64-bit hash value from a Spec such that if two
// Specs are deeply equal, then their hash values are equal.
func (spec Spec) DeepHash() uint64 {
hash := fnv.New64a()
// DeepHash computes a alphanumerically encoded hash value from a Spec
// such that, almost certainly, two Specs are deeply equal iff their
// hash values are equal (unless we've discovered a SHA512 collision).
func (spec Spec) DeepHash() string {
hash := sha512.New512_224()
spec.DefaultService.hash(hash)
for _, rule := range spec.Rules {
rule.hash(hash)
......@@ -710,7 +712,9 @@ func (spec Spec) DeepHash() uint64 {
for _, rw := range spec.Rewrites {
rw.hash(hash)
}
return hash.Sum64()
h := new(big.Int)
h.SetBytes(hash.Sum(nil))
return h.Text(62)
}
// Canonical returns a canonical form of a Spec, in which all of its
......
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