42 lines
1.4 KiB
Go
42 lines
1.4 KiB
Go
package controller
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
|
|
crawlv1alpha1 "gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/api/v1alpha1"
|
|
)
|
|
|
|
// specHashInput is the explicit set of fields whose change requires
|
|
// replacing the instance. Deliberately not ProxySpec wholesale: adding a
|
|
// spec field that doesn't affect the VM (attributes, maxLeases, healthCheck)
|
|
// must not churn the fleet on operator upgrade.
|
|
type specHashInput struct {
|
|
Placement *crawlv1alpha1.PlacementSpec `json:"placement,omitempty"`
|
|
CloudInit string `json:"cloudInit,omitempty"`
|
|
Port int32 `json:"port"`
|
|
}
|
|
|
|
// specHash returns the hex SHA-256 of the replacement-triggering spec
|
|
// fields. cloudInit is the already-resolved content, so rotating a
|
|
// referenced Secret changes the hash even though the spec is untouched.
|
|
func specHash(p *crawlv1alpha1.Proxy, cloudInit string) string {
|
|
in := specHashInput{
|
|
Placement: p.Spec.Placement,
|
|
CloudInit: cloudInit,
|
|
Port: p.EffectivePort(),
|
|
}
|
|
// nil and empty placement mean the same thing; hash them identically.
|
|
if in.Placement != nil && *in.Placement == (crawlv1alpha1.PlacementSpec{}) {
|
|
in.Placement = nil
|
|
}
|
|
b, err := json.Marshal(in)
|
|
if err != nil {
|
|
// A struct of strings and an int32 cannot fail to marshal.
|
|
panic(err)
|
|
}
|
|
sum := sha256.Sum256(b)
|
|
return hex.EncodeToString(sum[:])
|
|
}
|