Skip to content

Commit

Permalink
feat: Add resource.Quantity as a known field type for diffing. (argop…
Browse files Browse the repository at this point in the history
…roj#5095)

Signed-off-by: Noah Kantrowitz <noah@coderanger.net>
  • Loading branch information
coderanger authored Dec 21, 2020
1 parent cfdf1db commit 5b464c9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
14 changes: 11 additions & 3 deletions util/argo/normalizers/knowntypes_normalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"

Expand All @@ -26,6 +27,13 @@ type knownTypesNormalizer struct {
typeFields map[schema.GroupKind][]knownTypeField
}

// Register some non-code-generated types here. The bulk of them are in corev1_known_types.go
func init() {
knownTypes["core/Quantity"] = func() interface{} {
return &resource.Quantity{}
}
}

// NewKnownTypesNormalizer create a normalizer that re-format custom resource fields using built-in Kubernetes types.
func NewKnownTypesNormalizer(overrides map[string]v1alpha1.ResourceOverride) (*knownTypesNormalizer, error) {
normalizer := knownTypesNormalizer{typeFields: map[schema.GroupKind][]knownTypeField{}}
Expand Down Expand Up @@ -99,7 +107,7 @@ func normalize(obj map[string]interface{}, field knownTypeField, fieldPath []str
}
}

if fieldVal, ok, err := unstructured.NestedMap(obj, fieldPath...); ok && err == nil {
if fieldVal, ok, err := unstructured.NestedFieldNoCopy(obj, fieldPath...); ok && err == nil {
newFieldVal, err := remarshal(fieldVal, field)
if err != nil {
return err
Expand All @@ -113,7 +121,7 @@ func normalize(obj map[string]interface{}, field knownTypeField, fieldPath []str
return nil
}

func remarshal(fieldVal map[string]interface{}, field knownTypeField) (map[string]interface{}, error) {
func remarshal(fieldVal interface{}, field knownTypeField) (interface{}, error) {
data, err := json.Marshal(fieldVal)
if err != nil {
return nil, err
Expand All @@ -127,7 +135,7 @@ func remarshal(fieldVal map[string]interface{}, field knownTypeField) (map[strin
if err != nil {
return nil, err
}
newFieldVal := map[string]interface{}{}
var newFieldVal interface{}
err = json.Unmarshal(data, &newFieldVal)
if err != nil {
return nil, err
Expand Down
31 changes: 31 additions & 0 deletions util/argo/normalizers/knowntypes_normalizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,37 @@ spec:
assert.Equal(t, "2", cpu)
}

func TestNormalize_Quantity(t *testing.T) {
rollout := mustUnmarshalYAML(`apiVersion: some.io/v1alpha1
kind: TestCRD
metadata:
name: canary-demo
spec:
ram: 1.25G`)
normalizer, err := NewKnownTypesNormalizer(map[string]v1alpha1.ResourceOverride{
crdGroupKind: {
KnownTypeFields: []v1alpha1.KnownTypeField{{
Type: "core/Quantity",
Field: "spec.ram",
}},
},
})
if !assert.NoError(t, err) {
return
}

err = normalizer.Normalize(rollout)
if !assert.NoError(t, err) {
return
}

ram, ok, err := unstructured.NestedFieldNoCopy(rollout.Object, "spec", "ram")
if !assert.NoError(t, err) || !assert.True(t, ok) {
return
}
assert.Equal(t, "1250M", ram)
}

func TestFieldDoesNotExist(t *testing.T) {
rollout := mustUnmarshalYAML(someCRDYaml)
normalizer, err := NewKnownTypesNormalizer(map[string]v1alpha1.ResourceOverride{
Expand Down

0 comments on commit 5b464c9

Please sign in to comment.