Skip to content

Commit c178888

Browse files
authored
feat(mnq): resource credential (#1680)
1 parent c1b21e7 commit c178888

File tree

6 files changed

+1768
-2
lines changed

6 files changed

+1768
-2
lines changed

docs/resources/mnq_credential.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
page_title: "Scaleway: scaleway_mnq_credential"
3+
description: |-
4+
Manages Scaleway Messaging and Queuing Credential.
5+
---
6+
7+
# scaleway_mnq_namespace
8+
9+
This Terraform configuration creates and manage a Scaleway MNQ credential associated with a namespace.
10+
For additional details, kindly refer to our [website](https://www.scaleway.com/en/docs/serverless/messaging/) and
11+
the [API documentation](https://developers.scaleway.com/en/products/messaging_and_queuing/api/v1alpha1/#post-67608e)
12+
13+
## Examples
14+
15+
### NATS credential
16+
17+
```hcl
18+
resource "scaleway_mnq_namespace" "main" {
19+
name = "mnq-ns"
20+
protocol = "nats"
21+
}
22+
23+
resource "scaleway_mnq_credential" "main" {
24+
name = "creed-ns"
25+
namespace_id = scaleway_mnq_namespace.main.id
26+
}
27+
```
28+
29+
### SNS credential
30+
31+
```hcl
32+
resource "scaleway_mnq_namespace" "main" {
33+
name = "your-namespace"
34+
protocol = "sqs_sns"
35+
}
36+
37+
resource "scaleway_mnq_credential" "main" {
38+
name = "your-creed-sns"
39+
namespace_id = scaleway_mnq_namespace.main.id
40+
sqs_sns_credentials {
41+
permissions {
42+
can_publish = true
43+
can_receive = true
44+
can_manage = true
45+
}
46+
}
47+
}
48+
```
49+
50+
## Arguments Reference
51+
52+
The following arguments are supported:
53+
54+
- `name` - (Optional) The credential name..
55+
- `namespace_id` - (Required) The namespace containing the Credential.
56+
- `nats_credentials` - Credentials file used to connect to the NATS service. Only one of `nats_credentials` and `sqs_sns_credentials` may be set.
57+
- `content` - Raw content of the NATS credentials file.
58+
- `sqs_sns_credentials` - Credential used to connect to the SQS/SNS service. Only one of `nats_credentials`
59+
and `sqs_sns_credentials` may be set.
60+
- `permissions` List of permissions associated to this Credential. Only one of permissions may be set.
61+
- `can_publish` - (Optional). Defines if user can publish messages to the service.
62+
- `can_receive` - (Optional). Defines if user can receive messages from the service.
63+
- `can_manage` - (Optional). Defines if user can manage the associated resource(s).
64+
65+
## Attributes Reference
66+
67+
In addition to all arguments above, the following attributes are exported:
68+
69+
- `id` - The credential ID (UUID format).
70+
- `protocol` - The protocol associated to the Credential. Possible values are `nats` and `sqs_sns`.
71+
- `sqs_sns_credentials` - The credential used to connect to the SQS/SNS service.
72+
- `access_key` - The ID of the key.
73+
- `secret_key` - The Secret value of the key.
74+
- `region` - (Defaults to [provider](../index.md#region) `region`). The [region](../guides/regions_and_zones.md#regions)
75+
in which the namespace should be created.
76+
77+
## Import
78+
79+
Credential can be imported using the `{region}/{id}`, e.g.
80+
81+
```bash
82+
$ terraform import scaleway_mnq_credential.main fr-par/11111111111111111111111111111111
83+
```

scaleway/helpers_mnq.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ func mnqAPIWithRegionAndID(m interface{}, regionalID string) (*mnq.API, scw.Regi
2121
meta := m.(*Meta)
2222
mnqAPI := mnq.NewAPI(meta.scwClient)
2323

24-
zone, ID, err := parseRegionalID(regionalID)
24+
region, ID, err := parseRegionalID(regionalID)
2525
if err != nil {
2626
return nil, "", "", err
2727
}
28-
return mnqAPI, zone, ID, nil
28+
return mnqAPI, region, ID, nil
2929
}

scaleway/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
146146
"scaleway_object_bucket_policy": resourceScalewayObjectBucketPolicy(),
147147
"scaleway_object_bucket_website_configuration": ResourceBucketWebsiteConfiguration(),
148148
"scaleway_mnq_namespace": resourceScalewayMNQNamespace(),
149+
"scaleway_mnq_credential": resourceScalewayMNQCredential(),
149150
"scaleway_vpc_public_gateway": resourceScalewayVPCPublicGateway(),
150151
"scaleway_vpc_gateway_network": resourceScalewayVPCGatewayNetwork(),
151152
"scaleway_vpc_public_gateway_dhcp": resourceScalewayVPCPublicGatewayDHCP(),
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
package scaleway
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
mnq "github.com/scaleway/scaleway-sdk-go/api/mnq/v1alpha1"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
10+
)
11+
12+
func resourceScalewayMNQCredential() *schema.Resource {
13+
return &schema.Resource{
14+
CreateContext: resourceScalewayMNQCredentialCreate,
15+
ReadContext: resourceScalewayMNQCredentialRead,
16+
UpdateContext: resourceScalewayMNQCredentialUpdate,
17+
DeleteContext: resourceScalewayMNQCredentialDelete,
18+
Importer: &schema.ResourceImporter{
19+
StateContext: schema.ImportStatePassthroughContext,
20+
},
21+
SchemaVersion: 0,
22+
Schema: map[string]*schema.Schema{
23+
"name": {
24+
Type: schema.TypeString,
25+
Computed: true,
26+
Optional: true,
27+
Description: "The name of the Credential",
28+
},
29+
"namespace_id": {
30+
Type: schema.TypeString,
31+
Required: true,
32+
ForceNew: true,
33+
Description: "The ID of the Namespace associated to",
34+
},
35+
// computed
36+
"region": regionSchema(),
37+
"protocol": {
38+
Type: schema.TypeString,
39+
Computed: true,
40+
Description: "The Namespace protocol",
41+
},
42+
"nats_credentials": {
43+
Type: schema.TypeList,
44+
Optional: true,
45+
Computed: true,
46+
ConflictsWith: []string{"sqs_sns_credentials"},
47+
Description: "credential for NATS protocol",
48+
MaxItems: 1,
49+
Elem: &schema.Resource{
50+
Schema: map[string]*schema.Schema{
51+
"content": {
52+
Type: schema.TypeString,
53+
Computed: true,
54+
Sensitive: true,
55+
Description: "Raw content of the NATS credentials file",
56+
},
57+
},
58+
},
59+
},
60+
"sqs_sns_credentials": {
61+
Type: schema.TypeList,
62+
Optional: true,
63+
Description: "The credential used to connect to the SQS/SNS service",
64+
MaxItems: 1,
65+
ConflictsWith: []string{"nats_credentials"},
66+
Elem: &schema.Resource{
67+
Schema: map[string]*schema.Schema{
68+
"permissions": {
69+
Type: schema.TypeList,
70+
Optional: true,
71+
MaxItems: 1,
72+
Description: "The permission associated to this credential.",
73+
Elem: &schema.Resource{
74+
Schema: map[string]*schema.Schema{
75+
"can_publish": {
76+
Type: schema.TypeBool,
77+
Default: false,
78+
Optional: true,
79+
Description: "Allow publish messages to the service",
80+
},
81+
"can_receive": {
82+
Type: schema.TypeBool,
83+
Default: false,
84+
Optional: true,
85+
Description: "Allow receive messages from the service",
86+
},
87+
"can_manage": {
88+
Type: schema.TypeBool,
89+
Default: false,
90+
Optional: true,
91+
Description: "Allow manage the associated resource",
92+
},
93+
},
94+
},
95+
},
96+
"secret_key": {
97+
Type: schema.TypeString,
98+
Computed: true,
99+
Sensitive: true,
100+
Description: "The secret value of the key",
101+
},
102+
"access_key": {
103+
Type: schema.TypeString,
104+
Computed: true,
105+
Description: "The key of the credential",
106+
},
107+
},
108+
},
109+
},
110+
},
111+
}
112+
}
113+
114+
func resourceScalewayMNQCredentialCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
115+
api, region, err := newMNQAPI(d, meta)
116+
if err != nil {
117+
return diag.FromErr(err)
118+
}
119+
120+
request := &mnq.CreateCredentialRequest{
121+
Name: expandOrGenerateString(d.Get("name").(string), "cred"),
122+
NamespaceID: expandID(d.Get("namespace_id")),
123+
Region: region,
124+
}
125+
126+
if _, ok := d.GetOk("sqs_sns_credentials"); ok {
127+
perm := mnq.Permissions{}
128+
perm.CanPublish = expandBoolPtr(d.Get("sqs_sns_credentials.0.permissions.0.can_publish"))
129+
perm.CanManage = expandBoolPtr(d.Get("sqs_sns_credentials.0.permissions.0.can_manage"))
130+
perm.CanReceive = expandBoolPtr(d.Get("sqs_sns_credentials.0.permissions.0.can_receive"))
131+
request.Permissions = &perm
132+
}
133+
credential, err := api.CreateCredential(request, scw.WithContext(ctx))
134+
if err != nil {
135+
return diag.FromErr(err)
136+
}
137+
_ = d.Set(
138+
"nats_credentials",
139+
setCreedsNATS(credential.NatsCredentials),
140+
)
141+
_ = d.Set(
142+
"sqs_sns_credentials",
143+
setPermissionsSQS(credential.SqsSnsCredentials),
144+
)
145+
146+
d.SetId(newRegionalIDString(region, credential.ID))
147+
148+
return resourceScalewayMNQCredentialRead(ctx, d, meta)
149+
}
150+
151+
func resourceScalewayMNQCredentialRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
152+
api, region, id, err := mnqAPIWithRegionAndID(meta, d.Id())
153+
if err != nil {
154+
return diag.FromErr(err)
155+
}
156+
157+
request := &mnq.GetCredentialRequest{
158+
CredentialID: id,
159+
Region: region,
160+
}
161+
162+
credential, err := api.GetCredential(request, scw.WithContext(ctx))
163+
if err != nil {
164+
if is404Error(err) {
165+
d.SetId("")
166+
return nil
167+
}
168+
return diag.FromErr(err)
169+
}
170+
171+
_ = d.Set("name", credential.Name)
172+
_ = d.Set("protocol", credential.Protocol.String())
173+
_ = d.Set("region", region)
174+
175+
return nil
176+
}
177+
178+
func setCreedsNATS(credentials *mnq.CredentialNATSCredsFile) interface{} {
179+
var flattened []map[string]interface{}
180+
181+
if credentials == nil {
182+
return flattened
183+
}
184+
return []map[string]interface{}{{"content": credentials.Content}}
185+
}
186+
187+
func setPermissionsSQS(credentials *mnq.CredentialSQSSNSCreds) interface{} {
188+
var flattened []map[string]interface{}
189+
190+
if credentials == nil {
191+
return flattened
192+
}
193+
194+
flattened = []map[string]interface{}{
195+
{
196+
"access_key": credentials.AccessKey,
197+
"secret_key": credentials.SecretKey,
198+
},
199+
}
200+
201+
if credentials.Permissions != nil {
202+
flattened[0]["permissions"] = []map[string]interface{}{{
203+
"can_publish": credentials.Permissions.CanPublish,
204+
"can_receive": credentials.Permissions.CanReceive,
205+
"can_manage": credentials.Permissions.CanManage,
206+
}}
207+
}
208+
209+
return flattened
210+
}
211+
212+
func resourceScalewayMNQCredentialUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
213+
api, region, id, err := mnqAPIWithRegionAndID(meta, d.Id())
214+
if err != nil {
215+
return diag.FromErr(err)
216+
}
217+
218+
request := &mnq.UpdateCredentialRequest{
219+
CredentialID: id,
220+
Region: region,
221+
}
222+
223+
if d.HasChange("name") {
224+
request.Name = scw.StringPtr(d.Get("name").(string))
225+
}
226+
227+
if _, exist := d.GetOk("sqs_sns_credentials"); exist && d.HasChange("sqs_sns_credentials") {
228+
perm := mnq.Permissions{}
229+
perm.CanPublish = expandBoolPtr(d.Get("sqs_sns_credentials.0.permissions.0.can_publish"))
230+
perm.CanManage = expandBoolPtr(d.Get("sqs_sns_credentials.0.permissions.0.can_manage"))
231+
perm.CanReceive = expandBoolPtr(d.Get("sqs_sns_credentials.0.permissions.0.can_receive"))
232+
request.Permissions = &perm
233+
}
234+
235+
_, err = api.UpdateCredential(request, scw.WithContext(ctx))
236+
if err != nil {
237+
return diag.FromErr(err)
238+
}
239+
240+
return resourceScalewayMNQCredentialRead(ctx, d, meta)
241+
}
242+
243+
func resourceScalewayMNQCredentialDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
244+
api, region, id, err := mnqAPIWithRegionAndID(meta, d.Id())
245+
if err != nil {
246+
return diag.FromErr(err)
247+
}
248+
249+
request := &mnq.DeleteCredentialRequest{
250+
CredentialID: id,
251+
Region: region,
252+
}
253+
err = api.DeleteCredential(request, scw.WithContext(ctx))
254+
if err != nil && !is404Error(err) {
255+
return diag.FromErr(err)
256+
}
257+
258+
return nil
259+
}

0 commit comments

Comments
 (0)