Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add konnect_gateway_config_store resource #117

Merged
merged 6 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 82 additions & 1 deletion .speakeasy/gen.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
lockVersion: 2.0.0
id: 9d20c53e-7836-4ea8-88b8-a75fb7dce3a2
management:
docChecksum: 6482e5d4e550b26bd4a5cab39ea4b5ce
docChecksum: e0f244f00a8855da543ba307232d566f
docVersion: 2.0.0
speakeasyVersion: 1.486.0
generationVersion: 2.505.0
Expand Down Expand Up @@ -47,6 +47,7 @@ generatedFiles:
- examples/data-sources/konnect_gateway_basic_auth/data-source.tf
- examples/data-sources/konnect_gateway_ca_certificate/data-source.tf
- examples/data-sources/konnect_gateway_certificate/data-source.tf
- examples/data-sources/konnect_gateway_config_store/data-source.tf
- examples/data-sources/konnect_gateway_consumer/data-source.tf
- examples/data-sources/konnect_gateway_consumer_group/data-source.tf
- examples/data-sources/konnect_gateway_control_plane/data-source.tf
Expand Down Expand Up @@ -197,6 +198,8 @@ generatedFiles:
- examples/resources/konnect_gateway_ca_certificate/resource.tf
- examples/resources/konnect_gateway_certificate/import.sh
- examples/resources/konnect_gateway_certificate/resource.tf
- examples/resources/konnect_gateway_config_store/import.sh
- examples/resources/konnect_gateway_config_store/resource.tf
- examples/resources/konnect_gateway_consumer/import.sh
- examples/resources/konnect_gateway_consumer/resource.tf
- examples/resources/konnect_gateway_consumer_group/import.sh
Expand Down Expand Up @@ -516,6 +519,10 @@ generatedFiles:
- internal/provider/gatewaycertificate_data_source_sdk.go
- internal/provider/gatewaycertificate_resource.go
- internal/provider/gatewaycertificate_resource_sdk.go
- internal/provider/gatewayconfigstore_data_source.go
- internal/provider/gatewayconfigstore_data_source_sdk.go
- internal/provider/gatewayconfigstore_resource.go
- internal/provider/gatewayconfigstore_resource_sdk.go
- internal/provider/gatewayconsumer_data_source.go
- internal/provider/gatewayconsumer_data_source_sdk.go
- internal/provider/gatewayconsumer_resource.go
Expand Down Expand Up @@ -1268,6 +1275,7 @@ generatedFiles:
- internal/sdk/cacertificates.go
- internal/sdk/certificates.go
- internal/sdk/cloudgateways.go
- internal/sdk/configstores.go
- internal/sdk/consumergroups.go
- internal/sdk/consumers.go
- internal/sdk/controlplanegroups.go
Expand Down Expand Up @@ -1323,6 +1331,7 @@ generatedFiles:
- internal/sdk/models/operations/createcacertificate.go
- internal/sdk/models/operations/createcanaryplugin.go
- internal/sdk/models/operations/createcertificate.go
- internal/sdk/models/operations/createconfigstore.go
- internal/sdk/models/operations/createconfiguration.go
- internal/sdk/models/operations/createconfluentplugin.go
- internal/sdk/models/operations/createconsumer.go
Expand Down Expand Up @@ -1454,6 +1463,7 @@ generatedFiles:
- internal/sdk/models/operations/deletecacertificate.go
- internal/sdk/models/operations/deletecanaryplugin.go
- internal/sdk/models/operations/deletecertificate.go
- internal/sdk/models/operations/deleteconfigstore.go
- internal/sdk/models/operations/deleteconfluentplugin.go
- internal/sdk/models/operations/deleteconsumer.go
- internal/sdk/models/operations/deleteconsumergroup.go
Expand Down Expand Up @@ -1590,6 +1600,7 @@ generatedFiles:
- internal/sdk/models/operations/getcacertificate.go
- internal/sdk/models/operations/getcanaryplugin.go
- internal/sdk/models/operations/getcertificate.go
- internal/sdk/models/operations/getconfigstore.go
- internal/sdk/models/operations/getconfiguration.go
- internal/sdk/models/operations/getconfluentplugin.go
- internal/sdk/models/operations/getconsumer.go
Expand Down Expand Up @@ -1737,6 +1748,7 @@ generatedFiles:
- internal/sdk/models/operations/updatebasicauthplugin.go
- internal/sdk/models/operations/updatebotdetectionplugin.go
- internal/sdk/models/operations/updatecanaryplugin.go
- internal/sdk/models/operations/updateconfigstore.go
- internal/sdk/models/operations/updateconfluentplugin.go
- internal/sdk/models/operations/updatecontrolplane.go
- internal/sdk/models/operations/updatecorrelationidplugin.go
Expand Down Expand Up @@ -1890,6 +1902,7 @@ generatedFiles:
- internal/sdk/models/shared/canaryplugin.go
- internal/sdk/models/shared/certificate.go
- internal/sdk/models/shared/certificateinput.go
- internal/sdk/models/shared/configstore.go
- internal/sdk/models/shared/configurationdataplanegroup.go
- internal/sdk/models/shared/configurationdataplanegroupautoscale.go
- internal/sdk/models/shared/configurationdataplanegroupautoscaleautopilot.go
Expand All @@ -1916,6 +1929,7 @@ generatedFiles:
- internal/sdk/models/shared/createappauthstrategyrequest.go
- internal/sdk/models/shared/createappauthstrategyresponse.go
- internal/sdk/models/shared/createauditlogdestination.go
- internal/sdk/models/shared/createconfigstore.go
- internal/sdk/models/shared/createconfigurationdataplanegroup.go
- internal/sdk/models/shared/createconfigurationrequest.go
- internal/sdk/models/shared/createcontrolplanerequest.go
Expand Down Expand Up @@ -2087,6 +2101,7 @@ generatedFiles:
- internal/sdk/models/shared/updateappauthstrategyresponse.go
- internal/sdk/models/shared/updateauditlogdestination.go
- internal/sdk/models/shared/updateauditlogwebhook.go
- internal/sdk/models/shared/updateconfigstore.go
- internal/sdk/models/shared/updatecontrolplanerequest.go
- internal/sdk/models/shared/updatemeshcontrolplanerequest.go
- internal/sdk/models/shared/updateportalappearancerequest.go
Expand Down Expand Up @@ -8513,5 +8528,71 @@ examples:
application/problem+json: {"status": 404, "title": "Not Found", "type": "https://httpstatuses.com/404", "instance": "kong:trace:1234567890", "detail": "Not found"}
"409":
application/problem+json: {"status": 409, "title": "Conflict", "type": "https://httpstatuses.com/409", "instance": "kong:trace:1234567890", "detail": "Conflict"}
create-config-store:
speakeasy-default-create-config-store:
parameters:
path:
controlPlaneId: "9524ec7d-36d9-465d-a8c5-83a3c9390458"
requestBody:
application/json: {"name": "Config Store"}
responses:
"201":
application/json: {"id": "b9e81174-b5bb-4638-a3c3-8afe61a0abf8", "name": "My Name", "created_at": "2022-11-04T20:10:06.927Z", "updated_at": "2022-11-04T20:10:06.927Z"}
"400":
application/problem+json: {"status": 264934, "title": "<value>", "instance": "<value>", "detail": "<value>", "invalid_parameters": [{"field": "name", "rule": "enum", "reason": "is a required field", "choices": ["<value>"], "source": "body"}, {"field": "name", "rule": "enum", "reason": "is a required field", "choices": ["<value>", "<value>"], "source": "body"}]}
"401":
application/problem+json: {"status": 401, "title": "Unauthorized", "type": "https://httpstatuses.com/401", "instance": "kong:trace:1234567890", "detail": "Invalid credentials"}
"403":
application/problem+json: {"status": 403, "title": "Forbidden", "type": "https://httpstatuses.com/403", "instance": "kong:trace:1234567890", "detail": "Forbidden"}
"415":
application/problem+json: {"status": 415, "title": "UnsupportedMediaType", "type": "https://httpstatuses.com/415", "instance": "kong:trace:1234567890", "detail": "UnsupportedMediaType"}
get-config-store:
speakeasy-default-get-config-store:
parameters:
path:
controlPlaneId: "9524ec7d-36d9-465d-a8c5-83a3c9390458"
configStoreId: "d32d905a-ed33-46a3-a093-d8f536af9a8a"
responses:
"200":
application/json: {"id": "b9e81174-b5bb-4638-a3c3-8afe61a0abf8", "name": "My Name", "created_at": "2022-11-04T20:10:06.927Z", "updated_at": "2022-11-04T20:10:06.927Z"}
"401":
application/problem+json: {"status": 401, "title": "Unauthorized", "type": "https://httpstatuses.com/401", "instance": "kong:trace:1234567890", "detail": "Invalid credentials"}
"403":
application/problem+json: {"status": 403, "title": "Forbidden", "type": "https://httpstatuses.com/403", "instance": "kong:trace:1234567890", "detail": "Forbidden"}
update-config-store:
speakeasy-default-update-config-store:
parameters:
path:
controlPlaneId: "9524ec7d-36d9-465d-a8c5-83a3c9390458"
configStoreId: "d32d905a-ed33-46a3-a093-d8f536af9a8a"
requestBody:
application/json: {"name": "Config Store"}
responses:
"200":
application/json: {"id": "b9e81174-b5bb-4638-a3c3-8afe61a0abf8", "name": "My Name", "created_at": "2022-11-04T20:10:06.927Z", "updated_at": "2022-11-04T20:10:06.927Z"}
"400":
application/problem+json: {"status": 188203, "title": "<value>", "instance": "<value>", "detail": "<value>", "invalid_parameters": []}
"401":
application/problem+json: {"status": 401, "title": "Unauthorized", "type": "https://httpstatuses.com/401", "instance": "kong:trace:1234567890", "detail": "Invalid credentials"}
"403":
application/problem+json: {"status": 403, "title": "Forbidden", "type": "https://httpstatuses.com/403", "instance": "kong:trace:1234567890", "detail": "Forbidden"}
"404":
application/problem+json: {"status": 404, "title": "Not Found", "type": "https://httpstatuses.com/404", "instance": "kong:trace:1234567890", "detail": "Not found"}
"415":
application/problem+json: {"status": 415, "title": "UnsupportedMediaType", "type": "https://httpstatuses.com/415", "instance": "kong:trace:1234567890", "detail": "UnsupportedMediaType"}
delete-config-store:
speakeasy-default-delete-config-store:
parameters:
path:
controlPlaneId: "9524ec7d-36d9-465d-a8c5-83a3c9390458"
configStoreId: "d32d905a-ed33-46a3-a093-d8f536af9a8a"
query: {}
responses:
"400":
application/problem+json: {"status": 632538, "title": "<value>", "instance": "<value>", "detail": "<value>", "invalid_parameters": []}
"401":
application/problem+json: {"status": 401, "title": "Unauthorized", "type": "https://httpstatuses.com/401", "instance": "kong:trace:1234567890", "detail": "Invalid credentials"}
"403":
application/problem+json: {"status": 403, "title": "Forbidden", "type": "https://httpstatuses.com/403", "instance": "kong:trace:1234567890", "detail": "Forbidden"}
examplesVersion: 1.0.0
generatedTests: {}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Changelog

## 2.3.0
> Released on 2025/??/??

* Add support for `konnect_portal_team` resource
* Add support for `konnect_audit_log` resource
* Add support for `konnect_audit_log_destination` resource
* Add support for `konnect_gateway_config_store` resource

### Bug fixes

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
all: speakeasy

speakeasy: check-speakeasy
speakeasy run --skip-versioning --output console
speakeasy run --skip-versioning --output console --minimal
@go mod tidy
@go generate .
@git clean -fd examples docs > /dev/null
Expand Down
14 changes: 14 additions & 0 deletions examples/resources/gateway_config_store.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "konnect_gateway_config_store" "my_configstore" {
name = "tf-config-store"

control_plane_id = konnect_gateway_control_plane.tfdemo.id
}

resource "konnect_gateway_vault" "my_vault" {
name = "konnect"
prefix = "my-konnect-vault"
config = jsonencode({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the openAPI spec, config is expected to be an object, why do we encode it as string here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Terraform expects to deal with explicit schemas. Vaults are polymorphic and the config is different for every vault type.

We had two options here:

  1. Create one resource per vault type
  2. Use a single resource with a dynamic schema and the x-speakeasy-type-override: any annotation

We chose option two. This makes the provider accept a string, which is then deserialized in to an any type before being sent to the API.

This decision predates this PR and is in use for every other vault type too.

config_store_id = konnect_gateway_config_store.my_configstore.id
})
control_plane_id = konnect_gateway_control_plane.tfdemo.id
}
149 changes: 149 additions & 0 deletions internal/provider/gatewayconfigstore_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Code generated by Speakeasy (https://speakeasy.com). 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/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/kong/terraform-provider-konnect/v2/internal/sdk"
"github.com/kong/terraform-provider-konnect/v2/internal/sdk/models/operations"
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ datasource.DataSource = &GatewayConfigStoreDataSource{}
var _ datasource.DataSourceWithConfigure = &GatewayConfigStoreDataSource{}

func NewGatewayConfigStoreDataSource() datasource.DataSource {
return &GatewayConfigStoreDataSource{}
}

// GatewayConfigStoreDataSource is the data source implementation.
type GatewayConfigStoreDataSource struct {
client *sdk.Konnect
}

// GatewayConfigStoreDataSourceModel describes the data model.
type GatewayConfigStoreDataSourceModel struct {
ControlPlaneID types.String `tfsdk:"control_plane_id"`
CreatedAt types.String `tfsdk:"created_at"`
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
UpdatedAt types.String `tfsdk:"updated_at"`
}

// Metadata returns the data source type name.
func (r *GatewayConfigStoreDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_gateway_config_store"
}

// Schema defines the schema for the data source.
func (r *GatewayConfigStoreDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "GatewayConfigStore DataSource",

Attributes: map[string]schema.Attribute{
"control_plane_id": schema.StringAttribute{
Required: true,
Description: `The UUID of your control plane. This variable is available in the Konnect manager.`,
},
"created_at": schema.StringAttribute{
Computed: true,
Description: `An ISO-8601 timestamp representation of entity creation date.`,
},
"id": schema.StringAttribute{
Computed: true,
Description: `The Config Store ID.`,
},
"name": schema.StringAttribute{
Computed: true,
Description: `The name of the Config Store`,
},
"updated_at": schema.StringAttribute{
Computed: true,
Description: `An ISO-8601 timestamp representation of entity update date.`,
},
},
}
}

func (r *GatewayConfigStoreDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*sdk.Konnect)

if !ok {
resp.Diagnostics.AddError(
"Unexpected DataSource Configure Type",
fmt.Sprintf("Expected *sdk.Konnect, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

r.client = client
}

func (r *GatewayConfigStoreDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data *GatewayConfigStoreDataSourceModel
var item types.Object

resp.Diagnostics.Append(req.Config.Get(ctx, &item)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{
UnhandledNullAsEmpty: true,
UnhandledUnknownAsEmpty: true,
})...)

if resp.Diagnostics.HasError() {
return
}

var controlPlaneID string
controlPlaneID = data.ControlPlaneID.ValueString()

var configStoreID string
configStoreID = data.ID.ValueString()

request := operations.GetConfigStoreRequest{
ControlPlaneID: controlPlaneID,
ConfigStoreID: configStoreID,
}
res, err := r.client.ConfigStores.GetConfigStore(ctx, request)
if err != nil {
resp.Diagnostics.AddError("failure to invoke API", err.Error())
if res != nil && res.RawResponse != nil {
resp.Diagnostics.AddError("unexpected http request/response", debugResponse(res.RawResponse))
}
return
}
if res == nil {
resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res))
return
}
if res.StatusCode == 404 {
resp.State.RemoveResource(ctx)
return
}
if res.StatusCode != 200 {
resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse))
return
}
if !(res.ConfigStore != nil) {
resp.Diagnostics.AddError("unexpected response from API. Got an unexpected response body", debugResponse(res.RawResponse))
return
}
data.RefreshFromSharedConfigStore(res.ConfigStore)

// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
26 changes: 26 additions & 0 deletions internal/provider/gatewayconfigstore_data_source_sdk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.

package provider

import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/kong/terraform-provider-konnect/v2/internal/sdk/models/shared"
"time"
)

func (r *GatewayConfigStoreDataSourceModel) RefreshFromSharedConfigStore(resp *shared.ConfigStore) {
if resp != nil {
if resp.CreatedAt != nil {
r.CreatedAt = types.StringValue(resp.CreatedAt.Format(time.RFC3339Nano))
} else {
r.CreatedAt = types.StringNull()
}
r.ID = types.StringPointerValue(resp.ID)
r.Name = types.StringPointerValue(resp.Name)
if resp.UpdatedAt != nil {
r.UpdatedAt = types.StringValue(resp.UpdatedAt.Format(time.RFC3339Nano))
} else {
r.UpdatedAt = types.StringNull()
}
}
}
Loading