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
20 changes: 13 additions & 7 deletions build.assets/tooling/cmd/resource-ref-generator/config.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
source: "../../../../api"
destination: "../../../../docs/pages/reference/infrastructure-as-code/teleport-resources"

# Please alphabetize the resource list by type name.
resources:
- type: "InstallerV1"
- type: DiscoveryConfig
package: discoveryconfig
yaml_kind: discovery_config
yaml_version: v1
- type: InstallerV1
package: types
yaml_kind: "installer"
yaml_version: "v1"
yaml_kind: installer
yaml_version: v1
- type: OIDCConnectorV3
package: types
yaml_kind: "oidc"
yaml_version: "v3"
yaml_kind: oidc
yaml_version: v3
- type: SAMLConnectorV2
package: types
yaml_kind: "saml"
yaml_version: "v2"
yaml_kind: saml
yaml_version: v2

Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ func NewSourceData(rootPath string) (SourceData, error) {
// information about dynamic resource fields, which we can look up by
// package and declaration name.
typeDecls := make(map[PackageInfo]DeclarationInfo)
possibleFuncDecls := []DeclarationInfo{}

// Load each file in the source directory individually. Not using
// packages.Load here since the resulting []*Package does not expose
Expand Down Expand Up @@ -128,15 +127,8 @@ func NewSourceData(rootPath string) (SourceData, error) {
// - Type declarations
pn := NamedImports(file)
for _, decl := range file.Decls {
di := DeclarationInfo{
Decl: decl,
FilePath: relDeclPath,
PackageName: file.Name.Name,
NamedImports: pn,
}
l, ok := decl.(*ast.GenDecl)
if !ok {
possibleFuncDecls = append(possibleFuncDecls, di)
continue
}
if len(l.Specs) != 1 {
Expand Down Expand Up @@ -390,10 +382,10 @@ func (e NotAGenDeclError) Error() string {
return "the declaration is not a GenDecl"
}

// getRawTypes returns a representation of the type spec of decl to use for
// typeForDecl returns a representation of the type spec of decl to use for
// further processing. Returns an error if there is either no type spec or more
// than one.
func getRawTypes(decl DeclarationInfo, allDecls map[PackageInfo]DeclarationInfo) (rawType, error) {
func typeForDecl(decl DeclarationInfo, allDecls map[PackageInfo]DeclarationInfo) (rawType, error) {
gendecl, ok := decl.Decl.(*ast.GenDecl)
if !ok {
return rawType{}, NotAGenDeclError{}
Expand Down Expand Up @@ -734,12 +726,12 @@ func printableDescription(description, ident string) string {
return result
}

// handleEmbeddedStructFields finds embedded structs within fld and recursively
// allFieldsForDecl finds embedded structs within fld and recursively
// processes the fields of those structs as though the fields belonged to the
// containing struct. Uses decl and allDecls to look up fields within the base
// structs. Returns a modified slice of fields that include all non-embedded
// fields within fld.
func handleEmbeddedStructFields(decl DeclarationInfo, fld []rawField, allDecls map[PackageInfo]DeclarationInfo) ([]rawField, error) {
func allFieldsForDecl(decl DeclarationInfo, fld []rawField, allDecls map[PackageInfo]DeclarationInfo) ([]rawField, error) {
fieldsToProcess := []rawField{}
for _, l := range fld {
// Not an embedded struct field, so append it to the final
Expand Down Expand Up @@ -787,14 +779,14 @@ func handleEmbeddedStructFields(decl DeclarationInfo, fld []rawField, allDecls m
c.name,
)
}
e, err := getRawTypes(d, allDecls)
e, err := typeForDecl(d, allDecls)
if err != nil && !errors.As(err, &NotAGenDeclError{}) {
return nil, err
}

// The embedded struct field may have its own embedded struct
// fields.
nf, err := handleEmbeddedStructFields(decl, e.fields, allDecls)
nf, err := allFieldsForDecl(decl, e.fields, allDecls)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -827,12 +819,12 @@ func NamedImports(file *ast.File) map[string]string {
// ReferenceDataFromDeclaration gets data for the reference by examining decl.
// Looks up decl's fields in allDecls and methods in allMethods.
func ReferenceDataFromDeclaration(decl DeclarationInfo, allDecls map[PackageInfo]DeclarationInfo) (map[PackageInfo]ReferenceEntry, error) {
rs, err := getRawTypes(decl, allDecls)
rs, err := typeForDecl(decl, allDecls)
if err != nil {
return nil, err
}

fieldsToProcess, err := handleEmbeddedStructFields(decl, rs.fields, allDecls)
fieldsToProcess, err := allFieldsForDecl(decl, rs.fields, allDecls)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -872,7 +864,7 @@ func ReferenceDataFromDeclaration(decl DeclarationInfo, allDecls map[PackageInfo
// For any fields within decl that have a custom type, look up the
// declaration for that type and create a separate reference entry for
// it.
for _, f := range rs.fields {
for _, f := range fieldsToProcess {
// Don't make separate reference entries for embedded structs
// since they are part of the containing struct for the purposes
// of unmarshaling YAML.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,85 @@ type Metadata struct {
YAMLExample: `alias: "string"
name: "string"
active: true
`,
},
},
},
{
description: "embedded struct with struct field",
declInfo: PackageInfo{
DeclName: "MyResource",
PackageName: "mypkg",
},
source: `package mypkg
// MyResource is a resource declared for testing.
type MyResource struct{
// Alias is another name to call the resource.
Alias string BACKTICKjson:"alias"BACKTICK
types.Header
}
`,
declSources: []string{
`package types
type Header struct {
// Metadata is the resource metadata
Metadata Metadata BACKTICKjson:"metadata"BACKTICK
}

// Metadata describes information about a dynamic resource. Every dynamic
// resource in Teleport has a metadata object.
type Metadata struct {
// Name is the name of the resource.
Name string BACKTICKprotobuf:"bytes,1,opt,name=Name,proto3" json:"name"BACKTICK
// Active indicates whether the resource is currently in use.
Active bool BACKTICKjson:"active"BACKTICK
}`,
},
expected: map[PackageInfo]ReferenceEntry{
PackageInfo{
DeclName: "MyResource",
PackageName: "mypkg",
}: {
SectionName: "My Resource",
Description: "A resource declared for testing.",
SourcePath: "src/myfile.go",
Fields: []Field{
{
Name: "alias",
Description: "Another name to call the resource.",
Type: "string",
},
{
Name: "metadata",
Description: "The resource metadata",
Type: "[Metadata](#metadata)",
},
},
YAMLExample: `alias: "string"
metadata: # [...]
`,
},
PackageInfo{
DeclName: "Metadata",
PackageName: "types",
}: {
SectionName: "Metadata",
SourcePath: "src/myfile0.go",
Description: "Describes information about a dynamic resource. Every dynamic resource in Teleport has a metadata object.",
Fields: []Field{
{
Name: "active",
Description: "Indicates whether the resource is currently in use.",
Type: "Boolean",
},
{
Name: "name",
Description: "The name of the resource.",
Type: "string",
},
},
YAMLExample: `name: "string"
active: true
`,
},
},
Expand Down
Loading
Loading