diff --git a/cloudflarekv/cloudflarekv.go b/cloudflarekv/cloudflarekv.go index f0459d93..704657a7 100644 --- a/cloudflarekv/cloudflarekv.go +++ b/cloudflarekv/cloudflarekv.go @@ -8,15 +8,39 @@ import ( "github.com/cloudflare/cloudflare-go" ) +type APIInterface interface { + DeleteWorkersKVEntries(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.DeleteWorkersKVEntriesParams) (cloudflare.Response, error) + DeleteWorkersKVEntry(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.DeleteWorkersKVEntryParams) (cloudflare.Response, error) + GetWorkersKV(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.GetWorkersKVParams) ([]byte, error) + ListWorkersKVKeys(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.ListWorkersKVsParams) (cloudflare.ListStorageKeysResponse, error) + WriteWorkersKVEntry(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.WriteWorkersKVEntryParams) (cloudflare.Response, error) +} + type Storage struct { - api *cloudflare.API + api APIInterface email string accountID string namespaceID string } func New(config ...Config) *Storage { + cfg := configDefault(config...) + if cfg.Key == "test" { + api := &TestModule{ + baseUrl: "http://localhost:8787", + } + + storage := &Storage{ + api: api, + email: "example@cloudflare.org", + accountID: "dummy-ID", + namespaceID: "dummy-ID", + } + + return storage + } + api, err := cloudflare.NewWithAPIToken(cfg.Key) if err != nil { log.Println("Error with cloudflare api initialization") @@ -33,6 +57,7 @@ func New(config ...Config) *Storage { } func (s *Storage) Get(key string) ([]byte, error) { + resp, err := s.api.GetWorkersKV(context.Background(), cloudflare.AccountIdentifier(s.accountID), cloudflare.GetWorkersKVParams{NamespaceID: s.namespaceID, Key: key}) if err != nil { @@ -60,6 +85,7 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error { } func (s *Storage) Delete(key string) error { + _, err := s.api.DeleteWorkersKVEntry(context.Background(), cloudflare.AccountIdentifier(s.accountID), cloudflare.DeleteWorkersKVEntryParams{ NamespaceID: s.namespaceID, Key: key, @@ -123,6 +149,6 @@ func (s *Storage) Close() error { return nil } -func (s *Storage) Conn() *cloudflare.API { +func (s *Storage) Conn() APIInterface { return s.api } diff --git a/cloudflarekv/cloudflarekv_test.go b/cloudflarekv/cloudflarekv_test.go index a474c9e7..2315a057 100644 --- a/cloudflarekv/cloudflarekv_test.go +++ b/cloudflarekv/cloudflarekv_test.go @@ -12,10 +12,10 @@ var testStore *Storage func TestMain(m *testing.M) { testStore = New(Config{ - Key: os.Getenv("CF_AUTH_TOKEN"), - AccountID: os.Getenv("CF_ACCOUNT_ID"), - NamespaceID: os.Getenv("CF_KV_NAMESPACE"), - Email: os.Getenv("CF_EMAIL"), + Key: "test", + AccountID: "", + NamespaceID: "", + Email: "", Reset: true, }) @@ -42,6 +42,10 @@ func Test_CloudflareKV_Get(t *testing.T) { val = "doe" ) + err := testStore.Set(key, []byte("doe"), 0) + + require.NoError(t, err) + result, err := testStore.Get(key) require.NoError(t, err) diff --git a/cloudflarekv/test_module.go b/cloudflarekv/test_module.go new file mode 100644 index 00000000..c10e481e --- /dev/null +++ b/cloudflarekv/test_module.go @@ -0,0 +1,256 @@ +package cloudflarekv + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + + "github.com/cloudflare/cloudflare-go" +) + +type getWorkersKVBody struct { + Key string `json:"key"` +} + +type writeWorkersKVBody struct { + Key string `json:"key"` + Val string `json:"val"` +} + +type deleteworkerskvpairbykeyBody struct { + Key string `json:"key"` +} + +type listworkerskvkeysBody struct { + Limit string `json:"limit"` + Prefix string `json:"prefix"` + Cursor string `json:"cursor"` +} + +type deleteworkerskventriesBody struct { + Keys []string `json:"keys"` +} + +type TestModule struct { + baseUrl string +} + +func (t *TestModule) GetWorkersKV(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.GetWorkersKVParams) ([]byte, error) { + log.Println(ctx, rc) + + client := &http.Client{} + + jsonBody := getWorkersKVBody{ + Key: params.Key, + } + + marshalledBody, err := json.Marshal(jsonBody) + + if err != nil { + log.Println("Error in marshalling") + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, t.baseUrl+"/getworkerskvvaluebykey", bytes.NewReader(marshalledBody)) + + if err != nil { + log.Println("Error occur in /getworkerskvvaluebykey > making http call") + return nil, err + } + + resp, err := client.Do(req) + + if err != nil { + log.Println("Error occur in /getworkerskvvaluebykey > operating http call") + return nil, err + } + + defer resp.Body.Close() + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + str := string(respBody) + println(str) + } + + return respBody, nil +} + +func (t *TestModule) WriteWorkersKVEntry(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.WriteWorkersKVEntryParams) (cloudflare.Response, error) { + log.Println(ctx, rc) + + client := &http.Client{} + + jsonBody := writeWorkersKVBody{ + Key: params.Key, + Val: string(params.Value), + } + + marshalledBody, err := json.Marshal(jsonBody) + + if err != nil { + log.Println("Error in marshalling") + return cloudflare.Response{}, err + } + + req, err := http.NewRequest(http.MethodPost, t.baseUrl+"/writeworkerskvkeyvaluepair", bytes.NewReader(marshalledBody)) + + if err != nil { + log.Println("Error occur in /writeworkerskvkeyvaluepair > making http call") + return cloudflare.Response{}, err + } + + req.Header.Add("Content-Type", "application/json") + + resp, err := client.Do(req) + + if err != nil { + log.Println("Error occur in /writeworkerskvkeyvaluepair > operating http call") + return cloudflare.Response{}, err + } + + defer resp.Body.Close() + + return cloudflare.Response{ + Success: true, + }, nil + +} + +func (t *TestModule) DeleteWorkersKVEntry(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.DeleteWorkersKVEntryParams) (cloudflare.Response, error) { + log.Println(ctx, rc) + + client := &http.Client{} + + jsonBody := deleteworkerskvpairbykeyBody{ + Key: params.Key, + } + + marshalledBody, err := json.Marshal(jsonBody) + + if err != nil { + log.Println("Error in marshalling") + return cloudflare.Response{}, err + } + + req, err := http.NewRequest(http.MethodDelete, t.baseUrl+"/deleteworkerskvpairbykey", bytes.NewReader(marshalledBody)) + + if err != nil { + log.Println("Error occur in /deleteworkerskvpairbykey > making http call") + return cloudflare.Response{}, err + } + + resp, err := client.Do(req) + + if err != nil { + log.Println("Error occur in /deleteworkerskvpairbykey > operating http call") + return cloudflare.Response{}, err + } + + defer resp.Body.Close() + + return cloudflare.Response{ + Success: true, + }, nil + +} + +func (t *TestModule) ListWorkersKVKeys(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.ListWorkersKVsParams) (cloudflare.ListStorageKeysResponse, error) { + log.Println(ctx, rc) + + client := &http.Client{} + + jsonBody := listworkerskvkeysBody{ + Limit: fmt.Sprint(params.Limit), + Prefix: params.Prefix, + Cursor: params.Cursor, + } + + marshalledBody, err := json.Marshal(jsonBody) + + if err != nil { + log.Println("Error in marshalling") + return cloudflare.ListStorageKeysResponse{}, err + } + + req, err := http.NewRequest(http.MethodPost, t.baseUrl+"/listworkerskvkeys", bytes.NewReader(marshalledBody)) + + if err != nil { + log.Println("Error occur in /listworkerskvkeys > making http call") + return cloudflare.ListStorageKeysResponse{}, err + } + + req.Header.Add("Content-Type", "application/json") + + resp, err := client.Do(req) + + if err != nil { + log.Println("Error occur in /listworkerskvkeys > operating http call") + return cloudflare.ListStorageKeysResponse{}, err + } + + defer resp.Body.Close() + + result := []cloudflare.StorageKey{} + + respBody, err := io.ReadAll(resp.Body) + + if err != nil { + str := string(respBody) + println(str) + } + + if err := json.Unmarshal(respBody, &result); err != nil { + log.Println("Error with parsing response body") + return cloudflare.ListStorageKeysResponse{}, nil + } + + return cloudflare.ListStorageKeysResponse{ + Result: result, + }, nil +} + +func (t *TestModule) DeleteWorkersKVEntries(ctx context.Context, rc *cloudflare.ResourceContainer, params cloudflare.DeleteWorkersKVEntriesParams) (cloudflare.Response, error) { + log.Println(ctx, rc) + + client := &http.Client{} + + jsonBody := deleteworkerskventriesBody{ + Keys: params.Keys, + } + + marshalledBody, err := json.Marshal(jsonBody) + + if err != nil { + log.Println("Error in marshalling") + return cloudflare.Response{}, err + } + + req, err := http.NewRequest(http.MethodDelete, t.baseUrl+"/deleteworkerskventries", bytes.NewReader(marshalledBody)) + + if err != nil { + log.Println("Error occur in /deleteworkerskventries > making new request") + return cloudflare.Response{ + Errors: []cloudflare.ResponseInfo{}, + }, err + } + + req.Header.Add("Content-Type", "application/json") + + _, err = client.Do(req) + + if err != nil { + log.Println("Error occuer in /deleteworkerskventries > operating http call") + return cloudflare.Response{ + Errors: []cloudflare.ResponseInfo{}, + }, err + } + + return cloudflare.Response{ + Success: true, + }, nil +}