Skip to content

Commit 88dc563

Browse files
committed
feat(tem): add support for blockedlist
1 parent aff03e4 commit 88dc563

File tree

4 files changed

+1431
-0
lines changed

4 files changed

+1431
-0
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_gateway_network": vpcgw.ResourceNetwork(),

internal/services/tem/blockedlist.go

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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+
region, 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+
_, 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, domainID))
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, _, err := NewAPIWithRegionAndID(m, d.Id())
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: d.Get("domain_id").(string),
99+
}, scw.WithContext(ctx))
100+
if err != nil {
101+
if httperrors.Is404(err) {
102+
d.SetId("")
103+
return nil
104+
}
105+
return diag.FromErr(err)
106+
}
107+
108+
if len(blocklists.Blocklists) == 0 {
109+
d.SetId("")
110+
return nil
111+
}
112+
113+
_ = d.Set("email", blocklists.Blocklists[0].Email)
114+
_ = d.Set("reason", blocklists.Blocklists[0].Reason)
115+
_ = d.Set("domain_id", blocklists.Blocklists[0].DomainID)
116+
_ = d.Set("type", blocklists.Blocklists[0].Type)
117+
return nil
118+
}
119+
120+
func ResourceBlockedListDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
121+
api, region, id, err := NewAPIWithRegionAndID(m, d.Id())
122+
if err != nil {
123+
return diag.FromErr(err)
124+
}
125+
126+
err = api.DeleteBlocklist(&tem.DeleteBlocklistRequest{
127+
Region: region,
128+
BlocklistID: id,
129+
}, scw.WithContext(ctx))
130+
if err != nil && !httperrors.Is404(err) {
131+
return diag.FromErr(err)
132+
}
133+
d.SetId("")
134+
return nil
135+
}
+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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+
// Checks if the blocked email is present in Scaleway TEM API
73+
func isBlockedEmailPresent(tt *acctest.TestTools, n string) resource.TestCheckFunc {
74+
return func(state *terraform.State) error {
75+
rs, ok := state.RootModule().Resources[n]
76+
if !ok {
77+
return fmt.Errorf("resource not found: %s", n)
78+
}
79+
80+
api, region, domainID, err := tem.NewAPIWithRegionAndID(tt.Meta, rs.Primary.Attributes["domain_id"])
81+
if err != nil {
82+
return err
83+
}
84+
85+
blockedEmail := rs.Primary.Attributes["email"]
86+
87+
blocklists, err := api.ListBlocklists(&temSDK.ListBlocklistsRequest{
88+
Region: scw.Region(region),
89+
DomainID: domainID,
90+
Email: scw.StringPtr(blockedEmail),
91+
}, scw.WithContext(context.Background()))
92+
93+
if err != nil {
94+
return err
95+
}
96+
97+
if len(blocklists.Blocklists) == 0 {
98+
return fmt.Errorf("blocked email %s not found in blocklist", blockedEmail)
99+
}
100+
101+
return nil
102+
}
103+
}
104+
105+
// Checks if the blocked email is properly destroyed
106+
func isBlockedEmailDestroyed(tt *acctest.TestTools) resource.TestCheckFunc {
107+
return func(state *terraform.State) error {
108+
for _, rs := range state.RootModule().Resources {
109+
if rs.Type != "scaleway_tem_blocked_list" {
110+
continue
111+
}
112+
113+
api, region, domainID, err := tem.NewAPIWithRegionAndID(tt.Meta, rs.Primary.Attributes["domain_id"])
114+
if err != nil {
115+
return err
116+
}
117+
118+
blockedEmail := rs.Primary.Attributes["email"]
119+
120+
blocklists, err := api.ListBlocklists(&temSDK.ListBlocklistsRequest{
121+
Region: scw.Region(region),
122+
DomainID: domainID,
123+
Email: scw.StringPtr(blockedEmail),
124+
}, scw.WithContext(context.Background()))
125+
126+
if err != nil {
127+
return err
128+
}
129+
130+
if len(blocklists.Blocklists) > 0 {
131+
return fmt.Errorf("blocked email %s still present after deletion", blockedEmail)
132+
}
133+
}
134+
135+
return nil
136+
}
137+
}

0 commit comments

Comments
 (0)