dnscontrol/pkg/cloudflare-go/devices_policy.go
Tom Limoncelli 7fd6a74e0c
CLOUDFLAREAPI: CF_REDIRECT/CF_TEMP_REDIRECT should dtrt using Single Redirects (#3002)
Co-authored-by: Josh Zhang <jzhang1@stackoverflow.com>
2024-06-18 17:38:50 -04:00

378 lines
14 KiB
Go

package cloudflare
import (
"context"
"fmt"
"net/http"
"github.com/goccy/go-json"
)
type Enabled struct {
Enabled bool `json:"enabled"`
}
// DeviceClientCertificates identifies if the zero trust zone is configured for an account.
type DeviceClientCertificates struct {
Response
Result Enabled
}
type ServiceMode string
const (
oneDotOne ServiceMode = "1dot1"
warp ServiceMode = "warp"
proxy ServiceMode = "proxy"
postureOnly ServiceMode = "posture_only"
warpTunnelOnly ServiceMode = "warp_tunnel_only"
listDeviceSettingsPoliciesDefaultPageSize = 20
)
type ServiceModeV2 struct {
Mode ServiceMode `json:"mode,omitempty"`
Port int `json:"port,omitempty"`
}
type DeviceSettingsPolicy struct {
ServiceModeV2 *ServiceModeV2 `json:"service_mode_v2"`
DisableAutoFallback *bool `json:"disable_auto_fallback"`
FallbackDomains *[]FallbackDomain `json:"fallback_domains"`
Include *[]SplitTunnel `json:"include"`
Exclude *[]SplitTunnel `json:"exclude"`
GatewayUniqueID *string `json:"gateway_unique_id"`
SupportURL *string `json:"support_url"`
CaptivePortal *int `json:"captive_portal"`
AllowModeSwitch *bool `json:"allow_mode_switch"`
SwitchLocked *bool `json:"switch_locked"`
AllowUpdates *bool `json:"allow_updates"`
AutoConnect *int `json:"auto_connect"`
AllowedToLeave *bool `json:"allowed_to_leave"`
PolicyID *string `json:"policy_id"`
Enabled *bool `json:"enabled"`
Name *string `json:"name"`
Match *string `json:"match"`
Precedence *int `json:"precedence"`
Default bool `json:"default"`
ExcludeOfficeIps *bool `json:"exclude_office_ips"`
Description *string `json:"description"`
LANAllowMinutes *uint `json:"lan_allow_minutes"`
LANAllowSubnetSize *uint `json:"lan_allow_subnet_size"`
}
type DeviceSettingsPolicyResponse struct {
Response
Result DeviceSettingsPolicy
}
type DeleteDeviceSettingsPolicyResponse struct {
Response
Result []DeviceSettingsPolicy
}
type CreateDeviceSettingsPolicyParams struct {
DisableAutoFallback *bool `json:"disable_auto_fallback,omitempty"`
CaptivePortal *int `json:"captive_portal,omitempty"`
AllowModeSwitch *bool `json:"allow_mode_switch,omitempty"`
SwitchLocked *bool `json:"switch_locked,omitempty"`
AllowUpdates *bool `json:"allow_updates,omitempty"`
AutoConnect *int `json:"auto_connect,omitempty"`
AllowedToLeave *bool `json:"allowed_to_leave,omitempty"`
SupportURL *string `json:"support_url,omitempty"`
ServiceModeV2 *ServiceModeV2 `json:"service_mode_v2,omitempty"`
Precedence *int `json:"precedence,omitempty"`
Name *string `json:"name,omitempty"`
Match *string `json:"match,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
ExcludeOfficeIps *bool `json:"exclude_office_ips"`
Description *string `json:"description,omitempty"`
LANAllowMinutes *uint `json:"lan_allow_minutes,omitempty"`
LANAllowSubnetSize *uint `json:"lan_allow_subnet_size,omitempty"`
}
type UpdateDefaultDeviceSettingsPolicyParams struct {
DisableAutoFallback *bool `json:"disable_auto_fallback,omitempty"`
CaptivePortal *int `json:"captive_portal,omitempty"`
AllowModeSwitch *bool `json:"allow_mode_switch,omitempty"`
SwitchLocked *bool `json:"switch_locked,omitempty"`
AllowUpdates *bool `json:"allow_updates,omitempty"`
AutoConnect *int `json:"auto_connect,omitempty"`
AllowedToLeave *bool `json:"allowed_to_leave,omitempty"`
SupportURL *string `json:"support_url,omitempty"`
ServiceModeV2 *ServiceModeV2 `json:"service_mode_v2,omitempty"`
Precedence *int `json:"precedence,omitempty"`
Name *string `json:"name,omitempty"`
Match *string `json:"match,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
ExcludeOfficeIps *bool `json:"exclude_office_ips"`
Description *string `json:"description,omitempty"`
LANAllowMinutes *uint `json:"lan_allow_minutes,omitempty"`
LANAllowSubnetSize *uint `json:"lan_allow_subnet_size,omitempty"`
}
type UpdateDeviceSettingsPolicyParams struct {
PolicyID *string `json:"-"`
DisableAutoFallback *bool `json:"disable_auto_fallback,omitempty"`
CaptivePortal *int `json:"captive_portal,omitempty"`
AllowModeSwitch *bool `json:"allow_mode_switch,omitempty"`
SwitchLocked *bool `json:"switch_locked,omitempty"`
AllowUpdates *bool `json:"allow_updates,omitempty"`
AutoConnect *int `json:"auto_connect,omitempty"`
AllowedToLeave *bool `json:"allowed_to_leave,omitempty"`
SupportURL *string `json:"support_url,omitempty"`
ServiceModeV2 *ServiceModeV2 `json:"service_mode_v2,omitempty"`
Precedence *int `json:"precedence,omitempty"`
Name *string `json:"name,omitempty"`
Match *string `json:"match,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
ExcludeOfficeIps *bool `json:"exclude_office_ips"`
Description *string `json:"description,omitempty"`
LANAllowMinutes *uint `json:"lan_allow_minutes,omitempty"`
LANAllowSubnetSize *uint `json:"lan_allow_subnet_size,omitempty"`
}
type ListDeviceSettingsPoliciesResponse struct {
Response
ResultInfo ResultInfo `json:"result_info"`
Result []DeviceSettingsPolicy `json:"result"`
}
type UpdateDeviceClientCertificatesParams struct {
Enabled *bool `json:"enabled"`
}
type GetDeviceClientCertificatesParams struct{}
type GetDefaultDeviceSettingsPolicyParams struct{}
type GetDeviceSettingsPolicyParams struct {
PolicyID *string `json:"-"`
}
// UpdateDeviceClientCertificates controls the zero trust zone used to provision client certificates.
//
// API reference: https://api.cloudflare.com/#device-client-certificates
func (api *API) UpdateDeviceClientCertificates(ctx context.Context, rc *ResourceContainer, params UpdateDeviceClientCertificatesParams) (DeviceClientCertificates, error) {
if rc.Level != ZoneRouteLevel {
return DeviceClientCertificates{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy/certificates", rc.Level, rc.Identifier)
result := DeviceClientCertificates{Result: Enabled{false}}
res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
if err != nil {
return result, err
}
if err := json.Unmarshal(res, &result); err != nil {
return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result, err
}
// GetDeviceClientCertificates controls the zero trust zone used to provision
// client certificates.
//
// API reference: https://api.cloudflare.com/#device-client-certificates
func (api *API) GetDeviceClientCertificates(ctx context.Context, rc *ResourceContainer, params GetDeviceClientCertificatesParams) (DeviceClientCertificates, error) {
if rc.Level != ZoneRouteLevel {
return DeviceClientCertificates{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy/certificates", rc.Level, rc.Identifier)
result := DeviceClientCertificates{}
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return result, err
}
if err := json.Unmarshal(res, &result); err != nil {
return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result, err
}
// CreateDeviceSettingsPolicy creates a settings policy against devices that
// match the policy.
//
// API reference: https://api.cloudflare.com/#devices-create-device-settings-policy
func (api *API) CreateDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params CreateDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
if rc.Level != AccountRouteLevel {
return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy", rc.Level, rc.Identifier)
result := DeviceSettingsPolicyResponse{}
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
if err != nil {
return DeviceSettingsPolicy{}, err
}
if err := json.Unmarshal(res, &result); err != nil {
return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result.Result, err
}
// UpdateDefaultDeviceSettingsPolicy updates the default settings policy for an account
//
// API reference: https://api.cloudflare.com/#devices-update-default-device-settings-policy
func (api *API) UpdateDefaultDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params UpdateDefaultDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
if rc.Level != AccountRouteLevel {
return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
result := DeviceSettingsPolicyResponse{}
uri := fmt.Sprintf("/%s/%s/devices/policy", rc.Level, rc.Identifier)
res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
if err != nil {
return DeviceSettingsPolicy{}, err
}
if err := json.Unmarshal(res, &result); err != nil {
return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result.Result, err
}
// UpdateDeviceSettingsPolicy updates a settings policy
//
// API reference: https://api.cloudflare.com/#devices-update-device-settings-policy
func (api *API) UpdateDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params UpdateDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
if rc.Level != AccountRouteLevel {
return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy/%s", rc.Level, rc.Identifier, *params.PolicyID)
result := DeviceSettingsPolicyResponse{}
res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
if err != nil {
return DeviceSettingsPolicy{}, err
}
if err := json.Unmarshal(res, &result); err != nil {
return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result.Result, err
}
// DeleteDeviceSettingsPolicy deletes a settings policy and returns a list
// of all of the other policies in the account.
//
// API reference: https://api.cloudflare.com/#devices-delete-device-settings-policy
func (api *API) DeleteDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, policyID string) ([]DeviceSettingsPolicy, error) {
if rc.Level != AccountRouteLevel {
return []DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy/%s", rc.Level, rc.Identifier, policyID)
result := DeleteDeviceSettingsPolicyResponse{}
res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
if err != nil {
return []DeviceSettingsPolicy{}, err
}
if err := json.Unmarshal(res, &result); err != nil {
return []DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result.Result, err
}
// GetDefaultDeviceSettings gets the default device settings policy.
//
// API reference: https://api.cloudflare.com/#devices-get-default-device-settings-policy
func (api *API) GetDefaultDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params GetDefaultDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
if rc.Level != AccountRouteLevel {
return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy", rc.Level, rc.Identifier)
result := DeviceSettingsPolicyResponse{}
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return DeviceSettingsPolicy{}, err
}
if err := json.Unmarshal(res, &result); err != nil {
return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result.Result, err
}
// GetDefaultDeviceSettings gets the device settings policy by its policyID.
//
// API reference: https://api.cloudflare.com/#devices-get-device-settings-policy-by-id
func (api *API) GetDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params GetDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
if rc.Level != AccountRouteLevel {
return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
}
uri := fmt.Sprintf("/%s/%s/devices/policy/%s", rc.Level, rc.Identifier, *params.PolicyID)
result := DeviceSettingsPolicyResponse{}
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return DeviceSettingsPolicy{}, err
}
if err := json.Unmarshal(res, &result); err != nil {
return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
return result.Result, err
}
type ListDeviceSettingsPoliciesParams struct {
ResultInfo
}
// ListDeviceSettingsPolicies returns all device settings policies for an account
//
// API reference: https://api.cloudflare.com/#devices-list-device-settings-policies
func (api *API) ListDeviceSettingsPolicies(ctx context.Context, rc *ResourceContainer, params ListDeviceSettingsPoliciesParams) ([]DeviceSettingsPolicy, *ResultInfo, error) {
autoPaginate := true
if params.PerPage >= 1 || params.Page >= 1 {
autoPaginate = false
}
if params.PerPage < 1 {
params.PerPage = listDeviceSettingsPoliciesDefaultPageSize
}
var policies []DeviceSettingsPolicy
var lastResultInfo ResultInfo
for {
uri := buildURI(fmt.Sprintf("/%s/%s/devices/policies", rc.Level, rc.Identifier), params)
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, nil, err
}
var r ListDeviceSettingsPoliciesResponse
err = json.Unmarshal(res, &r)
if err != nil {
return nil, nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}
policies = append(policies, r.Result...)
lastResultInfo = r.ResultInfo
params.ResultInfo = r.ResultInfo.Next()
if params.ResultInfo.Done() || !autoPaginate {
break
}
}
return policies, &lastResultInfo, nil
}