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 +} 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) + } +}