Skip to content

Commit 7dc6bd0

Browse files
ahjonesvsin12
authored andcommitted
Added - Provisioned Concurrency for Oracle Functions
1 parent f640428 commit 7dc6bd0

File tree

9 files changed

+183
-11
lines changed

9 files changed

+183
-11
lines changed

examples/functions/main.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ resource "oci_functions_function" "test_function" {
102102
trace_config {
103103
is_enabled = var.function_trace_config.is_enabled
104104
}
105+
106+
provisioned_concurrency_config {
107+
strategy = "CONSTANT"
108+
count = 40
109+
}
105110
}
106111

107112
data "oci_functions_functions" "test_functions" {

internal/integrationtest/functions_function_test.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,21 @@ var (
4848
}
4949

5050
functionRepresentation = map[string]interface{}{
51-
"application_id": acctest.Representation{RepType: acctest.Required, Create: `${oci_functions_application.test_application.id}`},
52-
"display_name": acctest.Representation{RepType: acctest.Required, Create: `ExampleFunction`},
53-
"image": acctest.Representation{RepType: acctest.Required, Create: `${var.image}`, Update: `${var.image_for_update}`},
54-
"memory_in_mbs": acctest.Representation{RepType: acctest.Required, Create: `128`, Update: `256`},
55-
"config": acctest.Representation{RepType: acctest.Optional, Create: map[string]string{"MY_FUNCTION_CONFIG": "ConfVal"}},
56-
"defined_tags": acctest.Representation{RepType: acctest.Optional, Create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, Update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
57-
"freeform_tags": acctest.Representation{RepType: acctest.Optional, Create: map[string]string{"Department": "Finance"}, Update: map[string]string{"Department": "Accounting"}},
58-
"image_digest": acctest.Representation{RepType: acctest.Optional, Create: `${var.image_digest}`, Update: `${var.image_digest_for_update}`},
59-
"timeout_in_seconds": acctest.Representation{RepType: acctest.Optional, Create: `30`, Update: `31`},
60-
"trace_config": acctest.RepresentationGroup{RepType: acctest.Optional, Group: functionTraceConfigRepresentation},
51+
"application_id": acctest.Representation{RepType: acctest.Required, Create: `${oci_functions_application.test_application.id}`},
52+
"display_name": acctest.Representation{RepType: acctest.Required, Create: `ExampleFunction`},
53+
"image": acctest.Representation{RepType: acctest.Required, Create: `${var.image}`, Update: `${var.image_for_update}`},
54+
"memory_in_mbs": acctest.Representation{RepType: acctest.Required, Create: `128`, Update: `256`},
55+
"config": acctest.Representation{RepType: acctest.Optional, Create: map[string]string{"MY_FUNCTION_CONFIG": "ConfVal"}},
56+
"defined_tags": acctest.Representation{RepType: acctest.Optional, Create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, Update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
57+
"freeform_tags": acctest.Representation{RepType: acctest.Optional, Create: map[string]string{"Department": "Finance"}, Update: map[string]string{"Department": "Accounting"}},
58+
"image_digest": acctest.Representation{RepType: acctest.Optional, Create: `${var.image_digest}`, Update: `${var.image_digest_for_update}`},
59+
"provisioned_concurrency_config": acctest.RepresentationGroup{RepType: acctest.Optional, Group: functionProvisionedConcurrencyConfigRepresentation},
60+
"timeout_in_seconds": acctest.Representation{RepType: acctest.Optional, Create: `30`, Update: `31`},
61+
"trace_config": acctest.RepresentationGroup{RepType: acctest.Optional, Group: functionTraceConfigRepresentation},
62+
}
63+
functionProvisionedConcurrencyConfigRepresentation = map[string]interface{}{
64+
"strategy": acctest.Representation{RepType: acctest.Required, Create: `CONSTANT`, Update: `NONE`},
65+
"count": acctest.Representation{RepType: acctest.Optional, Create: `40`, Update: `0`},
6166
}
6267
functionTraceConfigRepresentation = map[string]interface{}{
6368
"is_enabled": acctest.Representation{RepType: acctest.Optional, Create: `false`, Update: `true`},
@@ -138,6 +143,9 @@ func TestFunctionsFunctionResource_basic(t *testing.T) {
138143
resource.TestCheckResourceAttr(resourceName, "image", image),
139144
resource.TestCheckResourceAttr(resourceName, "image_digest", imageDigest),
140145
resource.TestCheckResourceAttr(resourceName, "memory_in_mbs", "128"),
146+
resource.TestCheckResourceAttr(resourceName, "provisioned_concurrency_config.#", "1"),
147+
resource.TestCheckResourceAttr(resourceName, "provisioned_concurrency_config.0.count", "40"),
148+
resource.TestCheckResourceAttr(resourceName, "provisioned_concurrency_config.0.strategy", "CONSTANT"),
141149
resource.TestCheckResourceAttr(resourceName, "timeout_in_seconds", "30"),
142150
resource.TestCheckResourceAttr(resourceName, "trace_config.#", "1"),
143151
resource.TestCheckResourceAttr(resourceName, "trace_config.0.is_enabled", "false"),
@@ -167,6 +175,9 @@ func TestFunctionsFunctionResource_basic(t *testing.T) {
167175
resource.TestCheckResourceAttr(resourceName, "image", imageU),
168176
resource.TestCheckResourceAttr(resourceName, "image_digest", imageDigestU),
169177
resource.TestCheckResourceAttr(resourceName, "memory_in_mbs", "256"),
178+
resource.TestCheckResourceAttr(resourceName, "provisioned_concurrency_config.#", "1"),
179+
resource.TestCheckResourceAttr(resourceName, "provisioned_concurrency_config.0.count", "0"),
180+
resource.TestCheckResourceAttr(resourceName, "provisioned_concurrency_config.0.strategy", "NONE"),
170181
resource.TestCheckResourceAttr(resourceName, "timeout_in_seconds", "31"),
171182
resource.TestCheckResourceAttr(resourceName, "trace_config.#", "1"),
172183
resource.TestCheckResourceAttr(resourceName, "trace_config.0.is_enabled", "true"),
@@ -202,6 +213,9 @@ func TestFunctionsFunctionResource_basic(t *testing.T) {
202213
resource.TestCheckResourceAttr(datasourceName, "functions.0.image_digest", imageDigestU),
203214
resource.TestCheckResourceAttrSet(datasourceName, "functions.0.invoke_endpoint"),
204215
resource.TestCheckResourceAttr(datasourceName, "functions.0.memory_in_mbs", "256"),
216+
resource.TestCheckResourceAttr(datasourceName, "functions.0.provisioned_concurrency_config.#", "1"),
217+
resource.TestCheckResourceAttr(datasourceName, "functions.0.provisioned_concurrency_config.0.count", "0"),
218+
resource.TestCheckResourceAttr(datasourceName, "functions.0.provisioned_concurrency_config.0.strategy", "NONE"),
205219
resource.TestCheckResourceAttrSet(datasourceName, "functions.0.state"),
206220
resource.TestCheckResourceAttrSet(datasourceName, "functions.0.time_created"),
207221
resource.TestCheckResourceAttrSet(datasourceName, "functions.0.time_updated"),
@@ -227,6 +241,9 @@ func TestFunctionsFunctionResource_basic(t *testing.T) {
227241
resource.TestCheckResourceAttr(singularDatasourceName, "image_digest", imageDigestU),
228242
resource.TestCheckResourceAttrSet(singularDatasourceName, "invoke_endpoint"),
229243
resource.TestCheckResourceAttr(singularDatasourceName, "memory_in_mbs", "256"),
244+
resource.TestCheckResourceAttr(singularDatasourceName, "provisioned_concurrency_config.#", "1"),
245+
resource.TestCheckResourceAttr(singularDatasourceName, "provisioned_concurrency_config.0.count", "0"),
246+
resource.TestCheckResourceAttr(singularDatasourceName, "provisioned_concurrency_config.0.strategy", "NONE"),
230247
resource.TestCheckResourceAttrSet(singularDatasourceName, "state"),
231248
resource.TestCheckResourceAttrSet(singularDatasourceName, "time_created"),
232249
resource.TestCheckResourceAttrSet(singularDatasourceName, "time_updated"),

internal/service/functions/functions_function_data_source.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ func (s *FunctionsFunctionDataSourceCrud) SetData() error {
103103
s.D.Set("memory_in_mbs", strconv.FormatInt(*s.Res.MemoryInMBs, 10))
104104
}
105105

106+
if s.Res.ProvisionedConcurrencyConfig != nil {
107+
provisionedConcurrencyConfigArray := []interface{}{}
108+
if provisionedConcurrencyConfigMap := FunctionProvisionedConcurrencyConfigToMap(&s.Res.ProvisionedConcurrencyConfig); provisionedConcurrencyConfigMap != nil {
109+
provisionedConcurrencyConfigArray = append(provisionedConcurrencyConfigArray, provisionedConcurrencyConfigMap)
110+
}
111+
s.D.Set("provisioned_concurrency_config", provisionedConcurrencyConfigArray)
112+
} else {
113+
s.D.Set("provisioned_concurrency_config", nil)
114+
}
115+
106116
s.D.Set("state", s.Res.LifecycleState)
107117

108118
if s.Res.TimeCreated != nil {

internal/service/functions/functions_function_resource.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ package functions
66
import (
77
"context"
88
"fmt"
9+
"log"
910
"strconv"
11+
"strings"
1012

1113
"github.com/terraform-providers/terraform-provider-oci/internal/client"
1214
"github.com/terraform-providers/terraform-provider-oci/internal/tfresource"
1315

1416
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
1517
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
18+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1619

1720
oci_functions "github.com/oracle/oci-go-sdk/v65/functions"
1821
)
@@ -125,6 +128,36 @@ func FunctionsFunctionResource() *schema.Resource {
125128
return requireRecompute, nil
126129
},
127130
},
131+
"provisioned_concurrency_config": {
132+
Type: schema.TypeList,
133+
Optional: true,
134+
Computed: true,
135+
MaxItems: 1,
136+
MinItems: 1,
137+
Elem: &schema.Resource{
138+
Schema: map[string]*schema.Schema{
139+
// Required
140+
"strategy": {
141+
Type: schema.TypeString,
142+
Required: true,
143+
DiffSuppressFunc: tfresource.EqualIgnoreCaseSuppressDiff,
144+
ValidateFunc: validation.StringInSlice([]string{
145+
"CONSTANT",
146+
"NONE",
147+
}, true),
148+
},
149+
150+
// Optional
151+
"count": {
152+
Type: schema.TypeInt,
153+
Optional: true,
154+
Computed: true,
155+
},
156+
157+
// Computed
158+
},
159+
},
160+
},
128161
"timeout_in_seconds": {
129162
Type: schema.TypeInt,
130163
Optional: true,
@@ -297,6 +330,17 @@ func (s *FunctionsFunctionResourceCrud) Create() error {
297330
request.MemoryInMBs = &tmpInt64
298331
}
299332

333+
if provisionedConcurrencyConfig, ok := s.D.GetOkExists("provisioned_concurrency_config"); ok {
334+
if tmpList := provisionedConcurrencyConfig.([]interface{}); len(tmpList) > 0 {
335+
fieldKeyFormat := fmt.Sprintf("%s.%d.%%s", "provisioned_concurrency_config", 0)
336+
tmp, err := s.mapToFunctionProvisionedConcurrencyConfig(fieldKeyFormat)
337+
if err != nil {
338+
return err
339+
}
340+
request.ProvisionedConcurrencyConfig = tmp
341+
}
342+
}
343+
300344
if timeoutInSeconds, ok := s.D.GetOkExists("timeout_in_seconds"); ok {
301345
tmp := timeoutInSeconds.(int)
302346
request.TimeoutInSeconds = &tmp
@@ -385,6 +429,17 @@ func (s *FunctionsFunctionResourceCrud) Update() error {
385429
request.MemoryInMBs = &tmpInt64
386430
}
387431

432+
if provisionedConcurrencyConfig, ok := s.D.GetOkExists("provisioned_concurrency_config"); ok {
433+
if tmpList := provisionedConcurrencyConfig.([]interface{}); len(tmpList) > 0 {
434+
fieldKeyFormat := fmt.Sprintf("%s.%d.%%s", "provisioned_concurrency_config", 0)
435+
tmp, err := s.mapToFunctionProvisionedConcurrencyConfig(fieldKeyFormat)
436+
if err != nil {
437+
return err
438+
}
439+
request.ProvisionedConcurrencyConfig = tmp
440+
}
441+
}
442+
388443
if timeoutInSeconds, ok := s.D.GetOkExists("timeout_in_seconds"); ok {
389444
tmp := timeoutInSeconds.(int)
390445
request.TimeoutInSeconds = &tmp
@@ -461,6 +516,16 @@ func (s *FunctionsFunctionResourceCrud) SetData() error {
461516
s.D.Set("memory_in_mbs", strconv.FormatInt(*s.Res.MemoryInMBs, 10))
462517
}
463518

519+
if s.Res.ProvisionedConcurrencyConfig != nil {
520+
provisionedConcurrencyConfigArray := []interface{}{}
521+
if provisionedConcurrencyConfigMap := FunctionProvisionedConcurrencyConfigToMap(&s.Res.ProvisionedConcurrencyConfig); provisionedConcurrencyConfigMap != nil {
522+
provisionedConcurrencyConfigArray = append(provisionedConcurrencyConfigArray, provisionedConcurrencyConfigMap)
523+
}
524+
s.D.Set("provisioned_concurrency_config", provisionedConcurrencyConfigArray)
525+
} else {
526+
s.D.Set("provisioned_concurrency_config", nil)
527+
}
528+
464529
s.D.Set("state", s.Res.LifecycleState)
465530

466531
if s.Res.TimeCreated != nil {
@@ -484,6 +549,52 @@ func (s *FunctionsFunctionResourceCrud) SetData() error {
484549
return nil
485550
}
486551

552+
func (s *FunctionsFunctionResourceCrud) mapToFunctionProvisionedConcurrencyConfig(fieldKeyFormat string) (oci_functions.FunctionProvisionedConcurrencyConfig, error) {
553+
var baseObject oci_functions.FunctionProvisionedConcurrencyConfig
554+
//discriminator
555+
strategyRaw, ok := s.D.GetOkExists(fmt.Sprintf(fieldKeyFormat, "strategy"))
556+
var strategy string
557+
if ok {
558+
strategy = strategyRaw.(string)
559+
} else {
560+
strategy = "" // default value
561+
}
562+
switch strings.ToLower(strategy) {
563+
case strings.ToLower("CONSTANT"):
564+
details := oci_functions.ConstantProvisionedConcurrencyConfig{}
565+
if count, ok := s.D.GetOkExists(fmt.Sprintf(fieldKeyFormat, "count")); ok {
566+
tmp := count.(int)
567+
details.Count = &tmp
568+
}
569+
baseObject = details
570+
case strings.ToLower("NONE"):
571+
details := oci_functions.NoneProvisionedConcurrencyConfig{}
572+
baseObject = details
573+
default:
574+
return nil, fmt.Errorf("unknown strategy '%v' was specified", strategy)
575+
}
576+
return baseObject, nil
577+
}
578+
579+
func FunctionProvisionedConcurrencyConfigToMap(obj *oci_functions.FunctionProvisionedConcurrencyConfig) map[string]interface{} {
580+
result := map[string]interface{}{}
581+
switch v := (*obj).(type) {
582+
case oci_functions.ConstantProvisionedConcurrencyConfig:
583+
result["strategy"] = "CONSTANT"
584+
585+
if v.Count != nil {
586+
result["count"] = int(*v.Count)
587+
}
588+
case oci_functions.NoneProvisionedConcurrencyConfig:
589+
result["strategy"] = "NONE"
590+
default:
591+
log.Printf("[WARN] Received 'strategy' of unknown type %v", *obj)
592+
return nil
593+
}
594+
595+
return result
596+
}
597+
487598
func (s *FunctionsFunctionResourceCrud) mapToFunctionTraceConfig(fieldKeyFormat string) (oci_functions.FunctionTraceConfig, error) {
488599
result := oci_functions.FunctionTraceConfig{}
489600

internal/service/functions/functions_functions_data_source.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ func (s *FunctionsFunctionsDataSourceCrud) SetData() error {
154154
function["memory_in_mbs"] = strconv.FormatInt(*r.MemoryInMBs, 10)
155155
}
156156

157+
if r.ProvisionedConcurrencyConfig != nil {
158+
provisionedConcurrencyConfigArray := []interface{}{}
159+
if provisionedConcurrencyConfigMap := FunctionProvisionedConcurrencyConfigToMap(&r.ProvisionedConcurrencyConfig); provisionedConcurrencyConfigMap != nil {
160+
provisionedConcurrencyConfigArray = append(provisionedConcurrencyConfigArray, provisionedConcurrencyConfigMap)
161+
}
162+
function["provisioned_concurrency_config"] = provisionedConcurrencyConfigArray
163+
} else {
164+
function["provisioned_concurrency_config"] = nil
165+
}
166+
157167
function["state"] = r.LifecycleState
158168

159169
if r.TimeCreated != nil {

website/docs/d/functions_function.html.markdown

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ The following attributes are exported:
4545
* `image_digest` - The image digest for the version of the image that will be pulled when invoking this function. If no value is specified, the digest currently associated with the image in the Oracle Cloud Infrastructure Registry will be used. Example: `sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7`
4646
* `invoke_endpoint` - The base https invoke URL to set on a client in order to invoke a function. This URL will never change over the lifetime of the function and can be cached.
4747
* `memory_in_mbs` - Maximum usable memory for the function (MiB).
48+
* `provisioned_concurrency_config` - Define the strategy for provisioned concurrency for the function.
49+
* `count` -
50+
* `strategy` - The strategy for provisioned concurrency to be used.
4851
* `state` - The current state of the function.
4952
* `time_created` - The time the function was created, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-09-12T22:47:12.613Z`
5053
* `time_updated` - The time the function was updated, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-09-12T22:47:12.613Z`

website/docs/d/functions_functions.html.markdown

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ The following attributes are exported:
5959
* `image_digest` - The image digest for the version of the image that will be pulled when invoking this function. If no value is specified, the digest currently associated with the image in the Oracle Cloud Infrastructure Registry will be used. Example: `sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7`
6060
* `invoke_endpoint` - The base https invoke URL to set on a client in order to invoke a function. This URL will never change over the lifetime of the function and can be cached.
6161
* `memory_in_mbs` - Maximum usable memory for the function (MiB).
62+
* `provisioned_concurrency_config` - Define the strategy for provisioned concurrency for the function.
63+
* `count` -
64+
* `strategy` - The strategy for provisioned concurrency to be used.
6265
* `state` - The current state of the function.
6366
* `time_created` - The time the function was created, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-09-12T22:47:12.613Z`
6467
* `time_updated` - The time the function was updated, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-09-12T22:47:12.613Z`

website/docs/r/functions_function.html.markdown

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ resource "oci_functions_function" "test_function" {
2727
defined_tags = {"Operations.CostCenter"= "42"}
2828
freeform_tags = {"Department"= "Finance"}
2929
image_digest = var.function_image_digest
30+
provisioned_concurrency_config {
31+
#Required
32+
strategy = var.function_provisioned_concurrency_config_strategy
33+
34+
#Optional
35+
count = var.function_provisioned_concurrency_config_count
36+
}
3037
timeout_in_seconds = var.function_timeout_in_seconds
3138
trace_config {
3239
@@ -50,6 +57,9 @@ The following arguments are supported:
5057
* `image` - (Required) (Updatable) The qualified name of the Docker image to use in the function, including the image tag. The image should be in the Oracle Cloud Infrastructure Registry that is in the same region as the function itself. This field must be updated if image_digest is updated. Example: `phx.ocir.io/ten/functions/function:0.0.1`
5158
* `image_digest` - (Optional) (Updatable) The image digest for the version of the image that will be pulled when invoking this function. If no value is specified, the digest currently associated with the image in the Oracle Cloud Infrastructure Registry will be used. This field must be updated if image is updated. Example: `sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7`
5259
* `memory_in_mbs` - (Required) (Updatable) Maximum usable memory for the function (MiB).
60+
* `provisioned_concurrency_config` - (Optional) (Updatable) Define the strategy for provisioned concurrency for the function.
61+
* `count` - (Required when strategy=CONSTANT) (Updatable)
62+
* `strategy` - (Required) (Updatable) The strategy for provisioned concurrency to be used.
5363
* `timeout_in_seconds` - (Optional) (Updatable) Timeout for executions of the function. Value in seconds.
5464
* `trace_config` - (Optional) (Updatable) Define the tracing configuration for a function.
5565
* `is_enabled` - (Optional) (Updatable) Define if tracing is enabled for the resource.
@@ -75,6 +85,9 @@ The following attributes are exported:
7585
* `image_digest` - The image digest for the version of the image that will be pulled when invoking this function. If no value is specified, the digest currently associated with the image in the Oracle Cloud Infrastructure Registry will be used. This field must be updated if image is updated. Example: `sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7`
7686
* `invoke_endpoint` - The base https invoke URL to set on a client in order to invoke a function. This URL will never change over the lifetime of the function and can be cached.
7787
* `memory_in_mbs` - Maximum usable memory for the function (MiB).
88+
* `provisioned_concurrency_config` - Define the strategy for provisioned concurrency for the function.
89+
* `count` -
90+
* `strategy` - The strategy for provisioned concurrency to be used.
7891
* `state` - The current state of the function.
7992
* `time_created` - The time the function was created, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-09-12T22:47:12.613Z`
8093
* `time_updated` - The time the function was updated, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-09-12T22:47:12.613Z`

0 commit comments

Comments
 (0)