Skip to content

Commit fe9c8a7

Browse files
committed
feat(kms): add wrapping key resource and datasource
relates to STACKITTPR-416
1 parent 5e8c7a7 commit fe9c8a7

File tree

9 files changed

+1319
-0
lines changed

9 files changed

+1319
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_kms_wrapping_key Data Source - stackit"
4+
subcategory: ""
5+
description: |-
6+
KMS wrapping key datasource schema.
7+
---
8+
9+
# stackit_kms_wrapping_key (Data Source)
10+
11+
KMS wrapping key datasource schema.
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Required
19+
20+
- `keyring_id` (String) The ID of the associated keyring
21+
- `project_id` (String) STACKIT project ID to which the keyring is associated.
22+
- `wrapping_key_id` (String) The ID of the wrapping key
23+
24+
### Optional
25+
26+
- `region` (String) The resource region. If not defined, the provider region is used.
27+
28+
### Read-Only
29+
30+
- `access_scope` (String) The access scope of the key. Default is `PUBLIC`. Possible values are: `PUBLIC`, `SNA`.
31+
- `algorithm` (String) The wrapping algorithm used to wrap the key to import. Possible values are: `rsa_2048_oaep_sha256`, `rsa_3072_oaep_sha256`, `rsa_4096_oaep_sha256`, `rsa_4096_oaep_sha512`, `rsa_2048_oaep_sha256_aes_256_key_wrap`, `rsa_3072_oaep_sha256_aes_256_key_wrap`, `rsa_4096_oaep_sha256_aes_256_key_wrap`, `rsa_4096_oaep_sha512_aes_256_key_wrap`.
32+
- `description` (String) A user chosen description to distinguish multiple wrapping keys.
33+
- `display_name` (String) The display name to distinguish multiple wrapping keys.
34+
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`keyring_id`,`wrapping_key_id`".
35+
- `protection` (String) The underlying system that is responsible for protecting the key material. Possible values are: `software`.
36+
- `public_key` (String) The public key of the wrapping key.
37+
- `purpose` (String) The purpose for which the key will be used. Possible values are: `wrap_symmetric_key`, `wrap_asymmetric_key`.

docs/resources/kms_wrapping_key.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_kms_wrapping_key Resource - stackit"
4+
subcategory: ""
5+
description: |-
6+
KMS wrapping key resource schema.
7+
---
8+
9+
# stackit_kms_wrapping_key (Resource)
10+
11+
KMS wrapping key resource schema.
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Required
19+
20+
- `algorithm` (String) The wrapping algorithm used to wrap the key to import. Possible values are: `rsa_2048_oaep_sha256`, `rsa_3072_oaep_sha256`, `rsa_4096_oaep_sha256`, `rsa_4096_oaep_sha512`, `rsa_2048_oaep_sha256_aes_256_key_wrap`, `rsa_3072_oaep_sha256_aes_256_key_wrap`, `rsa_4096_oaep_sha256_aes_256_key_wrap`, `rsa_4096_oaep_sha512_aes_256_key_wrap`.
21+
- `display_name` (String) The display name to distinguish multiple wrapping keys.
22+
- `keyring_id` (String) The ID of the associated keyring
23+
- `project_id` (String) STACKIT project ID to which the keyring is associated.
24+
- `protection` (String) The underlying system that is responsible for protecting the key material. Possible values are: `software`.
25+
- `purpose` (String) The purpose for which the key will be used. Possible values are: `wrap_symmetric_key`, `wrap_asymmetric_key`.
26+
27+
### Optional
28+
29+
- `access_scope` (String) The access scope of the key. Default is `PUBLIC`. Possible values are: `PUBLIC`, `SNA`.
30+
- `description` (String) A user chosen description to distinguish multiple wrapping keys.
31+
- `region` (String) The resource region. If not defined, the provider region is used.
32+
33+
### Read-Only
34+
35+
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`keyring_id`,`wrapping_key_id`".
36+
- `public_key` (String) The public key of the wrapping key.
37+
- `wrapping_key_id` (String) The ID of the wrapping key

stackit/internal/services/kms/kms_acc_test.go

Lines changed: 354 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
variable "project_id" {}
2+
3+
variable "keyring_display_name" {}
4+
variable "display_name" {}
5+
variable "protection" {}
6+
variable "algorithm" {}
7+
variable "purpose" {}
8+
variable "description" {}
9+
10+
resource "stackit_kms_keyring" "keyring" {
11+
project_id = var.project_id
12+
display_name = var.keyring_display_name
13+
}
14+
15+
resource "stackit_kms_wrapping_key" "wrapping_key" {
16+
project_id = var.project_id
17+
keyring_id = stackit_kms_keyring.keyring.keyring_id
18+
protection = var.protection
19+
algorithm = var.algorithm
20+
display_name = var.display_name
21+
purpose = var.purpose
22+
description = var.description
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
variable "project_id" {}
2+
3+
variable "keyring_display_name" {}
4+
variable "display_name" {}
5+
variable "protection" {}
6+
variable "algorithm" {}
7+
variable "purpose" {}
8+
9+
resource "stackit_kms_keyring" "keyring" {
10+
project_id = var.project_id
11+
display_name = var.keyring_display_name
12+
}
13+
14+
resource "stackit_kms_wrapping_key" "wrapping_key" {
15+
project_id = var.project_id
16+
keyring_id = stackit_kms_keyring.keyring.keyring_id
17+
protection = var.protection
18+
algorithm = var.algorithm
19+
display_name = var.display_name
20+
purpose = var.purpose
21+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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+
sdkUtils "github.com/stackitcloud/stackit-sdk-go/core/utils"
13+
"github.com/stackitcloud/stackit-sdk-go/services/kms"
14+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
15+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
16+
kmsUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/kms/utils"
17+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
18+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
19+
)
20+
21+
var (
22+
_ datasource.DataSource = &wrappingKeyDataSource{}
23+
)
24+
25+
func NewWrappingKeyDataSource() datasource.DataSource {
26+
return &wrappingKeyDataSource{}
27+
}
28+
29+
type wrappingKeyDataSource struct {
30+
client *kms.APIClient
31+
providerData core.ProviderData
32+
}
33+
34+
func (w *wrappingKeyDataSource) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) {
35+
response.TypeName = request.ProviderTypeName + "_kms_wrapping_key"
36+
}
37+
38+
func (w *wrappingKeyDataSource) Configure(ctx context.Context, request datasource.ConfigureRequest, response *datasource.ConfigureResponse) {
39+
var ok bool
40+
w.providerData, ok = conversion.ParseProviderData(ctx, request.ProviderData, &response.Diagnostics)
41+
if !ok {
42+
return
43+
}
44+
45+
apiClient := kmsUtils.ConfigureClient(ctx, &w.providerData, &response.Diagnostics)
46+
if response.Diagnostics.HasError() {
47+
return
48+
}
49+
50+
w.client = apiClient
51+
tflog.Info(ctx, "Wrapping key configured")
52+
}
53+
54+
func (w *wrappingKeyDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, response *datasource.SchemaResponse) {
55+
response.Schema = schema.Schema{
56+
Description: "KMS wrapping key datasource schema.",
57+
Attributes: map[string]schema.Attribute{
58+
"access_scope": schema.StringAttribute{
59+
Description: fmt.Sprintf("The access scope of the key. Default is `%s`. %s", string(kms.ACCESSSCOPE_PUBLIC), utils.FormatPossibleValues(sdkUtils.EnumSliceToStringSlice(kms.AllowedAccessScopeEnumValues)...)),
60+
Computed: true,
61+
},
62+
"algorithm": schema.StringAttribute{
63+
Description: fmt.Sprintf("The wrapping algorithm used to wrap the key to import. %s", utils.FormatPossibleValues(sdkUtils.EnumSliceToStringSlice(kms.AllowedWrappingAlgorithmEnumValues)...)),
64+
Computed: true,
65+
},
66+
"description": schema.StringAttribute{
67+
Description: "A user chosen description to distinguish multiple wrapping keys.",
68+
Computed: true,
69+
},
70+
"display_name": schema.StringAttribute{
71+
Description: "The display name to distinguish multiple wrapping keys.",
72+
Computed: true,
73+
},
74+
"id": schema.StringAttribute{
75+
Description: "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`keyring_id`,`wrapping_key_id`\".",
76+
Computed: true,
77+
},
78+
"keyring_id": schema.StringAttribute{
79+
Description: "The ID of the associated keyring",
80+
Required: true,
81+
Validators: []validator.String{
82+
validate.UUID(),
83+
validate.NoSeparator(),
84+
},
85+
},
86+
"protection": schema.StringAttribute{
87+
Description: fmt.Sprintf("The underlying system that is responsible for protecting the key material. %s", utils.FormatPossibleValues(sdkUtils.EnumSliceToStringSlice(kms.AllowedProtectionEnumValues)...)),
88+
Computed: true,
89+
},
90+
"purpose": schema.StringAttribute{
91+
Description: fmt.Sprintf("The purpose for which the key will be used. %s", utils.FormatPossibleValues(sdkUtils.EnumSliceToStringSlice(kms.AllowedWrappingPurposeEnumValues)...)),
92+
Computed: true,
93+
},
94+
"project_id": schema.StringAttribute{
95+
Description: "STACKIT project ID to which the keyring is associated.",
96+
Required: true,
97+
Validators: []validator.String{
98+
validate.UUID(),
99+
validate.NoSeparator(),
100+
},
101+
},
102+
"region": schema.StringAttribute{
103+
Optional: true,
104+
Computed: true,
105+
Description: "The resource region. If not defined, the provider region is used.",
106+
},
107+
"wrapping_key_id": schema.StringAttribute{
108+
Description: "The ID of the wrapping key",
109+
Required: true,
110+
Validators: []validator.String{
111+
validate.UUID(),
112+
validate.NoSeparator(),
113+
},
114+
},
115+
"public_key": schema.StringAttribute{
116+
Description: "The public key of the wrapping key.",
117+
Computed: true,
118+
},
119+
},
120+
}
121+
}
122+
123+
func (w *wrappingKeyDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
124+
var model Model
125+
diags := request.Config.Get(ctx, &model)
126+
response.Diagnostics.Append(diags...)
127+
if response.Diagnostics.HasError() {
128+
return
129+
}
130+
131+
projectId := model.ProjectId.ValueString()
132+
keyRingId := model.KeyRingId.ValueString()
133+
region := w.providerData.GetRegionWithOverride(model.Region)
134+
wrappingKeyId := model.WrappingKeyId.ValueString()
135+
136+
ctx = tflog.SetField(ctx, "keyring_id", keyRingId)
137+
ctx = tflog.SetField(ctx, "project_id", projectId)
138+
ctx = tflog.SetField(ctx, "region", region)
139+
ctx = tflog.SetField(ctx, "wrapping_key_id", wrappingKeyId)
140+
141+
wrappingKeyResponse, err := w.client.GetWrappingKey(ctx, projectId, region, keyRingId, wrappingKeyId).Execute()
142+
if err != nil {
143+
utils.LogError(
144+
ctx,
145+
&response.Diagnostics,
146+
err,
147+
"Reading wrapping key",
148+
fmt.Sprintf("Wrapping key with ID %q does not exist in project %q.", wrappingKeyId, projectId),
149+
map[int]string{
150+
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
151+
},
152+
)
153+
response.State.RemoveResource(ctx)
154+
return
155+
}
156+
157+
err = mapFields(wrappingKeyResponse, &model, region)
158+
if err != nil {
159+
core.LogAndAddError(ctx, &response.Diagnostics, "Error reading wrapping key", fmt.Sprintf("Processing API payload: %v", err))
160+
return
161+
}
162+
diags = response.State.Set(ctx, model)
163+
response.Diagnostics.Append(diags...)
164+
if response.Diagnostics.HasError() {
165+
return
166+
}
167+
tflog.Info(ctx, "Wrapping key read")
168+
}

0 commit comments

Comments
 (0)