Skip to content

Commit 4bf994c

Browse files
committed
apiextensions: forbid x-kubernetes-embedded-resource inside of resource meta fields
1 parent e2fd72c commit 4bf994c

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,8 @@ func ValidateCustomResourceDefinitionValidation(customResourceValidation *apiext
640640
return allErrs
641641
}
642642

643+
var metaFields = sets.NewString("metadata", "apiVersion", "kind")
644+
643645
// ValidateCustomResourceDefinitionOpenAPISchema statically validates
644646
func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSchemaProps, fldPath *field.Path, ssv specStandardValidator, isRoot bool) field.ErrorList {
645647
allErrs := field.ErrorList{}
@@ -682,7 +684,7 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch
682684
if len(schema.Properties) != 0 {
683685
for property, jsonSchema := range schema.Properties {
684686
subSsv := ssv
685-
if (isRoot || schema.XEmbeddedResource) && property == "metadata" {
687+
if (isRoot || schema.XEmbeddedResource) && metaFields.Has(property) {
686688
// we recurse into the schema that applies to ObjectMeta.
687689
subSsv = ssv.withInsideResourceMeta()
688690
if isRoot {
@@ -846,6 +848,10 @@ func (v *specStandardValidatorV3) validate(schema *apiextensions.JSONSchemaProps
846848
allErrs = append(allErrs, field.Forbidden(fldPath.Child("items"), "items must be a schema object and not an array"))
847849
}
848850

851+
if v.isInsideResourceMeta && schema.XEmbeddedResource {
852+
allErrs = append(allErrs, field.Forbidden(fldPath.Child("x-kubernetes-embedded-resource"), "must not be used inside of resource meta"))
853+
}
854+
849855
return allErrs
850856
}
851857

staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,71 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
15671567
required("spec", "validation", "openAPIV3Schema", "type"),
15681568
},
15691569
},
1570+
{
1571+
name: "x-kubernetes-embedded-resource inside resource meta",
1572+
resource: &apiextensions.CustomResourceDefinition{
1573+
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
1574+
Spec: apiextensions.CustomResourceDefinitionSpec{
1575+
Group: "group.com",
1576+
Version: "version",
1577+
Versions: singleVersionList,
1578+
Scope: apiextensions.NamespaceScoped,
1579+
Names: apiextensions.CustomResourceDefinitionNames{
1580+
Plural: "plural",
1581+
Singular: "singular",
1582+
Kind: "Plural",
1583+
ListKind: "PluralList",
1584+
},
1585+
Validation: &apiextensions.CustomResourceValidation{
1586+
OpenAPIV3Schema: &apiextensions.JSONSchemaProps{
1587+
Type: "object",
1588+
Properties: map[string]apiextensions.JSONSchemaProps{
1589+
"embedded": {
1590+
Type: "object",
1591+
XEmbeddedResource: true,
1592+
Properties: map[string]apiextensions.JSONSchemaProps{
1593+
"metadata": {
1594+
Type: "object",
1595+
XEmbeddedResource: true,
1596+
XPreserveUnknownFields: pointer.BoolPtr(true),
1597+
},
1598+
"apiVersion": {
1599+
Type: "string",
1600+
Properties: map[string]apiextensions.JSONSchemaProps{
1601+
"foo": {
1602+
Type: "object",
1603+
XEmbeddedResource: true,
1604+
XPreserveUnknownFields: pointer.BoolPtr(true),
1605+
},
1606+
},
1607+
},
1608+
"kind": {
1609+
Type: "string",
1610+
Properties: map[string]apiextensions.JSONSchemaProps{
1611+
"foo": {
1612+
Type: "object",
1613+
XEmbeddedResource: true,
1614+
XPreserveUnknownFields: pointer.BoolPtr(true),
1615+
},
1616+
},
1617+
},
1618+
},
1619+
},
1620+
},
1621+
},
1622+
},
1623+
PreserveUnknownFields: pointer.BoolPtr(true),
1624+
},
1625+
Status: apiextensions.CustomResourceDefinitionStatus{
1626+
StoredVersions: []string{"version"},
1627+
},
1628+
},
1629+
errors: []validationMatch{
1630+
forbidden("spec", "validation", "openAPIV3Schema", "properties[embedded]", "properties[metadata]", "x-kubernetes-embedded-resource"),
1631+
forbidden("spec", "validation", "openAPIV3Schema", "properties[embedded]", "properties[apiVersion]", "properties[foo]", "x-kubernetes-embedded-resource"),
1632+
forbidden("spec", "validation", "openAPIV3Schema", "properties[embedded]", "properties[kind]", "properties[foo]", "x-kubernetes-embedded-resource"),
1633+
},
1634+
},
15701635
{
15711636
name: "defaults with enabled feature gate, unstructural schema",
15721637
resource: &apiextensions.CustomResourceDefinition{

0 commit comments

Comments
 (0)