Skip to content
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
4 changes: 1 addition & 3 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ If you want to onboard resources of a STACKIT service `foo` that was not yet in
2. Add a `foo_custom_endpoint` attribute to the provider's `Schema`, in `stackit/provider.go`
3. Check if the custom endpoint is defined and, if yes, use it. In the `Configure` method, add:
```go
if !(providerConfig.FooCustomEndpoint.IsUnknown() || providerConfig.FooCustomEndpoint.IsNull()) {
providerData.FooCustomEndpoint = providerConfig.FooCustomEndpoint.ValueString()
}
setStringField(providerConfig.FooCustomEndpoint, func(v string) { providerData.FooCustomEndpoint = v })
```
4. Create a utils package, for service `foo` it would be `stackit/internal/foo/utils`. Add a `ConfigureClient()` func and use it in your resource and datasource implementations.

Expand Down
38 changes: 38 additions & 0 deletions docs/data-sources/kms_keyring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackit_kms_keyring Data Source - stackit"
subcategory: ""
description: |-
KMS Keyring datasource schema. Uses the default_region specified in the provider configuration as a fallback in case no region is defined on datasource level.
---

# stackit_kms_keyring (Data Source)

KMS Keyring datasource schema. Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on datasource level.

## Example Usage

```terraform
data "stackit_kms_keyring" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
keyring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `keyring_id` (String) An auto generated unique id which identifies the keyring.
- `project_id` (String) STACKIT project ID to which the keyring is associated.

### Optional

- `region` (String) The resource region. If not defined, the provider region is used.

### Read-Only

- `description` (String) A user chosen description to distinguish multiple keyrings.
- `display_name` (String) The display name to distinguish multiple keyrings.
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`keyring_id`".
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ Note: AWS specific checks must be skipped as they do not work on STACKIT. For de
- `experiments` (List of String) Enables experiments. These are unstable features without official support. More information can be found in the README. Available Experiments: iam, routing-tables, network
- `git_custom_endpoint` (String) Custom endpoint for the Git service
- `iaas_custom_endpoint` (String) Custom endpoint for the IaaS service
- `kms_custom_endpoint` (String) Custom endpoint for the KMS service
- `loadbalancer_custom_endpoint` (String) Custom endpoint for the Load Balancer service
- `logme_custom_endpoint` (String) Custom endpoint for the LogMe service
- `mariadb_custom_endpoint` (String) Custom endpoint for the MariaDB service
Expand Down
42 changes: 42 additions & 0 deletions docs/resources/kms_keyring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackit_kms_keyring Resource - stackit"
subcategory: ""
description: |-
KMS Keyring resource schema. Uses the default_region specified in the provider configuration as a fallback in case no region is defined on resource level.
~> Keyrings will not be destroyed by terraform during a terraform destroy. They will just be thrown out of the Terraform state and not deleted on API side. This way we can ensure no keyring setups are deleted by accident and it gives you the option to recover your keys within the grace period.
---

# stackit_kms_keyring (Resource)

KMS Keyring resource schema. Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on resource level.

~> Keyrings will **not** be destroyed by terraform during a `terraform destroy`. They will just be thrown out of the Terraform state and not deleted on API side. **This way we can ensure no keyring setups are deleted by accident and it gives you the option to recover your keys within the grace period.**

## Example Usage

```terraform
resource "stackit_kms_keyring" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
display_name = "example name"
description = "example description"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `display_name` (String) The display name to distinguish multiple keyrings.
- `project_id` (String) STACKIT project ID to which the keyring is associated.

### Optional

- `description` (String) A user chosen description to distinguish multiple keyrings.
- `region` (String) The resource region. If not defined, the provider region is used.

### Read-Only

- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`keyring_id`".
- `keyring_id` (String) An auto generated unique id which identifies the keyring.
4 changes: 4 additions & 0 deletions examples/data-sources/stackit_kms_keyring/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
data "stackit_kms_keyring" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
keyring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
5 changes: 5 additions & 0 deletions examples/resources/stackit_kms_keyring/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "stackit_kms_keyring" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
display_name = "example name"
description = "example description"
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/stackitcloud/stackit-sdk-go/services/git v0.8.0
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha
github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.6.0
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1
github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.1
Expand Down Expand Up @@ -80,7 +81,7 @@ require (
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/oklog/run v1.2.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.9.0
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
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/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=
github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
Expand Down Expand Up @@ -166,6 +166,8 @@ github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0 h1:dnEjyapuv8WwRN5v
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0/go.mod h1:854gnLR92NvAbJAA1xZEumrtNh1DoBP1FXTMvhwYA6w=
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha h1:m1jq6a8dbUe+suFuUNdHmM/cSehpGLUtDbK1CqLqydg=
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha/go.mod h1:Nu1b5Phsv8plgZ51+fkxPVsU91ZJ5Ayz+cthilxdmQ8=
github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0 h1:zxoOv7Fu+FmdsvTKiKkbmLItrMKfL+QoVtz9ReEF30E=
github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0/go.mod h1:KEPVoO21pC4bjy5l0nyhjUJ0+uVwVWb+k2TYrzJ8xYw=
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.6.0 h1:q33ZaCBVEBUsnMDxYyuJKtJvGcE5nKgvuPed3s8zXNI=
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.6.0/go.mod h1:20QOZ3rBC9wTGgzXzLz9M6YheX0VaxWE0/JI+s8On7k=
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1 h1:hv5WrRU9rN6Jx4OwdOGJRyaQrfA9p1tzEoQK6/CDyoA=
Expand Down
10 changes: 7 additions & 3 deletions stackit/internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
)

// Separator used for concatenation of TF-internal resource ID
const Separator = ","

type ResourceType string

const (
Resource ResourceType = "resource"
Datasource ResourceType = "datasource"

// Separator used for concatenation of TF-internal resource ID
Separator = ","

ResourceRegionFallbackDocstring = "Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on resource level."
DatasourceRegionFallbackDocstring = "Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on datasource level."
)

type ProviderData struct {
Expand All @@ -33,6 +36,7 @@ type ProviderData struct {
DnsCustomEndpoint string
GitCustomEndpoint string
IaaSCustomEndpoint string
KMSCustomEndpoint string
LoadBalancerCustomEndpoint string
LogMeCustomEndpoint string
MariaDBCustomEndpoint string
Expand Down
139 changes: 139 additions & 0 deletions stackit/internal/services/kms/keyring/datasource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package kms

import (
"context"
"fmt"
"net/http"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/stackit-sdk-go/services/kms"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
kmsUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/kms/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
)

var (
_ datasource.DataSource = &keyRingDataSource{}
)

func NewKeyRingDataSource() datasource.DataSource {
return &keyRingDataSource{}
}

type keyRingDataSource struct {
client *kms.APIClient
providerData core.ProviderData
}

func (k *keyRingDataSource) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) {
response.TypeName = request.ProviderTypeName + "_kms_keyring"
}

func (k *keyRingDataSource) Configure(ctx context.Context, request datasource.ConfigureRequest, response *datasource.ConfigureResponse) {
var ok bool
k.providerData, ok = conversion.ParseProviderData(ctx, request.ProviderData, &response.Diagnostics)
if !ok {
return
}

apiClient := kmsUtils.ConfigureClient(ctx, &k.providerData, &response.Diagnostics)
if response.Diagnostics.HasError() {
return
}

k.client = apiClient
tflog.Info(ctx, "KMS client configured")
}

func (k *keyRingDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, response *datasource.SchemaResponse) {
response.Schema = schema.Schema{
Description: fmt.Sprintf("KMS Keyring datasource schema. %s", core.DatasourceRegionFallbackDocstring),
Attributes: map[string]schema.Attribute{
"description": schema.StringAttribute{
Description: "A user chosen description to distinguish multiple keyrings.",
Computed: true,
},
"display_name": schema.StringAttribute{
Description: "The display name to distinguish multiple keyrings.",
Computed: true,
},
"keyring_id": schema.StringAttribute{
Description: "An auto generated unique id which identifies the keyring.",
Required: true,
Validators: []validator.String{
validate.UUID(),
validate.NoSeparator(),
},
},
"id": schema.StringAttribute{
Description: "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`keyring_id`\".",
Computed: true,
},
"project_id": schema.StringAttribute{
Description: "STACKIT project ID to which the keyring is associated.",
Required: true,
Validators: []validator.String{
validate.UUID(),
validate.NoSeparator(),
},
},
"region": schema.StringAttribute{
Optional: true,
// must be computed to allow for storing the override value from the provider
Computed: true,
Description: "The resource region. If not defined, the provider region is used.",
},
},
}
}

func (k *keyRingDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
var model Model

diags := request.Config.Get(ctx, &model)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}
projectId := model.ProjectId.ValueString()
keyRingId := model.KeyRingId.ValueString()
region := k.providerData.GetRegionWithOverride(model.Region)

ctx = tflog.SetField(ctx, "keyring_id", keyRingId)
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)

keyRingResponse, err := k.client.GetKeyRing(ctx, projectId, region, keyRingId).Execute()
if err != nil {
utils.LogError(
ctx,
&response.Diagnostics,
err,
"Reading keyring",
fmt.Sprintf("Keyring with ID %q does not exist in project %q.", keyRingId, projectId),
map[int]string{
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
},
)
response.State.RemoveResource(ctx)
return
}

err = mapFields(keyRingResponse, &model, region)
if err != nil {
core.LogAndAddError(ctx, &response.Diagnostics, "Error reading keyring", fmt.Sprintf("Processing API payload: %v", err))
return
}

diags = response.State.Set(ctx, &model)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}
tflog.Info(ctx, "Key ring read")
}
Loading
Loading