forked from loafle/openapi-generator-original
[Terraform] New Terraform Provider generator (#22949)
* [new] Add Terraform provider generator Add a new experimental code generator that produces HashiCorp Terraform providers from OpenAPI specifications using the Plugin Framework SDK. The generator (terraform-provider) supports: - CRUD operation detection from REST patterns and vendor extensions - Resource, data source, and model generation per API tag - HTTP client with API key, bearer token, and basic auth - Type mapping from OpenAPI/Go types to Terraform schema types - Import state support - Configurable provider name, registry address, and version Includes mustache templates for: provider, resources, data sources, models, client, go.mod, GNUmakefile, README, and example configs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * [new] Add Terraform provider petstore sample and acceptance tests Add sample generation config and generated Terraform provider for the petstore OpenAPI spec, along with Go acceptance tests that exercise the provider lifecycle (create, read, update, delete, import). Generated output includes: - Provider with auth configuration (API key, bearer, basic) - Pet, User, and Store resources and data sources - Client package with HTTP client and model structs - Go acceptance tests using terraform-plugin-testing - Example Terraform configurations for each resource/data source Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: docs * terraform: add more sample tests and ci workflow * ci: get ci passing * ci: fixes * chore: docs --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
46
.github/workflows/samples-terraform.yaml
vendored
Normal file
46
.github/workflows/samples-terraform.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Samples Terraform
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'samples/client/petstore/terraform/**'
|
||||
- 'samples/client/petstore/terraform-addpet/**'
|
||||
- 'samples/client/petstore/terraform-server/**'
|
||||
- 'samples/client/others/terraform/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'samples/client/petstore/terraform/**'
|
||||
- 'samples/client/petstore/terraform-addpet/**'
|
||||
- 'samples/client/petstore/terraform-server/**'
|
||||
- 'samples/client/others/terraform/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Terraform Provider
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sample:
|
||||
- samples/client/petstore/terraform/
|
||||
- samples/client/petstore/terraform-addpet/
|
||||
- samples/client/petstore/terraform-server/
|
||||
- samples/client/others/terraform/allof-discriminator/
|
||||
- samples/client/others/terraform/oneof-anyof-required/
|
||||
- samples/client/others/terraform/oneof-discriminator-lookup/
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "stable"
|
||||
- run: go version
|
||||
- name: Install Dependencies
|
||||
working-directory: ${{ matrix.sample }}
|
||||
run: |
|
||||
go mod tidy
|
||||
- name: Build provider
|
||||
working-directory: ${{ matrix.sample }}
|
||||
run: go build -v ./...
|
||||
- name: Run tests
|
||||
working-directory: ${{ matrix.sample }}
|
||||
run: go test ./... -v -timeout 120m
|
||||
11
bin/configs/terraform-provider-allof-discriminator.yaml
Normal file
11
bin/configs/terraform-provider-allof-discriminator.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
generatorName: terraform-provider
|
||||
outputDir: samples/client/others/terraform/allof-discriminator
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/go/allof_multiple_ref_and_discriminator.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/terraform-provider
|
||||
gitHost: github.com
|
||||
gitUserId: example
|
||||
gitRepoId: terraform-provider-allof
|
||||
additionalProperties:
|
||||
providerName: "allof"
|
||||
providerAddress: "registry.terraform.io/example/allof"
|
||||
hideGenerationTimestamp: "true"
|
||||
11
bin/configs/terraform-provider-oneof-anyof-required.yaml
Normal file
11
bin/configs/terraform-provider-oneof-anyof-required.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
generatorName: terraform-provider
|
||||
outputDir: samples/client/others/terraform/oneof-anyof-required
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/go/spec-with-oneof-anyof-required.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/terraform-provider
|
||||
gitHost: github.com
|
||||
gitUserId: example
|
||||
gitRepoId: terraform-provider-oneof-anyof
|
||||
additionalProperties:
|
||||
providerName: "oneof"
|
||||
providerAddress: "registry.terraform.io/example/oneof-anyof"
|
||||
hideGenerationTimestamp: "true"
|
||||
@@ -0,0 +1,11 @@
|
||||
generatorName: terraform-provider
|
||||
outputDir: samples/client/others/terraform/oneof-discriminator-lookup
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/go/spec-with-oneof-discriminator.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/terraform-provider
|
||||
gitHost: github.com
|
||||
gitUserId: example
|
||||
gitRepoId: terraform-provider-oneof-disc
|
||||
additionalProperties:
|
||||
providerName: "oneof"
|
||||
providerAddress: "registry.terraform.io/example/oneof-disc"
|
||||
hideGenerationTimestamp: "true"
|
||||
11
bin/configs/terraform-provider-petstore-addpet.yaml
Normal file
11
bin/configs/terraform-provider-petstore-addpet.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
generatorName: terraform-provider
|
||||
outputDir: samples/client/petstore/terraform-addpet
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-addpet-only.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/terraform-provider
|
||||
gitHost: github.com
|
||||
gitUserId: example
|
||||
gitRepoId: terraform-provider-petstore-addpet
|
||||
additionalProperties:
|
||||
providerName: "petstore"
|
||||
providerAddress: "registry.terraform.io/example/petstore-addpet"
|
||||
hideGenerationTimestamp: "true"
|
||||
11
bin/configs/terraform-provider-petstore-new.yaml
Normal file
11
bin/configs/terraform-provider-petstore-new.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
generatorName: terraform-provider
|
||||
outputDir: samples/client/petstore/terraform
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/terraform-provider
|
||||
gitHost: github.com
|
||||
gitUserId: example
|
||||
gitRepoId: terraform-provider-petstore
|
||||
additionalProperties:
|
||||
providerName: "petstore"
|
||||
providerAddress: "registry.terraform.io/example/petstore"
|
||||
hideGenerationTimestamp: "true"
|
||||
11
bin/configs/terraform-provider-petstore-server.yaml
Normal file
11
bin/configs/terraform-provider-petstore-server.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
generatorName: terraform-provider
|
||||
outputDir: samples/client/petstore/terraform-server
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/go-server/petstore.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/terraform-provider
|
||||
gitHost: github.com
|
||||
gitUserId: example
|
||||
gitRepoId: terraform-provider-petstore-server
|
||||
additionalProperties:
|
||||
providerName: "petstore"
|
||||
providerAddress: "registry.terraform.io/example/petstore-server"
|
||||
hideGenerationTimestamp: "true"
|
||||
@@ -70,6 +70,7 @@ The following generators are available:
|
||||
* [swift-combine](generators/swift-combine.md)
|
||||
* [swift5 (deprecated)](generators/swift5.md)
|
||||
* [swift6](generators/swift6.md)
|
||||
* [terraform-provider (experimental)](generators/terraform-provider.md)
|
||||
* [typescript (experimental)](generators/typescript.md)
|
||||
* [typescript-angular](generators/typescript-angular.md)
|
||||
* [typescript-aurelia](generators/typescript-aurelia.md)
|
||||
|
||||
229
docs/generators/terraform-provider.md
Normal file
229
docs/generators/terraform-provider.md
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Documentation for the terraform-provider Generator
|
||||
---
|
||||
|
||||
## METADATA
|
||||
|
||||
| Property | Value | Notes |
|
||||
| -------- | ----- | ----- |
|
||||
| generator name | terraform-provider | pass this to the generate command after -g |
|
||||
| generator stability | EXPERIMENTAL | |
|
||||
| generator type | CLIENT | |
|
||||
| generator language | Go | |
|
||||
| generator default templating engine | mustache | |
|
||||
| helpTxt | Generates a Terraform provider (Go, using HashiCorp Plugin Framework). | |
|
||||
|
||||
## CONFIG OPTIONS
|
||||
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
|
||||
|
||||
| Option | Description | Values | Default |
|
||||
| ------ | ----------- | ------ | ------- |
|
||||
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|
||||
|packageName|Go package name (convention: lowercase).| |openapi|
|
||||
|packageVersion|Go package version.| |1.0.0|
|
||||
|providerAddress|Terraform provider registry address| |registry.terraform.io/example/example|
|
||||
|providerName|Terraform provider name (e.g. 'petstore')| |example|
|
||||
|providerVersion|Terraform provider version| |0.1.0|
|
||||
|
||||
## IMPORT MAPPING
|
||||
|
||||
| Type/Alias | Imports |
|
||||
| ---------- | ------- |
|
||||
|
||||
|
||||
## INSTANTIATION TYPES
|
||||
|
||||
| Type/Alias | Instantiated By |
|
||||
| ---------- | --------------- |
|
||||
|
||||
|
||||
## LANGUAGE PRIMITIVES
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>bool</li>
|
||||
<li>byte</li>
|
||||
<li>complex128</li>
|
||||
<li>complex64</li>
|
||||
<li>float32</li>
|
||||
<li>float64</li>
|
||||
<li>int</li>
|
||||
<li>int32</li>
|
||||
<li>int64</li>
|
||||
<li>interface{}</li>
|
||||
<li>map[string]interface{}</li>
|
||||
<li>rune</li>
|
||||
<li>string</li>
|
||||
<li>uint</li>
|
||||
<li>uint32</li>
|
||||
<li>uint64</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>bool</li>
|
||||
<li>break</li>
|
||||
<li>byte</li>
|
||||
<li>case</li>
|
||||
<li>chan</li>
|
||||
<li>complex128</li>
|
||||
<li>complex64</li>
|
||||
<li>const</li>
|
||||
<li>continue</li>
|
||||
<li>default</li>
|
||||
<li>defer</li>
|
||||
<li>else</li>
|
||||
<li>error</li>
|
||||
<li>fallthrough</li>
|
||||
<li>float32</li>
|
||||
<li>float64</li>
|
||||
<li>for</li>
|
||||
<li>func</li>
|
||||
<li>go</li>
|
||||
<li>goto</li>
|
||||
<li>if</li>
|
||||
<li>import</li>
|
||||
<li>int</li>
|
||||
<li>int16</li>
|
||||
<li>int32</li>
|
||||
<li>int64</li>
|
||||
<li>int8</li>
|
||||
<li>interface</li>
|
||||
<li>map</li>
|
||||
<li>nil</li>
|
||||
<li>package</li>
|
||||
<li>range</li>
|
||||
<li>return</li>
|
||||
<li>rune</li>
|
||||
<li>select</li>
|
||||
<li>string</li>
|
||||
<li>struct</li>
|
||||
<li>switch</li>
|
||||
<li>type</li>
|
||||
<li>uint</li>
|
||||
<li>uint16</li>
|
||||
<li>uint32</li>
|
||||
<li>uint64</li>
|
||||
<li>uint8</li>
|
||||
<li>uintptr</li>
|
||||
<li>var</li>
|
||||
</ul>
|
||||
|
||||
## FEATURE SET
|
||||
|
||||
|
||||
### Client Modification Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasePath|✗|ToolingExtension
|
||||
|Authorizations|✗|ToolingExtension
|
||||
|UserAgent|✗|ToolingExtension
|
||||
|MockServer|✗|ToolingExtension
|
||||
|
||||
### Data Type Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Custom|✗|OAS2,OAS3
|
||||
|Int32|✓|OAS2,OAS3
|
||||
|Int64|✓|OAS2,OAS3
|
||||
|Float|✓|OAS2,OAS3
|
||||
|Double|✓|OAS2,OAS3
|
||||
|Decimal|✓|ToolingExtension
|
||||
|String|✓|OAS2,OAS3
|
||||
|Byte|✓|OAS2,OAS3
|
||||
|Binary|✓|OAS2,OAS3
|
||||
|Boolean|✓|OAS2,OAS3
|
||||
|Date|✓|OAS2,OAS3
|
||||
|DateTime|✓|OAS2,OAS3
|
||||
|Password|✓|OAS2,OAS3
|
||||
|File|✓|OAS2
|
||||
|Uuid|✗|
|
||||
|Array|✓|OAS2,OAS3
|
||||
|Null|✗|OAS3
|
||||
|AnyType|✗|OAS2,OAS3
|
||||
|Object|✓|OAS2,OAS3
|
||||
|Maps|✓|ToolingExtension
|
||||
|CollectionFormat|✓|OAS2
|
||||
|CollectionFormatMulti|✓|OAS2
|
||||
|Enum|✓|OAS2,OAS3
|
||||
|ArrayOfEnum|✓|ToolingExtension
|
||||
|ArrayOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|
||||
|MapOfEnum|✓|ToolingExtension
|
||||
|MapOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|MapOfCollectionOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfEnum|✓|ToolingExtension
|
||||
|
||||
### Documentation Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Readme|✓|ToolingExtension
|
||||
|Model|✓|ToolingExtension
|
||||
|Api|✓|ToolingExtension
|
||||
|
||||
### Global Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Host|✓|OAS2,OAS3
|
||||
|BasePath|✓|OAS2,OAS3
|
||||
|Info|✓|OAS2,OAS3
|
||||
|Schemes|✗|OAS2,OAS3
|
||||
|PartialSchemes|✓|OAS2,OAS3
|
||||
|Consumes|✓|OAS2
|
||||
|Produces|✓|OAS2
|
||||
|ExternalDocumentation|✓|OAS2,OAS3
|
||||
|Examples|✓|OAS2,OAS3
|
||||
|XMLStructureDefinitions|✗|OAS2,OAS3
|
||||
|MultiServer|✗|OAS3
|
||||
|ParameterizedServer|✗|OAS3
|
||||
|ParameterStyling|✗|OAS3
|
||||
|Callbacks|✗|OAS3
|
||||
|LinkObjects|✗|OAS3
|
||||
|
||||
### Parameter Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Path|✓|OAS2,OAS3
|
||||
|Query|✓|OAS2,OAS3
|
||||
|Header|✓|OAS2,OAS3
|
||||
|Body|✓|OAS2
|
||||
|FormUnencoded|✓|OAS2
|
||||
|FormMultipart|✓|OAS2
|
||||
|Cookie|✓|OAS3
|
||||
|
||||
### Schema Support Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Simple|✓|OAS2,OAS3
|
||||
|Composite|✓|OAS2,OAS3
|
||||
|Polymorphism|✗|OAS2,OAS3
|
||||
|Union|✗|OAS3
|
||||
|allOf|✗|OAS2,OAS3
|
||||
|anyOf|✗|OAS3
|
||||
|oneOf|✗|OAS3
|
||||
|not|✗|OAS3
|
||||
|
||||
### Security Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasicAuth|✓|OAS2,OAS3
|
||||
|ApiKey|✓|OAS2,OAS3
|
||||
|OpenIDConnect|✗|OAS3
|
||||
|BearerToken|✓|OAS3
|
||||
|OAuth2_Implicit|✗|OAS2,OAS3
|
||||
|OAuth2_Password|✗|OAS2,OAS3
|
||||
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|
||||
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|
||||
|SignatureAuth|✗|OAS3
|
||||
|AWSV4Signature|✗|ToolingExtension
|
||||
|
||||
### Wire Format Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|JSON|✓|OAS2,OAS3
|
||||
|XML|✗|OAS2,OAS3
|
||||
|PROTOBUF|✗|ToolingExtension
|
||||
|Custom|✗|OAS2,OAS3
|
||||
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
import org.openapitools.codegen.meta.Stability;
|
||||
import org.openapitools.codegen.meta.features.*;
|
||||
import org.openapitools.codegen.model.ModelMap;
|
||||
import org.openapitools.codegen.model.ModelsMap;
|
||||
import org.openapitools.codegen.model.OperationMap;
|
||||
import org.openapitools.codegen.model.OperationsMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import static org.openapitools.codegen.utils.StringUtils.camelize;
|
||||
import static org.openapitools.codegen.utils.StringUtils.underscore;
|
||||
|
||||
public class TerraformProviderCodegen extends AbstractGoCodegen {
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(TerraformProviderCodegen.class);
|
||||
|
||||
public static final String PROVIDER_NAME = "providerName";
|
||||
public static final String PROVIDER_ADDRESS = "providerAddress";
|
||||
public static final String PROVIDER_VERSION = "providerVersion";
|
||||
|
||||
protected String providerName = "example";
|
||||
protected String providerAddress = "registry.terraform.io/example/example";
|
||||
protected String providerVersion = "0.1.0";
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "terraform-provider";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a Terraform provider (Go, using HashiCorp Plugin Framework).";
|
||||
}
|
||||
|
||||
public TerraformProviderCodegen() {
|
||||
super();
|
||||
|
||||
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||
.stability(Stability.EXPERIMENTAL)
|
||||
.build();
|
||||
|
||||
modifyFeatureSet(features -> features
|
||||
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
||||
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON))
|
||||
.securityFeatures(EnumSet.of(
|
||||
SecurityFeature.BasicAuth,
|
||||
SecurityFeature.BearerToken,
|
||||
SecurityFeature.ApiKey
|
||||
))
|
||||
.excludeGlobalFeatures(
|
||||
GlobalFeature.XMLStructureDefinitions,
|
||||
GlobalFeature.Callbacks,
|
||||
GlobalFeature.LinkObjects,
|
||||
GlobalFeature.ParameterStyling
|
||||
)
|
||||
.excludeSchemaSupportFeatures(
|
||||
SchemaSupportFeature.Polymorphism
|
||||
)
|
||||
);
|
||||
|
||||
outputFolder = "generated-code/terraform-provider";
|
||||
embeddedTemplateDir = templateDir = "terraform-provider";
|
||||
|
||||
// API templates: generate per-tag resource, data source, and model files
|
||||
apiTemplateFiles.put("resource.mustache", "_resource.go");
|
||||
apiTemplateFiles.put("data_source.mustache", "_data_source.go");
|
||||
apiTemplateFiles.put("resource_model.mustache", "_model.go");
|
||||
|
||||
// Model templates: generate per-schema Go structs for the client package
|
||||
modelTemplateFiles.put("model.mustache", ".go");
|
||||
|
||||
// No doc templates
|
||||
apiDocTemplateFiles.clear();
|
||||
modelDocTemplateFiles.clear();
|
||||
|
||||
hideGenerationTimestamp = Boolean.TRUE;
|
||||
|
||||
// Override type mappings for Terraform (no time.Time or *os.File)
|
||||
typeMapping.put("DateTime", "string");
|
||||
typeMapping.put("date", "string");
|
||||
typeMapping.put("File", "string");
|
||||
typeMapping.put("file", "string");
|
||||
typeMapping.put("binary", "string");
|
||||
|
||||
cliOptions.add(new CliOption(PROVIDER_NAME, "Terraform provider name (e.g. 'petstore')")
|
||||
.defaultValue(providerName));
|
||||
cliOptions.add(new CliOption(PROVIDER_ADDRESS, "Terraform provider registry address")
|
||||
.defaultValue(providerAddress));
|
||||
cliOptions.add(new CliOption(PROVIDER_VERSION, "Terraform provider version")
|
||||
.defaultValue(providerVersion));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey(PROVIDER_NAME)) {
|
||||
providerName = additionalProperties.get(PROVIDER_NAME).toString();
|
||||
}
|
||||
additionalProperties.put(PROVIDER_NAME, providerName);
|
||||
|
||||
if (additionalProperties.containsKey(PROVIDER_ADDRESS)) {
|
||||
providerAddress = additionalProperties.get(PROVIDER_ADDRESS).toString();
|
||||
}
|
||||
additionalProperties.put(PROVIDER_ADDRESS, providerAddress);
|
||||
|
||||
if (additionalProperties.containsKey(PROVIDER_VERSION)) {
|
||||
providerVersion = additionalProperties.get(PROVIDER_VERSION).toString();
|
||||
}
|
||||
additionalProperties.put(PROVIDER_VERSION, providerVersion);
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
|
||||
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
|
||||
} else {
|
||||
setPackageName("provider");
|
||||
}
|
||||
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
|
||||
|
||||
apiPackage = "internal" + File.separator + "provider";
|
||||
modelPackage = "internal" + File.separator + "client";
|
||||
|
||||
// Supporting files
|
||||
supportingFiles.add(new SupportingFile("main.mustache", "", "main.go"));
|
||||
supportingFiles.add(new SupportingFile("provider.mustache", "internal" + File.separator + "provider", "provider.go"));
|
||||
supportingFiles.add(new SupportingFile("client.mustache", "internal" + File.separator + "client", "client.go"));
|
||||
supportingFiles.add(new SupportingFile("go.mod.mustache", "", "go.mod"));
|
||||
supportingFiles.add(new SupportingFile("GNUmakefile.mustache", "", "GNUmakefile"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||
supportingFiles.add(new SupportingFile("provider_example.mustache", "examples" + File.separator + "provider", "provider.tf"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + File.separator + "internal" + File.separator + "provider";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + File.separator + "internal" + File.separator + "client";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return underscore(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return "model_" + underscore(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
|
||||
OperationMap objectMap = objs.getOperations();
|
||||
List<CodegenOperation> operations = objectMap.getOperation();
|
||||
|
||||
// Store original uppercase HTTP method and build fmt.Sprintf-ready paths
|
||||
for (CodegenOperation operation : operations) {
|
||||
// Store uppercase method for net/http (e.g. "POST", "GET")
|
||||
operation.vendorExtensions.put("x-terraform-http-method", operation.httpMethod.toUpperCase(Locale.ROOT));
|
||||
|
||||
// Convert path params to fmt.Sprintf format: /pet/{petId} -> /pet/%v
|
||||
if (operation.path != null && operation.pathParams != null && !operation.pathParams.isEmpty()) {
|
||||
String fmtPath = operation.path;
|
||||
for (CodegenParameter param : operation.pathParams) {
|
||||
fmtPath = fmtPath.replace("{" + param.baseName + "}", "%v");
|
||||
}
|
||||
operation.vendorExtensions.put("x-terraform-path-fmt", fmtPath);
|
||||
}
|
||||
|
||||
// http method verb conversion (e.g. PUT => Put) as parent does
|
||||
operation.httpMethod = camelize(operation.httpMethod.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
// CRUD detection per tag
|
||||
CodegenOperation createOp = null;
|
||||
CodegenOperation readOp = null;
|
||||
CodegenOperation updateOp = null;
|
||||
CodegenOperation deleteOp = null;
|
||||
CodegenOperation listOp = null;
|
||||
|
||||
// First pass: check for explicit vendor extensions
|
||||
for (CodegenOperation op : operations) {
|
||||
if (getBooleanVendorExtension(op, "x-terraform-exclude")) {
|
||||
continue;
|
||||
}
|
||||
if (getBooleanVendorExtension(op, "x-terraform-is-create") && createOp == null) {
|
||||
createOp = op;
|
||||
}
|
||||
if (getBooleanVendorExtension(op, "x-terraform-is-read") && readOp == null) {
|
||||
readOp = op;
|
||||
}
|
||||
if (getBooleanVendorExtension(op, "x-terraform-is-update") && updateOp == null) {
|
||||
updateOp = op;
|
||||
}
|
||||
if (getBooleanVendorExtension(op, "x-terraform-is-delete") && deleteOp == null) {
|
||||
deleteOp = op;
|
||||
}
|
||||
if (getBooleanVendorExtension(op, "x-terraform-is-list") && listOp == null) {
|
||||
listOp = op;
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: auto-detect using REST pattern methods
|
||||
for (CodegenOperation op : operations) {
|
||||
if (getBooleanVendorExtension(op, "x-terraform-exclude")) {
|
||||
continue;
|
||||
}
|
||||
if (createOp == null && op.isRestfulCreate()) {
|
||||
createOp = op;
|
||||
} else if (readOp == null && op.isRestfulShow()) {
|
||||
readOp = op;
|
||||
} else if (updateOp == null && op.isRestfulUpdate()) {
|
||||
updateOp = op;
|
||||
} else if (deleteOp == null && op.isRestfulDestroy()) {
|
||||
deleteOp = op;
|
||||
} else if (listOp == null && op.isRestfulIndex()) {
|
||||
listOp = op;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the selected operations with vendor extensions
|
||||
if (createOp != null) {
|
||||
createOp.vendorExtensions.put("x-terraform-is-create", true);
|
||||
}
|
||||
if (readOp != null) {
|
||||
readOp.vendorExtensions.put("x-terraform-is-read", true);
|
||||
}
|
||||
if (updateOp != null) {
|
||||
updateOp.vendorExtensions.put("x-terraform-is-update", true);
|
||||
}
|
||||
if (deleteOp != null) {
|
||||
deleteOp.vendorExtensions.put("x-terraform-is-delete", true);
|
||||
}
|
||||
if (listOp != null) {
|
||||
listOp.vendorExtensions.put("x-terraform-is-list", true);
|
||||
}
|
||||
|
||||
// Tag-level flags and CRUD details for template rendering
|
||||
objectMap.put("hasCreate", createOp != null);
|
||||
objectMap.put("hasRead", readOp != null);
|
||||
objectMap.put("hasUpdate", updateOp != null);
|
||||
objectMap.put("hasDelete", deleteOp != null);
|
||||
objectMap.put("hasList", listOp != null);
|
||||
|
||||
// Store CRUD operation details at tag level for simplified template access
|
||||
if (createOp != null) {
|
||||
objectMap.put("createMethod", createOp.vendorExtensions.get("x-terraform-http-method"));
|
||||
objectMap.put("createPath", createOp.path);
|
||||
}
|
||||
if (readOp != null) {
|
||||
objectMap.put("readMethod", readOp.vendorExtensions.get("x-terraform-http-method"));
|
||||
objectMap.put("readPath", readOp.vendorExtensions.getOrDefault("x-terraform-path-fmt", readOp.path));
|
||||
objectMap.put("readHasPathParams", readOp.pathParams != null && !readOp.pathParams.isEmpty());
|
||||
}
|
||||
if (updateOp != null) {
|
||||
objectMap.put("updateMethod", updateOp.vendorExtensions.get("x-terraform-http-method"));
|
||||
objectMap.put("updatePath", updateOp.vendorExtensions.getOrDefault("x-terraform-path-fmt", updateOp.path));
|
||||
objectMap.put("updateHasPathParams", updateOp.pathParams != null && !updateOp.pathParams.isEmpty());
|
||||
}
|
||||
if (deleteOp != null) {
|
||||
objectMap.put("deleteMethod", deleteOp.vendorExtensions.get("x-terraform-http-method"));
|
||||
objectMap.put("deletePath", deleteOp.vendorExtensions.getOrDefault("x-terraform-path-fmt", deleteOp.path));
|
||||
objectMap.put("deleteHasPathParams", deleteOp.pathParams != null && !deleteOp.pathParams.isEmpty());
|
||||
}
|
||||
|
||||
// Determine resource name from tag
|
||||
String tag = objectMap.getClassname();
|
||||
// Strip common suffixes like "Api", "API" from the tag name
|
||||
String cleanTag = tag.replaceAll("(?i)api$", "");
|
||||
if (cleanTag.isEmpty()) {
|
||||
cleanTag = tag;
|
||||
}
|
||||
String resourceName = underscore(cleanTag).toLowerCase(Locale.ROOT);
|
||||
// Allow override via x-terraform-resource-name on any operation
|
||||
for (CodegenOperation op : operations) {
|
||||
Object nameOverride = op.vendorExtensions.get("x-terraform-resource-name");
|
||||
if (nameOverride != null) {
|
||||
resourceName = nameOverride.toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
objectMap.put("resourceName", resourceName);
|
||||
objectMap.put("resourceClassName", camelize(resourceName));
|
||||
|
||||
// Detect ID field from read operation path params
|
||||
String idField = "id";
|
||||
if (readOp != null && readOp.pathParams != null && !readOp.pathParams.isEmpty()) {
|
||||
idField = readOp.pathParams.get(readOp.pathParams.size() - 1).paramName;
|
||||
}
|
||||
objectMap.put("idField", idField);
|
||||
|
||||
// Build model info for the resource schema
|
||||
// Use the response type from readOp (or createOp) as the resource model
|
||||
String responseModel = null;
|
||||
if (readOp != null && readOp.returnType != null) {
|
||||
responseModel = readOp.returnType;
|
||||
} else if (createOp != null && createOp.returnType != null) {
|
||||
responseModel = createOp.returnType;
|
||||
}
|
||||
objectMap.put("responseModel", responseModel);
|
||||
|
||||
// Build request model from createOp body params
|
||||
String requestModel = null;
|
||||
if (createOp != null && createOp.bodyParam != null && createOp.bodyParam.dataType != null) {
|
||||
requestModel = createOp.bodyParam.dataType;
|
||||
}
|
||||
objectMap.put("requestModel", requestModel);
|
||||
|
||||
// Collect model properties for schema generation and resolve ID field
|
||||
String idModelGoName = camelize(idField);
|
||||
String idModelGoType = "string";
|
||||
|
||||
if (responseModel != null) {
|
||||
for (ModelMap modelMap : allModels) {
|
||||
CodegenModel model = modelMap.getModel();
|
||||
if (model.classname.equals(responseModel)) {
|
||||
List<Map<String, Object>> tfAttributes = new ArrayList<>();
|
||||
boolean hasListAttributes = false;
|
||||
for (CodegenProperty prop : model.vars) {
|
||||
Map<String, Object> attr = new HashMap<>();
|
||||
attr.put("name", prop.baseName);
|
||||
attr.put("terraformName", underscore(prop.baseName).toLowerCase(Locale.ROOT));
|
||||
attr.put("goName", camelize(prop.baseName));
|
||||
attr.put("goType", prop.dataType);
|
||||
attr.put("terraformType", goTypeToTerraformType(prop.dataType));
|
||||
attr.put("terraformAttrType", goTypeToTerraformAttrType(prop.dataType, prop));
|
||||
attr.put("isRequired", prop.required);
|
||||
attr.put("isComputed", prop.isReadOnly);
|
||||
attr.put("isOptional", !prop.required && !prop.isReadOnly);
|
||||
attr.put("description", prop.description != null ? prop.description : "");
|
||||
attr.put("isSensitive", prop.isWriteOnly || getBooleanVendorExtension(prop, "x-terraform-sensitive"));
|
||||
attr.put("isString", "string".equals(prop.dataType));
|
||||
attr.put("isInt64", "int64".equals(prop.dataType) || "int32".equals(prop.dataType));
|
||||
attr.put("isFloat64", "float64".equals(prop.dataType) || "float32".equals(prop.dataType));
|
||||
attr.put("isBool", "bool".equals(prop.dataType));
|
||||
attr.put("isList", prop.isArray);
|
||||
attr.put("isObject", prop.isModel && !prop.isArray);
|
||||
if (prop.isArray) {
|
||||
hasListAttributes = true;
|
||||
if (prop.items != null) {
|
||||
attr.put("listElementType", goTypeToTerraformElementType(prop.items.dataType));
|
||||
}
|
||||
}
|
||||
tfAttributes.add(attr);
|
||||
}
|
||||
objectMap.put("tfAttributes", tfAttributes);
|
||||
objectMap.put("hasListAttributes", hasListAttributes);
|
||||
|
||||
// Resolve ID field: match path param name to a model property
|
||||
boolean idResolved = false;
|
||||
// Try exact match on baseName (case-insensitive)
|
||||
for (CodegenProperty prop : model.vars) {
|
||||
if (prop.baseName.equalsIgnoreCase(idField)) {
|
||||
idModelGoName = camelize(prop.baseName);
|
||||
idModelGoType = prop.dataType;
|
||||
idResolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Try stripping resource name prefix (e.g., petId -> id)
|
||||
if (!idResolved) {
|
||||
String strippedId = idField.replaceFirst("(?i)^" + resourceName, "");
|
||||
if (!strippedId.isEmpty()) {
|
||||
for (CodegenProperty prop : model.vars) {
|
||||
if (prop.baseName.equalsIgnoreCase(strippedId)) {
|
||||
idModelGoName = camelize(prop.baseName);
|
||||
idModelGoType = prop.dataType;
|
||||
idResolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fall back to "id" property
|
||||
if (!idResolved) {
|
||||
for (CodegenProperty prop : model.vars) {
|
||||
if ("id".equalsIgnoreCase(prop.baseName)) {
|
||||
idModelGoName = camelize(prop.baseName);
|
||||
idModelGoType = prop.dataType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectMap.put("idFieldExported", idModelGoName);
|
||||
|
||||
// Determine the value accessor for the ID field based on its type
|
||||
String idValueAccessor;
|
||||
if ("int64".equals(idModelGoType) || "int32".equals(idModelGoType) || "int".equals(idModelGoType)) {
|
||||
idValueAccessor = ".ValueInt64()";
|
||||
} else if ("float64".equals(idModelGoType) || "float32".equals(idModelGoType)) {
|
||||
idValueAccessor = ".ValueFloat64()";
|
||||
} else {
|
||||
idValueAccessor = ".ValueString()";
|
||||
}
|
||||
objectMap.put("idFieldValueAccessor", idValueAccessor);
|
||||
|
||||
// Terraform name for the ID field (for path.Root in ImportState)
|
||||
objectMap.put("idFieldTerraformName", underscore(idModelGoName).toLowerCase(Locale.ROOT));
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelsMap postProcessModels(ModelsMap objs) {
|
||||
// Call parent to handle Go-specific post-processing
|
||||
objs = super.postProcessModels(objs);
|
||||
|
||||
for (ModelMap m : objs.getModels()) {
|
||||
CodegenModel model = m.getModel();
|
||||
for (CodegenProperty prop : model.vars) {
|
||||
// Ensure x-go-datatag is set for all model vars.
|
||||
// The parent AbstractGoCodegen only sets x-go-datatag on
|
||||
// inheritedProperties (oneOf/anyOf entries) when the model has
|
||||
// composed schemas without allOf, leaving model.vars without
|
||||
// json tags. We fix this by generating the tag here when missing.
|
||||
if (!prop.vendorExtensions.containsKey("x-go-datatag")) {
|
||||
String goDataTag = "json:\"" + prop.baseName;
|
||||
if (!prop.required) {
|
||||
goDataTag += ",omitempty";
|
||||
}
|
||||
goDataTag += "\"";
|
||||
goDataTag = " `" + goDataTag + "`";
|
||||
prop.vendorExtensions.put("x-go-datatag", goDataTag);
|
||||
}
|
||||
|
||||
// Add Terraform-specific vendor extensions
|
||||
if (prop.isReadOnly) {
|
||||
prop.vendorExtensions.put("x-terraform-computed", true);
|
||||
}
|
||||
if (prop.required) {
|
||||
prop.vendorExtensions.put("x-terraform-required", true);
|
||||
}
|
||||
if (!prop.required && !prop.isReadOnly) {
|
||||
prop.vendorExtensions.put("x-terraform-optional", true);
|
||||
}
|
||||
if (prop.isWriteOnly) {
|
||||
prop.vendorExtensions.put("x-terraform-sensitive", true);
|
||||
}
|
||||
|
||||
// Map Go types to Terraform types
|
||||
prop.vendorExtensions.put("x-terraform-type", goTypeToTerraformType(prop.dataType));
|
||||
prop.vendorExtensions.put("x-terraform-attr-type", goTypeToTerraformAttrType(prop.dataType, prop));
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
private String goTypeToTerraformType(String goType) {
|
||||
if (goType == null) return "types.String";
|
||||
switch (goType) {
|
||||
case "string":
|
||||
return "types.String";
|
||||
case "int32":
|
||||
case "int64":
|
||||
case "int":
|
||||
return "types.Int64";
|
||||
case "float32":
|
||||
case "float64":
|
||||
return "types.Float64";
|
||||
case "bool":
|
||||
return "types.Bool";
|
||||
default:
|
||||
if (goType.startsWith("[]")) {
|
||||
return "types.List";
|
||||
}
|
||||
return "types.String";
|
||||
}
|
||||
}
|
||||
|
||||
private String goTypeToTerraformAttrType(String goType, CodegenProperty prop) {
|
||||
if (goType == null) return "schema.StringAttribute";
|
||||
switch (goType) {
|
||||
case "string":
|
||||
return "schema.StringAttribute";
|
||||
case "int32":
|
||||
case "int64":
|
||||
case "int":
|
||||
return "schema.Int64Attribute";
|
||||
case "float32":
|
||||
case "float64":
|
||||
return "schema.Float64Attribute";
|
||||
case "bool":
|
||||
return "schema.BoolAttribute";
|
||||
default:
|
||||
if (goType.startsWith("[]")) {
|
||||
return "schema.ListAttribute";
|
||||
}
|
||||
// Complex objects are serialized as JSON strings
|
||||
return "schema.StringAttribute";
|
||||
}
|
||||
}
|
||||
|
||||
private String goTypeToTerraformElementType(String goType) {
|
||||
if (goType == null) return "types.StringType";
|
||||
switch (goType) {
|
||||
case "string":
|
||||
return "types.StringType";
|
||||
case "int32":
|
||||
case "int64":
|
||||
case "int":
|
||||
return "types.Int64Type";
|
||||
case "float32":
|
||||
case "float64":
|
||||
return "types.Float64Type";
|
||||
case "bool":
|
||||
return "types.BoolType";
|
||||
default:
|
||||
return "types.StringType";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getBooleanVendorExtension(CodegenOperation op, String key) {
|
||||
return op.vendorExtensions.containsKey(key) && Boolean.TRUE.equals(op.vendorExtensions.get(key));
|
||||
}
|
||||
|
||||
private boolean getBooleanVendorExtension(CodegenProperty prop, String key) {
|
||||
return prop.vendorExtensions.containsKey(key) && Boolean.TRUE.equals(prop.vendorExtensions.get(key));
|
||||
}
|
||||
}
|
||||
@@ -149,6 +149,7 @@ org.openapitools.codegen.languages.StaticHtml2Generator
|
||||
org.openapitools.codegen.languages.Swift5ClientCodegen
|
||||
org.openapitools.codegen.languages.Swift6ClientCodegen
|
||||
org.openapitools.codegen.languages.SwiftCombineClientCodegen
|
||||
org.openapitools.codegen.languages.TerraformProviderCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptClientCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptAngularClientCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptAureliaClientCodegen
|
||||
|
||||
27
modules/openapi-generator/src/main/resources/terraform-provider/GNUmakefile.mustache
vendored
Normal file
27
modules/openapi-generator/src/main/resources/terraform-provider/GNUmakefile.mustache
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
default: testacc
|
||||
|
||||
# Run acceptance tests
|
||||
.PHONY: testacc
|
||||
testacc:
|
||||
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
|
||||
|
||||
# Build provider
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o terraform-provider-{{providerName}}
|
||||
|
||||
# Install provider locally
|
||||
.PHONY: install
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/{{providerAddress}}/{{providerVersion}}/$(shell go env GOOS)_$(shell go env GOARCH)
|
||||
mv terraform-provider-{{providerName}} ~/.terraform.d/plugins/{{providerAddress}}/{{providerVersion}}/$(shell go env GOOS)_$(shell go env GOARCH)/
|
||||
|
||||
# Generate documentation
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go generate ./...
|
||||
|
||||
# Run linter
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
61
modules/openapi-generator/src/main/resources/terraform-provider/README.mustache
vendored
Normal file
61
modules/openapi-generator/src/main/resources/terraform-provider/README.mustache
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
# Terraform Provider {{providerName}}
|
||||
|
||||
This Terraform provider was generated using [OpenAPI Generator](https://openapi-generator.tech).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Terraform](https://www.terraform.io/downloads.html) >= 1.0
|
||||
- [Go](https://golang.org/doc/install) >= 1.22
|
||||
|
||||
## Building The Provider
|
||||
|
||||
1. Clone the repository
|
||||
2. Enter the repository directory
|
||||
3. Build the provider using the Go `install` command:
|
||||
|
||||
```shell
|
||||
go install
|
||||
```
|
||||
|
||||
## Using the provider
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
{{providerName}} = {
|
||||
source = "{{providerAddress}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "{{providerName}}" {
|
||||
endpoint = "{{basePath}}"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing the Provider
|
||||
|
||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
|
||||
|
||||
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
|
||||
|
||||
For local development and testing, add a `dev_overrides` block to your `~/.terraformrc` so that Terraform uses the locally built binary instead of fetching from the registry:
|
||||
|
||||
```hcl
|
||||
provider_installation {
|
||||
dev_overrides {
|
||||
"{{providerAddress}}" = "${GOPATH}/bin"
|
||||
}
|
||||
direct {}
|
||||
}
|
||||
```
|
||||
|
||||
With `dev_overrides` configured, you do not need to run `terraform init` for the provider.
|
||||
|
||||
To generate or update documentation, run `go generate`.
|
||||
|
||||
In order to run the full suite of Acceptance tests, run `make testacc`.
|
||||
|
||||
```shell
|
||||
make testacc
|
||||
```
|
||||
77
modules/openapi-generator/src/main/resources/terraform-provider/client.mustache
vendored
Normal file
77
modules/openapi-generator/src/main/resources/terraform-provider/client.mustache
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
{{>partial_header}}
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the API client used to interact with the API.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
ApiKey string
|
||||
Token string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewClient creates a new API client with the given base URL.
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
HTTPClient: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
// DoRequest executes an HTTP request and returns the response body.
|
||||
func (c *Client) DoRequest(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
|
||||
var reqBody io.Reader
|
||||
if body != nil {
|
||||
jsonBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
reqBody = bytes.NewBuffer(jsonBody)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
// Authentication
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
} else if c.ApiKey != "" {
|
||||
req.Header.Set("Authorization", c.ApiKey)
|
||||
} else if c.Username != "" {
|
||||
req.SetBasicAuth(c.Username, c.Password)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
108
modules/openapi-generator/src/main/resources/terraform-provider/data_source.mustache
vendored
Normal file
108
modules/openapi-generator/src/main/resources/terraform-provider/data_source.mustache
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
{{#operations}}
|
||||
{{>partial_header}}
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
{{#hasRead}}
|
||||
"encoding/json"
|
||||
{{/hasRead}}
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
{{#hasRead}}
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
{{/hasRead}}
|
||||
|
||||
"{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/internal/client"
|
||||
)
|
||||
|
||||
var _ datasource.DataSource = &{{resourceClassName}}DataSource{}
|
||||
|
||||
func New{{resourceClassName}}DataSource() datasource.DataSource {
|
||||
return &{{resourceClassName}}DataSource{}
|
||||
}
|
||||
|
||||
type {{resourceClassName}}DataSource struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func (d *{{resourceClassName}}DataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_{{resourceName}}"
|
||||
}
|
||||
|
||||
func (d *{{resourceClassName}}DataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Description: "Fetches a {{resourceName}} data source.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
{{#tfAttributes}}
|
||||
"{{terraformName}}": schema.{{#isString}}String{{/isString}}{{#isInt64}}Int64{{/isInt64}}{{#isFloat64}}Float64{{/isFloat64}}{{#isBool}}Bool{{/isBool}}{{^isString}}{{^isInt64}}{{^isFloat64}}{{^isBool}}String{{/isBool}}{{/isFloat64}}{{/isInt64}}{{/isString}}Attribute{
|
||||
{{#isRequired}}
|
||||
Required: true,
|
||||
{{/isRequired}}
|
||||
{{^isRequired}}
|
||||
Computed: true,
|
||||
{{/isRequired}}
|
||||
Description: "{{description}}",
|
||||
},
|
||||
{{/tfAttributes}}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *{{resourceClassName}}DataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c, ok := req.ProviderData.(*client.Client)
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError(
|
||||
"Unexpected Data Source Configure Type",
|
||||
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
d.client = c
|
||||
}
|
||||
|
||||
{{#hasRead}}
|
||||
func (d *{{resourceClassName}}DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var config {{resourceClassName}}Model
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
{{#readHasPathParams}}
|
||||
respBody, err := d.client.DoRequest(ctx, "{{readMethod}}", fmt.Sprintf("{{readPath}}", config.{{idFieldExported}}{{idFieldValueAccessor}}), nil)
|
||||
{{/readHasPathParams}}
|
||||
{{^readHasPathParams}}
|
||||
respBody, err := d.client.DoRequest(ctx, "{{readMethod}}", "{{readPath}}", nil)
|
||||
{{/readHasPathParams}}
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error reading {{resourceName}}", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var result client.{{responseModel}}
|
||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||
resp.Diagnostics.AddError("Error parsing response", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
config.FromClientModel(&result)
|
||||
|
||||
tflog.Trace(ctx, "read {{resourceName}} data source")
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
|
||||
}
|
||||
{{/hasRead}}
|
||||
{{^hasRead}}
|
||||
func (d *{{resourceClassName}}DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
resp.Diagnostics.AddError("Not Supported", "Read is not supported for {{resourceName}}")
|
||||
}
|
||||
{{/hasRead}}
|
||||
{{/operations}}
|
||||
13
modules/openapi-generator/src/main/resources/terraform-provider/gitignore.mustache
vendored
Normal file
13
modules/openapi-generator/src/main/resources/terraform-provider/gitignore.mustache
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dylib
|
||||
*.so
|
||||
*.test
|
||||
*.out
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform/
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
terraform-provider-{{providerName}}
|
||||
11
modules/openapi-generator/src/main/resources/terraform-provider/go.mod.mustache
vendored
Normal file
11
modules/openapi-generator/src/main/resources/terraform-provider/go.mod.mustache
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
module {{gitHost}}/{{gitUserId}}/{{gitRepoId}}
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
)
|
||||
34
modules/openapi-generator/src/main/resources/terraform-provider/main.mustache
vendored
Normal file
34
modules/openapi-generator/src/main/resources/terraform-provider/main.mustache
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{{>partial_header}}
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||
|
||||
"{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/internal/provider"
|
||||
)
|
||||
|
||||
var (
|
||||
version string = "{{providerVersion}}"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var debug bool
|
||||
|
||||
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||
flag.Parse()
|
||||
|
||||
opts := providerserver.ServeOpts{
|
||||
Address: "{{providerAddress}}",
|
||||
Debug: debug,
|
||||
}
|
||||
|
||||
err := providerserver.Serve(context.Background(), provider.New(version), opts)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
13
modules/openapi-generator/src/main/resources/terraform-provider/model.mustache
vendored
Normal file
13
modules/openapi-generator/src/main/resources/terraform-provider/model.mustache
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{{>partial_header}}
|
||||
package client
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
|
||||
// {{classname}} - {{{description}}}{{^description}}{{classname}} struct{{/description}}
|
||||
type {{classname}} struct {
|
||||
{{#vars}}
|
||||
{{name}} {{#isArray}}[]{{#items}}{{dataType}}{{/items}}{{/isArray}}{{^isArray}}{{#isMap}}map[string]{{#items}}{{dataType}}{{/items}}{{/isMap}}{{^isMap}}{{dataType}}{{/isMap}}{{/isArray}}{{{vendorExtensions.x-go-datatag}}}
|
||||
{{/vars}}
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
1
modules/openapi-generator/src/main/resources/terraform-provider/partial_header.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/terraform-provider/partial_header.mustache
vendored
Normal file
@@ -0,0 +1 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
122
modules/openapi-generator/src/main/resources/terraform-provider/provider.mustache
vendored
Normal file
122
modules/openapi-generator/src/main/resources/terraform-provider/provider.mustache
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
{{>partial_header}}
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/internal/client"
|
||||
)
|
||||
|
||||
var _ provider.Provider = &{{providerName}}Provider{}
|
||||
|
||||
type {{providerName}}Provider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type {{providerName}}ProviderModel struct {
|
||||
Endpoint types.String `tfsdk:"endpoint"`
|
||||
ApiKey types.String `tfsdk:"api_key"`
|
||||
Token types.String `tfsdk:"token"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
}
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &{{providerName}}Provider{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *{{providerName}}Provider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "{{providerName}}"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *{{providerName}}Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"endpoint": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The API endpoint URL.",
|
||||
},
|
||||
"api_key": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The API key for authentication.",
|
||||
},
|
||||
"token": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The bearer token for authentication.",
|
||||
},
|
||||
"username": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The username for basic authentication.",
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The password for basic authentication.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *{{providerName}}Provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
var config {{providerName}}ProviderModel
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if config.Endpoint.IsUnknown() {
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Unknown Endpoint Value",
|
||||
"The provider endpoint value is not yet known. Defaulting to the spec-defined base path.",
|
||||
)
|
||||
}
|
||||
|
||||
endpoint := "{{{basePath}}}"
|
||||
if !config.Endpoint.IsNull() && !config.Endpoint.IsUnknown() {
|
||||
endpoint = config.Endpoint.ValueString()
|
||||
}
|
||||
|
||||
c := client.NewClient(endpoint)
|
||||
|
||||
if !config.ApiKey.IsNull() {
|
||||
c.ApiKey = config.ApiKey.ValueString()
|
||||
}
|
||||
if !config.Token.IsNull() {
|
||||
c.Token = config.Token.ValueString()
|
||||
}
|
||||
if !config.Username.IsNull() {
|
||||
c.Username = config.Username.ValueString()
|
||||
}
|
||||
if !config.Password.IsNull() {
|
||||
c.Password = config.Password.ValueString()
|
||||
}
|
||||
|
||||
resp.DataSourceData = c
|
||||
resp.ResourceData = c
|
||||
}
|
||||
|
||||
func (p *{{providerName}}Provider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
{{#apiInfo}}{{#apis}}{{#operations}} New{{resourceClassName}}Resource,
|
||||
{{/operations}}{{/apis}}{{/apiInfo}} }
|
||||
}
|
||||
|
||||
func (p *{{providerName}}Provider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{
|
||||
{{#apiInfo}}{{#apis}}{{#operations}} New{{resourceClassName}}DataSource,
|
||||
{{/operations}}{{/apis}}{{/apiInfo}} }
|
||||
}
|
||||
13
modules/openapi-generator/src/main/resources/terraform-provider/provider_example.mustache
vendored
Normal file
13
modules/openapi-generator/src/main/resources/terraform-provider/provider_example.mustache
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
{{providerName}} = {
|
||||
source = "{{providerAddress}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "{{providerName}}" {
|
||||
endpoint = "{{{basePath}}}"
|
||||
# api_key = "your-api-key"
|
||||
# token = "your-bearer-token"
|
||||
}
|
||||
247
modules/openapi-generator/src/main/resources/terraform-provider/resource.mustache
vendored
Normal file
247
modules/openapi-generator/src/main/resources/terraform-provider/resource.mustache
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
{{#operations}}
|
||||
{{>partial_header}}
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
{{#hasCreate}}
|
||||
"encoding/json"
|
||||
{{/hasCreate}}
|
||||
{{^hasCreate}}{{#hasRead}}
|
||||
"encoding/json"
|
||||
{{/hasRead}}{{/hasCreate}}
|
||||
{{^hasCreate}}{{^hasRead}}{{#hasUpdate}}
|
||||
"encoding/json"
|
||||
{{/hasUpdate}}{{/hasRead}}{{/hasCreate}}
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
{{#hasListAttributes}}
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
{{/hasListAttributes}}
|
||||
{{#hasCreate}}
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
{{/hasCreate}}
|
||||
{{^hasCreate}}{{#hasUpdate}}
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
{{/hasUpdate}}{{/hasCreate}}
|
||||
{{^hasCreate}}{{^hasUpdate}}{{#hasDelete}}
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
{{/hasDelete}}{{/hasUpdate}}{{/hasCreate}}
|
||||
|
||||
"{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/internal/client"
|
||||
)
|
||||
|
||||
var _ resource.Resource = &{{resourceClassName}}Resource{}
|
||||
var _ resource.ResourceWithImportState = &{{resourceClassName}}Resource{}
|
||||
|
||||
func New{{resourceClassName}}Resource() resource.Resource {
|
||||
return &{{resourceClassName}}Resource{}
|
||||
}
|
||||
|
||||
type {{resourceClassName}}Resource struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func (r *{{resourceClassName}}Resource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_{{resourceName}}"
|
||||
}
|
||||
|
||||
func (r *{{resourceClassName}}Resource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Description: "Manages a {{resourceName}} resource.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
{{#tfAttributes}}
|
||||
"{{terraformName}}": {{terraformAttrType}}{
|
||||
{{#isRequired}}
|
||||
Required: true,
|
||||
{{/isRequired}}
|
||||
{{#isComputed}}
|
||||
Computed: true,
|
||||
{{/isComputed}}
|
||||
{{#isOptional}}
|
||||
Optional: true,
|
||||
{{/isOptional}}
|
||||
{{#isSensitive}}
|
||||
Sensitive: true,
|
||||
{{/isSensitive}}
|
||||
{{#isList}}
|
||||
ElementType: {{listElementType}},
|
||||
{{/isList}}
|
||||
Description: "{{description}}",
|
||||
},
|
||||
{{/tfAttributes}}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *{{resourceClassName}}Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c, ok := req.ProviderData.(*client.Client)
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError(
|
||||
"Unexpected Resource Configure Type",
|
||||
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
r.client = c
|
||||
}
|
||||
|
||||
{{#hasCreate}}
|
||||
func (r *{{resourceClassName}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan {{resourceClassName}}Model
|
||||
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
reqBody := plan.ToClientModel()
|
||||
|
||||
respBody, err := r.client.DoRequest(ctx, "{{createMethod}}", "{{createPath}}", reqBody)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error creating {{resourceName}}", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var result client.{{responseModel}}
|
||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||
resp.Diagnostics.AddError("Error parsing response", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
plan.FromClientModel(&result)
|
||||
|
||||
tflog.Trace(ctx, "created {{resourceName}} resource")
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
{{/hasCreate}}
|
||||
{{^hasCreate}}
|
||||
func (r *{{resourceClassName}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
resp.Diagnostics.AddError("Not Supported", "Create is not supported for {{resourceName}}")
|
||||
}
|
||||
{{/hasCreate}}
|
||||
|
||||
{{#hasRead}}
|
||||
func (r *{{resourceClassName}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state {{resourceClassName}}Model
|
||||
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
{{#readHasPathParams}}
|
||||
respBody, err := r.client.DoRequest(ctx, "{{readMethod}}", fmt.Sprintf("{{readPath}}", state.{{idFieldExported}}{{idFieldValueAccessor}}), nil)
|
||||
{{/readHasPathParams}}
|
||||
{{^readHasPathParams}}
|
||||
respBody, err := r.client.DoRequest(ctx, "{{readMethod}}", "{{readPath}}", nil)
|
||||
{{/readHasPathParams}}
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error reading {{resourceName}}", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var result client.{{responseModel}}
|
||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||
resp.Diagnostics.AddError("Error parsing response", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
state.FromClientModel(&result)
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
{{/hasRead}}
|
||||
{{^hasRead}}
|
||||
func (r *{{resourceClassName}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
// No read endpoint available; keep existing state as-is.
|
||||
}
|
||||
{{/hasRead}}
|
||||
|
||||
{{#hasUpdate}}
|
||||
func (r *{{resourceClassName}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var plan {{resourceClassName}}Model
|
||||
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
reqBody := plan.ToClientModel()
|
||||
|
||||
{{#updateHasPathParams}}
|
||||
respBody, err := r.client.DoRequest(ctx, "{{updateMethod}}", fmt.Sprintf("{{updatePath}}", plan.{{idFieldExported}}{{idFieldValueAccessor}}), reqBody)
|
||||
{{/updateHasPathParams}}
|
||||
{{^updateHasPathParams}}
|
||||
respBody, err := r.client.DoRequest(ctx, "{{updateMethod}}", "{{updatePath}}", reqBody)
|
||||
{{/updateHasPathParams}}
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error updating {{resourceName}}", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var result client.{{responseModel}}
|
||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||
resp.Diagnostics.AddError("Error parsing response", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
plan.FromClientModel(&result)
|
||||
|
||||
tflog.Trace(ctx, "updated {{resourceName}} resource")
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
{{/hasUpdate}}
|
||||
{{^hasUpdate}}
|
||||
func (r *{{resourceClassName}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
// No update endpoint available; persist the planned values into state.
|
||||
var plan {{resourceClassName}}Model
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
{{/hasUpdate}}
|
||||
|
||||
{{#hasDelete}}
|
||||
func (r *{{resourceClassName}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var state {{resourceClassName}}Model
|
||||
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
{{#deleteHasPathParams}}
|
||||
_, err := r.client.DoRequest(ctx, "{{deleteMethod}}", fmt.Sprintf("{{deletePath}}", state.{{idFieldExported}}{{idFieldValueAccessor}}), nil)
|
||||
{{/deleteHasPathParams}}
|
||||
{{^deleteHasPathParams}}
|
||||
_, err := r.client.DoRequest(ctx, "{{deleteMethod}}", "{{deletePath}}", nil)
|
||||
{{/deleteHasPathParams}}
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error deleting {{resourceName}}", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
tflog.Trace(ctx, "deleted {{resourceName}} resource")
|
||||
}
|
||||
{{/hasDelete}}
|
||||
{{^hasDelete}}
|
||||
func (r *{{resourceClassName}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
// No delete endpoint available; remove the resource from state.
|
||||
}
|
||||
{{/hasDelete}}
|
||||
|
||||
func (r *{{resourceClassName}}Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("{{idFieldTerraformName}}"), req, resp)
|
||||
}
|
||||
{{/operations}}
|
||||
67
modules/openapi-generator/src/main/resources/terraform-provider/resource_model.mustache
vendored
Normal file
67
modules/openapi-generator/src/main/resources/terraform-provider/resource_model.mustache
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
{{#operations}}
|
||||
{{>partial_header}}
|
||||
package provider
|
||||
|
||||
{{#responseModel}}
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/internal/client"
|
||||
)
|
||||
{{/responseModel}}
|
||||
|
||||
// {{resourceClassName}}Model is the Terraform model for {{resourceName}}.
|
||||
type {{resourceClassName}}Model struct {
|
||||
{{#tfAttributes}}
|
||||
{{goName}} {{terraformType}} `tfsdk:"{{terraformName}}"`
|
||||
{{/tfAttributes}}
|
||||
}
|
||||
|
||||
{{#responseModel}}
|
||||
// ToClientModel converts a Terraform model to a client model.
|
||||
func (m *{{resourceClassName}}Model) ToClientModel() *client.{{responseModel}} {
|
||||
out := &client.{{responseModel}}{}
|
||||
{{#tfAttributes}}
|
||||
{{#isString}}
|
||||
if !m.{{goName}}.IsNull() && !m.{{goName}}.IsUnknown() {
|
||||
out.{{goName}} = m.{{goName}}.ValueString()
|
||||
}
|
||||
{{/isString}}
|
||||
{{#isInt64}}
|
||||
if !m.{{goName}}.IsNull() && !m.{{goName}}.IsUnknown() {
|
||||
out.{{goName}} = {{goType}}(m.{{goName}}.ValueInt64())
|
||||
}
|
||||
{{/isInt64}}
|
||||
{{#isFloat64}}
|
||||
if !m.{{goName}}.IsNull() && !m.{{goName}}.IsUnknown() {
|
||||
out.{{goName}} = {{goType}}(m.{{goName}}.ValueFloat64())
|
||||
}
|
||||
{{/isFloat64}}
|
||||
{{#isBool}}
|
||||
if !m.{{goName}}.IsNull() && !m.{{goName}}.IsUnknown() {
|
||||
out.{{goName}} = m.{{goName}}.ValueBool()
|
||||
}
|
||||
{{/isBool}}
|
||||
{{/tfAttributes}}
|
||||
return out
|
||||
}
|
||||
|
||||
// FromClientModel updates the Terraform model from a client model.
|
||||
func (m *{{resourceClassName}}Model) FromClientModel(c *client.{{responseModel}}) {
|
||||
{{#tfAttributes}}
|
||||
{{#isString}}
|
||||
m.{{goName}} = types.StringValue(c.{{goName}})
|
||||
{{/isString}}
|
||||
{{#isInt64}}
|
||||
m.{{goName}} = types.Int64Value(int64(c.{{goName}}))
|
||||
{{/isInt64}}
|
||||
{{#isFloat64}}
|
||||
m.{{goName}} = types.Float64Value(float64(c.{{goName}}))
|
||||
{{/isFloat64}}
|
||||
{{#isBool}}
|
||||
m.{{goName}} = types.BoolValue(c.{{goName}})
|
||||
{{/isBool}}
|
||||
{{/tfAttributes}}
|
||||
}
|
||||
{{/responseModel}}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.terraform.provider;
|
||||
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.config.CodegenConfigurator;
|
||||
import org.openapitools.codegen.languages.TerraformProviderCodegen;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TerraformProviderCodegenTest {
|
||||
|
||||
@Test
|
||||
public void testInitialConfigValues() throws Exception {
|
||||
final TerraformProviderCodegen codegen = new TerraformProviderCodegen();
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.getName(), "terraform-provider");
|
||||
Assert.assertEquals(codegen.getTag(), CodegenType.CLIENT);
|
||||
Assert.assertNotNull(codegen.getHelp());
|
||||
Assert.assertTrue(codegen.getHelp().contains("Terraform"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderNameOption() throws Exception {
|
||||
final TerraformProviderCodegen codegen = new TerraformProviderCodegen();
|
||||
codegen.additionalProperties().put(TerraformProviderCodegen.PROVIDER_NAME, "myapi");
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.additionalProperties().get(TerraformProviderCodegen.PROVIDER_NAME), "myapi");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratePetstore() throws Exception {
|
||||
File output = Files.createTempDirectory("terraform-provider-test").toFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(TerraformProviderCodegen.PROVIDER_NAME, "petstore");
|
||||
properties.put(TerraformProviderCodegen.PROVIDER_ADDRESS, "registry.terraform.io/example/petstore");
|
||||
properties.put("gitHost", "github.com");
|
||||
properties.put("gitUserId", "example");
|
||||
properties.put("gitRepoId", "terraform-provider-petstore");
|
||||
|
||||
final CodegenConfigurator configurator = new CodegenConfigurator()
|
||||
.setGeneratorName("terraform-provider")
|
||||
.setAdditionalProperties(properties)
|
||||
.setInputSpec("src/test/resources/3_0/petstore.yaml")
|
||||
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
|
||||
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
|
||||
files.forEach(File::deleteOnExit);
|
||||
|
||||
// Verify key files exist
|
||||
TestUtils.assertFileExists(Paths.get(output + "/main.go"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/go.mod"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/GNUmakefile"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/README.md"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/.gitignore"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/internal/provider/provider.go"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/internal/client/client.go"));
|
||||
TestUtils.assertFileExists(Paths.get(output + "/examples/provider/provider.tf"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMainGoContent() throws Exception {
|
||||
File output = Files.createTempDirectory("terraform-provider-test").toFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(TerraformProviderCodegen.PROVIDER_NAME, "petstore");
|
||||
properties.put(TerraformProviderCodegen.PROVIDER_ADDRESS, "registry.terraform.io/example/petstore");
|
||||
|
||||
final CodegenConfigurator configurator = new CodegenConfigurator()
|
||||
.setGeneratorName("terraform-provider")
|
||||
.setAdditionalProperties(properties)
|
||||
.setGitHost("github.com")
|
||||
.setGitUserId("example")
|
||||
.setGitRepoId("terraform-provider-petstore")
|
||||
.setInputSpec("src/test/resources/3_0/petstore.yaml")
|
||||
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
|
||||
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
|
||||
files.forEach(File::deleteOnExit);
|
||||
|
||||
// Verify main.go content
|
||||
TestUtils.assertFileContains(Paths.get(output + "/main.go"), "providerserver.Serve");
|
||||
TestUtils.assertFileContains(Paths.get(output + "/main.go"), "registry.terraform.io/example/petstore");
|
||||
|
||||
// Verify provider.go content
|
||||
TestUtils.assertFileContains(Paths.get(output + "/internal/provider/provider.go"), "petstoreProvider");
|
||||
TestUtils.assertFileContains(Paths.get(output + "/internal/provider/provider.go"), "provider.Provider");
|
||||
|
||||
// Verify client.go content
|
||||
TestUtils.assertFileContains(Paths.get(output + "/internal/client/client.go"), "type Client struct");
|
||||
TestUtils.assertFileContains(Paths.get(output + "/internal/client/client.go"), "func NewClient");
|
||||
|
||||
// Verify go.mod content
|
||||
TestUtils.assertFileContains(Paths.get(output + "/go.mod"), "github.com/example/terraform-provider-petstore");
|
||||
TestUtils.assertFileContains(Paths.get(output + "/go.mod"), "terraform-plugin-framework");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeMapping() throws Exception {
|
||||
final TerraformProviderCodegen codegen = new TerraformProviderCodegen();
|
||||
codegen.processOpts();
|
||||
|
||||
// Terraform provider should map DateTime to string (not time.Time)
|
||||
Assert.assertEquals(codegen.typeMapping().get("DateTime"), "string");
|
||||
Assert.assertEquals(codegen.typeMapping().get("File"), "string");
|
||||
Assert.assertEquals(codegen.typeMapping().get("binary"), "string");
|
||||
|
||||
// Standard Go type mappings should still work
|
||||
Assert.assertEquals(codegen.typeMapping().get("integer"), "int32");
|
||||
Assert.assertEquals(codegen.typeMapping().get("long"), "int64");
|
||||
Assert.assertEquals(codegen.typeMapping().get("boolean"), "bool");
|
||||
Assert.assertEquals(codegen.typeMapping().get("string"), "string");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilenames() throws Exception {
|
||||
final TerraformProviderCodegen codegen = new TerraformProviderCodegen();
|
||||
|
||||
Assert.assertEquals(codegen.toApiFilename("Pet"), "pet");
|
||||
Assert.assertEquals(codegen.toApiFilename("UserProfile"), "user_profile");
|
||||
Assert.assertEquals(codegen.toModelFilename("Pet"), "model_pet");
|
||||
Assert.assertEquals(codegen.toModelFilename("ApiResponse"), "model_api_response");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderExampleContent() throws Exception {
|
||||
File output = Files.createTempDirectory("terraform-provider-test").toFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(TerraformProviderCodegen.PROVIDER_NAME, "petstore");
|
||||
properties.put(TerraformProviderCodegen.PROVIDER_ADDRESS, "registry.terraform.io/example/petstore");
|
||||
properties.put("gitHost", "github.com");
|
||||
properties.put("gitUserId", "example");
|
||||
properties.put("gitRepoId", "terraform-provider-petstore");
|
||||
|
||||
final CodegenConfigurator configurator = new CodegenConfigurator()
|
||||
.setGeneratorName("terraform-provider")
|
||||
.setAdditionalProperties(properties)
|
||||
.setInputSpec("src/test/resources/3_0/petstore.yaml")
|
||||
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
|
||||
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
|
||||
files.forEach(File::deleteOnExit);
|
||||
|
||||
// Verify provider example
|
||||
TestUtils.assertFileContains(Paths.get(output + "/examples/provider/provider.tf"), "petstore");
|
||||
TestUtils.assertFileContains(Paths.get(output + "/examples/provider/provider.tf"), "registry.terraform.io/example/petstore");
|
||||
}
|
||||
}
|
||||
13
samples/client/others/terraform/allof-discriminator/.gitignore
vendored
Normal file
13
samples/client/others/terraform/allof-discriminator/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dylib
|
||||
*.so
|
||||
*.test
|
||||
*.out
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform/
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
terraform-provider-allof
|
||||
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1,11 @@
|
||||
.gitignore
|
||||
GNUmakefile
|
||||
README.md
|
||||
examples/provider/provider.tf
|
||||
go.mod
|
||||
internal/client/client.go
|
||||
internal/client/model_additional_data.go
|
||||
internal/client/model_base/item.go
|
||||
internal/client/model_final_item.go
|
||||
internal/provider/provider.go
|
||||
main.go
|
||||
@@ -0,0 +1 @@
|
||||
7.20.0-SNAPSHOT
|
||||
@@ -0,0 +1,27 @@
|
||||
default: testacc
|
||||
|
||||
# Run acceptance tests
|
||||
.PHONY: testacc
|
||||
testacc:
|
||||
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
|
||||
|
||||
# Build provider
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o terraform-provider-allof
|
||||
|
||||
# Install provider locally
|
||||
.PHONY: install
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/example/allof/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)
|
||||
mv terraform-provider-allof ~/.terraform.d/plugins/registry.terraform.io/example/allof/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)/
|
||||
|
||||
# Generate documentation
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go generate ./...
|
||||
|
||||
# Run linter
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
@@ -0,0 +1,61 @@
|
||||
# Terraform Provider allof
|
||||
|
||||
This Terraform provider was generated using [OpenAPI Generator](https://openapi-generator.tech).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Terraform](https://www.terraform.io/downloads.html) >= 1.0
|
||||
- [Go](https://golang.org/doc/install) >= 1.22
|
||||
|
||||
## Building The Provider
|
||||
|
||||
1. Clone the repository
|
||||
2. Enter the repository directory
|
||||
3. Build the provider using the Go `install` command:
|
||||
|
||||
```shell
|
||||
go install
|
||||
```
|
||||
|
||||
## Using the provider
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
allof = {
|
||||
source = "registry.terraform.io/example/allof"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "allof" {
|
||||
endpoint = "http://localhost"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing the Provider
|
||||
|
||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
|
||||
|
||||
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
|
||||
|
||||
For local development and testing, add a `dev_overrides` block to your `~/.terraformrc` so that Terraform uses the locally built binary instead of fetching from the registry:
|
||||
|
||||
```hcl
|
||||
provider_installation {
|
||||
dev_overrides {
|
||||
"registry.terraform.io/example/allof" = "${GOPATH}/bin"
|
||||
}
|
||||
direct {}
|
||||
}
|
||||
```
|
||||
|
||||
With `dev_overrides` configured, you do not need to run `terraform init` for the provider.
|
||||
|
||||
To generate or update documentation, run `go generate`.
|
||||
|
||||
In order to run the full suite of Acceptance tests, run `make testacc`.
|
||||
|
||||
```shell
|
||||
make testacc
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
allof = {
|
||||
source = "registry.terraform.io/example/allof"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "allof" {
|
||||
endpoint = "http://localhost"
|
||||
# api_key = "your-api-key"
|
||||
# token = "your-bearer-token"
|
||||
}
|
||||
11
samples/client/others/terraform/allof-discriminator/go.mod
Normal file
11
samples/client/others/terraform/allof-discriminator/go.mod
Normal file
@@ -0,0 +1,11 @@
|
||||
module github.com/example/terraform-provider-allof
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
)
|
||||
99
samples/client/others/terraform/allof-discriminator/go.sum
Normal file
99
samples/client/others/terraform/allof-discriminator/go.sum
Normal file
@@ -0,0 +1,99 @@
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,78 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the API client used to interact with the API.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
ApiKey string
|
||||
Token string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewClient creates a new API client with the given base URL.
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
HTTPClient: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
// DoRequest executes an HTTP request and returns the response body.
|
||||
func (c *Client) DoRequest(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
|
||||
var reqBody io.Reader
|
||||
if body != nil {
|
||||
jsonBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
reqBody = bytes.NewBuffer(jsonBody)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
// Authentication
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
} else if c.ApiKey != "" {
|
||||
req.Header.Set("Authorization", c.ApiKey)
|
||||
} else if c.Username != "" {
|
||||
req.SetBasicAuth(c.Username, c.Password)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// AdditionalData - AdditionalData struct
|
||||
type AdditionalData struct {
|
||||
Prop1 string `json:"prop1"`
|
||||
Quantity int32 `json:"quantity"`
|
||||
UnitPrice float64 `json:"unitPrice"`
|
||||
TotalPrice float64 `json:"totalPrice"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// BaseItem - BaseItem struct
|
||||
type BaseItem struct {
|
||||
Title string `json:"title"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// FinalItem - FinalItem struct
|
||||
type FinalItem struct {
|
||||
Prop1 string `json:"prop1"`
|
||||
Quantity int32 `json:"quantity"`
|
||||
UnitPrice float64 `json:"unitPrice"`
|
||||
TotalPrice float64 `json:"totalPrice"`
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/example/terraform-provider-allof/internal/client"
|
||||
)
|
||||
|
||||
var _ provider.Provider = &allofProvider{}
|
||||
|
||||
type allofProvider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type allofProviderModel struct {
|
||||
Endpoint types.String `tfsdk:"endpoint"`
|
||||
ApiKey types.String `tfsdk:"api_key"`
|
||||
Token types.String `tfsdk:"token"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
}
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &allofProvider{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *allofProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "allof"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *allofProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"endpoint": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The API endpoint URL.",
|
||||
},
|
||||
"api_key": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The API key for authentication.",
|
||||
},
|
||||
"token": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The bearer token for authentication.",
|
||||
},
|
||||
"username": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The username for basic authentication.",
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The password for basic authentication.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *allofProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
var config allofProviderModel
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if config.Endpoint.IsUnknown() {
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Unknown Endpoint Value",
|
||||
"The provider endpoint value is not yet known. Defaulting to the spec-defined base path.",
|
||||
)
|
||||
}
|
||||
|
||||
endpoint := "http://localhost"
|
||||
if !config.Endpoint.IsNull() && !config.Endpoint.IsUnknown() {
|
||||
endpoint = config.Endpoint.ValueString()
|
||||
}
|
||||
|
||||
c := client.NewClient(endpoint)
|
||||
|
||||
if !config.ApiKey.IsNull() {
|
||||
c.ApiKey = config.ApiKey.ValueString()
|
||||
}
|
||||
if !config.Token.IsNull() {
|
||||
c.Token = config.Token.ValueString()
|
||||
}
|
||||
if !config.Username.IsNull() {
|
||||
c.Username = config.Username.ValueString()
|
||||
}
|
||||
if !config.Password.IsNull() {
|
||||
c.Password = config.Password.ValueString()
|
||||
}
|
||||
|
||||
resp.DataSourceData = c
|
||||
resp.ResourceData = c
|
||||
}
|
||||
|
||||
func (p *allofProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
}
|
||||
}
|
||||
|
||||
func (p *allofProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{
|
||||
}
|
||||
}
|
||||
35
samples/client/others/terraform/allof-discriminator/main.go
Normal file
35
samples/client/others/terraform/allof-discriminator/main.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||
|
||||
"github.com/example/terraform-provider-allof/internal/provider"
|
||||
)
|
||||
|
||||
var (
|
||||
version string = "0.1.0"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var debug bool
|
||||
|
||||
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||
flag.Parse()
|
||||
|
||||
opts := providerserver.ServeOpts{
|
||||
Address: "registry.terraform.io/example/allof",
|
||||
Debug: debug,
|
||||
}
|
||||
|
||||
err := providerserver.Serve(context.Background(), provider.New(version), opts)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
13
samples/client/others/terraform/oneof-anyof-required/.gitignore
vendored
Normal file
13
samples/client/others/terraform/oneof-anyof-required/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dylib
|
||||
*.so
|
||||
*.test
|
||||
*.out
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform/
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
terraform-provider-oneof
|
||||
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1,12 @@
|
||||
.gitignore
|
||||
GNUmakefile
|
||||
README.md
|
||||
examples/provider/provider.tf
|
||||
go.mod
|
||||
internal/client/client.go
|
||||
internal/client/model_nested_object1.go
|
||||
internal/client/model_nested_object2.go
|
||||
internal/client/model_object.go
|
||||
internal/client/model_object2.go
|
||||
internal/provider/provider.go
|
||||
main.go
|
||||
@@ -0,0 +1 @@
|
||||
7.20.0-SNAPSHOT
|
||||
@@ -0,0 +1,27 @@
|
||||
default: testacc
|
||||
|
||||
# Run acceptance tests
|
||||
.PHONY: testacc
|
||||
testacc:
|
||||
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
|
||||
|
||||
# Build provider
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o terraform-provider-oneof
|
||||
|
||||
# Install provider locally
|
||||
.PHONY: install
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/example/oneof-anyof/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)
|
||||
mv terraform-provider-oneof ~/.terraform.d/plugins/registry.terraform.io/example/oneof-anyof/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)/
|
||||
|
||||
# Generate documentation
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go generate ./...
|
||||
|
||||
# Run linter
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
@@ -0,0 +1,61 @@
|
||||
# Terraform Provider oneof
|
||||
|
||||
This Terraform provider was generated using [OpenAPI Generator](https://openapi-generator.tech).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Terraform](https://www.terraform.io/downloads.html) >= 1.0
|
||||
- [Go](https://golang.org/doc/install) >= 1.22
|
||||
|
||||
## Building The Provider
|
||||
|
||||
1. Clone the repository
|
||||
2. Enter the repository directory
|
||||
3. Build the provider using the Go `install` command:
|
||||
|
||||
```shell
|
||||
go install
|
||||
```
|
||||
|
||||
## Using the provider
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
oneof = {
|
||||
source = "registry.terraform.io/example/oneof-anyof"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "oneof" {
|
||||
endpoint = "http://localhost"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing the Provider
|
||||
|
||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
|
||||
|
||||
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
|
||||
|
||||
For local development and testing, add a `dev_overrides` block to your `~/.terraformrc` so that Terraform uses the locally built binary instead of fetching from the registry:
|
||||
|
||||
```hcl
|
||||
provider_installation {
|
||||
dev_overrides {
|
||||
"registry.terraform.io/example/oneof-anyof" = "${GOPATH}/bin"
|
||||
}
|
||||
direct {}
|
||||
}
|
||||
```
|
||||
|
||||
With `dev_overrides` configured, you do not need to run `terraform init` for the provider.
|
||||
|
||||
To generate or update documentation, run `go generate`.
|
||||
|
||||
In order to run the full suite of Acceptance tests, run `make testacc`.
|
||||
|
||||
```shell
|
||||
make testacc
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
oneof = {
|
||||
source = "registry.terraform.io/example/oneof-anyof"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "oneof" {
|
||||
endpoint = "http://localhost"
|
||||
# api_key = "your-api-key"
|
||||
# token = "your-bearer-token"
|
||||
}
|
||||
11
samples/client/others/terraform/oneof-anyof-required/go.mod
Normal file
11
samples/client/others/terraform/oneof-anyof-required/go.mod
Normal file
@@ -0,0 +1,11 @@
|
||||
module github.com/example/terraform-provider-oneof-anyof
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
)
|
||||
99
samples/client/others/terraform/oneof-anyof-required/go.sum
Normal file
99
samples/client/others/terraform/oneof-anyof-required/go.sum
Normal file
@@ -0,0 +1,99 @@
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,78 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the API client used to interact with the API.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
ApiKey string
|
||||
Token string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewClient creates a new API client with the given base URL.
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
HTTPClient: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
// DoRequest executes an HTTP request and returns the response body.
|
||||
func (c *Client) DoRequest(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
|
||||
var reqBody io.Reader
|
||||
if body != nil {
|
||||
jsonBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
reqBody = bytes.NewBuffer(jsonBody)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
// Authentication
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
} else if c.ApiKey != "" {
|
||||
req.Header.Set("Authorization", c.ApiKey)
|
||||
} else if c.Username != "" {
|
||||
req.SetBasicAuth(c.Username, c.Password)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// NestedObject1 - NestedObject1 struct
|
||||
type NestedObject1 struct {
|
||||
Field1 string `json:"field1"`
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// NestedObject2 - NestedObject2 struct
|
||||
type NestedObject2 struct {
|
||||
Field2 string `json:"field2"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// Object - Object struct
|
||||
type Object struct {
|
||||
Field1 string `json:"field1"`
|
||||
Field2 string `json:"field2"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// Object2 - Object2 struct
|
||||
type Object2 struct {
|
||||
Field1 string `json:"field1"`
|
||||
Field2 string `json:"field2"`
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/example/terraform-provider-oneof-anyof/internal/client"
|
||||
)
|
||||
|
||||
var _ provider.Provider = &oneofProvider{}
|
||||
|
||||
type oneofProvider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type oneofProviderModel struct {
|
||||
Endpoint types.String `tfsdk:"endpoint"`
|
||||
ApiKey types.String `tfsdk:"api_key"`
|
||||
Token types.String `tfsdk:"token"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
}
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &oneofProvider{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "oneof"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"endpoint": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The API endpoint URL.",
|
||||
},
|
||||
"api_key": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The API key for authentication.",
|
||||
},
|
||||
"token": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The bearer token for authentication.",
|
||||
},
|
||||
"username": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The username for basic authentication.",
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The password for basic authentication.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
var config oneofProviderModel
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if config.Endpoint.IsUnknown() {
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Unknown Endpoint Value",
|
||||
"The provider endpoint value is not yet known. Defaulting to the spec-defined base path.",
|
||||
)
|
||||
}
|
||||
|
||||
endpoint := "http://localhost"
|
||||
if !config.Endpoint.IsNull() && !config.Endpoint.IsUnknown() {
|
||||
endpoint = config.Endpoint.ValueString()
|
||||
}
|
||||
|
||||
c := client.NewClient(endpoint)
|
||||
|
||||
if !config.ApiKey.IsNull() {
|
||||
c.ApiKey = config.ApiKey.ValueString()
|
||||
}
|
||||
if !config.Token.IsNull() {
|
||||
c.Token = config.Token.ValueString()
|
||||
}
|
||||
if !config.Username.IsNull() {
|
||||
c.Username = config.Username.ValueString()
|
||||
}
|
||||
if !config.Password.IsNull() {
|
||||
c.Password = config.Password.ValueString()
|
||||
}
|
||||
|
||||
resp.DataSourceData = c
|
||||
resp.ResourceData = c
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
}
|
||||
}
|
||||
|
||||
func (p *oneofProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{
|
||||
}
|
||||
}
|
||||
35
samples/client/others/terraform/oneof-anyof-required/main.go
Normal file
35
samples/client/others/terraform/oneof-anyof-required/main.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||
|
||||
"github.com/example/terraform-provider-oneof-anyof/internal/provider"
|
||||
)
|
||||
|
||||
var (
|
||||
version string = "0.1.0"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var debug bool
|
||||
|
||||
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||
flag.Parse()
|
||||
|
||||
opts := providerserver.ServeOpts{
|
||||
Address: "registry.terraform.io/example/oneof-anyof",
|
||||
Debug: debug,
|
||||
}
|
||||
|
||||
err := providerserver.Serve(context.Background(), provider.New(version), opts)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
13
samples/client/others/terraform/oneof-discriminator-lookup/.gitignore
vendored
Normal file
13
samples/client/others/terraform/oneof-discriminator-lookup/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dylib
|
||||
*.so
|
||||
*.test
|
||||
*.out
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform/
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
terraform-provider-oneof
|
||||
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1,11 @@
|
||||
.gitignore
|
||||
GNUmakefile
|
||||
README.md
|
||||
examples/provider/provider.tf
|
||||
go.mod
|
||||
internal/client/client.go
|
||||
internal/client/model_nested_object1.go
|
||||
internal/client/model_nested_object2.go
|
||||
internal/client/model_object.go
|
||||
internal/provider/provider.go
|
||||
main.go
|
||||
@@ -0,0 +1 @@
|
||||
7.20.0-SNAPSHOT
|
||||
@@ -0,0 +1,27 @@
|
||||
default: testacc
|
||||
|
||||
# Run acceptance tests
|
||||
.PHONY: testacc
|
||||
testacc:
|
||||
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
|
||||
|
||||
# Build provider
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o terraform-provider-oneof
|
||||
|
||||
# Install provider locally
|
||||
.PHONY: install
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/example/oneof-disc/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)
|
||||
mv terraform-provider-oneof ~/.terraform.d/plugins/registry.terraform.io/example/oneof-disc/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)/
|
||||
|
||||
# Generate documentation
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go generate ./...
|
||||
|
||||
# Run linter
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
@@ -0,0 +1,61 @@
|
||||
# Terraform Provider oneof
|
||||
|
||||
This Terraform provider was generated using [OpenAPI Generator](https://openapi-generator.tech).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Terraform](https://www.terraform.io/downloads.html) >= 1.0
|
||||
- [Go](https://golang.org/doc/install) >= 1.22
|
||||
|
||||
## Building The Provider
|
||||
|
||||
1. Clone the repository
|
||||
2. Enter the repository directory
|
||||
3. Build the provider using the Go `install` command:
|
||||
|
||||
```shell
|
||||
go install
|
||||
```
|
||||
|
||||
## Using the provider
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
oneof = {
|
||||
source = "registry.terraform.io/example/oneof-disc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "oneof" {
|
||||
endpoint = "http://localhost"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing the Provider
|
||||
|
||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
|
||||
|
||||
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
|
||||
|
||||
For local development and testing, add a `dev_overrides` block to your `~/.terraformrc` so that Terraform uses the locally built binary instead of fetching from the registry:
|
||||
|
||||
```hcl
|
||||
provider_installation {
|
||||
dev_overrides {
|
||||
"registry.terraform.io/example/oneof-disc" = "${GOPATH}/bin"
|
||||
}
|
||||
direct {}
|
||||
}
|
||||
```
|
||||
|
||||
With `dev_overrides` configured, you do not need to run `terraform init` for the provider.
|
||||
|
||||
To generate or update documentation, run `go generate`.
|
||||
|
||||
In order to run the full suite of Acceptance tests, run `make testacc`.
|
||||
|
||||
```shell
|
||||
make testacc
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
oneof = {
|
||||
source = "registry.terraform.io/example/oneof-disc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "oneof" {
|
||||
endpoint = "http://localhost"
|
||||
# api_key = "your-api-key"
|
||||
# token = "your-bearer-token"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
module github.com/example/terraform-provider-oneof-disc
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
)
|
||||
@@ -0,0 +1,99 @@
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,78 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the API client used to interact with the API.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
ApiKey string
|
||||
Token string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewClient creates a new API client with the given base URL.
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
HTTPClient: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
// DoRequest executes an HTTP request and returns the response body.
|
||||
func (c *Client) DoRequest(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
|
||||
var reqBody io.Reader
|
||||
if body != nil {
|
||||
jsonBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
reqBody = bytes.NewBuffer(jsonBody)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
// Authentication
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
} else if c.ApiKey != "" {
|
||||
req.Header.Set("Authorization", c.ApiKey)
|
||||
} else if c.Username != "" {
|
||||
req.SetBasicAuth(c.Username, c.Password)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// NestedObject1 - NestedObject1 struct
|
||||
type NestedObject1 struct {
|
||||
Field1 string `json:"field1"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// NestedObject2 - NestedObject2 struct
|
||||
type NestedObject2 struct {
|
||||
Field1 string `json:"field1,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// Object - Object struct
|
||||
type Object struct {
|
||||
Field1 string `json:"field1"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/example/terraform-provider-oneof-disc/internal/client"
|
||||
)
|
||||
|
||||
var _ provider.Provider = &oneofProvider{}
|
||||
|
||||
type oneofProvider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type oneofProviderModel struct {
|
||||
Endpoint types.String `tfsdk:"endpoint"`
|
||||
ApiKey types.String `tfsdk:"api_key"`
|
||||
Token types.String `tfsdk:"token"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
}
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &oneofProvider{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "oneof"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"endpoint": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The API endpoint URL.",
|
||||
},
|
||||
"api_key": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The API key for authentication.",
|
||||
},
|
||||
"token": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The bearer token for authentication.",
|
||||
},
|
||||
"username": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The username for basic authentication.",
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The password for basic authentication.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
var config oneofProviderModel
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if config.Endpoint.IsUnknown() {
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Unknown Endpoint Value",
|
||||
"The provider endpoint value is not yet known. Defaulting to the spec-defined base path.",
|
||||
)
|
||||
}
|
||||
|
||||
endpoint := "http://localhost"
|
||||
if !config.Endpoint.IsNull() && !config.Endpoint.IsUnknown() {
|
||||
endpoint = config.Endpoint.ValueString()
|
||||
}
|
||||
|
||||
c := client.NewClient(endpoint)
|
||||
|
||||
if !config.ApiKey.IsNull() {
|
||||
c.ApiKey = config.ApiKey.ValueString()
|
||||
}
|
||||
if !config.Token.IsNull() {
|
||||
c.Token = config.Token.ValueString()
|
||||
}
|
||||
if !config.Username.IsNull() {
|
||||
c.Username = config.Username.ValueString()
|
||||
}
|
||||
if !config.Password.IsNull() {
|
||||
c.Password = config.Password.ValueString()
|
||||
}
|
||||
|
||||
resp.DataSourceData = c
|
||||
resp.ResourceData = c
|
||||
}
|
||||
|
||||
func (p *oneofProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
}
|
||||
}
|
||||
|
||||
func (p *oneofProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||
|
||||
"github.com/example/terraform-provider-oneof-disc/internal/provider"
|
||||
)
|
||||
|
||||
var (
|
||||
version string = "0.1.0"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var debug bool
|
||||
|
||||
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||
flag.Parse()
|
||||
|
||||
opts := providerserver.ServeOpts{
|
||||
Address: "registry.terraform.io/example/oneof-disc",
|
||||
Debug: debug,
|
||||
}
|
||||
|
||||
err := providerserver.Serve(context.Background(), provider.New(version), opts)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
13
samples/client/petstore/terraform-addpet/.gitignore
vendored
Normal file
13
samples/client/petstore/terraform-addpet/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dylib
|
||||
*.so
|
||||
*.test
|
||||
*.out
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform/
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
terraform-provider-petstore
|
||||
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1,14 @@
|
||||
.gitignore
|
||||
GNUmakefile
|
||||
README.md
|
||||
examples/provider/provider.tf
|
||||
go.mod
|
||||
internal/client/client.go
|
||||
internal/client/model_category.go
|
||||
internal/client/model_pet.go
|
||||
internal/client/model_tag.go
|
||||
internal/provider/pet_data_source.go
|
||||
internal/provider/pet_model.go
|
||||
internal/provider/pet_resource.go
|
||||
internal/provider/provider.go
|
||||
main.go
|
||||
@@ -0,0 +1 @@
|
||||
7.20.0-SNAPSHOT
|
||||
27
samples/client/petstore/terraform-addpet/GNUmakefile
Normal file
27
samples/client/petstore/terraform-addpet/GNUmakefile
Normal file
@@ -0,0 +1,27 @@
|
||||
default: testacc
|
||||
|
||||
# Run acceptance tests
|
||||
.PHONY: testacc
|
||||
testacc:
|
||||
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
|
||||
|
||||
# Build provider
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o terraform-provider-petstore
|
||||
|
||||
# Install provider locally
|
||||
.PHONY: install
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/example/petstore-addpet/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)
|
||||
mv terraform-provider-petstore ~/.terraform.d/plugins/registry.terraform.io/example/petstore-addpet/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)/
|
||||
|
||||
# Generate documentation
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go generate ./...
|
||||
|
||||
# Run linter
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
61
samples/client/petstore/terraform-addpet/README.md
Normal file
61
samples/client/petstore/terraform-addpet/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Terraform Provider petstore
|
||||
|
||||
This Terraform provider was generated using [OpenAPI Generator](https://openapi-generator.tech).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Terraform](https://www.terraform.io/downloads.html) >= 1.0
|
||||
- [Go](https://golang.org/doc/install) >= 1.22
|
||||
|
||||
## Building The Provider
|
||||
|
||||
1. Clone the repository
|
||||
2. Enter the repository directory
|
||||
3. Build the provider using the Go `install` command:
|
||||
|
||||
```shell
|
||||
go install
|
||||
```
|
||||
|
||||
## Using the provider
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
petstore = {
|
||||
source = "registry.terraform.io/example/petstore-addpet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "petstore" {
|
||||
endpoint = "http://petstore.swagger.io/v2"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing the Provider
|
||||
|
||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
|
||||
|
||||
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
|
||||
|
||||
For local development and testing, add a `dev_overrides` block to your `~/.terraformrc` so that Terraform uses the locally built binary instead of fetching from the registry:
|
||||
|
||||
```hcl
|
||||
provider_installation {
|
||||
dev_overrides {
|
||||
"registry.terraform.io/example/petstore-addpet" = "${GOPATH}/bin"
|
||||
}
|
||||
direct {}
|
||||
}
|
||||
```
|
||||
|
||||
With `dev_overrides` configured, you do not need to run `terraform init` for the provider.
|
||||
|
||||
To generate or update documentation, run `go generate`.
|
||||
|
||||
In order to run the full suite of Acceptance tests, run `make testacc`.
|
||||
|
||||
```shell
|
||||
make testacc
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
petstore = {
|
||||
source = "registry.terraform.io/example/petstore-addpet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "petstore" {
|
||||
endpoint = "http://petstore.swagger.io/v2"
|
||||
# api_key = "your-api-key"
|
||||
# token = "your-bearer-token"
|
||||
}
|
||||
11
samples/client/petstore/terraform-addpet/go.mod
Normal file
11
samples/client/petstore/terraform-addpet/go.mod
Normal file
@@ -0,0 +1,11 @@
|
||||
module github.com/example/terraform-provider-petstore-addpet
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
)
|
||||
99
samples/client/petstore/terraform-addpet/go.sum
Normal file
99
samples/client/petstore/terraform-addpet/go.sum
Normal file
@@ -0,0 +1,99 @@
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,78 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the API client used to interact with the API.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
ApiKey string
|
||||
Token string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewClient creates a new API client with the given base URL.
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
HTTPClient: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
// DoRequest executes an HTTP request and returns the response body.
|
||||
func (c *Client) DoRequest(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
|
||||
var reqBody io.Reader
|
||||
if body != nil {
|
||||
jsonBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
reqBody = bytes.NewBuffer(jsonBody)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
// Authentication
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
} else if c.ApiKey != "" {
|
||||
req.Header.Set("Authorization", c.ApiKey)
|
||||
} else if c.Username != "" {
|
||||
req.SetBasicAuth(c.Username, c.Password)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// Category - A category for a pet
|
||||
type Category struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// Pet - A pet for sale in the pet store
|
||||
type Pet struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
Category Category `json:"category,omitempty"`
|
||||
Name string `json:"name"`
|
||||
PhotoUrls []string `json:"photoUrls"`
|
||||
Tags []Tag `json:"tags,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// Tag - A tag for a pet
|
||||
type Tag struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
|
||||
"github.com/example/terraform-provider-petstore-addpet/internal/client"
|
||||
)
|
||||
|
||||
var _ datasource.DataSource = &PetDataSource{}
|
||||
|
||||
func NewPetDataSource() datasource.DataSource {
|
||||
return &PetDataSource{}
|
||||
}
|
||||
|
||||
type PetDataSource struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func (d *PetDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_pet"
|
||||
}
|
||||
|
||||
func (d *PetDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Description: "Fetches a pet data source.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"category": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"name": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "",
|
||||
},
|
||||
"photo_urls": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "",
|
||||
},
|
||||
"tags": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"status": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "pet status in the store",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *PetDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c, ok := req.ProviderData.(*client.Client)
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError(
|
||||
"Unexpected Data Source Configure Type",
|
||||
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
d.client = c
|
||||
}
|
||||
|
||||
func (d *PetDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
resp.Diagnostics.AddError("Not Supported", "Read is not supported for pet")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
package provider
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/example/terraform-provider-petstore-addpet/internal/client"
|
||||
)
|
||||
|
||||
// PetModel is the Terraform model for pet.
|
||||
type PetModel struct {
|
||||
Id types.Int64 `tfsdk:"id"`
|
||||
Category types.String `tfsdk:"category"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
PhotoUrls types.List `tfsdk:"photo_urls"`
|
||||
Tags types.List `tfsdk:"tags"`
|
||||
Status types.String `tfsdk:"status"`
|
||||
}
|
||||
|
||||
// ToClientModel converts a Terraform model to a client model.
|
||||
func (m *PetModel) ToClientModel() *client.Pet {
|
||||
out := &client.Pet{}
|
||||
if !m.Id.IsNull() && !m.Id.IsUnknown() {
|
||||
out.Id = int64(m.Id.ValueInt64())
|
||||
}
|
||||
if !m.Name.IsNull() && !m.Name.IsUnknown() {
|
||||
out.Name = m.Name.ValueString()
|
||||
}
|
||||
if !m.Status.IsNull() && !m.Status.IsUnknown() {
|
||||
out.Status = m.Status.ValueString()
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// FromClientModel updates the Terraform model from a client model.
|
||||
func (m *PetModel) FromClientModel(c *client.Pet) {
|
||||
m.Id = types.Int64Value(int64(c.Id))
|
||||
m.Name = types.StringValue(c.Name)
|
||||
m.Status = types.StringValue(c.Status)
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
|
||||
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
|
||||
|
||||
|
||||
"github.com/example/terraform-provider-petstore-addpet/internal/client"
|
||||
)
|
||||
|
||||
var _ resource.Resource = &PetResource{}
|
||||
var _ resource.ResourceWithImportState = &PetResource{}
|
||||
|
||||
func NewPetResource() resource.Resource {
|
||||
return &PetResource{}
|
||||
}
|
||||
|
||||
type PetResource struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func (r *PetResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_pet"
|
||||
}
|
||||
|
||||
func (r *PetResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Description: "Manages a pet resource.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Description: "",
|
||||
},
|
||||
"category": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "",
|
||||
},
|
||||
"name": schema.StringAttribute{
|
||||
Required: true,
|
||||
Description: "",
|
||||
},
|
||||
"photo_urls": schema.ListAttribute{
|
||||
Required: true,
|
||||
ElementType: types.StringType,
|
||||
Description: "",
|
||||
},
|
||||
"tags": schema.ListAttribute{
|
||||
Optional: true,
|
||||
ElementType: types.StringType,
|
||||
Description: "",
|
||||
},
|
||||
"status": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "pet status in the store",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PetResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c, ok := req.ProviderData.(*client.Client)
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError(
|
||||
"Unexpected Resource Configure Type",
|
||||
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
r.client = c
|
||||
}
|
||||
|
||||
func (r *PetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var plan PetModel
|
||||
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
reqBody := plan.ToClientModel()
|
||||
|
||||
respBody, err := r.client.DoRequest(ctx, "POST", "/pet", reqBody)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error creating pet", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var result client.Pet
|
||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||
resp.Diagnostics.AddError("Error parsing response", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
plan.FromClientModel(&result)
|
||||
|
||||
tflog.Trace(ctx, "created pet resource")
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
func (r *PetResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
// No read endpoint available; keep existing state as-is.
|
||||
}
|
||||
|
||||
func (r *PetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
// No update endpoint available; persist the planned values into state.
|
||||
var plan PetModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
func (r *PetResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
// No delete endpoint available; remove the resource from state.
|
||||
}
|
||||
|
||||
func (r *PetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/example/terraform-provider-petstore-addpet/internal/client"
|
||||
)
|
||||
|
||||
var _ provider.Provider = &petstoreProvider{}
|
||||
|
||||
type petstoreProvider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type petstoreProviderModel struct {
|
||||
Endpoint types.String `tfsdk:"endpoint"`
|
||||
ApiKey types.String `tfsdk:"api_key"`
|
||||
Token types.String `tfsdk:"token"`
|
||||
Username types.String `tfsdk:"username"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
}
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &petstoreProvider{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *petstoreProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "petstore"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *petstoreProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"endpoint": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The API endpoint URL.",
|
||||
},
|
||||
"api_key": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The API key for authentication.",
|
||||
},
|
||||
"token": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The bearer token for authentication.",
|
||||
},
|
||||
"username": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "The username for basic authentication.",
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
Description: "The password for basic authentication.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *petstoreProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
var config petstoreProviderModel
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if config.Endpoint.IsUnknown() {
|
||||
resp.Diagnostics.AddWarning(
|
||||
"Unknown Endpoint Value",
|
||||
"The provider endpoint value is not yet known. Defaulting to the spec-defined base path.",
|
||||
)
|
||||
}
|
||||
|
||||
endpoint := "http://petstore.swagger.io/v2"
|
||||
if !config.Endpoint.IsNull() && !config.Endpoint.IsUnknown() {
|
||||
endpoint = config.Endpoint.ValueString()
|
||||
}
|
||||
|
||||
c := client.NewClient(endpoint)
|
||||
|
||||
if !config.ApiKey.IsNull() {
|
||||
c.ApiKey = config.ApiKey.ValueString()
|
||||
}
|
||||
if !config.Token.IsNull() {
|
||||
c.Token = config.Token.ValueString()
|
||||
}
|
||||
if !config.Username.IsNull() {
|
||||
c.Username = config.Username.ValueString()
|
||||
}
|
||||
if !config.Password.IsNull() {
|
||||
c.Password = config.Password.ValueString()
|
||||
}
|
||||
|
||||
resp.DataSourceData = c
|
||||
resp.ResourceData = c
|
||||
}
|
||||
|
||||
func (p *petstoreProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
NewPetResource,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *petstoreProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{
|
||||
NewPetDataSource,
|
||||
}
|
||||
}
|
||||
35
samples/client/petstore/terraform-addpet/main.go
Normal file
35
samples/client/petstore/terraform-addpet/main.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||
|
||||
"github.com/example/terraform-provider-petstore-addpet/internal/provider"
|
||||
)
|
||||
|
||||
var (
|
||||
version string = "0.1.0"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var debug bool
|
||||
|
||||
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||
flag.Parse()
|
||||
|
||||
opts := providerserver.ServeOpts{
|
||||
Address: "registry.terraform.io/example/petstore-addpet",
|
||||
Debug: debug,
|
||||
}
|
||||
|
||||
err := providerserver.Serve(context.Background(), provider.New(version), opts)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
13
samples/client/petstore/terraform-server/.gitignore
vendored
Normal file
13
samples/client/petstore/terraform-server/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dylib
|
||||
*.so
|
||||
*.test
|
||||
*.out
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
.terraform/
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
terraform-provider-petstore
|
||||
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1,33 @@
|
||||
.gitignore
|
||||
GNUmakefile
|
||||
README.md
|
||||
examples/provider/provider.tf
|
||||
go.mod
|
||||
internal/client/client.go
|
||||
internal/client/model_an_object.go
|
||||
internal/client/model_api_response.go
|
||||
internal/client/model_category.go
|
||||
internal/client/model_colour.go
|
||||
internal/client/model_gender.go
|
||||
internal/client/model_order.go
|
||||
internal/client/model_order_info.go
|
||||
internal/client/model_pet.go
|
||||
internal/client/model_special_info.go
|
||||
internal/client/model_species.go
|
||||
internal/client/model_tag.go
|
||||
internal/client/model_user.go
|
||||
internal/client/model_user_nullable.go
|
||||
internal/provider/fake_data_source.go
|
||||
internal/provider/fake_model.go
|
||||
internal/provider/fake_resource.go
|
||||
internal/provider/pet_data_source.go
|
||||
internal/provider/pet_model.go
|
||||
internal/provider/pet_resource.go
|
||||
internal/provider/provider.go
|
||||
internal/provider/store_data_source.go
|
||||
internal/provider/store_model.go
|
||||
internal/provider/store_resource.go
|
||||
internal/provider/user_data_source.go
|
||||
internal/provider/user_model.go
|
||||
internal/provider/user_resource.go
|
||||
main.go
|
||||
@@ -0,0 +1 @@
|
||||
7.20.0-SNAPSHOT
|
||||
27
samples/client/petstore/terraform-server/GNUmakefile
Normal file
27
samples/client/petstore/terraform-server/GNUmakefile
Normal file
@@ -0,0 +1,27 @@
|
||||
default: testacc
|
||||
|
||||
# Run acceptance tests
|
||||
.PHONY: testacc
|
||||
testacc:
|
||||
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
|
||||
|
||||
# Build provider
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o terraform-provider-petstore
|
||||
|
||||
# Install provider locally
|
||||
.PHONY: install
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/example/petstore-server/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)
|
||||
mv terraform-provider-petstore ~/.terraform.d/plugins/registry.terraform.io/example/petstore-server/0.1.0/$(shell go env GOOS)_$(shell go env GOARCH)/
|
||||
|
||||
# Generate documentation
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go generate ./...
|
||||
|
||||
# Run linter
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
61
samples/client/petstore/terraform-server/README.md
Normal file
61
samples/client/petstore/terraform-server/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Terraform Provider petstore
|
||||
|
||||
This Terraform provider was generated using [OpenAPI Generator](https://openapi-generator.tech).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Terraform](https://www.terraform.io/downloads.html) >= 1.0
|
||||
- [Go](https://golang.org/doc/install) >= 1.22
|
||||
|
||||
## Building The Provider
|
||||
|
||||
1. Clone the repository
|
||||
2. Enter the repository directory
|
||||
3. Build the provider using the Go `install` command:
|
||||
|
||||
```shell
|
||||
go install
|
||||
```
|
||||
|
||||
## Using the provider
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
petstore = {
|
||||
source = "registry.terraform.io/example/petstore-server"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "petstore" {
|
||||
endpoint = "http://petstore.swagger.io/v2"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing the Provider
|
||||
|
||||
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
|
||||
|
||||
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
|
||||
|
||||
For local development and testing, add a `dev_overrides` block to your `~/.terraformrc` so that Terraform uses the locally built binary instead of fetching from the registry:
|
||||
|
||||
```hcl
|
||||
provider_installation {
|
||||
dev_overrides {
|
||||
"registry.terraform.io/example/petstore-server" = "${GOPATH}/bin"
|
||||
}
|
||||
direct {}
|
||||
}
|
||||
```
|
||||
|
||||
With `dev_overrides` configured, you do not need to run `terraform init` for the provider.
|
||||
|
||||
To generate or update documentation, run `go generate`.
|
||||
|
||||
In order to run the full suite of Acceptance tests, run `make testacc`.
|
||||
|
||||
```shell
|
||||
make testacc
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
petstore = {
|
||||
source = "registry.terraform.io/example/petstore-server"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "petstore" {
|
||||
endpoint = "http://petstore.swagger.io/v2"
|
||||
# api_key = "your-api-key"
|
||||
# token = "your-bearer-token"
|
||||
}
|
||||
11
samples/client/petstore/terraform-server/go.mod
Normal file
11
samples/client/petstore/terraform-server/go.mod
Normal file
@@ -0,0 +1,11 @@
|
||||
module github.com/example/terraform-provider-petstore-server
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
)
|
||||
99
samples/client/petstore/terraform-server/go.sum
Normal file
99
samples/client/petstore/terraform-server/go.sum
Normal file
@@ -0,0 +1,99 @@
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,78 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the API client used to interact with the API.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
HTTPClient *http.Client
|
||||
ApiKey string
|
||||
Token string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewClient creates a new API client with the given base URL.
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
HTTPClient: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
// DoRequest executes an HTTP request and returns the response body.
|
||||
func (c *Client) DoRequest(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
|
||||
var reqBody io.Reader
|
||||
if body != nil {
|
||||
jsonBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
reqBody = bytes.NewBuffer(jsonBody)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
// Authentication
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
} else if c.ApiKey != "" {
|
||||
req.Header.Set("Authorization", c.ApiKey)
|
||||
} else if c.Username != "" {
|
||||
req.SetBasicAuth(c.Username, c.Password)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package client
|
||||
|
||||
// AnObject - An array 3-deep.
|
||||
type AnObject struct {
|
||||
Tag Tag `json:"tag,omitempty"`
|
||||
Pet []Pet `json:"Pet,omitempty"`
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user