Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ resource, which you can apply after installing the Teleport Kubernetes operator.

|Field|Type|Description|
|---|---|---|
|add_labels|[object](#specmappings itemsadd_labels)|AddLabels specifies which labels to add if any of the previous matches match.|
|match|[][object](#specmappings itemsmatch-items)|Match is a set of matching rules for this mapping. If any of these match, then the mapping will be applied.|
|add_labels|[object](#specmappings-itemsadd_labels)|AddLabels specifies which labels to add if any of the previous matches match.|
|match|[][object](#specmappings-itemsmatch-items)|Match is a set of matching rules for this mapping. If any of these match, then the mapping will be applied.|

### spec.mappings items.add_labels

Expand Down
143 changes: 72 additions & 71 deletions integrations/operator/crdgen/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,91 +138,92 @@ const statusDescription = "Status defines the observed state of the Teleport res
const statusName = "status"

func propertyTable(currentFieldName string, props *apiextv1.JSONSchemaProps) ([]PropertyTable, error) {
switch props.Type {
case "object":
tab := PropertyTable{
Name: currentFieldName,
// Only create a property table for an object field. For other types, we can
// describe the type within a table row.
if props.Type != "object" {
return nil, nil
}
tab := PropertyTable{
Name: currentFieldName,
}
fields := []PropertyTableField{}
tables := []PropertyTable{}
var i int
for k, v := range props.Properties {
// Don't document the Status field, which is for
// internal use.
if k == statusName && strings.HasPrefix(v.Description, statusDescription) {
continue
}
// Name the table after the hierarchy of
// field names to avoid duplication.
var tableName string
if currentFieldName != "" {
tableName = currentFieldName + "." + k
} else {
tableName = k
}
fields := []PropertyTableField{}
tables := []PropertyTable{}
var i int
for k, v := range props.Properties {
// Don't document the Status field, which is for
// internal use.
if k == statusName && strings.HasPrefix(v.Description, statusDescription) {
continue
}
// Name the table after the hierarchy of
// field names to avoid duplication.
var tableName string
if currentFieldName != "" {
tableName = currentFieldName + "." + k
} else {
tableName = k
}

var fieldType string
var fieldDesc string
switch v.Type {
case "object":
fieldType = "object"
if len(v.Properties) == 0 {
break
}
var fieldType string
var fieldDesc string
switch v.Type {
case "object":
fieldType = "object"
if len(v.Properties) == 0 {
break
}

extra, err := propertyTable(
tableName,
&v,
)
if err != nil {
return nil, err
}
fieldType = fmt.Sprintf("[object](#%v)", strings.ReplaceAll(strings.ReplaceAll(tableName, ".", ""), " ", "-"))
tables = append(tables, extra...)
case "array":
var subtp string
if v.Items.Schema.Type == "object" {
extra, err := propertyTable(
tableName,
&v,
fmt.Sprintf("%v items", tableName),
v.Items.Schema,
)
if err != nil {
return nil, err
}
fieldType = fmt.Sprintf("[object](#%v)", strings.ReplaceAll(tableName, ".", ""))
tables = append(tables, extra...)
case "array":
var subtp string
if v.Items.Schema.Type == "object" {
extra, err := propertyTable(
fmt.Sprintf("%v items", tableName),
v.Items.Schema,
)
if err != nil {
return nil, err
}
tables = append(tables, extra...)
subtp = fmt.Sprintf("[object](#%v-items)", strings.ReplaceAll(tableName, ".", ""))
} else {
subtp = v.Items.Schema.Type
}
fieldType = fmt.Sprintf("[]%v", subtp)
case "":
if !v.XIntOrString {
fieldType = v.Type
break
}
fieldType = "string or integer"
fieldDesc = strings.TrimSuffix(v.Description, ".") + ". " + "Can be either the string or the integer representation of each option."
default:
fieldType = v.Type
subtp = fmt.Sprintf("[object](#%v-items)", strings.ReplaceAll(strings.ReplaceAll(tableName, ".", ""), " ", "-"))
} else {
subtp = v.Items.Schema.Type
}

if fieldDesc == "" {
fieldDesc = v.Description
fieldType = fmt.Sprintf("[]%v", subtp)
case "":
if !v.XIntOrString {
fieldType = v.Type
break
}
fieldType = "string or integer"
fieldDesc = strings.TrimSuffix(v.Description, ".") + ". " + "Can be either the string or the integer representation of each option."
default:
fieldType = v.Type
}

fields = append(fields, PropertyTableField{
Name: k,
Type: fieldType,
Description: fieldDesc,
})
i++
if fieldDesc == "" {
fieldDesc = v.Description
}
tab.Fields = fields
sort.Sort(tab)
tables = append([]PropertyTable{tab}, tables...)
return tables, nil

fields = append(fields, PropertyTableField{
Name: k,
Type: fieldType,
Description: fieldDesc,
})
i++
}
return nil, nil
tab.Fields = fields
sort.Sort(tab)
tables = append([]PropertyTable{tab}, tables...)
return tables, nil
}

func formatAsDocsPage(crd apiextv1.CustomResourceDefinition) ([]byte, string, error) {
Expand Down
67 changes: 67 additions & 0 deletions integrations/operator/crdgen/handlerequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,73 @@ state of this API Resource.\n---\nThis struct is intended for direct use as an a
},
},
},
{
description: "array of objects with object field",
input: apiextv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextv1.JSONSchemaProps{
"mappings": apiextv1.JSONSchemaProps{
Type: "array",
Description: "Mappings is a list of matches that will map match conditions to labels.",
Items: &apiextv1.JSONSchemaPropsOrArray{
Schema: &apiextv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextv1.JSONSchemaProps{
"add_labels": apiextv1.JSONSchemaProps{
Type: "object",
Description: "AddLabels specifies which labels to add if any of the previous matches match.",
Nullable: true,
Properties: map[string]apiextv1.JSONSchemaProps{
"key": apiextv1.JSONSchemaProps{
Type: "string",
},
"value": apiextv1.JSONSchemaProps{
Type: "string",
},
},
},
},
},
},
},
},
},
expected: []PropertyTable{
{
Name: "",
Fields: []PropertyTableField{
{
Name: "mappings",
Type: "[][object](#mappings-items)",
Description: "Mappings is a list of matches that will map match conditions to labels.",
},
},
},
{
Name: "mappings items",
Fields: []PropertyTableField{
{
Name: "add_labels",
Type: "[object](#mappings-itemsadd_labels)",
Description: "AddLabels specifies which labels to add if any of the previous matches match.",
},
},
},
{
Name: "mappings items.add_labels",
Fields: []PropertyTableField{
{
Name: "key",
Type: "string",
},
{
Name: "value",
Type: "string",
},
},
},
},
},
}

for _, c := range cases {
Expand Down