-
Notifications
You must be signed in to change notification settings - Fork 289
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
engine: create KubernetesApplyStatus (#4681)
- Loading branch information
Showing
8 changed files
with
284 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package kubernetesapply | ||
|
||
import ( | ||
"crypto" | ||
"encoding/base64" | ||
"fmt" | ||
"hash" | ||
|
||
jsoniter "github.com/json-iterator/go" | ||
"github.com/pkg/errors" | ||
"k8s.io/apimachinery/pkg/types" | ||
|
||
"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" | ||
) | ||
|
||
var defaultJSONIterator = createDefaultJSONIterator() | ||
|
||
func createDefaultJSONIterator() jsoniter.API { | ||
return jsoniter.Config{ | ||
EscapeHTML: true, | ||
SortMapKeys: true, | ||
ValidateJsonRawMessage: true, | ||
CaseSensitive: true, | ||
}.Froze() | ||
} | ||
|
||
// Compute the hash of all the inputs we fed into this apply. | ||
func ComputeInputHash(spec v1alpha1.KubernetesApplySpec, imageMaps map[types.NamespacedName]*v1alpha1.ImageMap) (string, error) { | ||
w := newHashWriter() | ||
err := w.append(spec) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
for _, imageMapName := range spec.ImageMaps { | ||
imageMap, ok := imageMaps[types.NamespacedName{Name: imageMapName}] | ||
if !ok { | ||
return "", fmt.Errorf("missing image map: %v", err) | ||
} | ||
err = w.append(imageMap.Spec) | ||
if err != nil { | ||
return "", fmt.Errorf("hashing %s spec: %v", imageMapName, err) | ||
} | ||
err = w.append(imageMap.Status) | ||
if err != nil { | ||
return "", fmt.Errorf("hashing %s status: %v", imageMapName, err) | ||
} | ||
} | ||
|
||
return w.done(), nil | ||
} | ||
|
||
type hashWriter struct { | ||
h hash.Hash | ||
} | ||
|
||
func newHashWriter() *hashWriter { | ||
return &hashWriter{h: crypto.SHA1.New()} | ||
} | ||
|
||
func (w hashWriter) append(o interface{}) error { | ||
data, err := defaultJSONIterator.Marshal(o) | ||
if err != nil { | ||
return errors.Wrap(err, "serializing object for hash") | ||
} | ||
_, err = w.h.Write(data) | ||
if err != nil { | ||
return errors.Wrap(err, "computing hash") | ||
} | ||
return nil | ||
} | ||
|
||
func (w hashWriter) done() string { | ||
return base64.URLEncoding.EncodeToString(w.h.Sum(nil)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package kubernetesapply | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
|
||
"github.com/tilt-dev/tilt/internal/k8s/testyaml" | ||
"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" | ||
) | ||
|
||
// The hashes are hard-coded in this file to ensure we | ||
// don't accidentally change them. | ||
// | ||
// When updating the hashes, make sure that you don't accidentally | ||
// change two hashes to the same value | ||
func MustComputeInputHash(t testing.TB, spec v1alpha1.KubernetesApplySpec, imageMaps map[types.NamespacedName]*v1alpha1.ImageMap) string { | ||
hash, err := ComputeInputHash(spec, imageMaps) | ||
require.NoError(t, err) | ||
return hash | ||
} | ||
|
||
func TestComputeHashSancho(t *testing.T) { | ||
spec := v1alpha1.KubernetesApplySpec{YAML: testyaml.SanchoYAML} | ||
hash := MustComputeInputHash(t, spec, nil) | ||
assert.Equal(t, hash, "NgLB5gs3oLNMTnK1W71r1pfqO44=") | ||
} | ||
|
||
func TestComputeHashSanchoSidecar(t *testing.T) { | ||
spec := v1alpha1.KubernetesApplySpec{YAML: testyaml.SanchoSidecarYAML} | ||
hash := MustComputeInputHash(t, spec, nil) | ||
assert.Equal(t, hash, "1Cb6qJKoOTOJ4HFER755XZUJyk8=") | ||
} | ||
|
||
func TestComputeHashSanchoImageMap(t *testing.T) { | ||
spec := v1alpha1.KubernetesApplySpec{YAML: testyaml.SanchoYAML, ImageMaps: []string{"sancho"}} | ||
imageMaps := make(map[types.NamespacedName]*v1alpha1.ImageMap) | ||
imageMaps[types.NamespacedName{Name: "sancho"}] = &v1alpha1.ImageMap{ | ||
ObjectMeta: metav1.ObjectMeta{Name: "sancho"}, | ||
Spec: v1alpha1.ImageMapSpec{Selector: "sancho"}, | ||
Status: v1alpha1.ImageMapStatus{Image: "sancho:1234"}, | ||
} | ||
|
||
hash := MustComputeInputHash(t, spec, imageMaps) | ||
assert.Equal(t, hash, "ap_IM4fXlSII4EfidE1ciYSLePg=") | ||
} | ||
|
||
func TestComputeHashSanchoIgnoresIrrelevantImageMap(t *testing.T) { | ||
spec := v1alpha1.KubernetesApplySpec{YAML: testyaml.SanchoYAML} | ||
imageMaps := make(map[types.NamespacedName]*v1alpha1.ImageMap) | ||
imageMaps[types.NamespacedName{Name: "sancho"}] = &v1alpha1.ImageMap{ | ||
ObjectMeta: metav1.ObjectMeta{Name: "sancho"}, | ||
Spec: v1alpha1.ImageMapSpec{Selector: "sancho"}, | ||
Status: v1alpha1.ImageMapStatus{Image: "sancho:1234"}, | ||
} | ||
|
||
assert.Equal(t, MustComputeInputHash(t, spec, nil), MustComputeInputHash(t, spec, imageMaps)) | ||
} | ||
|
||
func TestComputeHashSanchoImageMapChange(t *testing.T) { | ||
spec := v1alpha1.KubernetesApplySpec{YAML: testyaml.SanchoYAML, ImageMaps: []string{"sancho"}} | ||
imageMaps := make(map[types.NamespacedName]*v1alpha1.ImageMap) | ||
imageMaps[types.NamespacedName{Name: "sancho"}] = &v1alpha1.ImageMap{ | ||
ObjectMeta: metav1.ObjectMeta{Name: "sancho"}, | ||
Spec: v1alpha1.ImageMapSpec{Selector: "sancho"}, | ||
Status: v1alpha1.ImageMapStatus{Image: "sancho:45678"}, | ||
} | ||
|
||
hash := MustComputeInputHash(t, spec, imageMaps) | ||
assert.Equal(t, hash, "6CHjHc7hicdn0U6UkGqo0qL3uO8=") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.