@@ -900,6 +900,223 @@ func Test_ValidateClusterVariable(t *testing.T) {
900
900
},
901
901
wantErr : true ,
902
902
},
903
+ {
904
+ name : "Valid object with x-kubernetes-preserve-unknown-fields" ,
905
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
906
+ Name : "testObject" ,
907
+ Required : true ,
908
+ Schema : clusterv1.VariableSchema {
909
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
910
+ Type : "object" ,
911
+ Properties : map [string ]clusterv1.JSONSchemaProps {
912
+ "knownProperty" : {
913
+ Type : "boolean" ,
914
+ },
915
+ },
916
+ // Preserves fields for the current object (in this case unknownProperty).
917
+ XPreserveUnknownFields : true ,
918
+ },
919
+ },
920
+ },
921
+ clusterVariable : & clusterv1.ClusterVariable {
922
+ Name : "testObject" ,
923
+ Value : apiextensionsv1.JSON {
924
+ Raw : []byte (`{"knownProperty":false,"unknownProperty":true}` ),
925
+ },
926
+ },
927
+ },
928
+ {
929
+ name : "Error if undefined field" ,
930
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
931
+ Name : "testObject" ,
932
+ Required : true ,
933
+ Schema : clusterv1.VariableSchema {
934
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
935
+ Type : "object" ,
936
+ Properties : map [string ]clusterv1.JSONSchemaProps {
937
+ "knownProperty" : {
938
+ Type : "boolean" ,
939
+ },
940
+ },
941
+ },
942
+ },
943
+ },
944
+ clusterVariable : & clusterv1.ClusterVariable {
945
+ Name : "testObject" ,
946
+ Value : apiextensionsv1.JSON {
947
+ // unknownProperty is not defined in the schema.
948
+ Raw : []byte (`{"knownProperty":false,"unknownProperty":true}` ),
949
+ },
950
+ },
951
+ wantErr : true ,
952
+ },
953
+ {
954
+ name : "Error if undefined field with different casing" ,
955
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
956
+ Name : "testObject" ,
957
+ Required : true ,
958
+ Schema : clusterv1.VariableSchema {
959
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
960
+ Type : "object" ,
961
+ Properties : map [string ]clusterv1.JSONSchemaProps {
962
+ "knownProperty" : {
963
+ Type : "boolean" ,
964
+ },
965
+ },
966
+ },
967
+ },
968
+ },
969
+ clusterVariable : & clusterv1.ClusterVariable {
970
+ Name : "testObject" ,
971
+ Value : apiextensionsv1.JSON {
972
+ // KnownProperty is only defined with lower case in the schema.
973
+ Raw : []byte (`{"KnownProperty":false}` ),
974
+ },
975
+ },
976
+ wantErr : true ,
977
+ },
978
+ {
979
+ name : "Valid nested object with x-kubernetes-preserve-unknown-fields" ,
980
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
981
+ Name : "testObject" ,
982
+ Required : true ,
983
+ Schema : clusterv1.VariableSchema {
984
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
985
+ Type : "object" ,
986
+ // XPreserveUnknownFields preservers recursively if the object has nested fields
987
+ // as no nested Properties are defined.
988
+ XPreserveUnknownFields : true ,
989
+ },
990
+ },
991
+ },
992
+ clusterVariable : & clusterv1.ClusterVariable {
993
+ Name : "testObject" ,
994
+ Value : apiextensionsv1.JSON {
995
+ Raw : []byte (`{"test": {"unknownProperty":false}}` ),
996
+ },
997
+ },
998
+ },
999
+ {
1000
+ name : "Valid object with nested fields and x-kubernetes-preserve-unknown-fields" ,
1001
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
1002
+ Name : "testObject" ,
1003
+ Required : true ,
1004
+ Schema : clusterv1.VariableSchema {
1005
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
1006
+ Type : "object" ,
1007
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1008
+ "test" : {
1009
+ Type : "object" ,
1010
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1011
+ "knownProperty" : {
1012
+ Type : "boolean" ,
1013
+ },
1014
+ },
1015
+ // Preserves fields on the current level (in this case unknownProperty).
1016
+ XPreserveUnknownFields : true ,
1017
+ },
1018
+ },
1019
+ },
1020
+ },
1021
+ },
1022
+ clusterVariable : & clusterv1.ClusterVariable {
1023
+ Name : "testObject" ,
1024
+ Value : apiextensionsv1.JSON {
1025
+ Raw : []byte (`{"test": {"knownProperty":false,"unknownProperty":true}}` ),
1026
+ },
1027
+ },
1028
+ },
1029
+ {
1030
+ name : "Error if undefined field nested" ,
1031
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
1032
+ Name : "testObject" ,
1033
+ Required : true ,
1034
+ Schema : clusterv1.VariableSchema {
1035
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
1036
+ Type : "object" ,
1037
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1038
+ "test" : {
1039
+ Type : "object" ,
1040
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1041
+ "knownProperty" : {
1042
+ Type : "boolean" ,
1043
+ },
1044
+ },
1045
+ },
1046
+ },
1047
+ },
1048
+ },
1049
+ },
1050
+ clusterVariable : & clusterv1.ClusterVariable {
1051
+ Name : "testObject" ,
1052
+ Value : apiextensionsv1.JSON {
1053
+ // unknownProperty is not defined in the schema.
1054
+ Raw : []byte (`{"test": {"knownProperty":false,"unknownProperty":true}}` ),
1055
+ },
1056
+ },
1057
+ wantErr : true ,
1058
+ },
1059
+ {
1060
+ name : "Error if undefined field nested and x-kubernetes-preserve-unknown-fields one level above" ,
1061
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
1062
+ Name : "testObject" ,
1063
+ Required : true ,
1064
+ Schema : clusterv1.VariableSchema {
1065
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
1066
+ Type : "object" ,
1067
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1068
+ "test" : {
1069
+ Type : "object" ,
1070
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1071
+ "knownProperty" : {
1072
+ Type : "boolean" ,
1073
+ },
1074
+ },
1075
+ },
1076
+ },
1077
+ // Preserves only on the current level as nested Properties are defined.
1078
+ XPreserveUnknownFields : true ,
1079
+ },
1080
+ },
1081
+ },
1082
+ clusterVariable : & clusterv1.ClusterVariable {
1083
+ Name : "testObject" ,
1084
+ Value : apiextensionsv1.JSON {
1085
+ Raw : []byte (`{"test": {"knownProperty":false,"unknownProperty":true}}` ),
1086
+ },
1087
+ },
1088
+ wantErr : true ,
1089
+ },
1090
+ {
1091
+ name : "Valid object with mid-level unknown fields" ,
1092
+ clusterClassVariable : & clusterv1.ClusterClassVariable {
1093
+ Name : "testObject" ,
1094
+ Required : true ,
1095
+ Schema : clusterv1.VariableSchema {
1096
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
1097
+ Type : "object" ,
1098
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1099
+ "test" : {
1100
+ Type : "object" ,
1101
+ Properties : map [string ]clusterv1.JSONSchemaProps {
1102
+ "knownProperty" : {
1103
+ Type : "boolean" ,
1104
+ },
1105
+ },
1106
+ },
1107
+ },
1108
+ // Preserves only on the current level as nested Properties are defined.
1109
+ XPreserveUnknownFields : true ,
1110
+ },
1111
+ },
1112
+ },
1113
+ clusterVariable : & clusterv1.ClusterVariable {
1114
+ Name : "testObject" ,
1115
+ Value : apiextensionsv1.JSON {
1116
+ Raw : []byte (`{"test": {"knownProperty":false},"unknownProperty":true}` ),
1117
+ },
1118
+ },
1119
+ },
903
1120
}
904
1121
for _ , tt := range tests {
905
1122
t .Run (tt .name , func (t * testing.T ) {
0 commit comments