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

tools/importer-rest-api-specs: refactoring the Parser package #4307

Merged
merged 58 commits into from
Oct 9, 2024
Merged
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
f255687
`tools/importer-rest-api-specs`: refactoring the `commonschema` Match…
tombuildsstuff Jul 4, 2024
0d1ab7f
`tools/importer-rest-api-specs`: refactoring the Constant package
tombuildsstuff Jul 4, 2024
33321b6
`tools/importer-rest-api-specs`: porting the Network workaround into …
tombuildsstuff Jul 5, 2024
5eea5fe
`tools/importer-rest-api-specs`: porting the `dataworkarounds` packag…
tombuildsstuff Jul 5, 2024
bcb98ac
`tools/importer-rest-api-specs`: scaffolding out the logic to parse a…
tombuildsstuff Jul 5, 2024
fdd6a18
`tools/importer-rest-api-specs`: porting over the "remove unused item…
tombuildsstuff Jul 5, 2024
d86c9be
`tools/importer-rest-api-specs`: adding a shim to the updated `datawo…
tombuildsstuff Jul 5, 2024
dc3da36
dependencies: updating to `v0.69.0` of `github.com/hashicorp/go-azure…
tombuildsstuff Jul 5, 2024
f315a58
`tools/importer-rest-api-specs`: refactoring the `normalization` pack…
tombuildsstuff Jul 5, 2024
4fc8d23
`tools/importer-rest-api-specs`: moving all of the `cleanup` items in…
tombuildsstuff Jul 5, 2024
2238e45
`tools/importer-rest-api-specs`: adding inner most sdk operation obje…
tombuildsstuff Jul 5, 2024
868c6be
`tools/importer-rest-api-specs`: moving the `commonids` into a subpac…
tombuildsstuff Jul 5, 2024
f316c93
`tools/data-api-sdk`: removing an empty todo file
tombuildsstuff Jul 5, 2024
5421539
`tools/importer-rest-api-specs`: refactoring more logic out to the ne…
tombuildsstuff Jul 5, 2024
022aa27
`tools/importer-rest-api-specs`: moving another `ignore` function
tombuildsstuff Jul 5, 2024
7da937c
WIP
tombuildsstuff Jul 9, 2024
9041a95
tools/importer-rest-api-specs: reimplementing #4290 atop the rebase
tombuildsstuff Jul 10, 2024
5ac3c6b
`tools/importer-rest-api-specs`: adding a placeholder for parsing an …
tombuildsstuff Jul 10, 2024
1c24bf8
`tools/importer-rest-api-specs`: refactoring the parser into smaller …
tombuildsstuff Jul 12, 2024
2a0a72a
`tools/importer-rest-api-specs`: fixing an issue where the `validate`…
tombuildsstuff Jul 12, 2024
1f89c95
`tools/importer-rest-api-specs`: title-casing the ReferenceName - whi…
tombuildsstuff Jul 12, 2024
1c27957
`tools/importer-rest-api-specs`: ensuring that TypeSpec examples are …
tombuildsstuff Jul 12, 2024
e19ecbc
`tools/importer-rest-api-specs`: trimming `*.json` from the filename …
tombuildsstuff Jul 12, 2024
84e3913
`tools/importer-rest-api-specs`: removing (most) of the old code path
tombuildsstuff Jul 12, 2024
41b548a
`tools/data-api-sdk`: making IsCommonType required so this is more ex…
tombuildsstuff Jul 12, 2024
61de948
`tools/importer-rest-api-specs`: fixing the validation
tombuildsstuff Jul 12, 2024
b05c0cf
`tools/importer-rest-api-specs`: re-enabling most of the tests
tombuildsstuff Jul 12, 2024
b77acef
`tools/importer-rest-api-specs`: consolidating/porting over the data …
tombuildsstuff Jul 15, 2024
58f5bae
`tools/importer-rest-api-specs`: fixing the test format
tombuildsstuff Jul 15, 2024
fe98217
tools/importer-rest-api-specs: skipping the local test
tombuildsstuff Jul 15, 2024
26268db
`tools/importer-rest-api-specs`: fixing the non-discriminator tests
tombuildsstuff Jul 15, 2024
9643f43
`tools/importer-rest-api-specs`: updating/reworking the supplementary…
tombuildsstuff Jul 15, 2024
898d028
`importer-rest-api-specs`: fix up discriminator handling for datafactory
manicminer Jul 17, 2024
4412616
`importer-rest-api-specs`: shelve SupplementaryData support for now, …
manicminer Jul 17, 2024
8526060
`importer-rest-api-specs`: implement `-services` argument
manicminer Jul 17, 2024
b585e84
`importer-rest-api-specs`: operate on maps instead of passing them ar…
manicminer Jul 17, 2024
6507fde
`importer-rest-api-specs`: normalize swagger tag names to prevent dup…
manicminer Jul 18, 2024
170e490
`importer-rest-api-specs`: normalize API resources after parsing all …
manicminer Jul 18, 2024
42b4244
`importer-rest-api-specs`: ensure new APIResource is populated
manicminer Jul 18, 2024
9d49558
`importer-rest-api-specs`: maps are pointers
manicminer Jul 19, 2024
dccc285
`importer-rest-api-specs`: dereference more maps
manicminer Jul 19, 2024
cc8d566
`importer-rest-api-specs`: remove use of strings.Title, dereference m…
manicminer Jul 19, 2024
0c29e2b
limit scope of SDK generation test to the SDK being tested
manicminer Jul 19, 2024
6af799d
`importer-rest-api-specs`: two loops become one
manicminer Jul 19, 2024
be21531
`importer-rest-api-specs`: workaround inconsistent casing of "Virtual…
manicminer Jul 19, 2024
530ffaf
Revert "`importer-rest-api-specs`: two loops become one"
manicminer Jul 19, 2024
5422698
`importer-rest-api-specs`: normalize "attachednetworks" segment of re…
manicminer Jul 19, 2024
a96d443
Revert "`tools/data-api-sdk`: making IsCommonType required so this is…
manicminer Sep 25, 2024
eaa8229
importer-rest-api-specs: use updated forks for `go-openapi/analysis`,…
manicminer Oct 1, 2024
ef8b51d
importer-rest-api-specs: remove Supplementary Data parser as is not u…
manicminer Oct 1, 2024
bb6631c
importer-rest-api-specs: rework the swagger spec parser and manually …
manicminer Oct 1, 2024
2d11e96
importer-rest-api-specs: fix format string, ensure model names are UR…
manicminer Oct 1, 2024
dbcf1ab
importer-rest-api-specs: updated tests for discriminated models to ex…
manicminer Oct 1, 2024
8fc6c76
importer-rest-api-specs: remove vestiges of supplementary data spike
manicminer Oct 1, 2024
4921b5c
importer-rest-api-specs: do not set the description, see https://gith…
manicminer Oct 1, 2024
a5c820f
importer-rest-api-specs: hack for conflicting constant names in the s…
manicminer Oct 1, 2024
1da6920
importer-rest-api-specs: disable check for non-default Resource Provi…
manicminer Oct 1, 2024
975945b
upper case URL in the go sdk
stephybun Oct 9, 2024
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
Prev Previous commit
Next Next commit
tools/importer-rest-api-specs: refactoring the normalization pack…
…age into the new structure
tombuildsstuff authored and stephybun committed Oct 9, 2024
commit f315a5884edbb22b56820bf6e075c76b11ab7c25
Original file line number Diff line number Diff line change
@@ -7,8 +7,10 @@ import (
"fmt"
"strings"

sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/dataworkarounds"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/resourceids"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/cleanup"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/logging"
importerModels "github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
)
@@ -92,7 +94,16 @@ func LoadAndParseFiles(directory string, fileNames []string, serviceName, apiVer
out = *output

for _, service := range out {
service.Resources = removeUnusedItems(service.Resources)
// temporary shim to enable using the new logic
version := sdkModels.APIVersion{
APIVersion: service.ApiVersion,
Generate: true,
Preview: service.IsPreviewVersion(),
Resources: service.Resources,
Source: sdkModels.AzureRestAPISpecsSourceDataOrigin,
}
version = cleanup.RemoveUnusedItems(version)
service.Resources = version.Resources
}

if len(out) > 1 {
49 changes: 0 additions & 49 deletions tools/importer-rest-api-specs/components/parser/normalization.go

This file was deleted.

7 changes: 4 additions & 3 deletions tools/importer-rest-api-specs/components/parser/operations.go
Original file line number Diff line number Diff line change
@@ -11,9 +11,10 @@ import (

"github.com/go-openapi/spec"
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/cleanup"
legacyCleanup "github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/cleanup"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/internal"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/resourceids"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/cleanup"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/constants"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/logging"
)
@@ -350,7 +351,7 @@ func (p operationsParser) optionsForOperation(input parsedOperation) (*map[strin

if strings.EqualFold(param.In, "header") || strings.EqualFold(param.In, "query") {
val := param.Name
name := cleanup.NormalizeName(val)
name := legacyCleanup.NormalizeName(val)

option := sdkModels.SDKOperationOption{
Required: param.Required,
@@ -537,7 +538,7 @@ func (d *SwaggerDefinition) findOperationsMatchingTag(tag *string) *[]parsedOper
continue
}

operationName := normalizeOperationName(operationDetails.ID, tag)
operationName := cleanup.NormalizeOperationName(operationDetails.ID, tag)
result = append(result, parsedOperation{
name: operationName,
uri: uri,
21 changes: 11 additions & 10 deletions tools/importer-rest-api-specs/components/parser/parser.go
Original file line number Diff line number Diff line change
@@ -10,8 +10,9 @@ import (
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/pandora/tools/data-api-sdk/v1/helpers"
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/cleanup"
legacyCleanup "github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/cleanup"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/resourceids"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/cleanup"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/logging"
importerModels "github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
)
@@ -33,8 +34,8 @@ func (d *SwaggerDefinition) parse(serviceName, apiVersion string, resourceProvid

if resource != nil {
logging.Tracef("The Tag %q has %d API Operations", tag, len(resource.Operations))
normalizedTag := normalizeTag(tag)
normalizedTag = cleanup.NormalizeResourceName(normalizedTag)
normalizedTag := cleanup.NormalizeTag(tag)
normalizedTag = legacyCleanup.NormalizeResourceName(normalizedTag)
resources[normalizedTag] = *resource
}
}
@@ -48,11 +49,11 @@ func (d *SwaggerDefinition) parse(serviceName, apiVersion string, resourceProvid

// Since we're dealing with missing tag data in the swagger, we'll assume the proper tag name here is the file name
// This is less than ideal, but _should_ be fine.
inferredTag := cleanup.PluraliseName(d.Name)
inferredTag := legacyCleanup.PluraliseName(d.Name)

if resource != nil {
normalizedTag := normalizeTag(inferredTag)
normalizedTag = cleanup.NormalizeResourceName(normalizedTag)
normalizedTag := cleanup.NormalizeTag(inferredTag)
normalizedTag = legacyCleanup.NormalizeResourceName(normalizedTag)

if mergeResources, ok := resources[normalizedTag]; ok {
resources[normalizedTag] = importerModels.MergeResourcesForTag(mergeResources, *resource)
@@ -76,8 +77,8 @@ func (d *SwaggerDefinition) parse(serviceName, apiVersion string, resourceProvid
swaggerFileName := strings.Split(d.Name, "/")
if len(resources) == 0 && len(swaggerFileName) > 2 {
// if we're here then there is no tag in this file, so we'll use the file name
inferredTag := cleanup.PluraliseName(swaggerFileName[len(swaggerFileName)-1])
normalizedTag := cleanup.NormalizeResourceName(inferredTag)
inferredTag := legacyCleanup.PluraliseName(swaggerFileName[len(swaggerFileName)-1])
normalizedTag := legacyCleanup.NormalizeResourceName(inferredTag)

result, err := d.findOrphanedDiscriminatedModels(serviceName)
if err != nil {
@@ -90,7 +91,7 @@ func (d *SwaggerDefinition) parse(serviceName, apiVersion string, resourceProvid
Constants: result.Constants,
Models: result.Models,
}
resource = normalizeAzureApiResource(resource)
resource = cleanup.NormalizeAPIResource(resource)

if mergeResources, ok := resources[normalizedTag]; ok {
resources[normalizedTag] = importerModels.MergeResourcesForTag(mergeResources, resource)
@@ -101,7 +102,7 @@ func (d *SwaggerDefinition) parse(serviceName, apiVersion string, resourceProvid
}

return &importerModels.AzureApiDefinition{
ServiceName: cleanup.NormalizeServiceName(serviceName),
ServiceName: legacyCleanup.NormalizeServiceName(serviceName),
ApiVersion: apiVersion,
Resources: resourcesOut,
}, nil
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ import (
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/internal"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/resourceids"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/cleanup"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/commonschema"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/components/apidefinitions/parser/constants"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/internal/logging"
@@ -70,7 +71,7 @@ func (d *SwaggerDefinition) parseResourcesWithinSwaggerTag(tag *string, resource
resource = switchOutCustomTypesAsNeeded(resource)

// first Normalize the names, meaning `foo` -> `Foo` for consistency
resource = normalizeAzureApiResource(resource)
resource = cleanup.NormalizeAPIResource(resource)

return &resource, nil
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package parser
package cleanup

import (
"fmt"
"strings"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/components/parser/cleanup"
)

// normalizeAzureApiResource works through the parsed AzureApiResource and ensures
// NormalizeAPIResource works through the parsed AzureApiResource and ensures
// that all the Names and References are consistent (TitleCase) as a final effort
// to ensure the Swagger Data is normalized.
func normalizeAzureApiResource(input sdkModels.APIResource) sdkModels.APIResource {
func NormalizeAPIResource(input sdkModels.APIResource) sdkModels.APIResource {
normalizedConstants := make(map[string]sdkModels.SDKConstant)
for k, v := range input.Constants {
name := cleanup.NormalizeName(k)
@@ -65,7 +68,7 @@ func normalizeAzureApiResource(input sdkModels.APIResource) sdkModels.APIResourc
for optionKey, optionVal := range v.Options {
optionKey = cleanup.NormalizeName(optionKey)

optionVal.ObjectDefinition = normalizeOptionsObjectDefinition(optionVal.ObjectDefinition)
optionVal.ObjectDefinition = normalizeSDKOptionsObjectDefinition(optionVal.ObjectDefinition)

normalizedOptions[optionKey] = optionVal
}
@@ -119,16 +122,54 @@ func normalizeSDKObjectDefinition(input sdkModels.SDKObjectDefinition) sdkModels
return input
}

func normalizeOptionsObjectDefinition(input sdkModels.SDKOperationOptionObjectDefinition) sdkModels.SDKOperationOptionObjectDefinition {
func normalizeSDKOptionsObjectDefinition(input sdkModels.SDKOperationOptionObjectDefinition) sdkModels.SDKOperationOptionObjectDefinition {
if input.ReferenceName != nil {
normalized := cleanup.NormalizeName(*input.ReferenceName)
input.ReferenceName = &normalized
}

if input.NestedItem != nil {
nestedItem := normalizeOptionsObjectDefinition(*input.NestedItem)
nestedItem := normalizeSDKOptionsObjectDefinition(*input.NestedItem)
input.NestedItem = pointer.To(nestedItem)
}

return input
}

func NormalizeOperationName(operationId string, tag *string) string {
operationName := operationId
// in some cases the OperationId *is* the Tag, in this instance I guess we take that as ok?
if tag != nil && !strings.EqualFold(operationName, *tag) {
// we're intentionally not using `strings.TrimPrefix` here since we want
// to account for the casing of the tag being different
if strings.HasPrefix(strings.ToLower(operationName), strings.ToLower(*tag)) {
operationName = operationName[len(*tag):]

// however if the Tag is `ManagementGroupsSubscriptions`, then we need to keep the extra `S` around
if *tag == "ManagementGroups" && !strings.HasPrefix(operationName, "_") {
operationName = fmt.Sprintf("S%s", operationName)
}
}
}
operationName = strings.ReplaceAll(operationName, "_", "")
operationName = strings.TrimPrefix(operationName, "Operations") // sanity checking
if !strings.HasPrefix(strings.ToLower(operationName), "subscriptions") {
operationName = strings.TrimPrefix(operationName, "s") // plurals
}
operationName = strings.TrimPrefix(operationName, "_")
operationName = cleanup.NormalizeName(operationName)
return operationName
}

func NormalizeTag(input string) string {
// NOTE: we could be smarter here, but given this is a handful of cases it's
// probably prudent to hard-code these for now (and fix the swaggers as we
// come across them?)
output := input
output = strings.ReplaceAll(output, "EndPoint", "Endpoint")
output = strings.ReplaceAll(output, "NetWork", "Network")
output = strings.ReplaceAll(output, "Baremetalinfrastructure", "BareMetalInfrastructure")
output = strings.ReplaceAll(output, "VirtualWans", "VirtualWANs")

return output
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package cleanup

import (
@@ -7,7 +10,7 @@ import (
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

func RemoveUnusedItems(input sdkModels.APIVersion) (*sdkModels.APIVersion, error) {
func RemoveUnusedItems(input sdkModels.APIVersion) sdkModels.APIVersion {
// The ordering matters here, we need to remove the ResourceIDs first since
// they contain references to Constants - as do Models, so remove unused
// Resource IDs, then Models, then Constants else we can have orphaned
@@ -59,7 +62,7 @@ func RemoveUnusedItems(input sdkModels.APIVersion) (*sdkModels.APIVersion, error
}

input.Resources = outputResources
return &input, nil
return input
}

func findUnusedConstants(operations map[string]sdkModels.SDKOperation, resourceIds map[string]sdkModels.ResourceID, resourceModels map[string]sdkModels.SDKModel, resourceConstants map[string]sdkModels.SDKConstant) []string {
Original file line number Diff line number Diff line change
@@ -33,19 +33,16 @@ func ParseAPIVersion(serviceName string, input discoveryModels.AvailableDataSetF

// Next let's apply any data workarounds
logging.Debugf("Applying Data Workarounds..")
output, err := dataworkarounds.Apply(serviceName, apiVersion)
withFixesApplied, err := dataworkarounds.Apply(serviceName, apiVersion)
if err != nil {
return nil, fmt.Errorf("applying Data Workarounds for Service %q / API Version %q: %+v", serviceName, input.APIVersion, err)
}
logging.Debugf("Applying Data Workarounds - Complete.")

// Finally let's remove any unused items
logging.Debugf("Removing unused items..")
output, err = cleanup.RemoveUnusedItems(*output)
if err != nil {
return nil, fmt.Errorf("removing unused items from Service %q / API Version %q: %+v", serviceName, input.APIVersion, err)
}
output := cleanup.RemoveUnusedItems(*withFixesApplied)
logging.Debugf("Removing unused items - Complete.")

return output, nil
return &output, nil
}