Skip to content

Commit a4b75e4

Browse files
chore: Autogen config supports overriding identifier attributes and ignoring specific operations for model generation (#3950)
* initial generation with no config support * correct generation of service account secret with config working * add unit test for overriding id attribute * unit testing in model generation
1 parent ea7d03a commit a4b75e4

File tree

13 files changed

+579
-24
lines changed

13 files changed

+579
-24
lines changed

internal/serviceapi/orgserviceaccountsecretapi/resource.go

Lines changed: 127 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/serviceapi/orgserviceaccountsecretapi/resource_schema.go

Lines changed: 71 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/codegen/codespec/api_to_provider_spec_mapper.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func ToCodeSpecModel(atlasAdminAPISpecFilePath, configPath string, resourceName
4343
}
4444

4545
var results []Resource
46-
for name, resourceConfig := range resourceConfigsToIterate {
46+
for name := range resourceConfigsToIterate {
47+
resourceConfig := resourceConfigsToIterate[name]
4748
log.Printf("[INFO] Generating resource model: %s", name)
4849
// find resource operations, schemas, etc from OAS
4950
oasResource, err := getAPISpecResource(&apiSpec.Model, &resourceConfig, name)
@@ -63,7 +64,8 @@ func ToCodeSpecModel(atlasAdminAPISpecFilePath, configPath string, resourceName
6364

6465
func validateRequiredOperations(resourceConfigs map[string]config.Resource) error {
6566
var validationErrors []error
66-
for name, resourceConfig := range resourceConfigs {
67+
for name := range resourceConfigs {
68+
resourceConfig := resourceConfigs[name]
6769
if resourceConfig.Create == nil {
6870
validationErrors = append(validationErrors, fmt.Errorf("resource %s missing Create operation in config file", name))
6971
}
@@ -88,16 +90,25 @@ func apiSpecResourceToCodeSpecModel(oasResource APISpecResource, resourceConfig
8890
configuredVersion = &resourceConfig.VersionHeader
8991
}
9092

91-
createRequestAttributes, err := opRequestToAttributes(createOp, configuredVersion)
92-
if err != nil {
93-
return nil, fmt.Errorf("failed to process create request attributes for %s: %w", name, err)
93+
var createRequestAttributes, updateRequestAttributes, createResponseAttributes, readResponseAttributes Attributes
94+
var err error
95+
96+
if !resourceConfig.Create.SchemaIgnore {
97+
createRequestAttributes, err = opRequestToAttributes(createOp, configuredVersion)
98+
if err != nil {
99+
return nil, fmt.Errorf("failed to process create request attributes for %s: %w", name, err)
100+
}
101+
createResponseAttributes = opResponseToAttributes(createOp, configuredVersion)
94102
}
95-
updateRequestAttributes, err := opRequestToAttributes(updateOp, configuredVersion)
96-
if err != nil {
97-
return nil, fmt.Errorf("failed to process update request attributes for %s: %w", name, err)
103+
if resourceConfig.Update != nil && !resourceConfig.Update.SchemaIgnore {
104+
updateRequestAttributes, err = opRequestToAttributes(updateOp, configuredVersion)
105+
if err != nil {
106+
return nil, fmt.Errorf("failed to process update request attributes for %s: %w", name, err)
107+
}
108+
}
109+
if !resourceConfig.Read.SchemaIgnore {
110+
readResponseAttributes = opResponseToAttributes(readOp, configuredVersion)
98111
}
99-
createResponseAttributes := opResponseToAttributes(createOp, configuredVersion)
100-
readResponseAttributes := opResponseToAttributes(readOp, configuredVersion)
101112

102113
attributes := mergeAttributes(&attributeDefinitionSources{
103114
createPathParams: createPathParams,
@@ -127,11 +138,12 @@ func apiSpecResourceToCodeSpecModel(oasResource APISpecResource, resourceConfig
127138
}
128139

129140
resource := &Resource{
130-
Name: name,
131-
PackageName: strings.ReplaceAll(name, "_", ""),
132-
Schema: schema,
133-
MoveState: moveState,
134-
Operations: operations,
141+
Name: name,
142+
PackageName: strings.ReplaceAll(name, "_", ""),
143+
Schema: schema,
144+
MoveState: moveState,
145+
Operations: operations,
146+
IDAttributes: resourceConfig.IDAttributes,
135147
}
136148

137149
if err := applyTransformationsWithConfigOpts(resourceConfig, resource); err != nil {

tools/codegen/codespec/api_to_provider_spec_mapper_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,3 +1358,40 @@ func TestConvertToProviderSpec_pathParamWithAlias(t *testing.T) {
13581358
assert.Contains(t, result.Resources[0].Operations.Update.Path, "{dbUser}", "Update path should use aliased path param")
13591359
assert.Contains(t, result.Resources[0].Operations.Delete.Path, "{dbUser}", "Delete path should use aliased path param")
13601360
}
1361+
1362+
func TestConvertToProviderSpec_ignoreSchemaAndIdAttributes(t *testing.T) {
1363+
tc := convertToSpecTestCase{
1364+
inputOpenAPISpecPath: testDataAPISpecPath,
1365+
inputConfigPath: testDataConfigPath,
1366+
inputResourceName: "test_schema_ignore_and_id_attributes",
1367+
1368+
expectedResult: &codespec.Model{
1369+
Resources: []codespec.Resource{{
1370+
Schema: &codespec.Schema{
1371+
Description: conversion.StringPtr("POST API description"),
1372+
// due to schema_ignore string_attr is not included in the attributes
1373+
Attributes: codespec.Attributes{
1374+
{
1375+
TFSchemaName: "group_id",
1376+
TFModelName: "GroupId",
1377+
APIName: "groupId",
1378+
ComputedOptionalRequired: codespec.Required,
1379+
String: &codespec.StringAttribute{},
1380+
Description: conversion.StringPtr(testPathParamDesc),
1381+
ReqBodyUsage: codespec.OmitAlways,
1382+
CreateOnly: true,
1383+
},
1384+
},
1385+
},
1386+
Name: "test_schema_ignore_and_id_attributes",
1387+
PackageName: "testschemaignoreandidattributes",
1388+
Operations: simpleTestResourceOperations,
1389+
IDAttributes: []string{"group_id", "id"},
1390+
}},
1391+
},
1392+
}
1393+
1394+
result, err := codespec.ToCodeSpecModel(tc.inputOpenAPISpecPath, tc.inputConfigPath, &tc.inputResourceName)
1395+
require.NoError(t, err)
1396+
assert.Equal(t, tc.expectedResult, result, "Expected result to match the specified structure")
1397+
}

tools/codegen/codespec/model.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ type Model struct {
3939
}
4040

4141
type Resource struct {
42-
Schema *Schema `yaml:"schema,omitempty"`
43-
Operations APIOperations `yaml:"operations"`
44-
MoveState *MoveState `yaml:"move_state,omitempty"`
45-
Name string `yaml:"name"`
46-
PackageName string `yaml:"packageName"`
42+
Schema *Schema `yaml:"schema,omitempty"`
43+
Operations APIOperations `yaml:"operations"`
44+
MoveState *MoveState `yaml:"move_state,omitempty"`
45+
Name string `yaml:"name"`
46+
PackageName string `yaml:"packageName"`
47+
IDAttributes []string `yaml:"id_attributes,omitempty"`
4748
}
4849

4950
type APIOperations struct {

tools/codegen/codespec/testdata/config.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,21 @@ resources:
172172
# and appears in request/response bodies. The apiname tag should preserve the
173173
# original API name "username" while the schema uses the aliased name "dbUser"
174174
username: dbUser
175+
176+
test_schema_ignore_and_id_attributes:
177+
read:
178+
path: /api/atlas/v2/groups/{groupId}/simpleTestResource
179+
method: GET
180+
schema_ignore: true
181+
create:
182+
path: /api/atlas/v2/groups/{groupId}/simpleTestResource
183+
method: POST
184+
schema_ignore: true
185+
update:
186+
path: /api/atlas/v2/groups/{groupId}/simpleTestResource
187+
method: PATCH
188+
schema_ignore: true
189+
delete:
190+
path: /api/atlas/v2/groups/{groupId}/simpleTestResource
191+
method: DELETE
192+
id_attributes: ["group_id", "id"]

tools/codegen/config.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,25 @@ resources:
765765
roles:
766766
type: set
767767

768+
org_service_account_secret_api:
769+
read:
770+
path: /api/atlas/v2/orgs/{orgId}/serviceAccounts/{clientId}
771+
method: GET
772+
schema_ignore: true # get operation for a single secret is not available, individual secret is found in service account read looking in `secrets` property
773+
create:
774+
path: /api/atlas/v2/orgs/{orgId}/serviceAccounts/{clientId}/secrets
775+
method: POST
776+
delete:
777+
path: /api/atlas/v2/orgs/{orgId}/serviceAccounts/{clientId}/secrets/{secretId}
778+
method: DELETE
779+
id_attributes: ["org_id", "client_id", "id"]
780+
schema:
781+
aliases:
782+
secretId: id # path param name does not match the API response property.
783+
overrides:
784+
secret:
785+
sensitive: true
786+
768787
alert_configuration_api:
769788
read:
770789
path: /api/atlas/v2/groups/{groupId}/alertConfigs/{alertConfigId}

tools/codegen/config/config_model.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type Resource struct {
1111
Delete *APIOperation `yaml:"delete"`
1212
MoveState *MoveState `yaml:"move_state"`
1313
VersionHeader string `yaml:"version_header"` // when not defined latest version defined in API Spec of the resource is used
14+
IDAttributes []string `yaml:"id_attributes"`
1415
DeprecationMessage *string `yaml:"deprecation_message"`
1516
SchemaOptions SchemaOptions `yaml:"schema"`
1617
}
@@ -19,7 +20,8 @@ type APIOperation struct {
1920
Wait *Wait `yaml:"wait"`
2021
Path string `yaml:"path"`
2122
Method string `yaml:"method"`
22-
StaticRequestBody string `yaml:"static_request_body"` // use at the moment for Delete when it's done with a PATCH or PUT and needs to send a static request body.
23+
StaticRequestBody string `yaml:"static_request_body"`
24+
SchemaIgnore bool `yaml:"schema_ignore"`
2325
}
2426

2527
type Wait struct {

0 commit comments

Comments
 (0)