Skip to content

Commit f8a8259

Browse files
authored
feat(tem): add support for blockedlist (#2983)
* feat(tem): add support for blockedlist * add test * fix test * fix test blockedlist
1 parent f1509df commit f8a8259

6 files changed

+2492
-420
lines changed

internal/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ func Provider(config *Config) plugin.ProviderFunc {
224224
"scaleway_secret_version": secret.ResourceVersion(),
225225
"scaleway_tem_domain": tem.ResourceDomain(),
226226
"scaleway_tem_domain_validation": tem.ResourceDomainValidation(),
227+
"scaleway_tem_blocked_list": tem.ResourceBlockedList(),
227228
"scaleway_tem_webhook": tem.ResourceWebhook(),
228229
"scaleway_vpc": vpc.ResourceVPC(),
229230
"scaleway_vpc_acl": vpc.ResourceACL(),

internal/services/tem/blockedlist.go

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package tem
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
10+
tem "github.com/scaleway/scaleway-sdk-go/api/tem/v1alpha1"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
14+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
15+
)
16+
17+
func ResourceBlockedList() *schema.Resource {
18+
return &schema.Resource{
19+
CreateContext: ResourceBlockedListCreate,
20+
ReadContext: ResourceBlockedListRead,
21+
DeleteContext: ResourceBlockedListDelete,
22+
Importer: &schema.ResourceImporter{
23+
StateContext: schema.ImportStatePassthroughContext,
24+
},
25+
Schema: map[string]*schema.Schema{
26+
"domain_id": {
27+
Type: schema.TypeString,
28+
Required: true,
29+
ForceNew: true,
30+
Description: "The ID of the domain affected by the blocklist.",
31+
},
32+
"email": {
33+
Type: schema.TypeString,
34+
Required: true,
35+
ForceNew: true,
36+
Description: "Email address to block.",
37+
},
38+
"type": {
39+
Type: schema.TypeString,
40+
Required: true,
41+
ForceNew: true,
42+
Description: "Type of the blocked list. (mailbox_full or mailbox_not_found)",
43+
ValidateFunc: validation.StringInSlice([]string{"mailbox_full", "mailbox_not_found"}, false),
44+
},
45+
"reason": {
46+
Type: schema.TypeString,
47+
Optional: true,
48+
Default: "manual_block",
49+
ForceNew: true,
50+
Description: "Reason for blocking the emails.",
51+
},
52+
"region": regional.Schema(),
53+
"project_id": account.ProjectIDSchema(),
54+
},
55+
}
56+
}
57+
58+
func ResourceBlockedListCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
59+
api, region, err := temAPIWithRegion(d, m)
60+
if err != nil {
61+
return diag.FromErr(err)
62+
}
63+
64+
_, domainID, err := regional.ParseID(d.Get("domain_id").(string))
65+
if err != nil {
66+
return diag.FromErr(err)
67+
}
68+
69+
emails := []string{d.Get("email").(string)}
70+
reason := d.Get("reason").(string)
71+
typeBlockedList := d.Get("type").(string)
72+
73+
resp, err := api.BulkCreateBlocklists(&tem.BulkCreateBlocklistsRequest{
74+
Emails: emails,
75+
Region: region,
76+
DomainID: domainID,
77+
Type: tem.BlocklistType(typeBlockedList),
78+
Reason: &reason,
79+
}, scw.WithContext(ctx))
80+
if err != nil {
81+
return diag.FromErr(err)
82+
}
83+
84+
d.SetId(fmt.Sprintf("%s/%s", region, resp.Blocklists[0].ID))
85+
86+
return ResourceBlockedListRead(ctx, d, m)
87+
}
88+
89+
func ResourceBlockedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
90+
api, region, domainID, err := NewAPIWithRegionAndID(m, d.Get("domain_id").(string))
91+
if err != nil {
92+
return diag.FromErr(err)
93+
}
94+
95+
blocklists, err := api.ListBlocklists(&tem.ListBlocklistsRequest{
96+
Region: region,
97+
Email: scw.StringPtr(d.Get("email").(string)),
98+
DomainID: domainID,
99+
}, scw.WithContext(ctx))
100+
if err != nil {
101+
if httperrors.Is404(err) {
102+
d.SetId("")
103+
104+
return nil
105+
}
106+
107+
return diag.FromErr(err)
108+
}
109+
110+
if len(blocklists.Blocklists) == 0 {
111+
d.SetId("")
112+
113+
return nil
114+
}
115+
116+
_ = d.Set("email", blocklists.Blocklists[0].Email)
117+
_ = d.Set("reason", blocklists.Blocklists[0].Reason)
118+
_ = d.Set("domain_id", fmt.Sprintf("%s/%s", region, blocklists.Blocklists[0].DomainID))
119+
_ = d.Set("type", blocklists.Blocklists[0].Type)
120+
121+
return nil
122+
}
123+
124+
func ResourceBlockedListDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
125+
api, region, id, err := NewAPIWithRegionAndID(m, d.Id())
126+
if err != nil {
127+
return diag.FromErr(err)
128+
}
129+
130+
err = api.DeleteBlocklist(&tem.DeleteBlocklistRequest{
131+
Region: region,
132+
BlocklistID: id,
133+
}, scw.WithContext(ctx))
134+
if err != nil && !httperrors.Is404(err) {
135+
return diag.FromErr(err)
136+
}
137+
138+
d.SetId("")
139+
140+
return nil
141+
}
+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package tem_test
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
10+
temSDK "github.com/scaleway/scaleway-sdk-go/api/tem/v1alpha1"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/tem"
14+
)
15+
16+
func TestAccBlockedList_Basic(t *testing.T) {
17+
tt := acctest.NewTestTools(t)
18+
defer tt.Cleanup()
19+
20+
subDomainName := "test-blockedlist"
21+
22+
blockedEmail := "[email protected]"
23+
24+
resource.ParallelTest(t, resource.TestCase{
25+
PreCheck: func() { acctest.PreCheck(t) },
26+
ProviderFactories: tt.ProviderFactories,
27+
CheckDestroy: isBlockedEmailDestroyed(tt),
28+
Steps: []resource.TestStep{
29+
{
30+
Config: fmt.Sprintf(`
31+
32+
resource "scaleway_domain_zone" "test" {
33+
domain = "%s"
34+
subdomain = "%s"
35+
}
36+
37+
resource scaleway_tem_domain cr01 {
38+
name = scaleway_domain_zone.test.id
39+
accept_tos = true
40+
autoconfig = true
41+
}
42+
43+
resource scaleway_tem_domain_validation valid {
44+
domain_id = scaleway_tem_domain.cr01.id
45+
region = scaleway_tem_domain.cr01.region
46+
timeout = 3600
47+
}
48+
49+
resource "scaleway_tem_blocked_list" "test" {
50+
domain_id = scaleway_tem_domain.cr01.id
51+
email = "%s"
52+
type = "mailbox_full"
53+
reason = "Spam detected"
54+
region = "fr-par"
55+
depends_on = [
56+
scaleway_tem_domain_validation.valid
57+
]
58+
}
59+
`, domainNameValidation, subDomainName, blockedEmail),
60+
Check: resource.ComposeTestCheckFunc(
61+
isBlockedEmailPresent(tt, "scaleway_tem_blocked_list.test"),
62+
resource.TestCheckResourceAttr("scaleway_tem_blocked_list.test", "email", blockedEmail),
63+
resource.TestCheckResourceAttr("scaleway_tem_blocked_list.test", "type", "mailbox_full"),
64+
resource.TestCheckResourceAttr("scaleway_tem_blocked_list.test", "reason", "Spam detected"),
65+
acctest.CheckResourceAttrUUID("scaleway_tem_blocked_list.test", "id"),
66+
),
67+
},
68+
},
69+
})
70+
}
71+
72+
func isBlockedEmailPresent(tt *acctest.TestTools, n string) resource.TestCheckFunc {
73+
return func(state *terraform.State) error {
74+
rs, ok := state.RootModule().Resources[n]
75+
if !ok {
76+
return fmt.Errorf("resource not found: %s", n)
77+
}
78+
79+
api, region, domainID, err := tem.NewAPIWithRegionAndID(tt.Meta, rs.Primary.Attributes["domain_id"])
80+
if err != nil {
81+
return err
82+
}
83+
84+
blockedEmail := rs.Primary.Attributes["email"]
85+
86+
blocklists, err := api.ListBlocklists(&temSDK.ListBlocklistsRequest{
87+
Region: region,
88+
DomainID: domainID,
89+
Email: scw.StringPtr(blockedEmail),
90+
}, scw.WithContext(context.Background()))
91+
if err != nil {
92+
return err
93+
}
94+
95+
if len(blocklists.Blocklists) == 0 {
96+
return fmt.Errorf("blocked email %s not found in blocklist", blockedEmail)
97+
}
98+
99+
return nil
100+
}
101+
}
102+
103+
func isBlockedEmailDestroyed(tt *acctest.TestTools) resource.TestCheckFunc {
104+
return func(state *terraform.State) error {
105+
for _, rs := range state.RootModule().Resources {
106+
if rs.Type != "scaleway_tem_blocked_list" {
107+
continue
108+
}
109+
110+
api, region, domainID, err := tem.NewAPIWithRegionAndID(tt.Meta, rs.Primary.Attributes["domain_id"])
111+
if err != nil {
112+
return err
113+
}
114+
115+
blockedEmail := rs.Primary.Attributes["email"]
116+
117+
blocklists, err := api.ListBlocklists(&temSDK.ListBlocklistsRequest{
118+
Region: region,
119+
DomainID: domainID,
120+
Email: scw.StringPtr(blockedEmail),
121+
}, scw.WithContext(context.Background()))
122+
if err != nil {
123+
return err
124+
}
125+
126+
if len(blocklists.Blocklists) > 0 {
127+
return fmt.Errorf("blocked email %s still present after deletion", blockedEmail)
128+
}
129+
}
130+
131+
return nil
132+
}
133+
}

0 commit comments

Comments
 (0)