Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lb): add support for certificates id list #1152

Merged
merged 5 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions docs/resources/lb_frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: |-

Creates and manages Scaleway Load-Balancer Frontends. For more information, see [the documentation](https://developers.scaleway.com/en/products/lb/zoned_api).

## Examples
## Examples Usage

### Basic

Expand All @@ -21,6 +21,40 @@ resource "scaleway_lb_frontend" "frontend01" {
}
```

## With Certificate

```hcl
resource scaleway_lb_ip ip01 {}

resource scaleway_lb lb01 {
ip_id = scaleway_lb_ip.ip01.id
name = "test-lb"
type = "lb-s"
}

resource scaleway_lb_backend bkd01 {
lb_id = scaleway_lb.lb01.id
forward_protocol = "tcp"
forward_port = 443
proxy_protocol = "none"
}

resource scaleway_lb_certificate cert01 {
lb_id = scaleway_lb.lb01.id
name = "test-cert-front-end"
letsencrypt {
common_name = "${replace(scaleway_lb_ip.ip01.ip_address,".", "-")}.lb.${scaleway_lb.lb01.region}.scw.cloud"
}
}

resource scaleway_lb_frontend frt01 {
lb_id = scaleway_lb.lb01.id
backend_id = scaleway_lb_backend.bkd01.id
inbound_port = 443
certificate_ids = [scaleway_lb_certificate.cert01.id]
}
```

## With ACLs

```hcl
Expand Down Expand Up @@ -94,7 +128,7 @@ The following arguments are supported:

- `timeout_client` - (Optional) Maximum inactivity time on the client side. (e.g.: `1s`)

- `certificate_id` - (Optional) Certificate ID that should be used by the frontend.
- `certificate_ids` - (Optional) List of Certificate IDs that should be used by the frontend.

- `acl` - (Optional) A list of ACL rules to apply to the load-balancer frontend. Defined below.

Expand Down Expand Up @@ -123,6 +157,8 @@ The following arguments are supported:
In addition to all arguments above, the following attributes are exported:

- `id` - The ID of the load-balancer frontend.
- `certificate_id` - (Deprecated) first certificate ID used by the frontend.


## Import

Expand Down
20 changes: 20 additions & 0 deletions scaleway/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,17 @@ func expandStringsPtr(data interface{}) *[]string {
return &stringSlice
}

func expandSliceIDsPtr(rawIDs interface{}) *[]string {
var stringSlice []string
if _, ok := rawIDs.([]interface{}); !ok || rawIDs == nil {
return &stringSlice
}
for _, s := range rawIDs.([]interface{}) {
stringSlice = append(stringSlice, expandID(s.(string)))
}
return &stringSlice
}

func expandStringsOrEmpty(data interface{}) []string {
var stringSlice []string
if _, ok := data.([]interface{}); !ok || data == nil {
Expand Down Expand Up @@ -440,6 +451,15 @@ func flattenSliceStringPtr(s []*string) interface{} {
return res
}

func flattenSliceIDs(certificates []string, zone scw.Zone) interface{} {
res := []interface{}(nil)
for _, certificateID := range certificates {
res = append(res, newZonedIDString(zone, certificateID))
}

return res
}

func expandStringPtr(data interface{}) *string {
if data == nil || data == "" {
return nil
Expand Down
39 changes: 31 additions & 8 deletions scaleway/resource_lb_frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,19 @@ func resourceScalewayLbFrontend() *schema.Resource {
Description: "Set the maximum inactivity time on the client side",
},
"certificate_id": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validationUUIDorUUIDWithLocality(),
Description: "Certificate ID",
Type: schema.TypeString,
Computed: true,
Description: "Certificate ID",
Deprecated: "Please use certificate_ids",
},
"certificate_ids": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validationUUIDorUUIDWithLocality(),
},
Description: "Collection of Certificate IDs related to the load balancer and domain",
},
"acl": {
Type: schema.TypeList,
Expand Down Expand Up @@ -182,15 +191,22 @@ func resourceScalewayLbFrontendCreate(ctx context.Context, d *schema.ResourceDat
if err != nil {
return diag.FromErr(err)
}
res, err := lbAPI.CreateFrontend(&lb.ZonedAPICreateFrontendRequest{

createFrontendRequest := &lb.ZonedAPICreateFrontendRequest{
Zone: zone,
LBID: lbID,
Name: expandOrGenerateString(d.Get("name"), "lb-frt"),
InboundPort: int32(d.Get("inbound_port").(int)),
BackendID: expandID(d.Get("backend_id")),
TimeoutClient: timeoutClient,
CertificateID: expandStringPtr(expandID(d.Get("certificate_id"))),
}, scw.WithContext(ctx))
}

certificatesRaw, certificatesExist := d.GetOk("certificate_ids")
if certificatesExist {
createFrontendRequest.CertificateIDs = expandSliceIDsPtr(certificatesRaw)
}

res, err := lbAPI.CreateFrontend(createFrontendRequest, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -235,6 +251,10 @@ func resourceScalewayLbFrontendRead(ctx context.Context, d *schema.ResourceData,
_ = d.Set("certificate_id", "")
}

if len(res.CertificateIDs) > 0 {
_ = d.Set("certificate_ids", flattenSliceIDs(res.CertificateIDs, zone))
}

//read related acls.
resACL, err := lbAPI.ListACLs(&lb.ZonedAPIListACLsRequest{
Zone: zone,
Expand Down Expand Up @@ -377,7 +397,10 @@ func resourceScalewayLbFrontendUpdate(ctx context.Context, d *schema.ResourceDat
InboundPort: int32(d.Get("inbound_port").(int)),
BackendID: expandID(d.Get("backend_id")),
TimeoutClient: timeoutClient,
CertificateID: expandStringPtr(expandID(d.Get("certificate_id"))),
}

if d.HasChanges("certificate_ids") {
req.CertificateIDs = expandSliceIDsPtr(d.Get("certificate_ids"))
}

_, err = lbAPI.UpdateFrontend(req, scw.WithContext(ctx))
Expand Down
104 changes: 104 additions & 0 deletions scaleway/resource_lb_frontend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,110 @@ func TestAccScalewayLbFrontend_Basic(t *testing.T) {
})
}

func TestAccScalewayLbFrontend_Certificate(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
testDNSZone := fmt.Sprintf("test.%s", testDomain)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayLbFrontendDestroy(tt),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource scaleway_lb_ip ip01 {}

resource "scaleway_domain_record" "tf_A" {
dns_zone = %[1]q
name = "test"
type = "A"
data = "${scaleway_lb_ip.ip01.ip_address}"
ttl = 3600
priority = 1
}

resource scaleway_lb lb01 {
ip_id = scaleway_lb_ip.ip01.id
name = "test-lb"
type = "lb-s"
}

resource scaleway_lb_backend bkd01 {
lb_id = scaleway_lb.lb01.id
forward_protocol = "http"
forward_port = 80
proxy_protocol = "none"
}

resource scaleway_lb_certificate cert01 {
lb_id = scaleway_lb.lb01.id
name = "test-cert-front-end"
letsencrypt {
common_name = "${replace(scaleway_lb_ip.ip01.ip_address,".", "-")}.lb.${scaleway_lb.lb01.region}.scw.cloud"
}
}

resource scaleway_lb_certificate cert02 {
lb_id = scaleway_lb.lb01.id
name = "test-cert-front-end2"
letsencrypt {
common_name = %[2]q
}
}

resource scaleway_lb_frontend frt01 {
lb_id = scaleway_lb.lb01.id
backend_id = scaleway_lb_backend.bkd01.id
inbound_port = 80
certificate_ids = [scaleway_lb_certificate.cert01.id, scaleway_lb_certificate.cert02.id]
}
`, testDomain, testDNSZone),
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbFrontendExists(tt, "scaleway_lb_frontend.frt01"),
testAccCheckScalewayFrontendCertificateExist(tt, "scaleway_lb_frontend.frt01", "scaleway_lb_certificate.cert01"),
testAccCheckScalewayFrontendCertificateExist(tt, "scaleway_lb_frontend.frt01", "scaleway_lb_certificate.cert02"),
resource.TestCheckResourceAttr("scaleway_lb_frontend.frt01",
"certificate_ids.#", "2"),
),
},
},
})
}
func testAccCheckScalewayFrontendCertificateExist(tt *TestTools, f, c string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[f]
if !ok {
return fmt.Errorf("resource not found: %s", f)
}

cs, ok := s.RootModule().Resources[c]
if !ok {
return fmt.Errorf("resource not found: %s", c)
}

lbAPI, zone, ID, err := lbAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

frEnd, err := lbAPI.GetFrontend(&lb.ZonedAPIGetFrontendRequest{
FrontendID: ID,
Zone: zone,
})
if err != nil {
return err
}

for _, id := range frEnd.CertificateIDs {
if expandID(cs.Primary.ID) == id {
return nil
}
}

return fmt.Errorf("certificate not found: %s", c)
}
}

func testAccCheckScalewayLbFrontendExists(tt *TestTools, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down
Loading