1package cloudflare 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 9 "github.com/pkg/errors" 10) 11 12// DevicePostureRule represents a device posture rule. 13type DevicePostureRule struct { 14 ID string `json:"id,omitempty"` 15 Type string `json:"type"` 16 Name string `json:"name"` 17 Description string `json:"description,omitempty"` 18 Schedule string `json:"schedule,omitempty"` 19 Match []DevicePostureRuleMatch `json:"match,omitempty"` 20 Input DevicePostureRuleInput `json:"input,omitempty"` 21} 22 23// DevicePostureRuleMatch represents the conditions that the client must match to run the rule. 24type DevicePostureRuleMatch struct { 25 Platform string `json:"platform,omitempty"` 26} 27 28// DevicePostureRuleInput represents the value to be checked against. 29type DevicePostureRuleInput struct { 30 ID string `json:"id,omitempty"` 31 Path string `json:"path,omitempty"` 32 Exists bool `json:"exists,omitempty"` 33 Thumbprint string `json:"thumbprint,omitempty"` 34 Sha256 string `json:"sha256,omitempty"` 35 Running bool `json:"running,omitempty"` 36 RequireAll bool `json:"requireAll,omitempty"` 37 Enabled bool `json:"enabled,omitempty"` 38 Version string `json:"version,omitempty"` 39 Operator string `json:"operator,omitempty"` 40 Domain string `json:"domain,omitempty"` 41} 42 43// DevicePostureRuleListResponse represents the response from the list 44// device posture rules endpoint. 45type DevicePostureRuleListResponse struct { 46 Result []DevicePostureRule `json:"result"` 47 Response 48 ResultInfo `json:"result_info"` 49} 50 51// DevicePostureRuleDetailResponse is the API response, containing a single 52// device posture rule. 53type DevicePostureRuleDetailResponse struct { 54 Response 55 Result DevicePostureRule `json:"result"` 56} 57 58// DevicePostureRules returns all device posture rules within an account. 59// 60// API reference: https://api.cloudflare.com/#device-posture-rules-list-device-posture-rules 61func (api *API) DevicePostureRules(ctx context.Context, accountID string) ([]DevicePostureRule, ResultInfo, error) { 62 uri := fmt.Sprintf("/%s/%s/devices/posture", AccountRouteRoot, accountID) 63 64 res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) 65 if err != nil { 66 return []DevicePostureRule{}, ResultInfo{}, err 67 } 68 69 var devicePostureRuleListResponse DevicePostureRuleListResponse 70 err = json.Unmarshal(res, &devicePostureRuleListResponse) 71 if err != nil { 72 return []DevicePostureRule{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) 73 } 74 75 return devicePostureRuleListResponse.Result, devicePostureRuleListResponse.ResultInfo, nil 76} 77 78// DevicePostureRule returns a single device posture rule based on the rule ID. 79// 80// API reference: https://api.cloudflare.com/#device-posture-rules-device-posture-rules-details 81func (api *API) DevicePostureRule(ctx context.Context, accountID, ruleID string) (DevicePostureRule, error) { 82 uri := fmt.Sprintf( 83 "/%s/%s/devices/posture/%s", 84 AccountRouteRoot, 85 accountID, 86 ruleID, 87 ) 88 89 res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) 90 if err != nil { 91 return DevicePostureRule{}, err 92 } 93 94 var devicePostureRuleDetailResponse DevicePostureRuleDetailResponse 95 err = json.Unmarshal(res, &devicePostureRuleDetailResponse) 96 if err != nil { 97 return DevicePostureRule{}, errors.Wrap(err, errUnmarshalError) 98 } 99 100 return devicePostureRuleDetailResponse.Result, nil 101} 102 103// CreateDevicePostureRule creates a new device posture rule. 104// 105// API reference: https://api.cloudflare.com/#device-posture-rules-create-device-posture-rule 106func (api *API) CreateDevicePostureRule(ctx context.Context, accountID string, rule DevicePostureRule) (DevicePostureRule, error) { 107 uri := fmt.Sprintf("/%s/%s/devices/posture", AccountRouteRoot, accountID) 108 109 res, err := api.makeRequestContext(ctx, http.MethodPost, uri, rule) 110 if err != nil { 111 return DevicePostureRule{}, err 112 } 113 114 var devicePostureRuleDetailResponse DevicePostureRuleDetailResponse 115 err = json.Unmarshal(res, &devicePostureRuleDetailResponse) 116 if err != nil { 117 return DevicePostureRule{}, errors.Wrap(err, errUnmarshalError) 118 } 119 120 return devicePostureRuleDetailResponse.Result, nil 121} 122 123// UpdateDevicePostureRule updates an existing device posture rule. 124// 125// API reference: https://api.cloudflare.com/#device-posture-rules-update-device-posture-rule 126func (api *API) UpdateDevicePostureRule(ctx context.Context, accountID string, rule DevicePostureRule) (DevicePostureRule, error) { 127 if rule.ID == "" { 128 return DevicePostureRule{}, errors.Errorf("device posture rule ID cannot be empty") 129 } 130 131 uri := fmt.Sprintf( 132 "/%s/%s/devices/posture/%s", 133 AccountRouteRoot, 134 accountID, 135 rule.ID, 136 ) 137 138 res, err := api.makeRequestContext(ctx, http.MethodPut, uri, rule) 139 if err != nil { 140 return DevicePostureRule{}, err 141 } 142 143 var devicePostureRuleDetailResponse DevicePostureRuleDetailResponse 144 err = json.Unmarshal(res, &devicePostureRuleDetailResponse) 145 if err != nil { 146 return DevicePostureRule{}, errors.Wrap(err, errUnmarshalError) 147 } 148 149 return devicePostureRuleDetailResponse.Result, nil 150} 151 152// DeleteDevicePostureRule deletes a device posture rule. 153// 154// API reference: https://api.cloudflare.com/#device-posture-rules-delete-device-posture-rule 155func (api *API) DeleteDevicePostureRule(ctx context.Context, accountID, ruleID string) error { 156 uri := fmt.Sprintf( 157 "/%s/%s/devices/posture/%s", 158 AccountRouteRoot, 159 accountID, 160 ruleID, 161 ) 162 163 _, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) 164 if err != nil { 165 return err 166 } 167 168 return nil 169} 170