Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

importer-rest-api-specs - Add Schema and Documentation Overrides #3610

Merged
merged 14 commits into from
Jan 16, 2024
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
8 changes: 4 additions & 4 deletions tools/data-api-differ/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ Example output:

The following new Static Identifiers were detected from the set of changes (new/updated Resource IDs).

> Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.
> ⚠️ Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.

Please review the following list of Static Identifiers:

Expand All @@ -197,7 +197,7 @@ Please review the following list of Static Identifiers:

---

> Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.
> ⚠️ Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.
```

Example of the Markdown Comment (rendered as Markdown):
Expand All @@ -207,7 +207,7 @@ Example of the Markdown Comment (rendered as Markdown):

The following new Static Identifiers were detected from the set of changes (new/updated Resource IDs).

> Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.
> ⚠️ Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.

Please review the following list of Static Identifiers:

Expand All @@ -222,5 +222,5 @@ Please review the following list of Static Identifiers:

---

> Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.
> ⚠️ Note: Resource ID segments should **always** be `camelCased` and not `TitleCased`, `lowercased` or `kebab-cased`.
```
4 changes: 2 additions & 2 deletions tools/data-api-differ/internal/views/resource_id_segments.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ No new Resource ID Segments containing Static Identifiers were identified in the

The following new Static Identifiers were detected from the set of changes (new/updated Resource IDs).

> Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
> ⚠️ Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.

Please review the following list of Static Identifiers:

Expand All @@ -82,7 +82,7 @@ Please review the following list of Static Identifiers:

---

> Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
> ⚠️ Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
`, strings.Join(lines, "\n"))
output = strings.ReplaceAll(output, "'", "`")
//TODO: add a "see the link for how to fix this" to the comment above when the associated documentation is available
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestResourceIdSegmentsView_Markdown_WithChanges(t *testing.T) {

The following new Static Identifiers were detected from the set of changes (new/updated Resource IDs).

> Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
> ⚠️ Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.

Please review the following list of Static Identifiers:

Expand All @@ -70,7 +70,7 @@ Please review the following list of Static Identifiers:

---

> Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
> ⚠️ Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
`, "'", "`")
testhelpers.AssertTemplatedCodeMatches(t, expected, *actual)
}
Expand Down Expand Up @@ -148,7 +148,7 @@ func TestResourceIdSegmentsView_Markdown_WithRelevantAndIrrelevantChanges(t *tes

The following new Static Identifiers were detected from the set of changes (new/updated Resource IDs).

> Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
> ⚠️ Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.

Please review the following list of Static Identifiers:

Expand All @@ -162,7 +162,7 @@ Please review the following list of Static Identifiers:

---

> Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
> ⚠️ Note: Resource ID segments should **always** be 'camelCased' and not 'TitleCased', 'lowercased' or 'kebab-cased'.
`, "'", "`")
testhelpers.AssertTemplatedCodeMatches(t, expected, *actual)
}
11 changes: 11 additions & 0 deletions tools/generator-terraform/generator/mappings/assignments.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ func (m *Mappings) SchemaModelToSdkModelAssignmentLine(mappings []resourcemanage
}
}

if field, ok := sdkModel.Fields[mapping.ModelToModel.SdkFieldName]; ok {
if field.ObjectDefinition.Type == resourcemanager.RawObjectApiObjectDefinitionType {
continue
}
}

assignmentLine, err := assignment.assignmentForCreateUpdateMapping(mapping, schemaModel, sdkModel, sdkConstant, m.apiResourcePackageName)
if err != nil {
return nil, fmt.Errorf("building create/update assignment line for assignment type %q (Mapping %q): %+v", string(mapping.Type), mapping.String(), err)
Expand Down Expand Up @@ -172,6 +178,11 @@ func (m *Mappings) SdkModelToSchemaModelAssignmentLine(mappings []resourcemanage
}
}

if field, ok := sdkModel.Fields[mapping.ModelToModel.SdkFieldName]; ok {
if field.ObjectDefinition.Type == resourcemanager.RawObjectApiObjectDefinitionType {
continue
}
}
assignmentLine, err := assignment.assignmentForReadMapping(mapping, schemaModel, sdkModel, sdkConstant, m.apiResourcePackageName)
if err != nil {
return nil, fmt.Errorf("building read assignment line for constant assignment type %q: %+v", mapping.Type, err)
Expand Down
3 changes: 2 additions & 1 deletion tools/importer-rest-api-specs/cmd/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/resources"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/schema"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
"github.com/hashicorp/pandora/tools/sdk/config/definitions"
"github.com/hashicorp/pandora/tools/sdk/resourcemanager"
"github.com/hashicorp/pandora/tools/sdk/services"
Expand Down Expand Up @@ -127,7 +128,7 @@ func run(input Input) error {

for resourceName, resource := range candidates.Resources {
logger.Trace(fmt.Sprintf("Found Resource %q..", resourceName))
schemaDefinition, mappings, err := builder.Build(resource, logger.Named(fmt.Sprintf("Resource %q", resourceName)))
schemaDefinition, mappings, err := builder.Build(resource, &models.ResourceBuildInfo{}, logger.Named(fmt.Sprintf("Resource %q", resourceName)))
if err != nil {
return fmt.Errorf("processing schema for candidate %s: %+v", resourceName, err)
}
Expand Down
22 changes: 22 additions & 0 deletions tools/importer-rest-api-specs/components/helpers/title_case.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package helpers

import (
"unicode"
)

func ConvertFromSnakeToTitleCase(input string) string {
output := make([]rune, 0)

for k, v := range input {
if v == '_' {
continue
}
if k == 0 || (k > 0 && input[k-1] == '_') {
output = append(output, unicode.ToUpper(v))
continue
}
output = append(output, v)
}

return string(output)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package helpers

import "testing"

func TestConvertFromSnakeToTitleCase(t *testing.T) {
testData := []struct {
input string
expected string
}{
{
input: "oh_lawd_he_coming",
expected: "OhLawdHeComing",
},
{
input: "dns_name",
expected: "DnsName",
},
{
input: "ThisIsAlreadyTitleCased",
expected: "ThisIsAlreadyTitleCased",
},
{
input: "1_2_3_4",
expected: "1234",
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %s", v.input)
actual := ConvertFromSnakeToTitleCase(v.input)
if actual != v.expected {
t.Fatalf("Expected %s but got %s", v.expected, actual)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
"github.com/hashicorp/pandora/tools/sdk/resourcemanager"
)

Expand Down Expand Up @@ -335,7 +336,9 @@ func TestBuildForChaosStudioExperimentWithRealData(t *testing.T) {
SchemaModelName: "Experiment",
}

actualModels, actualMappings, err := builder.Build(input, hclog.New(hclog.DefaultOptions))
var inputResourceBuildInfo *models.ResourceBuildInfo

actualModels, actualMappings, err := builder.Build(input, inputResourceBuildInfo, hclog.New(hclog.DefaultOptions))
if err != nil {
t.Errorf("building schema: %+v", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
"github.com/hashicorp/pandora/tools/sdk/resourcemanager"
)

Expand Down Expand Up @@ -145,7 +146,10 @@ func TestBuildForResourceGroupHappyPathAllModelsTheSame(t *testing.T) {
TimeoutInMinutes: 30,
},
}
actualModels, actualMappings, err := builder.Build(input, hclog.New(hclog.DefaultOptions))

var inputResourceBuildInfo *models.ResourceBuildInfo

actualModels, actualMappings, err := builder.Build(input, inputResourceBuildInfo, hclog.New(hclog.DefaultOptions))
if err != nil {
t.Fatalf("building schema: %+v", err)
}
Expand Down Expand Up @@ -345,7 +349,10 @@ func TestBuildForResourceGroupUsingRealData(t *testing.T) {
TimeoutInMinutes: 30,
},
}
actualModels, actualMappings, err := builder.Build(input, hclog.New(hclog.DefaultOptions))

var inputResourceBuildInfo *models.ResourceBuildInfo

actualModels, actualMappings, err := builder.Build(input, inputResourceBuildInfo, hclog.New(hclog.DefaultOptions))
if err != nil {
t.Fatalf("building schema: %+v", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
"github.com/hashicorp/pandora/tools/sdk/resourcemanager"
)

Expand Down Expand Up @@ -520,7 +521,9 @@ func TestBuildForSearchServiceUsingRealData(t *testing.T) {
},
}

actualModels, actualMappings, err := builder.Build(input, hclog.New(hclog.DefaultOptions))
var inputResourceBuildInfo *models.ResourceBuildInfo

actualModels, actualMappings, err := builder.Build(input, inputResourceBuildInfo, hclog.New(hclog.DefaultOptions))
if err != nil {
t.Fatalf("building schema: %+v", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
"github.com/hashicorp/pandora/tools/sdk/resourcemanager"
)

Expand Down Expand Up @@ -237,7 +238,10 @@ func TestBuildForServiceBusNamespaceHappyPath(t *testing.T) {
TimeoutInMinutes: 30,
},
}
actualModels, actualMappings, err := builder.Build(input, hclog.New(hclog.DefaultOptions))

var inputResourceBuildInfo *models.ResourceBuildInfo

actualModels, actualMappings, err := builder.Build(input, inputResourceBuildInfo, hclog.New(hclog.DefaultOptions))
if err != nil {
t.Errorf("building schema: %+v", err)
}
Expand Down Expand Up @@ -965,7 +969,10 @@ func TestBuildForServiceBusNamespaceUsingRealData(t *testing.T) {
TimeoutInMinutes: 30,
},
}
actualModels, actualMappings, err := builder.Build(input, hclog.New(hclog.DefaultOptions))

var inputResourceBuildInfo *models.ResourceBuildInfo

actualModels, actualMappings, err := builder.Build(input, inputResourceBuildInfo, hclog.New(hclog.DefaultOptions))
if err != nil {
t.Fatalf("building schema: %+v", err)
}
Expand Down
18 changes: 9 additions & 9 deletions tools/importer-rest-api-specs/components/schema/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package schema

import (
"fmt"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/helpers"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/schema/processors"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
"github.com/hashicorp/pandora/tools/sdk/resourcemanager"
)

Expand Down Expand Up @@ -35,13 +35,13 @@ func NewBuilder(constants map[string]resourcemanager.ConstantDetails, models map
}

// Build produces a map of TerraformSchemaModelDefinitions which comprise the Schema for this Resource
func (b Builder) Build(input resourcemanager.TerraformResourceDetails, logger hclog.Logger) (*map[string]resourcemanager.TerraformSchemaModelDefinition, *resourcemanager.MappingDefinition, error) {
func (b Builder) Build(input resourcemanager.TerraformResourceDetails, resourceBuildInfo *models.ResourceBuildInfo, logger hclog.Logger) (*map[string]resourcemanager.TerraformSchemaModelDefinition, *resourcemanager.MappingDefinition, error) {
mappings := resourcemanager.MappingDefinition{
Fields: []resourcemanager.FieldMappingDefinition{},
ResourceId: []resourcemanager.ResourceIdMappingDefinition{},
}

parsedTopLevelModel, err := b.schemaFromTopLevelModel(input, &mappings, logger.Named("top level model"))
parsedTopLevelModel, err := b.schemaFromTopLevelModel(input, &mappings, resourceBuildInfo, logger.Named("top level model"))
if err != nil {
return nil, nil, fmt.Errorf("building schema from top level model: %+v", err)
}
Expand All @@ -66,7 +66,7 @@ func (b Builder) Build(input resourcemanager.TerraformResourceDetails, logger hc
// models should be prefixed with the resource name to avoid conflicts where a model is reused across a package
// for example `VirtualMachineAdditionalCapabilitiesSchema`
prefixedModelName := fmt.Sprintf("%s%s", input.SchemaModelName, modelName)
nestedModelDetails, updatedMappings, err := b.buildNestedModelDefinition(prefixedModelName, input.SchemaModelName, modelName, modelDetails, input, mappings, logger.Named(fmt.Sprintf("Nested Model Definition %q", modelName)))
nestedModelDetails, updatedMappings, err := b.buildNestedModelDefinition(prefixedModelName, input.SchemaModelName, modelName, modelDetails, input, mappings, resourceBuildInfo, logger.Named(fmt.Sprintf("Nested Model Definition %q", modelName)))
if err != nil {
return nil, nil, fmt.Errorf("building model definition for nested model %q: %+v", modelName, err)
}
Expand Down Expand Up @@ -247,7 +247,7 @@ type modelParseResult struct {
nestedModels map[string]resourcemanager.ModelDetails
}

func (b Builder) schemaFromTopLevelModel(input resourcemanager.TerraformResourceDetails, mappings *resourcemanager.MappingDefinition, logger hclog.Logger) (*modelParseResult, error) {
func (b Builder) schemaFromTopLevelModel(input resourcemanager.TerraformResourceDetails, mappings *resourcemanager.MappingDefinition, resourceBuildInfo *models.ResourceBuildInfo, logger hclog.Logger) (*modelParseResult, error) {
createReadUpdateMethods, err := b.findCreateUpdateReadPayloads(input)
if err != nil {
return nil, fmt.Errorf("finding create/update/read payloads: %+v", err)
Expand All @@ -269,15 +269,15 @@ func (b Builder) schemaFromTopLevelModel(input resourcemanager.TerraformResource
if !ok {
return nil, fmt.Errorf("couldn't find Resource ID named %q", input.ResourceIdName)
}
fieldsWithinResourceId, mappings, err := b.identifyTopLevelFieldsWithinResourceID(resourceId, mappings, input.DisplayName, logger.Named("TopLevelFields ResourceID"))
fieldsWithinResourceId, mappings, err := b.identifyTopLevelFieldsWithinResourceID(resourceId, mappings, input.DisplayName, resourceBuildInfo, logger.Named("TopLevelFields ResourceID"))
if err != nil {
return nil, fmt.Errorf("identifying top level fields within Resource ID %q: %+v", resourceId.Id, err)
}
for k, v := range *fieldsWithinResourceId {
schemaFields[k] = v
}

fieldsWithinProperties, mappings, err := b.identifyFieldsWithinPropertiesBlock(input.SchemaModelName, *createReadUpdateMethods, &input, mappings, logger.Named("TopLevelFields PropertiesFields"))
fieldsWithinProperties, mappings, err := b.identifyFieldsWithinPropertiesBlock(input.SchemaModelName, *createReadUpdateMethods, &input, mappings, resourceBuildInfo, logger.Named("TopLevelFields PropertiesFields"))
if err != nil {
return nil, fmt.Errorf("parsing fields within the `properties` block for the create/read/update methods: %+v", err)
}
Expand Down Expand Up @@ -434,7 +434,7 @@ func (b Builder) findCreateUpdateReadPayloads(input resourcemanager.TerraformRes
return &out, nil
}

func (b Builder) buildNestedModelDefinition(schemaModelName, topLevelModelName, sdkModelName string, model resourcemanager.ModelDetails, details resourcemanager.TerraformResourceDetails, mappings resourcemanager.MappingDefinition, logger hclog.Logger) (*resourcemanager.TerraformSchemaModelDefinition, *resourcemanager.MappingDefinition, error) {
func (b Builder) buildNestedModelDefinition(schemaModelName, topLevelModelName, sdkModelName string, model resourcemanager.ModelDetails, details resourcemanager.TerraformResourceDetails, mappings resourcemanager.MappingDefinition, resourceBuildInfo *models.ResourceBuildInfo, logger hclog.Logger) (*resourcemanager.TerraformSchemaModelDefinition, *resourcemanager.MappingDefinition, error) {
out := make(map[string]resourcemanager.TerraformSchemaFieldDefinition, 0)

for sdkFieldName, sdkField := range model.Fields {
Expand Down Expand Up @@ -462,7 +462,7 @@ func (b Builder) buildNestedModelDefinition(schemaModelName, topLevelModelName,
return nil, nil, fmt.Errorf("converting ObjectDefinition for field to a TerraformFieldObjectDefinition: %+v", err)
}
definition.ObjectDefinition = *fieldObjectDefinition
schemaFieldName, err := updateFieldName(sdkFieldName, &model, &details, b.constants)
schemaFieldName, err := updateFieldName(sdkFieldName, &model, &details, b.constants, resourceBuildInfo)
if err != nil {
return nil, nil, err
}
Expand Down
Loading
Loading