Skip to content

Commit c69e247

Browse files
committed
feat(function): add vpc integration for namespace resource
1 parent e096766 commit c69e247

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

docs/resources/function_namespace.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ The following arguments are supported:
4040

4141
- `secret_environment_variables` - (Optional) The secret environment variables of the namespace.
4242

43+
- `activate_vpc_integration` - (Optional) Activates VPC integration for the namespace. Functions of a namespace with VPC integration activated will be able to connect to a Private Network.
44+
45+
~> **Important** Updates to `activate_vpc_integration` will recreate the namespace.
46+
4347
## Attributes Reference
4448

4549
The `scaleway_function_namespace` resource exports certain attributes once the Functions namespace has been created. These attributes can be referenced in other parts of your Terraform configuration.

internal/services/function/function.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
1515
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
1616
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
17+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1718
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
1819
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
1920
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
@@ -170,6 +171,11 @@ func ResourceFunction() *schema.Resource {
170171
Computed: true,
171172
Description: "The native function domain name.",
172173
},
174+
"private_network_id": {
175+
Type: schema.TypeString,
176+
Optional: true,
177+
Description: "ID of the Private Network the container is connected to",
178+
},
173179
"region": regional.Schema(),
174180
"organization_id": account.OrganizationIDSchema(),
175181
"project_id": account.ProjectIDSchema(),
@@ -214,6 +220,10 @@ func ResourceFunctionCreate(ctx context.Context, d *schema.ResourceData, m inter
214220
req.Timeout = &scw.Duration{Seconds: int64(timeout.(int))}
215221
}
216222

223+
if pnID, ok := d.GetOk("private_network_id"); ok {
224+
req.PrivateNetworkID = types.ExpandStringPtr(locality.ExpandID(pnID.(string)))
225+
}
226+
217227
f, err := api.CreateFunction(req, scw.WithContext(ctx))
218228
if err != nil {
219229
return diag.FromErr(err)
@@ -324,6 +334,10 @@ func ResourceFunctionRead(ctx context.Context, d *schema.ResourceData, m interfa
324334
_ = d.Set("secret_environment_variables", flattenFunctionSecrets(f.SecretEnvironmentVariables))
325335
_ = d.Set("tags", types.FlattenSliceString(f.Tags))
326336

337+
if f.PrivateNetworkID != nil {
338+
_ = d.Set("private_network_id", regional.NewID(region, types.FlattenStringPtr(f.PrivateNetworkID).(string)).String())
339+
}
340+
327341
return diags
328342
}
329343

@@ -415,6 +429,16 @@ func ResourceFunctionUpdate(ctx context.Context, d *schema.ResourceData, m inter
415429
updated = true
416430
}
417431

432+
if d.HasChanges("private_network_id") {
433+
if _, newPNID := d.GetChange("private_network_id"); newPNID != nil && newPNID.(string) != "" {
434+
req.PrivateNetworkID = types.ExpandUpdatedStringPtr(locality.ExpandID(newPNID.(string)))
435+
} else {
436+
req.PrivateNetworkID = nil
437+
}
438+
439+
updated = true
440+
}
441+
418442
if updated {
419443
_, err = api.UpdateFunction(req, scw.WithContext(ctx))
420444
if err != nil {

internal/services/function/namespace.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ func ResourceNamespace() *schema.Resource {
8686
Computed: true,
8787
Description: "The ID of the registry namespace",
8888
},
89+
"activate_vpc_integration": {
90+
Type: schema.TypeBool,
91+
ForceNew: true,
92+
Optional: true,
93+
Default: false,
94+
Description: "Activate VPC integration for the namespace",
95+
},
8996
"region": regional.Schema(),
9097
"organization_id": account.OrganizationIDSchema(),
9198
"project_id": account.ProjectIDSchema(),
@@ -113,6 +120,10 @@ func ResourceFunctionNamespaceCreate(ctx context.Context, d *schema.ResourceData
113120
createReq.Tags = types.ExpandStrings(rawTag)
114121
}
115122

123+
if activateVPC, ok := d.GetOk("activate_vpc_integration"); ok {
124+
createReq.ActivateVpcIntegration = activateVPC.(bool)
125+
}
126+
116127
ns, err := api.CreateNamespace(createReq, scw.WithContext(ctx))
117128
if err != nil {
118129
return diag.FromErr(err)
@@ -155,6 +166,7 @@ func ResourceFunctionNamespaceRead(ctx context.Context, d *schema.ResourceData,
155166
_ = d.Set("registry_endpoint", ns.RegistryEndpoint)
156167
_ = d.Set("registry_namespace_id", ns.RegistryNamespaceID)
157168
_ = d.Set("secret_environment_variables", flattenFunctionSecrets(ns.SecretEnvironmentVariables))
169+
_ = d.Set("activate_vpc_integration", types.FlattenBoolPtr(ns.VpcIntegrationActivated))
158170

159171
return nil
160172
}

internal/services/function/namespace_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
1111
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1212
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/function"
13+
vpcchecks "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/vpc/testfuncs"
1314
)
1415

1516
func TestAccFunctionNamespace_Basic(t *testing.T) {
@@ -179,6 +180,84 @@ func TestAccFunctionNamespace_EnvironmentVariables(t *testing.T) {
179180
})
180181
}
181182

183+
func TestAccFunctionNamespace_VPCIntegration(t *testing.T) {
184+
tt := acctest.NewTestTools(t)
185+
defer tt.Cleanup()
186+
187+
namespaceID := ""
188+
189+
resource.ParallelTest(t, resource.TestCase{
190+
PreCheck: func() { acctest.PreCheck(t) },
191+
ProviderFactories: tt.ProviderFactories,
192+
CheckDestroy: resource.ComposeTestCheckFunc(
193+
testAccCheckFunctionNamespaceDestroy(tt),
194+
testAccCheckFunctionDestroy(tt),
195+
vpcchecks.CheckPrivateNetworkDestroy(tt),
196+
),
197+
Steps: []resource.TestStep{
198+
{
199+
Config: `
200+
resource scaleway_vpc_private_network main {}
201+
202+
resource scaleway_function_namespace main {}
203+
204+
resource scaleway_function main {
205+
namespace_id = scaleway_function_namespace.main.id
206+
privacy = "private"
207+
runtime = "go123"
208+
handler = "Handle"
209+
}
210+
`,
211+
Check: resource.ComposeTestCheckFunc(
212+
testAccCheckFunctionNamespaceExists(tt, "scaleway_function_namespace.main"),
213+
resource.TestCheckResourceAttr("scaleway_function_namespace.main", "activate_vpc_integration", "false"),
214+
acctest.CheckResourceIDPersisted("scaleway_function_namespace.main", &namespaceID),
215+
),
216+
},
217+
//{
218+
// Config: `
219+
// resource scaleway_vpc_private_network main {}
220+
//
221+
// resource scaleway_function_namespace main {}
222+
//
223+
// resource scaleway_function main {
224+
// namespace_id = scaleway_function_namespace.main.id
225+
// privacy = "private"
226+
// runtime = "go123"
227+
// handler = "Handle"
228+
// private_network_id = scaleway_vpc_private_network.main.id
229+
// }
230+
// `,
231+
// ExpectError: regexp.MustCompile("Application can't be attached to private network, vpc integration must be activated on its parent namespace"),
232+
//},
233+
{
234+
Config: `
235+
resource scaleway_vpc_private_network main {}
236+
237+
resource scaleway_function_namespace main {
238+
activate_vpc_integration = true
239+
}
240+
241+
resource scaleway_function main {
242+
namespace_id = scaleway_function_namespace.main.id
243+
privacy = "private"
244+
runtime = "go123"
245+
handler = "Handle"
246+
private_network_id = scaleway_vpc_private_network.main.id
247+
}
248+
`,
249+
Check: resource.ComposeTestCheckFunc(
250+
testAccCheckFunctionNamespaceExists(tt, "scaleway_function_namespace.main"),
251+
testAccCheckFunctionExists(tt, "scaleway_function.main"),
252+
resource.TestCheckResourceAttr("scaleway_function_namespace.main", "activate_vpc_integration", "true"),
253+
resource.TestCheckResourceAttrPair("scaleway_function.main", "private_network_id", "scaleway_vpc_private_network.main", "id"),
254+
acctest.CheckResourceIDChanged("scaleway_function_namespace.main", &namespaceID),
255+
),
256+
},
257+
},
258+
})
259+
}
260+
182261
func testAccCheckFunctionNamespaceExists(tt *acctest.TestTools, n string) resource.TestCheckFunc {
183262
return func(state *terraform.State) error {
184263
rs, ok := state.RootModule().Resources[n]

0 commit comments

Comments
 (0)