Skip to content

Commit 5f87a14

Browse files
committed
fix: don't create files for resources/datasources that don't expose qualifying create/read endpoints
1 parent 561aa2e commit 5f87a14

3 files changed

Lines changed: 97 additions & 7 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TerraformProviderCodegen.java

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public class TerraformProviderCodegen extends AbstractGoCodegen {
4545
protected String providerAddress = "registry.terraform.io/example/example";
4646
protected String providerVersion = "0.1.0";
4747

48+
// Track which tags qualify as resources vs data sources so we can
49+
// delete non-qualifying files in postProcessFile.
50+
private final Set<String> resourceNames = new HashSet<>();
51+
private final Set<String> dataSourceNames = new HashSet<>();
52+
4853
@Override
4954
public CodegenType getTag() {
5055
return CodegenType.CLIENT;
@@ -122,6 +127,9 @@ public TerraformProviderCodegen() {
122127
public void processOpts() {
123128
super.processOpts();
124129

130+
// Enable postProcessFile so we can delete non-qualifying API files
131+
this.setEnablePostProcessFile(true);
132+
125133
if (additionalProperties.containsKey(PROVIDER_NAME)) {
126134
providerName = additionalProperties.get(PROVIDER_NAME).toString();
127135
}
@@ -272,6 +280,14 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
272280
objectMap.put("hasDelete", deleteOp != null);
273281
objectMap.put("hasList", listOp != null);
274282

283+
// A tag qualifies as a Terraform resource only if it has a create
284+
// operation; without one the resource cannot be instantiated.
285+
// A tag qualifies as a data source if it has a read (show) operation.
286+
boolean isResource = (createOp != null);
287+
boolean isDataSource = (readOp != null);
288+
objectMap.put("isResource", isResource);
289+
objectMap.put("isDataSource", isDataSource);
290+
275291
// Store CRUD operation details at tag level for simplified template access
276292
if (createOp != null) {
277293
objectMap.put("createMethod", createOp.vendorExtensions.get("x-terraform-http-method"));
@@ -312,6 +328,13 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
312328
objectMap.put("resourceName", resourceName);
313329
objectMap.put("resourceClassName", camelize(resourceName));
314330

331+
if (isResource) {
332+
resourceNames.add(resourceName);
333+
}
334+
if (isDataSource) {
335+
dataSourceNames.add(resourceName);
336+
}
337+
315338
// Detect ID field from read operation path params
316339
String idField = "id";
317340
if (readOp != null && readOp.pathParams != null && !readOp.pathParams.isEmpty()) {
@@ -354,7 +377,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
354377
attr.put("goType", prop.dataType);
355378
attr.put("terraformType", goTypeToTerraformType(prop.dataType));
356379
attr.put("terraformAttrType", goTypeToTerraformAttrType(prop.dataType, prop));
357-
attr.put("isRequired", prop.required);
380+
attr.put("isRequired", prop.required && !prop.isReadOnly);
358381
attr.put("isComputed", prop.isReadOnly);
359382
attr.put("isOptional", !prop.required && !prop.isReadOnly);
360383
attr.put("description", prop.description != null ? prop.description : "");
@@ -407,11 +430,19 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
407430
if ("id".equalsIgnoreCase(prop.baseName)) {
408431
idModelGoName = camelize(prop.baseName);
409432
idModelGoType = prop.dataType;
433+
idResolved = true;
410434
break;
411435
}
412436
}
413437
}
414438

439+
if (!idResolved) {
440+
LOGGER.warn("Could not resolve ID field '{}' in response model '{}' for resource '{}'. "
441+
+ "The generated code will not compile. Add an '{}' property to the response "
442+
+ "schema or use x-terraform-id-field to specify the correct property.",
443+
idField, responseModel, resourceName, idField);
444+
}
445+
415446
break;
416447
}
417448
}
@@ -482,6 +513,42 @@ public ModelsMap postProcessModels(ModelsMap objs) {
482513
return objs;
483514
}
484515

516+
@Override
517+
public void postProcessFile(File file, String fileType) {
518+
super.postProcessFile(file, fileType);
519+
if (file == null || !file.exists() || !"api".equals(fileType)) {
520+
return;
521+
}
522+
523+
String fileName = file.getName();
524+
525+
if (fileName.endsWith("_resource.go")) {
526+
String tag = fileName.substring(0, fileName.length() - "_resource.go".length());
527+
if (!resourceNames.contains(tag)) {
528+
LOGGER.info("Skipping non-resource file: {}", file.getAbsolutePath());
529+
file.delete();
530+
return;
531+
}
532+
}
533+
534+
if (fileName.endsWith("_data_source.go")) {
535+
String tag = fileName.substring(0, fileName.length() - "_data_source.go".length());
536+
if (!dataSourceNames.contains(tag)) {
537+
LOGGER.info("Skipping non-data-source file: {}", file.getAbsolutePath());
538+
file.delete();
539+
return;
540+
}
541+
}
542+
543+
if (fileName.endsWith("_model.go")) {
544+
String tag = fileName.substring(0, fileName.length() - "_model.go".length());
545+
if (!resourceNames.contains(tag) && !dataSourceNames.contains(tag)) {
546+
LOGGER.info("Skipping unused model file: {}", file.getAbsolutePath());
547+
file.delete();
548+
}
549+
}
550+
}
551+
485552
private String goTypeToTerraformType(String goType) {
486553
if (goType == null) return "types.String";
487554
switch (goType) {
Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module {{gitHost}}/{{gitUserId}}/{{gitRepoId}}
1+
module github.com/teamlumos/knowledge-server
22

33
go 1.24.0
44

@@ -7,5 +7,28 @@ toolchain go1.24.4
77
require (
88
github.com/hashicorp/terraform-plugin-framework v1.17.0
99
github.com/hashicorp/terraform-plugin-log v0.10.0
10-
github.com/hashicorp/terraform-plugin-testing v1.14.0
10+
)
11+
12+
require (
13+
github.com/fatih/color v1.16.0 // indirect
14+
github.com/golang/protobuf v1.5.4 // indirect
15+
github.com/hashicorp/go-hclog v1.6.3 // indirect
16+
github.com/hashicorp/go-plugin v1.7.0 // indirect
17+
github.com/hashicorp/go-uuid v1.0.3 // indirect
18+
github.com/hashicorp/terraform-plugin-go v0.29.0 // indirect
19+
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
20+
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
21+
github.com/hashicorp/yamux v0.1.2 // indirect
22+
github.com/mattn/go-colorable v0.1.13 // indirect
23+
github.com/mattn/go-isatty v0.0.20 // indirect
24+
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
25+
github.com/oklog/run v1.1.0 // indirect
26+
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
27+
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
28+
golang.org/x/net v0.47.0 // indirect
29+
golang.org/x/sys v0.38.0 // indirect
30+
golang.org/x/text v0.31.0 // indirect
31+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
32+
google.golang.org/grpc v1.75.1 // indirect
33+
google.golang.org/protobuf v1.36.9 // indirect
1134
)

modules/openapi-generator/src/main/resources/terraform-provider/provider.mustache

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ func (p *{{providerName}}Provider) Configure(ctx context.Context, req provider.C
111111

112112
func (p *{{providerName}}Provider) Resources(_ context.Context) []func() resource.Resource {
113113
return []func() resource.Resource{
114-
{{#apiInfo}}{{#apis}}{{#operations}} New{{resourceClassName}}Resource,
115-
{{/operations}}{{/apis}}{{/apiInfo}} }
114+
{{#apiInfo}}{{#apis}}{{#operations}}{{#isResource}} New{{resourceClassName}}Resource,
115+
{{/isResource}}{{/operations}}{{/apis}}{{/apiInfo}} }
116116
}
117117

118118
func (p *{{providerName}}Provider) DataSources(_ context.Context) []func() datasource.DataSource {
119119
return []func() datasource.DataSource{
120-
{{#apiInfo}}{{#apis}}{{#operations}} New{{resourceClassName}}DataSource,
121-
{{/operations}}{{/apis}}{{/apiInfo}} }
120+
{{#apiInfo}}{{#apis}}{{#operations}}{{#isDataSource}} New{{resourceClassName}}DataSource,
121+
{{/isDataSource}}{{/operations}}{{/apis}}{{/apiInfo}} }
122122
}

0 commit comments

Comments
 (0)