Skip to content

Commit ec00b4f

Browse files
authored
Merge pull request kubernetes#89833 from liggitt/json-raw
preserve integers decoding raw JSON values
2 parents 0c9245a + 8b91658 commit ec00b4f

File tree

38 files changed

+241
-87
lines changed

38 files changed

+241
-87
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ require (
138138
k8s.io/klog v1.0.0
139139
k8s.io/kube-aggregator v0.0.0
140140
k8s.io/kube-controller-manager v0.0.0
141-
k8s.io/kube-openapi v0.0.0-20200401025727-01dfbe2eec3d
141+
k8s.io/kube-openapi v0.0.0-20200403204345-e1beb1bd0f35
142142
k8s.io/kube-proxy v0.0.0
143143
k8s.io/kube-scheduler v0.0.0
144144
k8s.io/kubectl v0.0.0
@@ -537,7 +537,7 @@ replace (
537537
k8s.io/klog => k8s.io/klog v1.0.0
538538
k8s.io/kube-aggregator => ./staging/src/k8s.io/kube-aggregator
539539
k8s.io/kube-controller-manager => ./staging/src/k8s.io/kube-controller-manager
540-
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200401025727-01dfbe2eec3d
540+
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200403204345-e1beb1bd0f35
541541
k8s.io/kube-proxy => ./staging/src/k8s.io/kube-proxy
542542
k8s.io/kube-scheduler => ./staging/src/k8s.io/kube-scheduler
543543
k8s.io/kubectl => ./staging/src/k8s.io/kubectl

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,8 @@ k8s.io/heapster v1.2.0-beta.1 h1:lUsE/AHOMHpi3MLlBEkaU8Esxm5QhdyCrv1o7ot0s84=
606606
k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM=
607607
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
608608
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
609-
k8s.io/kube-openapi v0.0.0-20200401025727-01dfbe2eec3d h1:SaMrAnTezfJejw3Y3Ysw9DHTUW2qwW/EzzaTw1xtL74=
610-
k8s.io/kube-openapi v0.0.0-20200401025727-01dfbe2eec3d/go.mod h1:NwPpO8COeh/j9Q9ModsqBxwHcWDo/PmrJOPyquZCC1A=
609+
k8s.io/kube-openapi v0.0.0-20200403204345-e1beb1bd0f35 h1:FDWYFE3itI1G8UFOMjUuLbROZExo+Rrfm/Qaf473rm4=
610+
k8s.io/kube-openapi v0.0.0-20200403204345-e1beb1bd0f35/go.mod h1:NwPpO8COeh/j9Q9ModsqBxwHcWDo/PmrJOPyquZCC1A=
611611
k8s.io/repo-infra v0.0.1-alpha.1 h1:2us1n30u3cOcoPsacNfCvCssS9B9Yldr1ZGOdK0728U=
612612
k8s.io/repo-infra v0.0.1-alpha.1/go.mod h1:wO1t9WaB99V80ljbeENTnayuEEwNZt7gECYh/CEyOJ8=
613613
k8s.io/system-validators v1.1.2 h1:0xzEb0PqnDnUOuf/2E/gaJBOBN7j+qf0LIn12jw3oc4=

staging/src/k8s.io/api/go.sum

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/apiextensions-apiserver/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ require (
2828
k8s.io/code-generator v0.0.0
2929
k8s.io/component-base v0.0.0
3030
k8s.io/klog v1.0.0
31-
k8s.io/kube-openapi v0.0.0-20200401025727-01dfbe2eec3d
31+
k8s.io/kube-openapi v0.0.0-20200403204345-e1beb1bd0f35
3232
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
3333
sigs.k8s.io/yaml v1.2.0
3434
)

staging/src/k8s.io/apiextensions-apiserver/go.sum

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/goopenapi_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ func TestStructuralRoundtrip(t *testing.T) {
3838
f.RandSource(rand.New(rand.NewSource(seed)))
3939
f.Funcs(
4040
func(s *JSON, c fuzz.Continue) {
41-
switch c.Intn(6) {
41+
switch c.Intn(7) {
4242
case 0:
43-
s.Object = float64(42.0)
43+
s.Object = float64(42.2)
4444
case 1:
4545
s.Object = map[string]interface{}{"foo": "bar"}
4646
case 2:
@@ -51,6 +51,8 @@ func TestStructuralRoundtrip(t *testing.T) {
5151
s.Object = map[string]interface{}{}
5252
case 5:
5353
s.Object = nil
54+
case 6:
55+
s.Object = int64(42)
5456
}
5557
},
5658
)

staging/src/k8s.io/apiextensions-apiserver/test/integration/defaulting_test.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ var defaultingFixture = &apiextensionsv1.CustomResourceDefinition{
5353
Served: true,
5454
Subresources: &apiextensionsv1.CustomResourceSubresources{
5555
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
56+
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
57+
SpecReplicasPath: ".spec.replicas",
58+
StatusReplicasPath: ".status.replicas",
59+
},
5660
},
5761
},
5862
{
@@ -61,6 +65,10 @@ var defaultingFixture = &apiextensionsv1.CustomResourceDefinition{
6165
Served: false,
6266
Subresources: &apiextensionsv1.CustomResourceSubresources{
6367
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
68+
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
69+
SpecReplicasPath: ".spec.replicas",
70+
StatusReplicasPath: ".status.replicas",
71+
},
6472
},
6573
},
6674
},
@@ -94,6 +102,11 @@ properties:
94102
default: "v1beta1"
95103
v1beta2:
96104
type: string
105+
replicas:
106+
default: 1
107+
format: int32
108+
minimum: 0
109+
type: integer
97110
status:
98111
type: object
99112
properties:
@@ -110,6 +123,11 @@ properties:
110123
default: "v1beta1"
111124
v1beta2:
112125
type: string
126+
replicas:
127+
default: 0
128+
format: int32
129+
minimum: 0
130+
type: integer
113131
`
114132

115133
const defaultingFooV1beta2Schema = `
@@ -131,6 +149,11 @@ properties:
131149
v1beta2:
132150
type: string
133151
default: "v1beta2"
152+
replicas:
153+
default: 1
154+
format: int32
155+
minimum: 0
156+
type: integer
134157
status:
135158
type: object
136159
properties:
@@ -147,6 +170,11 @@ properties:
147170
v1beta2:
148171
type: string
149172
default: "v1beta2"
173+
replicas:
174+
default: 0
175+
format: int32
176+
minimum: 0
177+
type: integer
150178
`
151179

152180
const defaultingFooInstance = `
@@ -274,15 +302,15 @@ func testDefaulting(t *testing.T, watchCache bool) {
274302
// spec.a and spec.b are defaulted in both versions
275303
// spec.v1beta1 is defaulted when reading the incoming request
276304
// spec.v1beta2 is defaulted when reading the storage response
277-
mustExist(foo.Object, [][]string{{"spec", "a"}, {"spec", "b"}, {"spec", "v1beta1"}, {"spec", "v1beta2"}})
305+
mustExist(foo.Object, [][]string{{"spec", "a"}, {"spec", "b"}, {"spec", "v1beta1"}, {"spec", "v1beta2"}, {"spec", "replicas"}})
278306
mustNotExist(foo.Object, [][]string{{"status"}})
279307

280308
t.Logf("Updating status and expecting 'a' and 'b' to show up.")
281309
unstructured.SetNestedField(foo.Object, map[string]interface{}{}, "status")
282310
if foo, err = fooClient.UpdateStatus(context.TODO(), foo, metav1.UpdateOptions{}); err != nil {
283311
t.Fatal(err)
284312
}
285-
mustExist(foo.Object, [][]string{{"spec", "a"}, {"spec", "b"}, {"status", "a"}, {"status", "b"}})
313+
mustExist(foo.Object, [][]string{{"spec", "a"}, {"spec", "b"}, {"status", "a"}, {"status", "b"}, {"status", "replicas"}})
286314

287315
t.Logf("Add 'c' default to the storage version and wait until GET sees it in both status and spec")
288316
addDefault("v1beta2", "c", "C")

staging/src/k8s.io/apimachinery/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
gopkg.in/inf.v0 v0.9.1
3131
gopkg.in/yaml.v2 v2.2.8
3232
k8s.io/klog v1.0.0
33-
k8s.io/kube-openapi v0.0.0-20200401025727-01dfbe2eec3d
33+
k8s.io/kube-openapi v0.0.0-20200403204345-e1beb1bd0f35
3434
sigs.k8s.io/structured-merge-diff/v3 v3.0.0
3535
sigs.k8s.io/yaml v1.2.0
3636
)

staging/src/k8s.io/apimachinery/go.sum

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/apimachinery/pkg/util/json/json.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,36 @@ func Unmarshal(data []byte, v interface{}) error {
6666
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
6767
return convertSliceNumbers(*v, 0)
6868

69+
case *interface{}:
70+
// Build a decoder from the given data
71+
decoder := json.NewDecoder(bytes.NewBuffer(data))
72+
// Preserve numbers, rather than casting to float64 automatically
73+
decoder.UseNumber()
74+
// Run the decode
75+
if err := decoder.Decode(v); err != nil {
76+
return err
77+
}
78+
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
79+
return convertInterfaceNumbers(v, 0)
80+
6981
default:
7082
return json.Unmarshal(data, v)
7183
}
7284
}
7385

86+
func convertInterfaceNumbers(v *interface{}, depth int) error {
87+
var err error
88+
switch v2 := (*v).(type) {
89+
case json.Number:
90+
*v, err = convertNumber(v2)
91+
case map[string]interface{}:
92+
err = convertMapNumbers(v2, depth+1)
93+
case []interface{}:
94+
err = convertSliceNumbers(v2, depth+1)
95+
}
96+
return err
97+
}
98+
7499
// convertMapNumbers traverses the map, converting any json.Number values to int64 or float64.
75100
// values which are map[string]interface{} or []interface{} are recursively visited
76101
func convertMapNumbers(m map[string]interface{}, depth int) error {

0 commit comments

Comments
 (0)