@@ -27,6 +27,7 @@ import (
27
27
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
28
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
29
29
"k8s.io/apimachinery/pkg/runtime/schema"
30
+ "k8s.io/apimachinery/pkg/types"
30
31
"k8s.io/apimachinery/pkg/util/wait"
31
32
"k8s.io/apimachinery/pkg/util/yaml"
32
33
@@ -780,21 +781,25 @@ spec:
780
781
if v := "spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields" ; ! strings .Contains (cond .Message , v ) {
781
782
t .Fatalf ("expected violation %q, but got: %v" , v , cond .Message )
782
783
}
784
+ if v := "spec.preserveUnknownFields: Invalid value: true: must be false" ; ! strings .Contains (cond .Message , v ) {
785
+ t .Fatalf ("expected violation %q, but got: %v" , v , cond .Message )
786
+ }
783
787
784
788
// remove schema
785
789
t .Log ("Remove schema" )
786
790
for retry := 0 ; retry < 5 ; retry ++ {
787
- crd , err = apiExtensionClient . ApiextensionsV1beta1 (). CustomResourceDefinitions (). Get ( context . TODO (), name , metav1. GetOptions {})
788
- if err != nil {
789
- t . Fatalf ( "unexpected get error: %v" , err )
790
- }
791
- crd . Spec . Validation = nil
792
- if _ , err = apiExtensionClient .ApiextensionsV1beta1 ().CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {}); apierrors .IsConflict (err ) {
791
+ // This patch fixes two fields to resolve
792
+ // 1. property type validation error
793
+ // 2. preserveUnknownFields validation error
794
+ patch := [] byte ( "[{ \" op \" : \" add \" , \" path \" : \" /spec/validation/openAPIV3Schema/properties/a/type \" , \" value \" : \" int \" }," +
795
+ "{ \" op \" : \" replace \" , \" path \" : \" /spec/preserveUnknownFields \" , \" value \" :false}]" )
796
+ if _ , err = apiExtensionClient .ApiextensionsV1beta1 ().CustomResourceDefinitions ().Patch (context .TODO (), name , types . JSONPatchType , patch , metav1.PatchOptions {}); apierrors .IsConflict (err ) {
793
797
continue
794
798
}
795
799
if err != nil {
796
800
t .Fatalf ("unexpected update error: %v" , err )
797
801
}
802
+ break
798
803
}
799
804
if err != nil {
800
805
t .Fatalf ("unexpected update error: %v" , err )
@@ -821,13 +826,15 @@ spec:
821
826
if err != nil {
822
827
t .Fatalf ("unexpected get error: %v" , err )
823
828
}
829
+ crd .Spec .PreserveUnknownFields = nil
824
830
crd .Spec .Validation = & apiextensionsv1beta1.CustomResourceValidation {OpenAPIV3Schema : origSchema }
825
831
if _ , err = apiExtensionClient .ApiextensionsV1beta1 ().CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {}); apierrors .IsConflict (err ) {
826
832
continue
827
833
}
828
834
if err != nil {
829
835
t .Fatalf ("unexpected update error: %v" , err )
830
836
}
837
+ break
831
838
}
832
839
if err != nil {
833
840
t .Fatalf ("unexpected update error: %v" , err )
@@ -849,6 +856,9 @@ spec:
849
856
if v := "spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields" ; ! strings .Contains (cond .Message , v ) {
850
857
t .Fatalf ("expected violation %q, but got: %v" , v , cond .Message )
851
858
}
859
+ if v := "spec.preserveUnknownFields: Invalid value: true: must be false" ; ! strings .Contains (cond .Message , v ) {
860
+ t .Fatalf ("expected violation %q, but got: %v" , v , cond .Message )
861
+ }
852
862
}
853
863
854
864
func TestNonStructuralSchemaCondition (t * testing.T ) {
@@ -862,6 +872,7 @@ func TestNonStructuralSchemaCondition(t *testing.T) {
862
872
apiVersion: apiextensions.k8s.io/v1beta1
863
873
kind: CustomResourceDefinition
864
874
spec:
875
+ preserveUnknownFields: PRESERVE_UNKNOWN_FIELDS
865
876
version: v1beta1
866
877
names:
867
878
plural: foos
@@ -882,14 +893,27 @@ spec:
882
893
883
894
type Test struct {
884
895
desc string
896
+ preserveUnknownFields string
885
897
globalSchema , v1Schema , v1beta1Schema string
886
898
expectedCreateErrors []string
887
899
unexpectedCreateErrors []string
888
900
expectedViolations []string
889
901
unexpectedViolations []string
890
902
}
891
903
tests := []Test {
892
- {"empty" , "" , "" , "" , nil , nil , nil , nil },
904
+ {
905
+ desc : "empty" ,
906
+ expectedViolations : []string {
907
+ "spec.preserveUnknownFields: Invalid value: true: must be false" ,
908
+ },
909
+ },
910
+ {
911
+ desc : "preserve unknown fields is false" ,
912
+ preserveUnknownFields : "false" ,
913
+ globalSchema : `
914
+ type: object
915
+ ` ,
916
+ },
893
917
{
894
918
desc : "int-or-string and preserve-unknown-fields true" ,
895
919
globalSchema : `
@@ -922,7 +946,8 @@ x-kubernetes-embedded-resource: true
922
946
},
923
947
},
924
948
{
925
- desc : "embedded-resource without preserve-unknown-fields, but properties" ,
949
+ desc : "embedded-resource without preserve-unknown-fields, but properties" ,
950
+ preserveUnknownFields : "false" ,
926
951
globalSchema : `
927
952
type: object
928
953
x-kubernetes-embedded-resource: true
@@ -934,16 +959,15 @@ properties:
934
959
metadata:
935
960
type: object
936
961
` ,
937
- expectedViolations : []string {},
938
962
},
939
963
{
940
- desc : "embedded-resource with preserve-unknown-fields" ,
964
+ desc : "embedded-resource with preserve-unknown-fields" ,
965
+ preserveUnknownFields : "false" ,
941
966
globalSchema : `
942
967
type: object
943
968
x-kubernetes-embedded-resource: true
944
969
x-kubernetes-preserve-unknown-fields: true
945
970
` ,
946
- expectedViolations : []string {},
947
971
},
948
972
{
949
973
desc : "embedded-resource with wrong type" ,
@@ -1330,7 +1354,8 @@ oneOf:
1330
1354
},
1331
1355
},
1332
1356
{
1333
- desc : "structural complete" ,
1357
+ desc : "structural complete" ,
1358
+ preserveUnknownFields : "false" ,
1334
1359
globalSchema : `
1335
1360
type: object
1336
1361
properties:
@@ -1391,7 +1416,6 @@ oneOf:
1391
1416
- properties:
1392
1417
g: {}
1393
1418
` ,
1394
- expectedViolations : nil ,
1395
1419
},
1396
1420
{
1397
1421
desc : "invalid v1beta1 schema" ,
@@ -1472,7 +1496,8 @@ properties:
1472
1496
},
1473
1497
},
1474
1498
{
1475
- desc : "metadata with name property" ,
1499
+ desc : "metadata with name property" ,
1500
+ preserveUnknownFields : "false" ,
1476
1501
globalSchema : `
1477
1502
type: object
1478
1503
properties:
@@ -1483,10 +1508,10 @@ properties:
1483
1508
type: string
1484
1509
pattern: "^[a-z]+$"
1485
1510
` ,
1486
- expectedViolations : []string {},
1487
1511
},
1488
1512
{
1489
- desc : "metadata with generateName property" ,
1513
+ desc : "metadata with generateName property" ,
1514
+ preserveUnknownFields : "false" ,
1490
1515
globalSchema : `
1491
1516
type: object
1492
1517
properties:
@@ -1497,10 +1522,10 @@ properties:
1497
1522
type: string
1498
1523
pattern: "^[a-z]+$"
1499
1524
` ,
1500
- expectedViolations : []string {},
1501
1525
},
1502
1526
{
1503
- desc : "metadata with name and generateName property" ,
1527
+ desc : "metadata with name and generateName property" ,
1528
+ preserveUnknownFields : "false" ,
1504
1529
globalSchema : `
1505
1530
type: object
1506
1531
properties:
@@ -1514,7 +1539,6 @@ properties:
1514
1539
type: string
1515
1540
pattern: "^[a-z]+$"
1516
1541
` ,
1517
- expectedViolations : []string {},
1518
1542
},
1519
1543
{
1520
1544
desc : "metadata under junctors" ,
@@ -1597,6 +1621,7 @@ properties:
1597
1621
"GLOBAL_SCHEMA" , toValidationJSON (tst .globalSchema ),
1598
1622
"V1BETA1_SCHEMA" , toValidationJSON (tst .v1beta1Schema ),
1599
1623
"V1_SCHEMA" , toValidationJSON (tst .v1Schema ),
1624
+ "PRESERVE_UNKNOWN_FIELDS" , tst .preserveUnknownFields ,
1600
1625
).Replace (tmpl )
1601
1626
1602
1627
// decode CRD manifest
0 commit comments