Skip to content

Commit

Permalink
Add Workers for Platforms APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
WalshyDev committed Feb 29, 2024
1 parent 0156ecb commit 6c0d2b2
Show file tree
Hide file tree
Showing 7 changed files with 415 additions and 5 deletions.
7 changes: 7 additions & 0 deletions .changelog/1508.txt
@@ -0,0 +1,7 @@
```release-note:enhancement
workers_for_platforms: Add ability to list Workers for Platforms namespaces, get a namespace, create a new namespace or delete a namespace.
```

```release-note:enhancement
workers: Add Workers for Platforms support for getting a Worker, content and bindings
```
13 changes: 12 additions & 1 deletion workers.go
Expand Up @@ -262,6 +262,14 @@ func (api *API) DeleteWorker(ctx context.Context, rc *ResourceContainer, params
//
// API reference: https://developers.cloudflare.com/api/operations/worker-script-download-worker
func (api *API) GetWorker(ctx context.Context, rc *ResourceContainer, scriptName string) (WorkerScriptResponse, error) {
return api.GetWorkerWithDispatchNamespace(ctx, rc, scriptName, "")
}

// GetWorker fetch raw script content for your worker returns string containing
// worker code js.
//
// API reference: https://developers.cloudflare.com/api/operations/worker-script-download-worker
func (api *API) GetWorkerWithDispatchNamespace(ctx context.Context, rc *ResourceContainer, scriptName string, dispatchNamespace string) (WorkerScriptResponse, error) {
if rc.Level != AccountRouteLevel {
return WorkerScriptResponse{}, ErrRequiredAccountLevelResourceContainer
}
Expand All @@ -271,6 +279,9 @@ func (api *API) GetWorker(ctx context.Context, rc *ResourceContainer, scriptName
}

uri := fmt.Sprintf("/accounts/%s/workers/scripts/%s", rc.Identifier, scriptName)
if dispatchNamespace != "" {
uri = fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces/%s/scripts/%s/content", rc.Identifier, dispatchNamespace, scriptName)
}
res, err := api.makeRequestContextWithHeadersComplete(ctx, http.MethodGet, uri, nil, nil)
var r WorkerScriptResponse
if err != nil {
Expand Down Expand Up @@ -354,7 +365,7 @@ func (api *API) UploadWorker(ctx context.Context, rc *ResourceContainer, params
}

uri := fmt.Sprintf("/accounts/%s/workers/scripts/%s", rc.Identifier, params.ScriptName)
if params.DispatchNamespaceName != nil {
if params.DispatchNamespaceName != nil && *params.DispatchNamespaceName != "" {
uri = fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces/%s/scripts/%s", rc.Identifier, *params.DispatchNamespaceName, params.ScriptName)
}

Expand Down
12 changes: 8 additions & 4 deletions workers_bindings.go
Expand Up @@ -49,7 +49,8 @@ const (
)

type ListWorkerBindingsParams struct {
ScriptName string
ScriptName string
DispatchNamespace *string
}

// WorkerBindingListItem a struct representing an individual binding in a list of bindings.
Expand Down Expand Up @@ -426,9 +427,9 @@ func (b WorkerD1DatabaseBinding) serialize(bindingName string) (workerBindingMet
}

return workerBindingMeta{
"name": bindingName,
"type": b.Type(),
"id": b.DatabaseID,
"name": bindingName,
"type": b.Type(),
"id": b.DatabaseID,
}, nil, nil
}

Expand Down Expand Up @@ -468,6 +469,9 @@ func (api *API) ListWorkerBindings(ctx context.Context, rc *ResourceContainer, p
}

uri := fmt.Sprintf("/accounts/%s/workers/scripts/%s/bindings", rc.Identifier, params.ScriptName)
if params.DispatchNamespace != nil && *params.DispatchNamespace != "" {
uri = fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces/%s/scripts/%s/bindings", rc.Identifier, *params.DispatchNamespace, params.ScriptName)
}

var jsonRes struct {
Response
Expand Down
85 changes: 85 additions & 0 deletions workers_bindings_test.go
Expand Up @@ -108,6 +108,91 @@ func TestListWorkerBindings(t *testing.T) {
assert.Equal(t, WorkerD1DataseBindingType, res.BindingList[8].Binding.Type())
}

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

mux.HandleFunc("/accounts/"+testAccountID+"/workers/dispatch/namespaces/my-namespace/scripts/my-script/bindings", 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, listBindingsResponseData)
})

res, err := client.ListWorkerBindings(context.Background(), AccountIdentifier(testAccountID), ListWorkerBindingsParams{
ScriptName: "my-script",
DispatchNamespace: &[]string{"my-namespace"}[0],
})
assert.NoError(t, err)

assert.Equal(t, successResponse, res.Response)
assert.Equal(t, 9, len(res.BindingList))

assert.Equal(t, res.BindingList[0], WorkerBindingListItem{
Name: "MY_KV",
Binding: WorkerKvNamespaceBinding{
NamespaceID: "89f5f8fd93f94cb98473f6f421aa3b65",
},
})
assert.Equal(t, WorkerKvNamespaceBindingType, res.BindingList[0].Binding.Type())

// WASM binding - No binding content endpoint exists for WfP

assert.Equal(t, res.BindingList[2], WorkerBindingListItem{
Name: "MY_PLAIN_TEXT",
Binding: WorkerPlainTextBinding{
Text: "text",
},
})
assert.Equal(t, WorkerPlainTextBindingType, res.BindingList[2].Binding.Type())

assert.Equal(t, res.BindingList[3], WorkerBindingListItem{
Name: "MY_SECRET_TEXT",
Binding: WorkerSecretTextBinding{},
})
assert.Equal(t, WorkerSecretTextBindingType, res.BindingList[3].Binding.Type())

environment := "MY_ENVIRONMENT"
assert.Equal(t, res.BindingList[4], WorkerBindingListItem{
Name: "MY_SERVICE_BINDING",
Binding: WorkerServiceBinding{
Service: "MY_SERVICE",
Environment: &environment,
},
})
assert.Equal(t, WorkerServiceBindingType, res.BindingList[4].Binding.Type())

assert.Equal(t, res.BindingList[5], WorkerBindingListItem{
Name: "MY_NEW_BINDING",
Binding: WorkerInheritBinding{},
})
assert.Equal(t, WorkerInheritBindingType, res.BindingList[5].Binding.Type())

assert.Equal(t, res.BindingList[6], WorkerBindingListItem{
Name: "MY_BUCKET",
Binding: WorkerR2BucketBinding{
BucketName: "bucket",
},
})
assert.Equal(t, WorkerR2BucketBindingType, res.BindingList[6].Binding.Type())

assert.Equal(t, res.BindingList[7], WorkerBindingListItem{
Name: "MY_DATASET",
Binding: WorkerAnalyticsEngineBinding{
Dataset: "my_dataset",
},
})

assert.Equal(t, WorkerAnalyticsEngineBindingType, res.BindingList[7].Binding.Type())

assert.Equal(t, res.BindingList[8], WorkerBindingListItem{
Name: "MY_DATABASE",
Binding: WorkerD1DatabaseBinding{
DatabaseID: "cef5331f-e5c7-4c8a-a415-7908ae45f92a",
},
})
assert.Equal(t, WorkerD1DataseBindingType, res.BindingList[8].Binding.Type())
}

func ExampleUnsafeBinding() {
pretty := func(meta workerBindingMeta) string {
buf := bytes.NewBufferString("")
Expand Down
139 changes: 139 additions & 0 deletions workers_for_platforms.go
@@ -0,0 +1,139 @@
package cloudflare

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

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

type WorkersForPlatformsDispatchNamespace struct {
NamespaceId string `json:"namespace_id"`
NamespaceName string `json:"namespace_name"`
CreatedOn time.Time `json:"created_on"`
CreatedBy string `json:"created_by"`
ModifiedOn time.Time `json:"modified_on"`
ModifiedBy string `json:"modified_by"`
}

type ListWorkersForPlatformsDispatchNamespaceResponse struct {
Response
Result []WorkersForPlatformsDispatchNamespace `json:"result"`
}

type GetWorkersForPlatformsDispatchNamespaceResponse struct {
Response
Result WorkersForPlatformsDispatchNamespace `json:"result"`
}

type CreateWorkersForPlatformsDispatchNamespaceParams struct {
Name string `json:"name"`
}

// ListWorkersForPlatformsDispatchNamespaces lists the dispatch namespaces.
//
// API reference: https://developers.cloudflare.com/api/operations/namespace-worker-list
func (api *API) ListWorkersForPlatformsDispatchNamespaces(ctx context.Context, rc *ResourceContainer) (*ListWorkersForPlatformsDispatchNamespaceResponse, error) {
if rc.Level != AccountRouteLevel {
return nil, ErrRequiredAccountLevelResourceContainer
}

if rc.Identifier == "" {
return nil, ErrMissingAccountID
}

uri := fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces", rc.Identifier)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)

var r ListWorkersForPlatformsDispatchNamespaceResponse
if err != nil {
return nil, err
}

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

return &r, nil
}

// GetWorkersForPlatformsDispatchNamespace gets a specific dispatch namespace.
//
// API reference: https://developers.cloudflare.com/api/operations/namespace-worker-get-namespace
func (api *API) GetWorkersForPlatformsDispatchNamespace(ctx context.Context, rc *ResourceContainer, name string) (*GetWorkersForPlatformsDispatchNamespaceResponse, error) {
if rc.Level != AccountRouteLevel {
return nil, ErrRequiredAccountLevelResourceContainer
}

if rc.Identifier == "" {
return nil, ErrMissingAccountID
}

uri := fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces/%s", rc.Identifier, name)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)

var r GetWorkersForPlatformsDispatchNamespaceResponse
if err != nil {
return nil, err
}

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

return &r, nil
}

// CreateWorkersForPlatformsDispatchNamespace creates a new dispatch namespace.
//
// API reference: https://developers.cloudflare.com/api/operations/namespace-worker-create
func (api *API) CreateWorkersForPlatformsDispatchNamespace(ctx context.Context, rc *ResourceContainer, params CreateWorkersForPlatformsDispatchNamespaceParams) (*GetWorkersForPlatformsDispatchNamespaceResponse, error) {
if rc.Level != AccountRouteLevel {
return nil, ErrRequiredAccountLevelResourceContainer
}

if rc.Identifier == "" {
return nil, ErrMissingAccountID
}

uri := fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces", rc.Identifier)
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)

var r GetWorkersForPlatformsDispatchNamespaceResponse
if err != nil {
return nil, err
}

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

return &r, nil
}

// DeleteWorkersForPlatformsDispatchNamespace deletes a dispatch namespace.
//
// API reference: https://developers.cloudflare.com/api/operations/namespace-worker-delete-namespace
func (api *API) DeleteWorkersForPlatformsDispatchNamespace(ctx context.Context, rc *ResourceContainer, name string) error {
if rc.Level != AccountRouteLevel {
return ErrRequiredAccountLevelResourceContainer
}

if rc.Identifier == "" {
return ErrMissingAccountID
}

uri := fmt.Sprintf("/accounts/%s/workers/dispatch/namespaces/%s", rc.Identifier, name)
_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)

if err != nil {
return err
}

return nil
}

0 comments on commit 6c0d2b2

Please sign in to comment.