mirror of
https://github.com/rancher/steve.git
synced 2025-09-20 11:00:25 +00:00
Merge a6152a497d
into 57ce685118
This commit is contained in:
@@ -305,13 +305,11 @@ func Test_byID(t *testing.T) {
|
|||||||
Description: "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
Description: "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||||
},
|
},
|
||||||
"binaryData": {
|
"binaryData": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "BinaryData contains the binary data. Each key must consist of alphanumeric characters, '-', '_' or '.'. BinaryData can contain byte sequences that are not in the UTF-8 range. The keys stored in BinaryData must not overlap with the ones in the Data field, this is enforced during validation process. Using this field will require 1.10+ apiserver and kubelet.",
|
Description: "BinaryData contains the binary data. Each key must consist of alphanumeric characters, '-', '_' or '.'. BinaryData can contain byte sequences that are not in the UTF-8 range. The keys stored in BinaryData must not overlap with the ones in the Data field, this is enforced during validation process. Using this field will require 1.10+ apiserver and kubelet.",
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.",
|
Description: "Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.",
|
||||||
},
|
},
|
||||||
"immutable": {
|
"immutable": {
|
||||||
@@ -323,8 +321,7 @@ func Test_byID(t *testing.T) {
|
|||||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"annotations": {
|
"annotations": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "annotations of the resource",
|
Description: "annotations of the resource",
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
@@ -393,8 +390,7 @@ func Test_byID(t *testing.T) {
|
|||||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"annotations": {
|
"annotations": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "annotations of the resource",
|
Description: "annotations of the resource",
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
@@ -443,8 +439,7 @@ func Test_byID(t *testing.T) {
|
|||||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"annotations": {
|
"annotations": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "annotations of the resource",
|
Description: "annotations of the resource",
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
@@ -517,8 +512,7 @@ func Test_byID(t *testing.T) {
|
|||||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"annotations": {
|
"annotations": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "annotations of the resource",
|
Description: "annotations of the resource",
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
@@ -566,8 +560,7 @@ func Test_byID(t *testing.T) {
|
|||||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"annotations": {
|
"annotations": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
SubType: "string",
|
|
||||||
Description: "annotations of the resource",
|
Description: "annotations of the resource",
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
package definitions
|
package definitions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/kube-openapi/pkg/util/proto"
|
"k8s.io/kube-openapi/pkg/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,12 +18,12 @@ func (s *schemaFieldVisitor) VisitArray(array *proto.Array) {
|
|||||||
field := definitionField{
|
field := definitionField{
|
||||||
Description: array.GetDescription(),
|
Description: array.GetDescription(),
|
||||||
}
|
}
|
||||||
// this currently is not recursive and provides little information for nested types- while this isn't optimal,
|
// Recursively visit the value subtype
|
||||||
// it was kept this way to provide backwards compat with previous endpoints.
|
subVisitor := &schemaFieldVisitor{definitions: s.definitions}
|
||||||
array.SubType.Accept(s)
|
array.SubType.Accept(subVisitor)
|
||||||
subField := s.field
|
subField := subVisitor.field
|
||||||
field.Type = "array"
|
// Represent the map as "array[<value_type>]"
|
||||||
field.SubType = subField.Type
|
field.Type = fmt.Sprintf("array[%s]", subField.Type)
|
||||||
s.field = field
|
s.field = field
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,12 +33,12 @@ func (s *schemaFieldVisitor) VisitMap(protoMap *proto.Map) {
|
|||||||
field := definitionField{
|
field := definitionField{
|
||||||
Description: protoMap.GetDescription(),
|
Description: protoMap.GetDescription(),
|
||||||
}
|
}
|
||||||
// this currently is not recursive and provides little information for nested types- while this isn't optimal,
|
// Recursively visit the value subtype
|
||||||
// it was kept this way to provide backwards compat with previous endpoints.
|
subVisitor := &schemaFieldVisitor{definitions: s.definitions}
|
||||||
protoMap.SubType.Accept(s)
|
protoMap.SubType.Accept(subVisitor)
|
||||||
subField := s.field
|
subField := subVisitor.field
|
||||||
field.Type = "map"
|
// Represent the map as "map[<value_type>]"
|
||||||
field.SubType = subField.Type
|
field.Type = fmt.Sprintf("map[%s]", subField.Type)
|
||||||
s.field = field
|
s.field = field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,6 +72,18 @@ var (
|
|||||||
Description: "testArbitrary",
|
Description: "testArbitrary",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
protoNestedMap = proto.Map{
|
||||||
|
BaseSchema: proto.BaseSchema{
|
||||||
|
Description: "nestedMap",
|
||||||
|
},
|
||||||
|
SubType: &protoKind,
|
||||||
|
}
|
||||||
|
protoEmpty = proto.Kind{
|
||||||
|
BaseSchema: proto.BaseSchema{
|
||||||
|
Description: "emptySchema",
|
||||||
|
Path: proto.NewPath("io.cattle.empty"),
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSchemaFieldVisitor(t *testing.T) {
|
func TestSchemaFieldVisitor(t *testing.T) {
|
||||||
@@ -87,9 +99,8 @@ func TestSchemaFieldVisitor(t *testing.T) {
|
|||||||
inputSchema: &protoArray,
|
inputSchema: &protoArray,
|
||||||
wantDefinitions: map[string]definition{},
|
wantDefinitions: map[string]definition{},
|
||||||
wantField: definitionField{
|
wantField: definitionField{
|
||||||
Type: "array",
|
Type: "array[string]",
|
||||||
Description: protoArray.Description,
|
Description: protoArray.Description,
|
||||||
SubType: protoPrimitive.Type,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -97,9 +108,8 @@ func TestSchemaFieldVisitor(t *testing.T) {
|
|||||||
inputSchema: &protoMap,
|
inputSchema: &protoMap,
|
||||||
wantDefinitions: map[string]definition{},
|
wantDefinitions: map[string]definition{},
|
||||||
wantField: definitionField{
|
wantField: definitionField{
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
Description: protoMap.Description,
|
Description: protoMap.Description,
|
||||||
SubType: protoPrimitive.Type,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -136,15 +146,13 @@ func TestSchemaFieldVisitor(t *testing.T) {
|
|||||||
protoKind.Path.String(): {
|
protoKind.Path.String(): {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"protoArray": {
|
"protoArray": {
|
||||||
Type: "array",
|
Type: "array[" + protoPrimitive.Type + "]",
|
||||||
Description: protoArray.Description,
|
Description: protoArray.Description,
|
||||||
SubType: protoPrimitive.Type,
|
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
"protoMap": {
|
"protoMap": {
|
||||||
Type: "map",
|
Type: "map[" + protoPrimitive.Type + "]",
|
||||||
Description: protoMap.Description,
|
Description: protoMap.Description,
|
||||||
SubType: protoPrimitive.Type,
|
|
||||||
},
|
},
|
||||||
"protoPrimitive": {
|
"protoPrimitive": {
|
||||||
Type: protoPrimitive.Type,
|
Type: protoPrimitive.Type,
|
||||||
@@ -181,15 +189,13 @@ func TestSchemaFieldVisitor(t *testing.T) {
|
|||||||
protoKind.Path.String(): {
|
protoKind.Path.String(): {
|
||||||
ResourceFields: map[string]definitionField{
|
ResourceFields: map[string]definitionField{
|
||||||
"protoArray": {
|
"protoArray": {
|
||||||
Type: "array",
|
Type: "array[string]",
|
||||||
Description: protoArray.Description,
|
Description: protoArray.Description,
|
||||||
SubType: protoPrimitive.Type,
|
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
"protoMap": {
|
"protoMap": {
|
||||||
Type: "map",
|
Type: "map[string]",
|
||||||
Description: protoMap.Description,
|
Description: protoMap.Description,
|
||||||
SubType: protoPrimitive.Type,
|
|
||||||
},
|
},
|
||||||
"protoPrimitive": {
|
"protoPrimitive": {
|
||||||
Type: protoPrimitive.Type,
|
Type: protoPrimitive.Type,
|
||||||
@@ -219,6 +225,79 @@ func TestSchemaFieldVisitor(t *testing.T) {
|
|||||||
Description: protoArbitrary.Description,
|
Description: protoArbitrary.Description,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "nested map with kind",
|
||||||
|
inputSchema: &protoNestedMap,
|
||||||
|
wantDefinitions: map[string]definition{
|
||||||
|
protoKind.Path.String(): {
|
||||||
|
ResourceFields: map[string]definitionField{
|
||||||
|
"protoArray": {
|
||||||
|
Type: "array[string]",
|
||||||
|
Description: protoArray.Description,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"protoMap": {
|
||||||
|
Type: "map[string]",
|
||||||
|
Description: protoMap.Description,
|
||||||
|
},
|
||||||
|
"protoPrimitive": {
|
||||||
|
Type: protoPrimitive.Type,
|
||||||
|
Description: protoPrimitive.Description,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"protoRef": {
|
||||||
|
Type: protoKind.Path.String(),
|
||||||
|
Description: protoRef.Description,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Type: protoKind.Path.String(),
|
||||||
|
Description: protoKind.Description,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantField: definitionField{
|
||||||
|
Type: "map[io.cattle.test]",
|
||||||
|
Description: protoNestedMap.Description,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multi-level nested maps and arrays",
|
||||||
|
inputSchema: &proto.Map{
|
||||||
|
BaseSchema: proto.BaseSchema{
|
||||||
|
Description: "multi-level nested structure",
|
||||||
|
},
|
||||||
|
SubType: &proto.Array{
|
||||||
|
BaseSchema: proto.BaseSchema{
|
||||||
|
Description: "nested array",
|
||||||
|
},
|
||||||
|
SubType: &proto.Map{
|
||||||
|
BaseSchema: proto.BaseSchema{
|
||||||
|
Description: "deeply nested map",
|
||||||
|
},
|
||||||
|
SubType: &protoPrimitive,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantDefinitions: map[string]definition{},
|
||||||
|
wantField: definitionField{
|
||||||
|
Type: "map[array[map[string]]]",
|
||||||
|
Description: "multi-level nested structure",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty schema",
|
||||||
|
inputSchema: &protoEmpty,
|
||||||
|
wantDefinitions: map[string]definition{
|
||||||
|
"io.cattle.empty": {
|
||||||
|
ResourceFields: map[string]definitionField{},
|
||||||
|
Type: "io.cattle.empty",
|
||||||
|
Description: protoEmpty.Description,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantField: definitionField{
|
||||||
|
Type: "io.cattle.empty",
|
||||||
|
Description: protoEmpty.Description,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
Reference in New Issue
Block a user