Skip to content

Commit

Permalink
FLPROD-796: Create snippets api client
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Davydov committed Oct 22, 2024
1 parent e2a1fae commit f62fd6a
Show file tree
Hide file tree
Showing 5 changed files with 430 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/3458.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
Add Snippets API client
```
114 changes: 114 additions & 0 deletions snippets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package cloudflare

import (
"bytes"
"context"
"fmt"
"mime/multipart"
"net/http"
"time"

"github.com/goccy/go-json"
)

type SnippetsResponse struct {
Response
Result []Snippet `json:"result"`
}

type Snippet struct {
CreatedOn time.Time `json:"created_on"`
ModifiedOn time.Time `json:"modified_on"`
SnippetName string `json:"snippet_name"`
}

type SnippetFile struct {
FileName string `json:"file_name"`
Content string `json:"content"`
}

type SnippetRequest struct {
SnippetName string `json:"snippet_name"`
MainFile string `json:"main_file"`
Files []SnippetFile `json:"files"`
}

func (api *API) ListZoneSnippets(ctx context.Context, rc *ResourceContainer) ([]Snippet, error) {
if rc.Identifier == "" {
return nil, ErrMissingZoneID
}

uri := buildURI(fmt.Sprintf("/zones/%s/snippets", rc.Identifier), nil)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, err
}

result := SnippetsResponse{}
if err := json.Unmarshal(res, &result); err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return result.Result, nil
}

type SnippetMetadata struct {
MainModule string `json:"main_module"`
}

func snippetMultipartBody(request SnippetRequest) (string, *bytes.Buffer, error) {
body := new(bytes.Buffer)
mw := multipart.NewWriter(body)
defer mw.Close()

for _, file := range request.Files {
tp, err := mw.CreateFormFile(file.FileName, file.FileName)
if err != nil {
return "", nil, err
}
_, err = tp.Write([]byte(file.Content))
if err != nil {
return "", nil, err
}
}

tp, err := mw.CreateFormField("metadata")
if err != nil {
return "", nil, err
}

if err = json.NewEncoder(tp).Encode(SnippetMetadata{
MainModule: request.MainFile,
}); err != nil {
return "", nil, err
}

return mw.Boundary(), body, nil
}

func (api *API) UpdateZoneSnippet(ctx context.Context, rc *ResourceContainer, params SnippetRequest) ([]Snippet, error) {
if rc.Identifier == "" {
return nil, ErrMissingZoneID
}

uri := fmt.Sprintf("/zones/%s/snippets/%s", rc.Identifier, params.SnippetName)

boundary, body, err := snippetMultipartBody(params)
if err != nil {
return nil, err
}

res, err := api.makeRequestContextWithHeaders(ctx, http.MethodPut, uri, body, http.Header{
"Content-Type": []string{fmt.Sprintf("multipart/form-data; boundary=%s", boundary)},
})
if err != nil {
return nil, err
}

result := SnippetsResponse{}
if err := json.Unmarshal(res, &result); err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return result.Result, nil
}
66 changes: 66 additions & 0 deletions snippets_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cloudflare

import (
"context"
"fmt"
"net/http"

"github.com/goccy/go-json"
)

type SnippetsRulesResponse struct {
Response
Result []SnippetRule `json:"result"`
}

type SnippetRule struct {
ID string `json:"id"`
Enabled *bool `json:"enabled,omitempty"`
Expression string `json:"expression"`
SnippetName string `json:"snippet_name"`
Description string `json:"description"`
}

func (api *API) ListZoneSnippetsRules(ctx context.Context, rc *ResourceContainer) ([]SnippetRule, error) {
if rc.Identifier == "" {
return nil, ErrMissingZoneID
}

uri := buildURI(fmt.Sprintf("/zones/%s/snippets/rules", rc.Identifier), nil)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, err
}

result := SnippetsRulesResponse{}
if err := json.Unmarshal(res, &result); err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return result.Result, nil
}

func (api *API) UpdateZoneSnippetsRules(ctx context.Context, rc *ResourceContainer, params []SnippetRule) ([]SnippetRule, error) {
if rc.Identifier == "" {
return nil, ErrMissingZoneID
}

uri := fmt.Sprintf("/zones/%s/snippets/rules", rc.Identifier)

payload, err := json.Marshal(params)
if err != nil {
return nil, err
}

res, err := api.makeRequestContext(ctx, http.MethodPut, uri, payload)
if err != nil {
return nil, err
}

result := SnippetsRulesResponse{}
if err := json.Unmarshal(res, &result); err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return result.Result, nil
}
131 changes: 131 additions & 0 deletions snippets_rules_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package cloudflare

import (
"context"
"fmt"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
)

func TestSnippetsRules(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, `{
"result": [
{
"id": "some_id_1",
"expression": "true",
"enabled": true,
"description": "some description",
"snippet_name": "snippet_1"
},
{
"id": "some_id_2",
"expression": "true",
"enabled": true,
"description": "some description",
"snippet_name": "snippet_2"
}
],
"success": true,
"errors": [],
"messages": []
}`)
}
mux.HandleFunc("/zones/"+testZoneID+"/snippets/rules", handler)

want := []SnippetRule{
{
ID: "some_id_1",
Expression: "true",
Enabled: BoolPtr(true),
Description: "some description",
SnippetName: "snippet_1",
},
{
ID: "some_id_2",
Expression: "true",
Enabled: BoolPtr(true),
Description: "some description",
SnippetName: "snippet_2",
},
}

zoneActual, err := client.ListZoneSnippetsRules(context.Background(), ZoneIdentifier(testZoneID))
if assert.NoError(t, err) {
assert.Equal(t, want, zoneActual)
}
}

func TestUpdateSnippetsRules(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, `{
"result": [
{
"id": "some_id_1",
"expression": "true",
"enabled": false,
"description": "some description",
"snippet_name": "snippet_1"
},
{
"id": "some_id_2",
"expression": "true",
"enabled": false,
"description": "some description",
"snippet_name": "snippet_2"
}
],
"success": true,
"errors": [],
"messages": []
}`)
}

mux.HandleFunc("/zones/"+testZoneID+"/snippets/rules", handler)
toUpdate := []SnippetRule{
{
Expression: "true",
Enabled: BoolPtr(false),
Description: "some description",
SnippetName: "snippet_1",
},
{
Expression: "true",
Enabled: BoolPtr(false),
Description: "some description",
SnippetName: "snippet_2",
},
}
want := []SnippetRule{
{
ID: "some_id_1",
Expression: "true",
Enabled: BoolPtr(false),
Description: "some description",
SnippetName: "snippet_1",
},
{
ID: "some_id_2",
Expression: "true",
Enabled: BoolPtr(false),
Description: "some description",
SnippetName: "snippet_2",
},
}
zoneActual, err := client.UpdateZoneSnippetsRules(context.Background(), ZoneIdentifier(testZoneID), toUpdate)
if assert.NoError(t, err) {
assert.Equal(t, want, zoneActual)
}
}
Loading

0 comments on commit f62fd6a

Please sign in to comment.