Skip to content

Commit d667641

Browse files
committed
feat(kms): add keyring resource and datasource
relates to STACKITTPR-410
1 parent 64d6fa9 commit d667641

File tree

18 files changed

+1028
-6
lines changed

18 files changed

+1028
-6
lines changed

CONTRIBUTION.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ If you want to onboard resources of a STACKIT service `foo` that was not yet in
8080
2. Add a `foo_custom_endpoint` attribute to the provider's `Schema`, in `stackit/provider.go`
8181
3. Check if the custom endpoint is defined and, if yes, use it. In the `Configure` method, add:
8282
```go
83-
if !(providerConfig.FooCustomEndpoint.IsUnknown() || providerConfig.FooCustomEndpoint.IsNull()) {
84-
providerData.FooCustomEndpoint = providerConfig.FooCustomEndpoint.ValueString()
85-
}
83+
setStringField(providerConfig.FooCustomEndpoint, func(v string) { providerData.FooCustomEndpoint = v })
8684
```
8785
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.
8886

docs/data-sources/kms_keyring.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_kms_keyring Data Source - stackit"
4+
subcategory: ""
5+
description: |-
6+
KMS Keyring resource schema.
7+
---
8+
9+
# stackit_kms_keyring (Data Source)
10+
11+
KMS Keyring resource schema.
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "stackit_kms_keyring" "example" {
17+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
18+
keyring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
19+
}
20+
```
21+
22+
<!-- schema generated by tfplugindocs -->
23+
## Schema
24+
25+
### Required
26+
27+
- `keyring_id` (String) An auto generated unique id which identifies the keyring.
28+
- `project_id` (String) STACKIT project ID to which the keyring is associated.
29+
30+
### Read-Only
31+
32+
- `description` (String) A user chosen description to distinguish multiple keyrings.
33+
- `display_name` (String) The display name to distinguish multiple keyrings.
34+
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`keyring_id`".
35+
- `region` (String) The resource region. If not defined, the provider region is used.

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ Note: AWS specific checks must be skipped as they do not work on STACKIT. For de
162162
- `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
163163
- `git_custom_endpoint` (String) Custom endpoint for the Git service
164164
- `iaas_custom_endpoint` (String) Custom endpoint for the IaaS service
165+
- `kms_custom_endpoint` (String) Custom endpoint for the KMS service
165166
- `loadbalancer_custom_endpoint` (String) Custom endpoint for the Load Balancer service
166167
- `logme_custom_endpoint` (String) Custom endpoint for the LogMe service
167168
- `mariadb_custom_endpoint` (String) Custom endpoint for the MariaDB service

docs/resources/kms_keyring.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_kms_keyring Resource - stackit"
4+
subcategory: ""
5+
description: |-
6+
KMS Keyring resource schema.
7+
~> 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.
8+
---
9+
10+
# stackit_kms_keyring (Resource)
11+
12+
KMS Keyring resource schema.
13+
14+
~> 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.**
15+
16+
## Example Usage
17+
18+
```terraform
19+
resource "stackit_kms_keyring" "example" {
20+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
21+
display_name = "example name"
22+
description = "example description"
23+
}
24+
```
25+
26+
<!-- schema generated by tfplugindocs -->
27+
## Schema
28+
29+
### Required
30+
31+
- `display_name` (String) The display name to distinguish multiple keyrings.
32+
- `project_id` (String) STACKIT project ID to which the keyring is associated.
33+
34+
### Optional
35+
36+
- `description` (String) A user chosen description to distinguish multiple keyrings.
37+
- `region` (String) The resource region. If not defined, the provider region is used.
38+
39+
### Read-Only
40+
41+
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`keyring_id`".
42+
- `keyring_id` (String) An auto generated unique id which identifies the keyring.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
data "stackit_kms_keyring" "example" {
2+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
keyring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
4+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
resource "stackit_kms_keyring" "example" {
2+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
display_name = "example name"
4+
description = "example description"
5+
}

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/stackitcloud/stackit-sdk-go/services/git v0.8.0
1818
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0
1919
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha
20+
github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0
2021
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.6.0
2122
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1
2223
github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.1
@@ -80,7 +81,7 @@ require (
8081
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
8182
github.com/mitchellh/mapstructure v1.5.0 // indirect
8283
github.com/mitchellh/reflectwalk v1.0.2 // indirect
83-
github.com/oklog/run v1.1.0 // indirect
84+
github.com/oklog/run v1.2.0 // indirect
8485
github.com/rogpeppe/go-internal v1.13.1 // indirect
8586
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.9.0
8687
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
137137
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
138138
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
139139
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
140-
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
141-
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
140+
github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=
141+
github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk=
142142
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
143143
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
144144
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@@ -166,6 +166,8 @@ github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0 h1:dnEjyapuv8WwRN5v
166166
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0/go.mod h1:854gnLR92NvAbJAA1xZEumrtNh1DoBP1FXTMvhwYA6w=
167167
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha h1:m1jq6a8dbUe+suFuUNdHmM/cSehpGLUtDbK1CqLqydg=
168168
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha/go.mod h1:Nu1b5Phsv8plgZ51+fkxPVsU91ZJ5Ayz+cthilxdmQ8=
169+
github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0 h1:zxoOv7Fu+FmdsvTKiKkbmLItrMKfL+QoVtz9ReEF30E=
170+
github.com/stackitcloud/stackit-sdk-go/services/kms v1.0.0/go.mod h1:KEPVoO21pC4bjy5l0nyhjUJ0+uVwVWb+k2TYrzJ8xYw=
169171
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.6.0 h1:q33ZaCBVEBUsnMDxYyuJKtJvGcE5nKgvuPed3s8zXNI=
170172
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.6.0/go.mod h1:20QOZ3rBC9wTGgzXzLz9M6YheX0VaxWE0/JI+s8On7k=
171173
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.1 h1:hv5WrRU9rN6Jx4OwdOGJRyaQrfA9p1tzEoQK6/CDyoA=

stackit/internal/core/core.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type ProviderData struct {
3333
DnsCustomEndpoint string
3434
GitCustomEndpoint string
3535
IaaSCustomEndpoint string
36+
KMSCustomEndpoint string
3637
LoadBalancerCustomEndpoint string
3738
LogMeCustomEndpoint string
3839
MariaDBCustomEndpoint string
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package kms
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
8+
"github.com/hashicorp/terraform-plugin-framework/datasource"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
11+
"github.com/hashicorp/terraform-plugin-log/tflog"
12+
"github.com/stackitcloud/stackit-sdk-go/services/kms"
13+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
14+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
15+
kmsUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/kms/utils"
16+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
17+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
18+
)
19+
20+
var (
21+
_ datasource.DataSource = &keyRingDataSource{}
22+
)
23+
24+
func NewKeyRingDataSource() datasource.DataSource {
25+
return &keyRingDataSource{}
26+
}
27+
28+
type keyRingDataSource struct {
29+
client *kms.APIClient
30+
providerData core.ProviderData
31+
}
32+
33+
func (k *keyRingDataSource) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) {
34+
response.TypeName = request.ProviderTypeName + "_kms_keyring"
35+
}
36+
37+
func (k *keyRingDataSource) Configure(ctx context.Context, request datasource.ConfigureRequest, response *datasource.ConfigureResponse) {
38+
var ok bool
39+
k.providerData, ok = conversion.ParseProviderData(ctx, request.ProviderData, &response.Diagnostics)
40+
if !ok {
41+
return
42+
}
43+
44+
apiClient := kmsUtils.ConfigureClient(ctx, &k.providerData, &response.Diagnostics)
45+
if response.Diagnostics.HasError() {
46+
return
47+
}
48+
49+
k.client = apiClient
50+
tflog.Info(ctx, "Keyring configured")
51+
}
52+
53+
func (k *keyRingDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, response *datasource.SchemaResponse) {
54+
response.Schema = schema.Schema{
55+
Description: "KMS Keyring resource schema.",
56+
Attributes: map[string]schema.Attribute{
57+
"description": schema.StringAttribute{
58+
Description: "A user chosen description to distinguish multiple keyrings.",
59+
Computed: true,
60+
},
61+
"display_name": schema.StringAttribute{
62+
Description: "The display name to distinguish multiple keyrings.",
63+
Computed: true,
64+
},
65+
"keyring_id": schema.StringAttribute{
66+
Description: "An auto generated unique id which identifies the keyring.",
67+
Computed: false,
68+
Required: true,
69+
Validators: []validator.String{
70+
validate.UUID(),
71+
validate.NoSeparator(),
72+
},
73+
},
74+
"id": schema.StringAttribute{
75+
Description: "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`keyring_id`\".",
76+
Computed: true,
77+
},
78+
"project_id": schema.StringAttribute{
79+
Description: "STACKIT project ID to which the keyring is associated.",
80+
Required: true,
81+
Validators: []validator.String{
82+
validate.UUID(),
83+
validate.NoSeparator(),
84+
},
85+
},
86+
"region": schema.StringAttribute{
87+
Computed: true,
88+
Description: "The resource region. If not defined, the provider region is used.",
89+
},
90+
},
91+
}
92+
}
93+
94+
func (k *keyRingDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
95+
var model Model
96+
97+
diags := request.Config.Get(ctx, &model)
98+
response.Diagnostics.Append(diags...)
99+
if response.Diagnostics.HasError() {
100+
return
101+
}
102+
projectId := model.ProjectId.ValueString()
103+
keyRingId := model.KeyRingId.ValueString()
104+
region := k.providerData.GetRegionWithOverride(model.Region)
105+
106+
ctx = tflog.SetField(ctx, "keyring_id", keyRingId)
107+
ctx = tflog.SetField(ctx, "project_id", projectId)
108+
ctx = tflog.SetField(ctx, "region", region)
109+
110+
keyRingResponse, err := k.client.GetKeyRing(ctx, projectId, region, keyRingId).Execute()
111+
if err != nil {
112+
utils.LogError(
113+
ctx,
114+
&response.Diagnostics,
115+
err,
116+
"Reading keyring",
117+
fmt.Sprintf("Keyring with ID %q does not exist in project %q.", keyRingId, projectId),
118+
map[int]string{
119+
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
120+
},
121+
)
122+
response.State.RemoveResource(ctx)
123+
return
124+
}
125+
126+
err = mapFields(keyRingResponse, &model, region)
127+
if err != nil {
128+
core.LogAndAddError(ctx, &response.Diagnostics, "Error reading keyring", fmt.Sprintf("Processing API payload: %v", err))
129+
return
130+
}
131+
132+
diags = response.State.Set(ctx, &model)
133+
response.Diagnostics.Append(diags...)
134+
if response.Diagnostics.HasError() {
135+
return
136+
}
137+
tflog.Info(ctx, "Key ring read")
138+
}

0 commit comments

Comments
 (0)