github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.0/pkg/appsec/rate_policy.go (about) 1 package appsec 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 9 validation "github.com/go-ozzo/ozzo-validation/v4" 10 ) 11 12 type ( 13 // The RatePolicy interface supports creating, retrieving, updating and removing rate policies. 14 // 15 // https://developer.akamai.com/api/cloud_security/application_security/v1.html#ratepolicy 16 RatePolicy interface { 17 // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getratepolicies 18 GetRatePolicies(ctx context.Context, params GetRatePoliciesRequest) (*GetRatePoliciesResponse, error) 19 20 // https://developer.akamai.com/api/cloud_security/application_security/v1.html#getratepolicy 21 GetRatePolicy(ctx context.Context, params GetRatePolicyRequest) (*GetRatePolicyResponse, error) 22 23 // https://developer.akamai.com/api/cloud_security/application_security/v1.html#postratepolicies 24 CreateRatePolicy(ctx context.Context, params CreateRatePolicyRequest) (*CreateRatePolicyResponse, error) 25 26 // https://developer.akamai.com/api/cloud_security/application_security/v1.html#putratepolicy 27 UpdateRatePolicy(ctx context.Context, params UpdateRatePolicyRequest) (*UpdateRatePolicyResponse, error) 28 29 // https://developer.akamai.com/api/cloud_security/application_security/v1.html#deleteratepolicy 30 RemoveRatePolicy(ctx context.Context, params RemoveRatePolicyRequest) (*RemoveRatePolicyResponse, error) 31 } 32 33 // CreateRatePolicyRequest is used to create a rate policy. 34 CreateRatePolicyRequest struct { 35 ID int `json:"-"` 36 ConfigID int `json:"configId"` 37 ConfigVersion int `json:"configVersion"` 38 JsonPayloadRaw json.RawMessage `json:"-"` 39 } 40 41 // CreateRatePolicyResponse is returned from a call to CreateRatePolicy. 42 CreateRatePolicyResponse struct { 43 ID int `json:"id"` 44 ConfigID int `json:"configId"` 45 ConfigVersion int `json:"configVersion"` 46 MatchType string `json:"matchType"` 47 Type string `json:"type"` 48 Name string `json:"name"` 49 Description string `json:"description"` 50 AverageThreshold int `json:"averageThreshold"` 51 BurstThreshold int `json:"burstThreshold"` 52 ClientIdentifier string `json:"clientIdentifier"` 53 UseXForwardForHeaders bool `json:"useXForwardForHeaders"` 54 RequestType string `json:"requestType"` 55 SameActionOnIpv6 bool `json:"sameActionOnIpv6"` 56 Path struct { 57 PositiveMatch bool `json:"positiveMatch"` 58 Values []string `json:"values"` 59 } `json:"path"` 60 PathMatchType string `json:"pathMatchType"` 61 PathURIPositiveMatch bool `json:"pathUriPositiveMatch"` 62 FileExtensions struct { 63 PositiveMatch bool `json:"positiveMatch"` 64 Values []string `json:"values"` 65 } `json:"fileExtensions"` 66 Hosts *RatePoliciesHosts `json:"hosts,omitempty"` 67 Hostnames []string `json:"hostnames"` 68 AdditionalMatchOptions []RatePolicyMatchOption `json:"additionalMatchOptions,omitempty"` 69 QueryParameters []struct { 70 Name string `json:"name"` 71 Values []string `json:"values"` 72 PositiveMatch bool `json:"positiveMatch"` 73 ValueInRange bool `json:"valueInRange"` 74 } `json:"queryParameters"` 75 CreateDate string `json:"-"` 76 UpdateDate string `json:"-"` 77 Used json.RawMessage `json:"used"` 78 } 79 80 // UpdateRatePolicyRequest is used to modify an existing rate policy. 81 UpdateRatePolicyRequest struct { 82 RatePolicyID int `json:"id"` 83 ConfigID int `json:"configId"` 84 ConfigVersion int `json:"configVersion"` 85 JsonPayloadRaw json.RawMessage `json:"-"` 86 } 87 88 // UpdateRatePolicyResponse is returned from a call to UpdateRatePolicy. 89 UpdateRatePolicyResponse struct { 90 ID int `json:"id"` 91 ConfigID int `json:"configId"` 92 ConfigVersion int `json:"configVersion"` 93 MatchType string `json:"matchType"` 94 Type string `json:"type"` 95 Name string `json:"name"` 96 Description string `json:"description"` 97 AverageThreshold int `json:"averageThreshold"` 98 BurstThreshold int `json:"burstThreshold"` 99 ClientIdentifier string `json:"clientIdentifier"` 100 UseXForwardForHeaders bool `json:"useXForwardForHeaders"` 101 RequestType string `json:"requestType"` 102 SameActionOnIpv6 bool `json:"sameActionOnIpv6"` 103 Path struct { 104 PositiveMatch bool `json:"positiveMatch"` 105 Values []string `json:"values"` 106 } `json:"path"` 107 PathMatchType string `json:"pathMatchType"` 108 PathURIPositiveMatch bool `json:"pathUriPositiveMatch"` 109 FileExtensions struct { 110 PositiveMatch bool `json:"positiveMatch"` 111 Values []string `json:"values"` 112 } `json:"fileExtensions"` 113 Hosts *RatePoliciesHosts `json:"hosts,omitempty"` 114 Hostnames []string `json:"hostnames"` 115 AdditionalMatchOptions []RatePolicyMatchOption `json:"additionalMatchOptions,omitempty"` 116 QueryParameters []struct { 117 Name string `json:"name"` 118 Values []string `json:"values"` 119 PositiveMatch bool `json:"positiveMatch"` 120 ValueInRange bool `json:"valueInRange"` 121 } `json:"queryParameters"` 122 CreateDate string `json:"-"` 123 UpdateDate string `json:"-"` 124 Used json.RawMessage `json:"used"` 125 } 126 127 // RemoveRatePolicyRequest is used to remove a rate policy. 128 RemoveRatePolicyRequest struct { 129 ConfigID int `json:"configId"` 130 ConfigVersion int `json:"configVersion"` 131 RatePolicyID int `json:"ratePolicyId"` 132 } 133 134 // RemoveRatePolicyResponse is returned from a call to RemoveRatePolicy. 135 RemoveRatePolicyResponse struct { 136 ID int `json:"id"` 137 ConfigID int `json:"configId"` 138 ConfigVersion int `json:"configVersion"` 139 MatchType string `json:"matchType"` 140 Type string `json:"type"` 141 Name string `json:"name"` 142 Description string `json:"description"` 143 AverageThreshold int `json:"averageThreshold"` 144 BurstThreshold int `json:"burstThreshold"` 145 ClientIdentifier string `json:"clientIdentifier"` 146 UseXForwardForHeaders bool `json:"useXForwardForHeaders"` 147 RequestType string `json:"requestType"` 148 SameActionOnIpv6 bool `json:"sameActionOnIpv6"` 149 Path struct { 150 PositiveMatch bool `json:"positiveMatch"` 151 Values []string `json:"values"` 152 } `json:"path"` 153 PathMatchType string `json:"pathMatchType"` 154 PathURIPositiveMatch bool `json:"pathUriPositiveMatch"` 155 FileExtensions struct { 156 PositiveMatch bool `json:"positiveMatch"` 157 Values []string `json:"values"` 158 } `json:"fileExtensions"` 159 Hosts *RatePoliciesHosts `json:"hosts,omitempty"` 160 Hostnames []string `json:"hostnames"` 161 AdditionalMatchOptions []RatePolicyMatchOption `json:"additionalMatchOptions,omitempty"` 162 QueryParameters []struct { 163 Name string `json:"name"` 164 Values []string `json:"values"` 165 PositiveMatch bool `json:"positiveMatch"` 166 ValueInRange bool `json:"valueInRange"` 167 } `json:"queryParameters"` 168 CreateDate string `json:"-"` 169 UpdateDate string `json:"-"` 170 Used json.RawMessage `json:"used"` 171 } 172 173 // GetRatePoliciesRequest is used to retrieve the rate policies for a configuration. 174 GetRatePoliciesRequest struct { 175 ConfigID int `json:"configId"` 176 ConfigVersion int `json:"configVersion"` 177 RatePolicyID int `json:"ratePolicyId"` 178 } 179 180 // GetRatePoliciesResponse is returned from a call to GetRatePolicies. 181 GetRatePoliciesResponse struct { 182 RatePolicies []struct { 183 ID int `json:"id"` 184 ConfigID int `json:"-"` 185 ConfigVersion int `json:"-"` 186 MatchType string `json:"matchType,omitempty"` 187 Type string `json:"type,omitempty"` 188 Name string `json:"name,omitempty"` 189 Description string `json:"description,omitempty"` 190 AverageThreshold int `json:"averageThreshold,omitempty"` 191 BurstThreshold int `json:"burstThreshold,omitempty"` 192 ClientIdentifier string `json:"clientIdentifier,omitempty"` 193 UseXForwardForHeaders bool `json:"useXForwardForHeaders"` 194 RequestType string `json:"requestType,omitempty"` 195 SameActionOnIpv6 bool `json:"sameActionOnIpv6"` 196 Path *RatePolicyPath `json:"path,omitempty"` 197 PathMatchType string `json:"pathMatchType,omitempty"` 198 PathURIPositiveMatch bool `json:"pathUriPositiveMatch"` 199 FileExtensions *RatePolicyFileExtensions `json:"fileExtensions,omitempty"` 200 Hosts *RatePoliciesHosts `json:"hosts,omitempty"` 201 Hostnames []string `json:"hostnames,omitempty"` 202 AdditionalMatchOptions []RatePolicyMatchOption `json:"additionalMatchOptions,omitempty"` 203 QueryParameters *RatePolicyQueryParameters `json:"queryParameters,omitempty"` 204 CreateDate string `json:"-"` 205 UpdateDate string `json:"-"` 206 Used json.RawMessage `json:"used"` 207 SameActionOnIpv bool `json:"sameActionOnIpv"` 208 APISelectors *RatePolicyAPISelectors `json:"apiSelectors,omitempty"` 209 BodyParameters *RatePolicyBodyParameters `json:"bodyParameters,omitempty"` 210 } `json:"ratePolicies,omitempty"` 211 } 212 213 // GetRatePolicyRequest is used to retrieve information about a specific rate policy. 214 GetRatePolicyRequest struct { 215 ConfigID int `json:"configId"` 216 ConfigVersion int `json:"configVersion"` 217 RatePolicyID int `json:"ratePolicyId"` 218 } 219 220 // GetRatePolicyResponse is returned from a call to GetRatePolicy. 221 GetRatePolicyResponse struct { 222 ID int `json:"-"` 223 ConfigID int `json:"-"` 224 ConfigVersion int `json:"-"` 225 MatchType string `json:"matchType,omitempty"` 226 Type string `json:"type,omitempty"` 227 Name string `json:"name,omitempty"` 228 Description string `json:"description,omitempty"` 229 AverageThreshold int `json:"averageThreshold,omitempty"` 230 BurstThreshold int `json:"burstThreshold,omitempty"` 231 ClientIdentifier string `json:"clientIdentifier,omitempty"` 232 UseXForwardForHeaders bool `json:"useXForwardForHeaders"` 233 RequestType string `json:"requestType,omitempty"` 234 SameActionOnIpv6 bool `json:"sameActionOnIpv6"` 235 Path *RatePolicyPath `json:"path,omitempty"` 236 PathMatchType string `json:"pathMatchType,omitempty"` 237 PathURIPositiveMatch bool `json:"pathUriPositiveMatch"` 238 FileExtensions *RatePolicyFileExtensions `json:"fileExtensions,omitempty"` 239 Hosts *RatePoliciesHosts `json:"hosts,omitempty"` 240 Hostnames []string `json:"hostnames,omitempty"` 241 AdditionalMatchOptions []RatePolicyMatchOption `json:"additionalMatchOptions,omitempty"` 242 QueryParameters *RatePolicyQueryParameters `json:"queryParameters,omitempty"` 243 CreateDate string `json:"-"` 244 UpdateDate string `json:"-"` 245 Used bool `json:"-"` 246 } 247 248 // RatePolicyAPISelectors is used as part of a rate policy description. 249 RatePolicyAPISelectors []struct { 250 APIDefinitionID int `json:"apiDefinitionId,omitempty"` 251 DefinedResources *bool `json:"definedResources,omitempty"` 252 ResourceIds []int `json:"resourceIds"` 253 UndefinedResources *bool `json:"undefinedResources,omitempty"` 254 } 255 256 // RatePolicyBodyParameters is used as part of a rate policy description. 257 RatePolicyBodyParameters []struct { 258 Name string `json:"name,omitempty"` 259 Values []string `json:"values,omitempty"` 260 PositiveMatch bool `json:"positiveMatch"` 261 ValueInRange bool `json:"valueInRange"` 262 } 263 264 // RatePolicyPath is used as part of a rate policy description. 265 RatePolicyPath struct { 266 PositiveMatch bool `json:"positiveMatch"` 267 Values []string `json:"values,omitempty"` 268 } 269 270 // RatePolicyFileExtensions is used as part of a rate policy description. 271 RatePolicyFileExtensions struct { 272 PositiveMatch bool `json:"positiveMatch"` 273 Values []string `json:"values,omitempty"` 274 } 275 276 // RatePolicyMatchOption is used as part of a rate policy description. 277 RatePolicyMatchOption struct { 278 PositiveMatch bool `json:"positiveMatch"` 279 Type string `json:"type,omitempty"` 280 Values []string `json:"values,omitempty"` 281 } 282 283 // RatePolicyQueryParameters is used as part of a rate policy description. 284 RatePolicyQueryParameters []struct { 285 Name string `json:"name,omitempty"` 286 Values []string `json:"values,omitempty"` 287 PositiveMatch bool `json:"positiveMatch"` 288 ValueInRange bool `json:"valueInRange"` 289 } 290 291 // RatePoliciesHosts is used as part of a rate policy description. 292 RatePoliciesHosts struct { 293 Values *[]string `json:"values,omitempty"` 294 PositiveMatch *json.RawMessage `json:"positiveMatch,omitempty"` 295 } 296 ) 297 298 // Validate validates a GetRatePolicyRequest. 299 func (v GetRatePolicyRequest) Validate() error { 300 return validation.Errors{ 301 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 302 "ConfigVersion": validation.Validate(v.ConfigVersion, validation.Required), 303 "RatePolicyID": validation.Validate(v.RatePolicyID, validation.Required), 304 }.Filter() 305 } 306 307 // Validate validates a GetRatePolicysRequest. 308 func (v GetRatePoliciesRequest) Validate() error { 309 return validation.Errors{ 310 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 311 "ConfigVersion": validation.Validate(v.ConfigVersion, validation.Required), 312 }.Filter() 313 } 314 315 // Validate validates a CreateRatePolicyRequest. 316 func (v CreateRatePolicyRequest) Validate() error { 317 return validation.Errors{ 318 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 319 "ConfigVersion": validation.Validate(v.ConfigVersion, validation.Required), 320 }.Filter() 321 } 322 323 // Validate validates an UpdateRatePolicyRequest. 324 func (v UpdateRatePolicyRequest) Validate() error { 325 return validation.Errors{ 326 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 327 "ConfigVersion": validation.Validate(v.ConfigVersion, validation.Required), 328 "RatePolicyID": validation.Validate(v.RatePolicyID, validation.Required), 329 }.Filter() 330 } 331 332 // Validate validates a RemoveRatePolicyRequest. 333 func (v RemoveRatePolicyRequest) Validate() error { 334 return validation.Errors{ 335 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 336 "ConfigVersion": validation.Validate(v.ConfigVersion, validation.Required), 337 "RatePolicyID": validation.Validate(v.RatePolicyID, validation.Required), 338 }.Filter() 339 } 340 341 func (p *appsec) GetRatePolicy(ctx context.Context, params GetRatePolicyRequest) (*GetRatePolicyResponse, error) { 342 logger := p.Log(ctx) 343 logger.Debug("GetRatePolicy") 344 345 if err := params.Validate(); err != nil { 346 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 347 } 348 349 uri := fmt.Sprintf( 350 "/appsec/v1/configs/%d/versions/%d/rate-policies/%d", 351 params.ConfigID, 352 params.ConfigVersion, 353 params.RatePolicyID) 354 355 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 356 if err != nil { 357 return nil, fmt.Errorf("failed to create GetRatePolicy request: %w", err) 358 } 359 360 var result GetRatePolicyResponse 361 resp, err := p.Exec(req, &result) 362 if err != nil { 363 return nil, fmt.Errorf("get rate policy request failed: %w", err) 364 } 365 if resp.StatusCode != http.StatusOK { 366 return nil, p.Error(resp) 367 } 368 369 return &result, nil 370 } 371 372 func (p *appsec) GetRatePolicies(ctx context.Context, params GetRatePoliciesRequest) (*GetRatePoliciesResponse, error) { 373 logger := p.Log(ctx) 374 logger.Debug("GetRatePolicies") 375 376 if err := params.Validate(); err != nil { 377 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 378 } 379 380 uri := fmt.Sprintf( 381 "/appsec/v1/configs/%d/versions/%d/rate-policies", 382 params.ConfigID, 383 params.ConfigVersion, 384 ) 385 386 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 387 if err != nil { 388 return nil, fmt.Errorf("failed to create GetRatePolicies request: %w", err) 389 } 390 391 var result GetRatePoliciesResponse 392 resp, err := p.Exec(req, &result) 393 if err != nil { 394 return nil, fmt.Errorf("get rate policies request failed: %w", err) 395 } 396 if resp.StatusCode != http.StatusOK { 397 return nil, p.Error(resp) 398 } 399 400 if params.RatePolicyID != 0 { 401 var filteredResult GetRatePoliciesResponse 402 for _, val := range result.RatePolicies { 403 if val.ID == params.RatePolicyID { 404 filteredResult.RatePolicies = append(filteredResult.RatePolicies, val) 405 } 406 } 407 return &filteredResult, nil 408 } 409 410 return &result, nil 411 } 412 413 func (p *appsec) UpdateRatePolicy(ctx context.Context, params UpdateRatePolicyRequest) (*UpdateRatePolicyResponse, error) { 414 logger := p.Log(ctx) 415 logger.Debug("UpdateRatePolicy") 416 417 if err := params.Validate(); err != nil { 418 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 419 } 420 421 uri := fmt.Sprintf( 422 "/appsec/v1/configs/%d/versions/%d/rate-policies/%d", 423 params.ConfigID, 424 params.ConfigVersion, 425 params.RatePolicyID, 426 ) 427 428 req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri, nil) 429 if err != nil { 430 return nil, fmt.Errorf("failed to create UpdateRatePolicy request: %w", err) 431 } 432 433 var result UpdateRatePolicyResponse 434 req.Header.Set("Content-Type", "application/json") 435 resp, err := p.Exec(req, &result, params.JsonPayloadRaw) 436 if err != nil { 437 return nil, fmt.Errorf("update rate policy request failed: %w", err) 438 } 439 if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { 440 return nil, p.Error(resp) 441 } 442 443 return &result, nil 444 } 445 446 func (p *appsec) CreateRatePolicy(ctx context.Context, params CreateRatePolicyRequest) (*CreateRatePolicyResponse, error) { 447 logger := p.Log(ctx) 448 logger.Debug("CreateRatePolicy") 449 450 if err := params.Validate(); err != nil { 451 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 452 } 453 454 uri := fmt.Sprintf( 455 "/appsec/v1/configs/%d/versions/%d/rate-policies", 456 params.ConfigID, 457 params.ConfigVersion, 458 ) 459 460 req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil) 461 if err != nil { 462 return nil, fmt.Errorf("failed to create CreateRatePolicy request: %w", err) 463 } 464 465 var result CreateRatePolicyResponse 466 req.Header.Set("Content-Type", "application/json") 467 resp, err := p.Exec(req, &result, params.JsonPayloadRaw) 468 if err != nil { 469 return nil, fmt.Errorf("create rate policy request failed: %w", err) 470 } 471 if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { 472 return nil, p.Error(resp) 473 } 474 475 return &result, nil 476 } 477 478 func (p *appsec) RemoveRatePolicy(ctx context.Context, params RemoveRatePolicyRequest) (*RemoveRatePolicyResponse, error) { 479 logger := p.Log(ctx) 480 logger.Debug("RemoveRatePolicy") 481 482 if err := params.Validate(); err != nil { 483 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 484 } 485 486 uri := fmt.Sprintf("/appsec/v1/configs/%d/versions/%d/rate-policies/%d", params.ConfigID, params.ConfigVersion, params.RatePolicyID) 487 req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil) 488 if err != nil { 489 return nil, fmt.Errorf("failed to create RemoveRatePolicy request: %w", err) 490 } 491 492 var result RemoveRatePolicyResponse 493 resp, err := p.Exec(req, &result) 494 if err != nil { 495 return nil, fmt.Errorf("remove rate policy request failed: %w", err) 496 } 497 if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK { 498 return nil, p.Error(resp) 499 } 500 501 return &result, nil 502 }