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

Support text func code for fgs #1096

Merged
merged 1 commit into from
Apr 30, 2021
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
33 changes: 31 additions & 2 deletions docs/resources/fgs_function.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ subcategory: "FunctionGraph"
Manages a Function resource within HuaweiCloud.
This is an alternative to `huaweicloud_fgs_function_v2`

## Example Usage
## Example Usage With base64 func code

```hcl
resource "huaweicloud_fgs_function" "f_1" {
Expand All @@ -24,6 +24,35 @@ resource "huaweicloud_fgs_function" "f_1" {
}
```

## Example Usage With text code

```hcl
resource "huaweicloud_fgs_function" "f_1" {
name = "func_1"
app = "default"
agency = "test"
description = "fuction test"
handler = "test.handler"
memory_size = 128
timeout = 3
runtime = "Python2.7"
code_type = "inline"
func_code = <<EOF
# -*- coding:utf-8 -*-
import json
def handler (event, context):
return {
"statusCode": 200,
"isBase64Encoded": False,
"body": json.dumps(event),
"headers": {
"Content-Type": "application/json"
}
}
EOF
}
```

## Argument Reference

The following arguments are supported:
Expand Down Expand Up @@ -60,7 +89,7 @@ The following arguments are supported:
Changing this creates a new function.

* `func_code` - (Required, String, ForceNew) Function code. When code_type is set to inline, zip, or jar, this parameter is mandatory,
and the code must be encoded using Base64. Changing this creates a new function.
and the code can be encoded using Base64 or just with the text code. Changing this creates a new function.


## Attributes Reference
Expand Down
44 changes: 39 additions & 5 deletions huaweicloud/resource_huaweicloud_fgs_function_v2.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package huaweicloud

import (
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"fmt"
"log"
"strings"
Expand Down Expand Up @@ -113,6 +116,14 @@ func resourceFgsFunctionV2() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: func(v interface{}) string {
switch v.(type) {
case string:
return funcCodeHashSum(v.(string))
default:
return ""
}
},
},
},
}
Expand Down Expand Up @@ -146,10 +157,6 @@ func resourceFgsFunctionV2Create(d *schema.ResourceData, meta interface{}) error
agency_v = v.(string)
}

func_code := function.FunctionCodeOpts{
File: d.Get("func_code").(string),
}

createOpts := function.CreateOpts{
FuncName: d.Get("name").(string),
Package: pack_v,
Expand All @@ -163,7 +170,14 @@ func resourceFgsFunctionV2Create(d *schema.ResourceData, meta interface{}) error
Timeout: d.Get("timeout").(int),
UserData: d.Get("user_data").(string),
Xrole: agency_v,
FuncCode: func_code,
}

if v, ok := d.GetOk("func_code"); ok {
funcCode := funcCodeEncode(v.(string))
func_code := function.FunctionCodeOpts{
File: funcCode,
}
createOpts.FuncCode = func_code
}

log.Printf("[DEBUG] Create Options: %#v", createOpts)
Expand Down Expand Up @@ -236,3 +250,23 @@ func resourceFgsFunctionV2Delete(d *schema.ResourceData, meta interface{}) error
d.SetId("")
return nil
}

func funcCodeHashSum(script string) string {
// Check whether the func_code is not Base64 encoded.
// Always calculate hash of base64 decoded value since we
// check against double-encoding when setting it
v, base64DecodeError := base64.StdEncoding.DecodeString(script)
if base64DecodeError != nil {
v = []byte(script)
}

hash := sha1.Sum(v)
return hex.EncodeToString(hash[:])
}

func funcCodeEncode(script string) string {
if _, err := base64.StdEncoding.DecodeString(script); err != nil {
return base64.StdEncoding.EncodeToString([]byte(script))
}
return script
}
69 changes: 61 additions & 8 deletions huaweicloud/resource_huaweicloud_fgs_function_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"

Expand All @@ -13,16 +14,38 @@ import (

func TestAccFgsV2Function_basic(t *testing.T) {
var f function.Function
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))
resourceName := "huaweicloud_fgs_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckFgsV2FunctionDestroy,
Steps: []resource.TestStep{
{
Config: testAccFgsV2Function_basic,
Config: testAccFgsV2Function_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckFgsV2FunctionExists("huaweicloud_fgs_function_v2.f_1", &f),
testAccCheckFgsV2FunctionExists(resourceName, &f),
),
},
},
})
}

func TestAccFgsV2Function_text(t *testing.T) {
var f function.Function
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))
resourceName := "huaweicloud_fgs_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckFgsV2FunctionDestroy,
Steps: []resource.TestStep{
{
Config: testAccFgsV2Function_text(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckFgsV2FunctionExists(resourceName, &f),
),
},
},
Expand All @@ -37,7 +60,7 @@ func testAccCheckFgsV2FunctionDestroy(s *terraform.State) error {
}

for _, rs := range s.RootModule().Resources {
if rs.Type != "huaweicloud_fgs_function_v2" {
if rs.Type != "huaweicloud_fgs_function" {
continue
}

Expand Down Expand Up @@ -82,16 +105,46 @@ func testAccCheckFgsV2FunctionExists(n string, ft *function.Function) resource.T
}
}

const testAccFgsV2Function_basic = `
resource "huaweicloud_fgs_function_v2" "f_1" {
name = "func_1"
func testAccFgsV2Function_basic(rName string) string {
return fmt.Sprintf(`
resource "huaweicloud_fgs_function" "test" {
name = "%s"
app = "default"
description = "fuction test"
handler = "test.handler"
handler = "index.handler"
memory_size = 128
timeout = 3
runtime = "Python2.7"
code_type = "inline"
func_code = "aW1wb3J0IGpzb24KZGVmIGhhbmRsZXIgKGV2ZW50LCBjb250ZXh0KToKICAgIG91dHB1dCA9ICdIZWxsbyBtZXNzYWdlOiAnICsganNvbi5kdW1wcyhldmVudCkKICAgIHJldHVybiBvdXRwdXQ="
}
`
`, rName)
}

func testAccFgsV2Function_text(rName string) string {
return fmt.Sprintf(`
resource "huaweicloud_fgs_function" "test" {
name = "%s"
app = "default"
description = "fuction test"
handler = "index.handler"
memory_size = 128
timeout = 3
runtime = "Python2.7"
code_type = "inline"
func_code = <<EOF
# -*- coding:utf-8 -*-
import json
def handler (event, context):
return {
"statusCode": 200,
"isBase64Encoded": False,
"body": json.dumps(event),
"headers": {
"Content-Type": "application/json"
}
}
EOF
}
`, rName)
}