Repository: cloudflare/cloudflare-go
Pull request #1148 (2022-12-15 15:53:19)

Support for Managed networks
Provide a general summary of your changes in the title above. You should
remove this overview, any sections and any section descriptions you
don't need below before submitting. There isn't a strict requirement to
use this template if you can structure your description and still cover
these points.

## Description

Allow users ability to manage managed networks using terraform.

## Has your change been tested?

Yes using unit tests

## Screenshots (if appropriate):

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This change is using publicly documented (api.cloudflare.com or developers.cloudflare.com) and stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/



Patch:
diff --git a/.changelog/1148.txt b/.changelog/1148.txt
new file mode 100644
index 000000000..55149599e
--- /dev/null
+++ b/.changelog/1148.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+managed_networks: add CRUD functionality for managednetworks
+```
\ No newline at end of file
diff --git a/devices_managed_networks.go b/devices_managed_networks.go
new file mode 100644
index 000000000..1f6129a6a
--- /dev/null
+++ b/devices_managed_networks.go
@@ -0,0 +1,164 @@
+package cloudflare
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"net/http"
+)
+
+type Config struct {
+	TlsSockAddr string `json:"tls_sockaddr,omitempty"`
+	Sha256      string `json:"sha256,omitempty"`
+}
+
+type DeviceManagedNetwork struct {
+	NetworkID string  `json:"network_id,omitempty"`
+	Type      string  `json:"type"`
+	Name      string  `json:"name"`
+	Config    *Config `json:"config"`
+}
+
+type DeviceManagedNetworkResponse struct {
+	Response
+	Result DeviceManagedNetwork `json:"result"`
+}
+
+type DeviceManagedNetworkListResponse struct {
+	Response
+	Result []DeviceManagedNetwork `json:"result"`
+}
+
+type ListDeviceManagedNetworksParams struct{}
+
+type CreateDeviceManagedNetworkParams struct {
+	NetworkID string  `json:"network_id,omitempty"`
+	Type      string  `json:"type"`
+	Name      string  `json:"name"`
+	Config    *Config `json:"config"`
+}
+
+type UpdateDeviceManagedNetworkParams struct {
+	NetworkID string  `json:"network_id,omitempty"`
+	Type      string  `json:"type"`
+	Name      string  `json:"name"`
+	Config    *Config `json:"config"`
+}
+
+// ListDeviceManagedNetwork returns all Device Managed Networks for a given
+// account.
+//
+// API reference : https://api.cloudflare.com/#device-managed-networks-list-device-managed-networks
+func (api *API) ListDeviceManagedNetworks(ctx context.Context, rc *ResourceContainer, params ListDeviceManagedNetworksParams) ([]DeviceManagedNetwork, error) {
+	if rc.Level != AccountRouteLevel {
+		return []DeviceManagedNetwork{}, ErrRequiredAccountLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/networks", rc.Level, rc.Identifier)
+
+	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
+	if err != nil {
+		return []DeviceManagedNetwork{}, err
+	}
+
+	var response DeviceManagedNetworkListResponse
+	err = json.Unmarshal(res, &response)
+	if err != nil {
+		return []DeviceManagedNetwork{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return response.Result, nil
+}
+
+// CreateDeviceManagedNetwork creates a new Device Managed Network.
+//
+// API reference: https://api.cloudflare.com/#device-managed-networks-create-device-managed-network
+func (api *API) CreateDeviceManagedNetwork(ctx context.Context, rc *ResourceContainer, params CreateDeviceManagedNetworkParams) (DeviceManagedNetwork, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceManagedNetwork{}, ErrRequiredAccountLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/networks", rc.Level, rc.Identifier)
+
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
+	if err != nil {
+		return DeviceManagedNetwork{}, err
+	}
+
+	var deviceManagedNetworksResponse DeviceManagedNetworkResponse
+	if err := json.Unmarshal(res, &deviceManagedNetworksResponse); err != nil {
+		return DeviceManagedNetwork{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return deviceManagedNetworksResponse.Result, err
+}
+
+// UpdateDeviceManagedNetwork Update a Device Managed Network.
+//
+// API reference: https://api.cloudflare.com/#device-managed-networks-update-device-managed-network
+func (api *API) UpdateDeviceManagedNetwork(ctx context.Context, rc *ResourceContainer, params UpdateDeviceManagedNetworkParams) (DeviceManagedNetwork, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceManagedNetwork{}, ErrRequiredAccountLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/networks/%s", rc.Level, rc.Identifier, params.NetworkID)
+
+	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
+	if err != nil {
+		return DeviceManagedNetwork{}, err
+	}
+
+	var deviceManagedNetworksResponse DeviceManagedNetworkResponse
+
+	if err := json.Unmarshal(res, &deviceManagedNetworksResponse); err != nil {
+		return DeviceManagedNetwork{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return deviceManagedNetworksResponse.Result, err
+}
+
+// GetDeviceManagedNetwork gets a single Device Managed Network.
+//
+// API reference: https://api.cloudflare.com/#device-managed-networks-device-managed-network-details
+func (api *API) GetDeviceManagedNetwork(ctx context.Context, rc *ResourceContainer, networkID string) (DeviceManagedNetwork, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceManagedNetwork{}, ErrRequiredAccountLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/networks/%s", rc.Level, rc.Identifier, networkID)
+
+	deviceManagedNetworksResponse := DeviceManagedNetworkResponse{}
+	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
+	if err != nil {
+		return DeviceManagedNetwork{}, err
+	}
+
+	if err := json.Unmarshal(res, &deviceManagedNetworksResponse); err != nil {
+		return DeviceManagedNetwork{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return deviceManagedNetworksResponse.Result, err
+}
+
+// DeleteManagedNetworks deletes a Device Managed Network.
+//
+// API reference: https://api.cloudflare.com/#device-managed-networks-delete-device-managed-network
+func (api *API) DeleteManagedNetworks(ctx context.Context, rc *ResourceContainer, networkID string) ([]DeviceManagedNetwork, error) {
+	if rc.Level != AccountRouteLevel {
+		return []DeviceManagedNetwork{}, ErrRequiredAccountLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/networks/%s", rc.Level, rc.Identifier, networkID)
+
+	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
+	if err != nil {
+		return []DeviceManagedNetwork{}, err
+	}
+
+	var response DeviceManagedNetworkListResponse
+	if err := json.Unmarshal(res, &response); err != nil {
+		return []DeviceManagedNetwork{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return response.Result, err
+}


Test patch:
diff --git a/devices_managed_networks_test.go b/devices_managed_networks_test.go
new file mode 100644
index 000000000..7f2f4bb6b
--- /dev/null
+++ b/devices_managed_networks_test.go
@@ -0,0 +1,194 @@
+package cloudflare
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+const testNetworkID = "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"
+
+func TestGetDeviceManagedNetworks(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.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result": [
+			  {
+				"network_id": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+				"type": "tls",
+				"name": "managed-network-1",
+				"config": {
+				  "tls_sockaddr": "foobar:1234",
+				  "sha256": "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"
+				}
+			  }
+			]
+		  }`)
+	}
+
+	want := []DeviceManagedNetwork{{
+		NetworkID: testNetworkID,
+		Type:      "tls",
+		Name:      "managed-network-1",
+		Config: &Config{
+			TlsSockAddr: "foobar:1234",
+			Sha256:      "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c",
+		},
+	}}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/devices/networks", handler)
+
+	actual, err := client.ListDeviceManagedNetworks(context.Background(), AccountIdentifier(testAccountID), ListDeviceManagedNetworksParams{})
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}
+
+func TestDeviceManagedNetwork(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.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result":
+			  {
+				"network_id": "%s",
+				"type": "tls",
+				"name": "managed-network-1",
+				"config": {
+				  "tls_sockaddr": "foobar:1234",
+				  "sha256": "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"
+				}
+			  }
+		  }`, testNetworkID)
+	}
+
+	want := DeviceManagedNetwork{
+		NetworkID: testNetworkID,
+		Type:      "tls",
+		Name:      "managed-network-1",
+		Config: &Config{
+			TlsSockAddr: "foobar:1234",
+			Sha256:      "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c",
+		},
+	}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/devices/networks/"+testNetworkID, handler)
+
+	actual, err := client.GetDeviceManagedNetwork(context.Background(), AccountIdentifier(testAccountID), testNetworkID)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}
+
+func TestCreateDeviceManagedNetwork(t *testing.T) {
+	setup()
+	defer teardown()
+
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result":
+			  {
+				"network_id": "%s",
+				"type": "tls",
+				"name": "managed-network-1",
+				"config": {
+				  "tls_sockaddr": "foobar:1234",
+				  "sha256": "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"
+				}
+			  }
+		  }`, testNetworkID)
+	}
+
+	want := DeviceManagedNetwork{
+		NetworkID: testNetworkID,
+		Type:      "tls",
+		Name:      "managed-network-1",
+		Config: &Config{
+			TlsSockAddr: "foobar:1234",
+			Sha256:      "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c",
+		},
+	}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/devices/networks", handler)
+
+	actual, err := client.CreateDeviceManagedNetwork(context.Background(), AccountIdentifier(testAccountID), CreateDeviceManagedNetworkParams{
+		NetworkID: testNetworkID,
+		Type:      "tls",
+		Name:      "managed-network-1",
+		Config: &Config{
+			TlsSockAddr: "foobar:1234",
+			Sha256:      "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c",
+		},
+	})
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}
+
+func TestDeleteDeviceManagedNetwork(t *testing.T) {
+	setup()
+	defer teardown()
+
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result": [
+			  {
+				"network_id": "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+				"type": "tls",
+				"name": "managed-network-1",
+				"config": {
+				  "tls_sockaddr": "foobar:1234",
+				  "sha256": "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"
+				}
+			  }
+			]
+		  }`)
+	}
+
+	want := []DeviceManagedNetwork{{
+		NetworkID: testNetworkID,
+		Type:      "tls",
+		Name:      "managed-network-1",
+		Config: &Config{
+			TlsSockAddr: "foobar:1234",
+			Sha256:      "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c",
+		},
+	}}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/devices/networks/"+testNetworkID, handler)
+
+	actual, err := client.DeleteManagedNetworks(context.Background(), AccountIdentifier(testAccountID), testNetworkID)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}