github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/policy.go (about) 1 package cloudlets 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "net/http" 8 "net/url" 9 "regexp" 10 "strconv" 11 12 validation "github.com/go-ozzo/ozzo-validation/v4" 13 ) 14 15 type ( 16 // Policies is a cloudlets policies API interface. 17 Policies interface { 18 // ListPolicies lists policies. 19 // 20 // See: https://techdocs.akamai.com/cloudlets/v2/reference/get-policies 21 ListPolicies(context.Context, ListPoliciesRequest) ([]Policy, error) 22 23 // GetPolicy gets policy by policyID. 24 // 25 // See: https://techdocs.akamai.com/cloudlets/v2/reference/get-policy 26 GetPolicy(context.Context, GetPolicyRequest) (*Policy, error) 27 28 // CreatePolicy creates policy. 29 // 30 // See: https://techdocs.akamai.com/cloudlets/v2/reference/post-policy 31 CreatePolicy(context.Context, CreatePolicyRequest) (*Policy, error) 32 33 // RemovePolicy removes policy. 34 // 35 // See: https://techdocs.akamai.com/cloudlets/v2/reference/delete-policy 36 RemovePolicy(context.Context, RemovePolicyRequest) error 37 38 // UpdatePolicy updates policy. 39 // 40 // See: https://techdocs.akamai.com/cloudlets/v2/reference/put-policy 41 UpdatePolicy(context.Context, UpdatePolicyRequest) (*Policy, error) 42 } 43 44 // Policy is response returned by GetPolicy or UpdatePolicy 45 Policy struct { 46 Location string `json:"location"` 47 PolicyID int64 `json:"policyId"` 48 GroupID int64 `json:"groupId"` 49 Name string `json:"name"` 50 Description string `json:"description"` 51 CreatedBy string `json:"createdBy"` 52 CreateDate float64 `json:"createDate"` 53 LastModifiedBy string `json:"lastModifiedBy"` 54 LastModifiedDate float64 `json:"lastModifiedDate"` 55 Activations []PolicyActivation `json:"activations"` 56 CloudletID int64 `json:"cloudletId"` 57 CloudletCode string `json:"cloudletCode"` 58 APIVersion string `json:"apiVersion"` 59 Deleted bool `json:"deleted"` 60 } 61 62 // PolicyActivation represents a policy activation resource 63 PolicyActivation struct { 64 APIVersion string `json:"apiVersion"` 65 Network PolicyActivationNetwork `json:"network"` 66 PolicyInfo PolicyInfo `json:"policyInfo"` 67 PropertyInfo PropertyInfo `json:"propertyInfo"` 68 } 69 70 // PolicyInfo represents a policy info resource 71 PolicyInfo struct { 72 PolicyID int64 `json:"policyId"` 73 Name string `json:"name"` 74 Version int64 `json:"version"` 75 Status PolicyActivationStatus `json:"status"` 76 StatusDetail string `json:"statusDetail,omitempty"` 77 ActivatedBy string `json:"activatedBy"` 78 ActivationDate int64 `json:"activationDate"` 79 } 80 81 // PropertyInfo represents a property info resource 82 PropertyInfo struct { 83 Name string `json:"name"` 84 Version int64 `json:"version"` 85 GroupID int64 `json:"groupId"` 86 Status PolicyActivationStatus `json:"status"` 87 ActivatedBy string `json:"activatedBy"` 88 ActivationDate int64 `json:"activationDate"` 89 } 90 91 // PolicyActivationStatus is an activation status type for policy 92 PolicyActivationStatus string 93 94 // GetPolicyRequest describes the body of the get policy request 95 GetPolicyRequest struct { 96 PolicyID int64 97 } 98 99 // CreatePolicyRequest describes the body of the create policy request 100 CreatePolicyRequest struct { 101 Name string `json:"name"` 102 CloudletID int64 `json:"cloudletId"` 103 Description string `json:"description,omitempty"` 104 PropertyName string `json:"propertyName,omitempty"` 105 GroupID int64 `json:"groupId,omitempty"` 106 } 107 108 // UpdatePolicy describes the body of the update policy request 109 UpdatePolicy struct { 110 Name string `json:"name,omitempty"` 111 Description string `json:"description,omitempty"` 112 PropertyName string `json:"propertyName,omitempty"` 113 GroupID int64 `json:"groupId,omitempty"` 114 Deleted bool `json:"deleted,omitempty"` 115 } 116 117 // ListPoliciesRequest describes the parameters for the list policies request 118 ListPoliciesRequest struct { 119 CloudletID *int64 120 IncludeDeleted bool 121 Offset int 122 PageSize *int 123 } 124 125 // UpdatePolicyRequest describes the parameters for the update policy request 126 UpdatePolicyRequest struct { 127 UpdatePolicy 128 PolicyID int64 129 } 130 131 // RemovePolicyRequest describes the body of the remove policy request 132 RemovePolicyRequest struct { 133 PolicyID int64 134 } 135 ) 136 137 const ( 138 // PolicyActivationStatusActive is an activation that is currently active 139 PolicyActivationStatusActive PolicyActivationStatus = "active" 140 // PolicyActivationStatusDeactivated is an activation that is deactivated 141 PolicyActivationStatusDeactivated PolicyActivationStatus = "deactivated" 142 // PolicyActivationStatusInactive is an activation that is not active 143 PolicyActivationStatusInactive PolicyActivationStatus = "inactive" 144 // PolicyActivationStatusPending is status of a pending activation 145 PolicyActivationStatusPending PolicyActivationStatus = "pending" 146 // PolicyActivationStatusFailed is status of a failed activation 147 PolicyActivationStatusFailed PolicyActivationStatus = "failed" 148 ) 149 150 var nameRegexp = regexp.MustCompile("^[a-z_A-Z0-9]+$") 151 var propertyNameRegexp = regexp.MustCompile("^[a-z_A-Z0-9.\\-]+$") 152 153 // Validate validates CreatePolicyRequest 154 func (v CreatePolicyRequest) Validate() error { 155 return validation.Errors{ 156 "Name": validation.Validate(v.Name, validation.Required, validation.Length(0, 64), validation.Match(nameRegexp)), 157 "PropertyName": validation.Validate(v.PropertyName, validation.Match(propertyNameRegexp)), 158 "CloudletID": validation.Validate(v.CloudletID, validation.Min(0), validation.Max(13)), 159 "Description": validation.Validate(v.Description, validation.Length(0, 255)), 160 "GroupID": validation.Validate(v.GroupID), 161 }.Filter() 162 } 163 164 // Validate validates UpdatePolicyRequest 165 func (v UpdatePolicyRequest) Validate() error { 166 return validation.Errors{ 167 "Name": validation.Validate(v.Name, validation.Length(0, 64), validation.Match(nameRegexp)), 168 "Description": validation.Validate(v.Description, validation.Length(0, 255)), 169 "PropertyName": validation.Validate(v.PropertyName, validation.Match(propertyNameRegexp)), 170 "GroupID": validation.Validate(v.GroupID), 171 "Deleted": validation.Validate(v.Deleted), 172 }.Filter() 173 } 174 175 var ( 176 // ErrListPolicies is returned when ListPolicies fails 177 ErrListPolicies = errors.New("list policies") 178 // ErrGetPolicy is returned when GetPolicy fails 179 ErrGetPolicy = errors.New("get policy") 180 // ErrCreatePolicy is returned when CreatePolicy fails 181 ErrCreatePolicy = errors.New("create policy") 182 // ErrRemovePolicy is returned when RemovePolicy fails 183 ErrRemovePolicy = errors.New("remove policy") 184 // ErrUpdatePolicy is returned when UpdatePolicy fails 185 ErrUpdatePolicy = errors.New("update policy") 186 ) 187 188 func (c *cloudlets) ListPolicies(ctx context.Context, params ListPoliciesRequest) ([]Policy, error) { 189 logger := c.Log(ctx) 190 logger.Debug("ListPolicies") 191 192 uri, err := url.Parse("/cloudlets/api/v2/policies") 193 if err != nil { 194 return nil, fmt.Errorf("%w: failed to parse url: %s", ErrListPolicies, err) 195 } 196 197 q := uri.Query() 198 if params.CloudletID != nil { 199 q.Add("cloudletId", fmt.Sprintf("%d", *params.CloudletID)) 200 } 201 if params.PageSize != nil { 202 q.Add("pageSize", fmt.Sprintf("%d", *params.PageSize)) 203 } 204 q.Add("offset", fmt.Sprintf("%d", params.Offset)) 205 q.Add("includeDeleted", strconv.FormatBool(params.IncludeDeleted)) 206 uri.RawQuery = q.Encode() 207 208 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil) 209 if err != nil { 210 return nil, fmt.Errorf("%w: failed to create request: %s", ErrListPolicies, err) 211 } 212 213 var result []Policy 214 resp, err := c.Exec(req, &result) 215 if err != nil { 216 return nil, fmt.Errorf("%w: request failed: %s", ErrListPolicies, err) 217 } 218 219 if resp.StatusCode != http.StatusOK { 220 return nil, fmt.Errorf("%s: %w", ErrListPolicies, c.Error(resp)) 221 } 222 223 return result, nil 224 } 225 226 func (c *cloudlets) GetPolicy(ctx context.Context, params GetPolicyRequest) (*Policy, error) { 227 logger := c.Log(ctx) 228 logger.Debug("GetPolicy") 229 230 var result Policy 231 232 uri, err := url.Parse(fmt.Sprintf("/cloudlets/api/v2/policies/%d", params.PolicyID)) 233 if err != nil { 234 return nil, fmt.Errorf("%w: failed to parse url: %s", ErrGetPolicy, err) 235 } 236 237 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil) 238 if err != nil { 239 return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetPolicy, err) 240 } 241 242 resp, err := c.Exec(req, &result) 243 if err != nil { 244 return nil, fmt.Errorf("%w: request failed: %s", ErrGetPolicy, err) 245 } 246 247 if resp.StatusCode != http.StatusOK { 248 return nil, fmt.Errorf("%s: %w", ErrGetPolicy, c.Error(resp)) 249 } 250 251 return &result, nil 252 } 253 254 func (c *cloudlets) CreatePolicy(ctx context.Context, params CreatePolicyRequest) (*Policy, error) { 255 logger := c.Log(ctx) 256 logger.Debug("CreatePolicy") 257 258 if err := params.Validate(); err != nil { 259 return nil, fmt.Errorf("%s: %w: %s", ErrCreatePolicy, ErrStructValidation, err) 260 } 261 262 uri, err := url.Parse("/cloudlets/api/v2/policies") 263 if err != nil { 264 return nil, fmt.Errorf("%w: failed to parse url: %s", ErrCreatePolicy, err) 265 } 266 267 req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri.String(), nil) 268 if err != nil { 269 return nil, fmt.Errorf("%w: failed to create request: %s", ErrCreatePolicy, err) 270 } 271 272 var result Policy 273 274 resp, err := c.Exec(req, &result, params) 275 if err != nil { 276 return nil, fmt.Errorf("%w: request failed: %s", ErrCreatePolicy, err) 277 } 278 279 if resp.StatusCode != http.StatusCreated { 280 return nil, fmt.Errorf("%s: %w", ErrCreatePolicy, c.Error(resp)) 281 } 282 283 return &result, nil 284 } 285 286 func (c *cloudlets) RemovePolicy(ctx context.Context, params RemovePolicyRequest) error { 287 logger := c.Log(ctx) 288 logger.Debug("RemovePolicy") 289 290 uri, err := url.Parse(fmt.Sprintf("/cloudlets/api/v2/policies/%d", params.PolicyID)) 291 if err != nil { 292 return fmt.Errorf("%w: failed to parse url: %s", ErrRemovePolicy, err) 293 } 294 295 req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri.String(), nil) 296 if err != nil { 297 return fmt.Errorf("%w: failed to create request: %s", ErrRemovePolicy, err) 298 } 299 300 resp, err := c.Exec(req, nil) 301 if err != nil { 302 return fmt.Errorf("%w: request failed: %s", ErrRemovePolicy, err) 303 } 304 305 if resp.StatusCode != http.StatusNoContent { 306 return fmt.Errorf("%s: %w", ErrRemovePolicy, c.Error(resp)) 307 } 308 309 return nil 310 } 311 312 func (c *cloudlets) UpdatePolicy(ctx context.Context, params UpdatePolicyRequest) (*Policy, error) { 313 logger := c.Log(ctx) 314 logger.Debug("UpdatePolicy") 315 316 if err := params.Validate(); err != nil { 317 return nil, fmt.Errorf("%s: %w: %s", ErrUpdatePolicy, ErrStructValidation, err) 318 } 319 320 uri, err := url.Parse(fmt.Sprintf( 321 "/cloudlets/api/v2/policies/%d", 322 params.PolicyID), 323 ) 324 if err != nil { 325 return nil, fmt.Errorf("%w: failed to parse url: %s", ErrUpdatePolicy, err) 326 } 327 328 req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri.String(), nil) 329 if err != nil { 330 return nil, fmt.Errorf("%w: failed to create request: %s", ErrUpdatePolicy, err) 331 } 332 333 var result Policy 334 335 resp, err := c.Exec(req, &result, params.UpdatePolicy) 336 if err != nil { 337 return nil, fmt.Errorf("%w: request failed: %s", ErrUpdatePolicy, err) 338 } 339 340 if resp.StatusCode != http.StatusOK { 341 return nil, fmt.Errorf("%s: %w", ErrUpdatePolicy, c.Error(resp)) 342 } 343 344 return &result, nil 345 }