github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.0/pkg/cloudlets/match_rule.go (about) 1 package cloudlets 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 8 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v2/pkg/edgegriderr" 9 10 validation "github.com/go-ozzo/ozzo-validation/v4" 11 ) 12 13 type ( 14 // MatchRule is base interface for MarchRuleALB and MatchRuleER 15 MatchRule interface { 16 // cloudletType is a private method to ensure that only match rules for supported cloudlets can be used 17 cloudletType() string 18 Validate() error 19 } 20 21 // MatchRules is an array of *MarchRuleALB or *MatchRuleER depending on the cloudletId (9 or 0) of the policy 22 MatchRules []MatchRule 23 24 // MatchRuleALB represents an Application Load Balancer (ALB) match rule resource for create or update resource 25 MatchRuleALB struct { 26 Name string `json:"name,omitempty"` 27 Type MatchRuleType `json:"type,omitempty"` 28 Start int64 `json:"start,omitempty"` 29 End int64 `json:"end,omitempty"` 30 ID int64 `json:"id,omitempty"` 31 Matches []MatchCriteriaALB `json:"matches,omitempty"` 32 MatchURL string `json:"matchURL,omitempty"` 33 MatchesAlways bool `json:"matchesAlways"` 34 ForwardSettings ForwardSettingsALB `json:"forwardSettings"` 35 Disabled bool `json:"disabled,omitempty"` 36 } 37 38 // ForwardSettingsALB represents forward settings for an Application Load Balancer (ALB) 39 ForwardSettingsALB struct { 40 OriginID string `json:"originId"` 41 } 42 43 // MatchRuleAP represents an API Prioritization (AP) match rule resource for create or update 44 MatchRuleAP struct { 45 Name string `json:"name,omitempty"` 46 Type MatchRuleType `json:"type,omitempty"` 47 Start int64 `json:"start,omitempty"` 48 End int64 `json:"end,omitempty"` 49 ID int64 `json:"id,omitempty"` 50 Matches []MatchCriteriaAP `json:"matches,omitempty"` 51 MatchURL string `json:"matchURL,omitempty"` 52 PassThroughPercent *float64 `json:"passThroughPercent"` 53 Disabled bool `json:"disabled,omitempty"` 54 } 55 56 // MatchRuleAS represents an Application Segmentation (AS) match rule resource for create or update resource 57 MatchRuleAS struct { 58 Name string `json:"name,omitempty"` 59 Type MatchRuleType `json:"type,omitempty"` 60 Start int64 `json:"start,omitempty"` 61 End int64 `json:"end,omitempty"` 62 ID int64 `json:"id,omitempty"` 63 Matches []MatchCriteriaAS `json:"matches,omitempty"` 64 MatchURL string `json:"matchURL,omitempty"` 65 ForwardSettings ForwardSettingsAS `json:"forwardSettings"` 66 Disabled bool `json:"disabled,omitempty"` 67 } 68 69 // ForwardSettingsAS represents forward settings for an Application Segmentation (AS) 70 ForwardSettingsAS struct { 71 PathAndQS string `json:"pathAndQS,omitempty"` 72 UseIncomingQueryString bool `json:"useIncomingQueryString,omitempty"` 73 OriginID string `json:"originId,omitempty"` 74 } 75 76 // MatchRulePR represents a Phased Release (PR aka CD) match rule resource for create or update resource 77 MatchRulePR struct { 78 Name string `json:"name,omitempty"` 79 Type MatchRuleType `json:"type,omitempty"` 80 Start int64 `json:"start,omitempty"` 81 End int64 `json:"end,omitempty"` 82 ID int64 `json:"id,omitempty"` 83 Matches []MatchCriteriaPR `json:"matches,omitempty"` 84 MatchURL string `json:"matchURL,omitempty"` 85 ForwardSettings ForwardSettingsPR `json:"forwardSettings"` 86 Disabled bool `json:"disabled,omitempty"` 87 MatchesAlways bool `json:"matchesAlways,omitempty"` 88 } 89 90 // ForwardSettingsPR represents forward settings for a Phased Release (PR aka CD) 91 ForwardSettingsPR struct { 92 OriginID string `json:"originId"` 93 Percent int `json:"percent"` 94 } 95 96 // MatchRuleER represents an Edge Redirector (ER) match rule resource for create or update resource 97 MatchRuleER struct { 98 Name string `json:"name,omitempty"` 99 Type MatchRuleType `json:"type,omitempty"` 100 Start int64 `json:"start,omitempty"` 101 End int64 `json:"end,omitempty"` 102 ID int64 `json:"id,omitempty"` 103 Matches []MatchCriteriaER `json:"matches,omitempty"` 104 UseRelativeURL string `json:"useRelativeUrl,omitempty"` 105 StatusCode int `json:"statusCode"` 106 RedirectURL string `json:"redirectURL"` 107 MatchURL string `json:"matchURL,omitempty"` 108 UseIncomingQueryString bool `json:"useIncomingQueryString"` 109 UseIncomingSchemeAndHost bool `json:"useIncomingSchemeAndHost"` 110 Disabled bool `json:"disabled,omitempty"` 111 } 112 113 // MatchRuleFR represents a Forward Rewrite (FR) match rule resource for create or update resource 114 MatchRuleFR struct { 115 Name string `json:"name,omitempty"` 116 Type MatchRuleType `json:"type,omitempty"` 117 Start int64 `json:"start,omitempty"` 118 End int64 `json:"end,omitempty"` 119 ID int64 `json:"id,omitempty"` 120 Matches []MatchCriteriaFR `json:"matches,omitempty"` 121 MatchURL string `json:"matchURL,omitempty"` 122 ForwardSettings ForwardSettingsFR `json:"forwardSettings"` 123 Disabled bool `json:"disabled,omitempty"` 124 } 125 126 // ForwardSettingsFR represents forward settings for a Forward Rewrite (FR) 127 ForwardSettingsFR struct { 128 PathAndQS string `json:"pathAndQS,omitempty"` 129 UseIncomingQueryString bool `json:"useIncomingQueryString,omitempty"` 130 OriginID string `json:"originId,omitempty"` 131 } 132 133 // MatchRuleRC represents a Request Control (RC aka IG) match rule resource for create or update resource 134 MatchRuleRC struct { 135 Name string `json:"name,omitempty"` 136 Type MatchRuleType `json:"type,omitempty"` 137 Start int64 `json:"start,omitempty"` 138 End int64 `json:"end,omitempty"` 139 ID int64 `json:"id,omitempty"` 140 Matches []MatchCriteriaRC `json:"matches,omitempty"` 141 MatchesAlways bool `json:"matchesAlways,omitempty"` 142 AllowDeny AllowDeny `json:"allowDeny"` 143 Disabled bool `json:"disabled,omitempty"` 144 } 145 146 // MatchRuleVP represents a Visitor Prioritization (VP) match rule resource for create or update resource 147 MatchRuleVP struct { 148 Name string `json:"name,omitempty"` 149 Type MatchRuleType `json:"type,omitempty"` 150 Start int64 `json:"start,omitempty"` 151 End int64 `json:"end,omitempty"` 152 ID int64 `json:"id,omitempty"` 153 Matches []MatchCriteriaVP `json:"matches,omitempty"` 154 MatchURL string `json:"matchURL,omitempty"` 155 PassThroughPercent *float64 `json:"passThroughPercent"` 156 Disabled bool `json:"disabled,omitempty"` 157 } 158 159 // MatchCriteria represents a match criteria resource for match rule for cloudlet 160 MatchCriteria struct { 161 MatchType string `json:"matchType,omitempty"` 162 MatchValue string `json:"matchValue,omitempty"` 163 MatchOperator MatchOperator `json:"matchOperator,omitempty"` 164 CaseSensitive bool `json:"caseSensitive"` 165 Negate bool `json:"negate"` 166 CheckIPs CheckIPs `json:"checkIPs,omitempty"` 167 ObjectMatchValue interface{} `json:"objectMatchValue,omitempty"` 168 } 169 170 // MatchCriteriaALB represents a match criteria resource for match rule for cloudlet Application Load Balancer (ALB) 171 // ObjectMatchValue can contain ObjectMatchValueObject, ObjectMatchValueSimple or ObjectMatchValueRange 172 MatchCriteriaALB MatchCriteria 173 174 // MatchCriteriaAP represents a match criteria resource for match rule for cloudlet API Prioritization (AP) 175 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple 176 MatchCriteriaAP MatchCriteria 177 178 // MatchCriteriaAS represents a match criteria resource for match rule for cloudlet Application Segmentation (AS) 179 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple or ObjectMatchValueRange 180 MatchCriteriaAS MatchCriteria 181 182 // MatchCriteriaPR represents a match criteria resource for match rule for cloudlet Phased Release (PR aka CD) 183 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple 184 MatchCriteriaPR MatchCriteria 185 186 // MatchCriteriaER represents a match criteria resource for match rule for cloudlet Edge Redirector (ER) 187 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple 188 MatchCriteriaER MatchCriteria 189 190 // MatchCriteriaFR represents a match criteria resource for match rule for cloudlet Forward Rewrite (FR) 191 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple 192 MatchCriteriaFR MatchCriteria 193 194 // MatchCriteriaRC represents a match criteria resource for match rule for cloudlet Request Control (RC aka IG) 195 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple 196 MatchCriteriaRC MatchCriteria 197 198 // MatchCriteriaVP represents a match criteria resource for match rule for cloudlet Visitor Prioritization (VP) 199 // ObjectMatchValue can contain ObjectMatchValueObject or ObjectMatchValueSimple 200 MatchCriteriaVP MatchCriteria 201 202 // ObjectMatchValueObject represents an object match value resource for match criteria of type object 203 ObjectMatchValueObject struct { 204 Name string `json:"name"` 205 Type ObjectMatchValueObjectType `json:"type"` 206 NameCaseSensitive bool `json:"nameCaseSensitive"` 207 NameHasWildcard bool `json:"nameHasWildcard"` 208 Options *Options `json:"options,omitempty"` 209 } 210 211 // ObjectMatchValueSimple represents an object match value resource for match criteria of type simple 212 ObjectMatchValueSimple struct { 213 Type ObjectMatchValueSimpleType `json:"type"` 214 Value []string `json:"value,omitempty"` 215 } 216 217 // ObjectMatchValueRange represents an object match value resource for match criteria of type range 218 ObjectMatchValueRange struct { 219 Type ObjectMatchValueRangeType `json:"type"` 220 Value []int64 `json:"value,omitempty"` 221 } 222 223 // Options represents an option resource for ObjectMatchValueObject 224 Options struct { 225 Value []string `json:"value,omitempty"` 226 ValueHasWildcard bool `json:"valueHasWildcard,omitempty"` 227 ValueCaseSensitive bool `json:"valueCaseSensitive,omitempty"` 228 ValueEscaped bool `json:"valueEscaped,omitempty"` 229 } 230 231 //MatchRuleType enum type 232 MatchRuleType string 233 // MatchRuleFormat enum type 234 MatchRuleFormat string 235 // MatchOperator enum type 236 MatchOperator string 237 // AllowDeny enum type 238 AllowDeny string 239 // CheckIPs enum type 240 CheckIPs string 241 // ObjectMatchValueRangeType enum type 242 ObjectMatchValueRangeType string 243 // ObjectMatchValueSimpleType enum type 244 ObjectMatchValueSimpleType string 245 // ObjectMatchValueObjectType enum type 246 ObjectMatchValueObjectType string 247 ) 248 249 const ( 250 // MatchRuleTypeALB represents rule type for Application Load Balancer (ALB) cloudlets 251 MatchRuleTypeALB MatchRuleType = "albMatchRule" 252 // MatchRuleTypeAP represents rule type for API Prioritization (AP) cloudlets 253 MatchRuleTypeAP MatchRuleType = "apMatchRule" 254 // MatchRuleTypeAS represents rule type for Application Segmentation (AS) cloudlets 255 MatchRuleTypeAS MatchRuleType = "asMatchRule" 256 // MatchRuleTypePR represents rule type for Phased Release (PR aka CD) cloudlets 257 MatchRuleTypePR MatchRuleType = "cdMatchRule" 258 // MatchRuleTypeER represents rule type for Edge Redirector (ER) cloudlets 259 MatchRuleTypeER MatchRuleType = "erMatchRule" 260 // MatchRuleTypeFR represents rule type for Forward Rewrite (FR) cloudlets 261 MatchRuleTypeFR MatchRuleType = "frMatchRule" 262 // MatchRuleTypeRC represents rule type for Request Control (RC aka IG) cloudlets 263 MatchRuleTypeRC MatchRuleType = "igMatchRule" 264 // MatchRuleTypeVP represents rule type for Visitor Prioritization (VP) cloudlets 265 MatchRuleTypeVP MatchRuleType = "vpMatchRule" 266 ) 267 268 const ( 269 // MatchRuleFormat10 represents default match rule format 270 MatchRuleFormat10 MatchRuleFormat = "1.0" 271 ) 272 273 const ( 274 // MatchOperatorContains represents contains operator 275 MatchOperatorContains MatchOperator = "contains" 276 // MatchOperatorExists represents exists operator 277 MatchOperatorExists MatchOperator = "exists" 278 // MatchOperatorEquals represents equals operator 279 MatchOperatorEquals MatchOperator = "equals" 280 ) 281 282 const ( 283 // Allow represents allow option 284 Allow AllowDeny = "allow" 285 // Deny represents deny option 286 Deny AllowDeny = "deny" 287 // DenyBranded represents denybranded option 288 DenyBranded AllowDeny = "denybranded" 289 ) 290 291 const ( 292 // CheckIPsConnectingIP represents connecting ip option 293 CheckIPsConnectingIP CheckIPs = "CONNECTING_IP" 294 // CheckIPsXFFHeaders represents xff headers option 295 CheckIPsXFFHeaders CheckIPs = "XFF_HEADERS" 296 // CheckIPsConnectingIPXFFHeaders represents connecting ip + xff headers option 297 CheckIPsConnectingIPXFFHeaders CheckIPs = "CONNECTING_IP XFF_HEADERS" 298 ) 299 300 const ( 301 // Range represents range option 302 Range ObjectMatchValueRangeType = "range" 303 // Simple represents simple option 304 Simple ObjectMatchValueSimpleType = "simple" 305 // Object represents object option 306 Object ObjectMatchValueObjectType = "object" 307 ) 308 309 var ( 310 // ErrUnmarshallMatchCriteriaALB is returned when unmarshalling of MatchCriteriaALB fails 311 ErrUnmarshallMatchCriteriaALB = errors.New("unmarshalling MatchCriteriaALB") 312 // ErrUnmarshallMatchCriteriaAP is returned when unmarshalling of MatchCriteriaAP fails 313 ErrUnmarshallMatchCriteriaAP = errors.New("unmarshalling MatchCriteriaAP") 314 // ErrUnmarshallMatchCriteriaAS is returned when unmarshalling of MatchCriteriaAS fails 315 ErrUnmarshallMatchCriteriaAS = errors.New("unmarshalling MatchCriteriaAS") 316 // ErrUnmarshallMatchCriteriaPR is returned when unmarshalling of MatchCriteriaPR fails 317 ErrUnmarshallMatchCriteriaPR = errors.New("unmarshalling MatchCriteriaPR") 318 // ErrUnmarshallMatchCriteriaER is returned when unmarshalling of MatchCriteriaER fails 319 ErrUnmarshallMatchCriteriaER = errors.New("unmarshalling MatchCriteriaER") 320 // ErrUnmarshallMatchCriteriaFR is returned when unmarshalling of MatchCriteriaFR fails 321 ErrUnmarshallMatchCriteriaFR = errors.New("unmarshalling MatchCriteriaFR") 322 // ErrUnmarshallMatchCriteriaRC is returned when unmarshalling of MatchCriteriaRC fails 323 ErrUnmarshallMatchCriteriaRC = errors.New("unmarshalling MatchCriteriaRC") 324 // ErrUnmarshallMatchCriteriaVP is returned when unmarshalling of MatchCriteriaVP fails 325 ErrUnmarshallMatchCriteriaVP = errors.New("unmarshalling MatchCriteriaVP") 326 // ErrUnmarshallMatchRules is returned when unmarshalling of MatchRules fails 327 ErrUnmarshallMatchRules = errors.New("unmarshalling MatchRules") 328 ) 329 330 // matchRuleHandlers contains mapping between name of the type for MatchRule and its implementation 331 // It makes the UnmarshalJSON more compact and easier to support more cloudlet types 332 var matchRuleHandlers = map[string]func() MatchRule{ 333 "albMatchRule": func() MatchRule { return &MatchRuleALB{} }, 334 "apMatchRule": func() MatchRule { return &MatchRuleAP{} }, 335 "asMatchRule": func() MatchRule { return &MatchRuleAS{} }, 336 "cdMatchRule": func() MatchRule { return &MatchRulePR{} }, 337 "erMatchRule": func() MatchRule { return &MatchRuleER{} }, 338 "frMatchRule": func() MatchRule { return &MatchRuleFR{} }, 339 "igMatchRule": func() MatchRule { return &MatchRuleRC{} }, 340 "vpMatchRule": func() MatchRule { return &MatchRuleVP{} }, 341 } 342 343 // objectOrRangeOrSimpleMatchValueHandlers contains mapping between name of the type for ObjectMatchValue and its implementation 344 // It makes the UnmarshalJSON more compact and easier to support more types 345 var objectOrRangeOrSimpleMatchValueHandlers = map[string]func() interface{}{ 346 "object": func() interface{} { return &ObjectMatchValueObject{} }, 347 "range": func() interface{} { return &ObjectMatchValueRange{} }, 348 "simple": func() interface{} { return &ObjectMatchValueSimple{} }, 349 } 350 351 // simpleObjectMatchValueHandlers contains mapping between name of the types (simple or object) for ObjectMatchValue and their implementations 352 // It makes the UnmarshalJSON more compact and easier to support more types 353 var simpleObjectMatchValueHandlers = map[string]func() interface{}{ 354 "object": func() interface{} { return &ObjectMatchValueObject{} }, 355 "simple": func() interface{} { return &ObjectMatchValueSimple{} }, 356 } 357 358 // Validate validates MatchRules 359 func (m MatchRules) Validate() error { 360 type matchRules MatchRules 361 362 errs := validation.Errors{ 363 "MatchRules": validation.Validate(matchRules(m), validation.Length(0, 5000)), 364 } 365 return edgegriderr.ParseValidationErrors(errs) 366 } 367 368 // Validate validates MatchRuleALB 369 func (m MatchRuleALB) Validate() error { 370 return validation.Errors{ 371 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeALB).Error( 372 fmt.Sprintf("value '%s' is invalid. Must be: 'albMatchRule'", (&m).Type))), 373 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 374 "Start": validation.Validate(m.Start, validation.Min(0)), 375 "End": validation.Validate(m.End, validation.Min(0)), 376 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 377 "ForwardSettings.OriginID": validation.Validate(m.ForwardSettings.OriginID, validation.Required, validation.Length(0, 8192)), 378 "Matches": validation.Validate(m.Matches), 379 }.Filter() 380 } 381 382 // Validate validates MatchRuleAP 383 func (m MatchRuleAP) Validate() error { 384 return validation.Errors{ 385 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeAP).Error( 386 fmt.Sprintf("value '%s' is invalid. Must be: 'apMatchRule'", (&m).Type))), 387 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 388 "Start": validation.Validate(m.Start, validation.Min(0)), 389 "End": validation.Validate(m.End, validation.Min(0)), 390 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 391 "PassThroughPercent": validation.Validate(m.PassThroughPercent, validation.By(passThroughPercentValidation)), 392 "Matches": validation.Validate(m.Matches), 393 }.Filter() 394 } 395 396 // Validate validates MatchRuleAS 397 func (m MatchRuleAS) Validate() error { 398 return validation.Errors{ 399 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeAS).Error( 400 fmt.Sprintf("value '%s' is invalid. Must be: 'asMatchRule'", (&m).Type))), 401 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 402 "Start": validation.Validate(m.Start, validation.Min(0)), 403 "End": validation.Validate(m.End, validation.Min(0)), 404 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 405 "Matches": validation.Validate(m.Matches), 406 "ForwardSettings": validation.Validate(m.ForwardSettings, validation.Required), 407 "ForwardSettings.PathAndQS": validation.Validate(m.ForwardSettings.PathAndQS, validation.Length(1, 8192)), 408 "ForwardSettings.OriginID": validation.Validate(m.ForwardSettings.OriginID, validation.Length(0, 8192)), 409 }.Filter() 410 } 411 412 // Validate validates MatchRulePR 413 func (m MatchRulePR) Validate() error { 414 return validation.Errors{ 415 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypePR).Error( 416 fmt.Sprintf("value '%s' is invalid. Must be: 'cdMatchRule'", (&m).Type))), 417 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 418 "Start": validation.Validate(m.Start, validation.Min(0)), 419 "End": validation.Validate(m.End, validation.Min(0)), 420 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 421 "ForwardSettings": validation.Validate(m.ForwardSettings, validation.Required), 422 "ForwardSettings.OriginID": validation.Validate(m.ForwardSettings.OriginID, validation.Required, validation.Length(0, 8192)), 423 "ForwardSettings.Percent": validation.Validate(m.ForwardSettings.Percent, validation.Required, validation.Min(1), validation.Max(100)), 424 "Matches": validation.Validate(m.Matches), 425 }.Filter() 426 } 427 428 // Validate validates MatchRuleER 429 func (m MatchRuleER) Validate() error { 430 return validation.Errors{ 431 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeER).Error( 432 fmt.Sprintf("value '%s' is invalid. Must be: 'erMatchRule'", (&m).Type))), 433 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 434 "Start": validation.Validate(m.Start, validation.Min(0)), 435 "End": validation.Validate(m.End, validation.Min(0)), 436 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 437 "RedirectURL": validation.Validate(m.RedirectURL, validation.Required, validation.Length(1, 8192)), 438 "UseRelativeURL": validation.Validate(m.UseRelativeURL, validation.In("none", "copy_scheme_hostname", "relative_url").Error( 439 fmt.Sprintf("value '%s' is invalid. Must be one of: 'none', 'copy_scheme_hostname', 'relative_url' or '' (empty)", (&m).UseRelativeURL))), 440 "StatusCode": validation.Validate(m.StatusCode, validation.Required, validation.In(301, 302, 303, 307, 308).Error( 441 fmt.Sprintf("value '%d' is invalid. Must be one of: 301, 302, 303, 307 or 308", (&m).StatusCode))), 442 "Matches": validation.Validate(m.Matches), 443 }.Filter() 444 } 445 446 // Validate validates MatchRuleFR 447 func (m MatchRuleFR) Validate() error { 448 return validation.Errors{ 449 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeFR).Error( 450 fmt.Sprintf("value '%s' is invalid. Must be: 'frMatchRule'", (&m).Type))), 451 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 452 "Start": validation.Validate(m.Start, validation.Min(0)), 453 "End": validation.Validate(m.End, validation.Min(0)), 454 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 455 "Matches": validation.Validate(m.Matches), 456 "ForwardSettings": validation.Validate(m.ForwardSettings, validation.Required), 457 "ForwardSettings.PathAndQS": validation.Validate(m.ForwardSettings.PathAndQS, validation.Length(1, 8192)), 458 "ForwardSettings.OriginID": validation.Validate(m.ForwardSettings.OriginID, validation.Length(0, 8192)), 459 }.Filter() 460 } 461 462 // Validate validates MatchRuleRC 463 func (m MatchRuleRC) Validate() error { 464 return validation.Errors{ 465 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeRC).Error( 466 fmt.Sprintf("value '%s' is invalid. Must be: 'igMatchRule'", (&m).Type))), 467 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 468 "Start": validation.Validate(m.Start, validation.Min(0)), 469 "End": validation.Validate(m.End, validation.Min(0)), 470 "Matches": validation.Validate(m.Matches, validation.When(m.MatchesAlways, validation.Empty.Error("must be blank when 'matchesAlways' is set"))), 471 "AllowDeny": validation.Validate(m.AllowDeny, validation.Required, validation.In(Allow, Deny, DenyBranded).Error( 472 fmt.Sprintf("value '%s' is invalid. Must be one of: '%s', '%s' or '%s'", (&m).AllowDeny, Allow, Deny, DenyBranded), 473 )), 474 }.Filter() 475 } 476 477 // Validate validates MatchRuleVP 478 func (m MatchRuleVP) Validate() error { 479 return validation.Errors{ 480 "Type": validation.Validate(m.Type, validation.Required, validation.In(MatchRuleTypeVP).Error( 481 fmt.Sprintf("value '%s' is invalid. Must be: 'vpMatchRule'", (&m).Type))), 482 "Name": validation.Validate(m.Name, validation.Length(0, 8192)), 483 "Start": validation.Validate(m.Start, validation.Min(0)), 484 "End": validation.Validate(m.End, validation.Min(0)), 485 "MatchURL": validation.Validate(m.MatchURL, validation.Length(0, 8192)), 486 "PassThroughPercent": validation.Validate(m.PassThroughPercent, validation.By(passThroughPercentValidation)), 487 "Matches": validation.Validate(m.Matches), 488 }.Filter() 489 } 490 491 // Validate validates MatchCriteriaALB 492 func (m MatchCriteriaALB) Validate() error { 493 return validation.Errors{ 494 "MatchType": validation.Validate(m.MatchType, validation.In("clientip", "continent", "cookie", "countrycode", 495 "deviceCharacteristics", "extension", "header", "hostname", "method", "path", "protocol", "proxy", "query", "regioncode", "range").Error( 496 fmt.Sprintf("value '%s' is invalid. Must be one of: 'clientip', 'continent', 'cookie', 'countrycode', 'deviceCharacteristics', "+ 497 "'extension', 'header', 'hostname', 'method', 'path', 'protocol', 'proxy', 'query', 'regioncode', 'range' or '' (empty)", (&m).MatchType))), 498 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 499 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 500 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 501 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 502 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 503 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 504 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 505 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrRangeOrObjectValidation)), 506 }.Filter() 507 } 508 509 // Validate validates MatchCriteriaAP 510 func (m MatchCriteriaAP) Validate() error { 511 return validation.Errors{ 512 "MatchType": validation.Validate(m.MatchType, validation.In( 513 "header", "hostname", "path", "extension", "query", "cookie", "deviceCharacteristics", "clientip", 514 "continent", "countrycode", "regioncode", "protocol", "method", "proxy").Error( 515 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'cookie', "+ 516 "'deviceCharacteristics', 'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy'", (&m).MatchType))), 517 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 518 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 519 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 520 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 521 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 522 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 523 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 524 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrObjectValidation)), 525 }.Filter() 526 } 527 528 // Validate validates MatchCriteriaAS 529 func (m MatchCriteriaAS) Validate() error { 530 return validation.Errors{ 531 "MatchType": validation.Validate(m.MatchType, validation.In("header", "hostname", "path", "extension", "query", "range", 532 "regex", "cookie", "deviceCharacteristics", "clientip", "continent", "countrycode", "regioncode", "protocol", "method", "proxy").Error( 533 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'range', "+ 534 "'regex', 'cookie', 'deviceCharacteristics', 'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy'", (&m).MatchType))), 535 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 536 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 537 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 538 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 539 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 540 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 541 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 542 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrRangeOrObjectValidation)), 543 }.Filter() 544 } 545 546 // Validate validates MatchCriteriaPR 547 func (m MatchCriteriaPR) Validate() error { 548 return validation.Errors{ 549 "MatchType": validation.Validate(m.MatchType, validation.In("header", "hostname", "path", "extension", 550 "query", "cookie", "deviceCharacteristics", "clientip", "continent", "countrycode", "regioncode", "protocol", 551 "method", "proxy").Error( 552 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'cookie', "+ 553 "'deviceCharacteristics', 'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy'", (&m).MatchType))), 554 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 555 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 556 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 557 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 558 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 559 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 560 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 561 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrObjectValidation)), 562 }.Filter() 563 } 564 565 // Validate validates MatchCriteriaER 566 func (m MatchCriteriaER) Validate() error { 567 return validation.Errors{ 568 "MatchType": validation.Validate(m.MatchType, validation.In("header", "hostname", "path", "extension", "query", 569 "regex", "cookie", "deviceCharacteristics", "clientip", "continent", "countrycode", "regioncode", "protocol", "method", "proxy").Error( 570 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'regex', 'cookie', "+ 571 "'deviceCharacteristics', 'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy' or '' (empty)", (&m).MatchType))), 572 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 573 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 574 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 575 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 576 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 577 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 578 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 579 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrObjectValidation)), 580 }.Filter() 581 } 582 583 // Validate validates MatchCriteriaFR 584 func (m MatchCriteriaFR) Validate() error { 585 return validation.Errors{ 586 "MatchType": validation.Validate(m.MatchType, validation.Required, validation.In("header", "hostname", "path", "extension", "query", "regex", 587 "cookie", "deviceCharacteristics", "clientip", "continent", "countrycode", "regioncode", "protocol", "method", "proxy").Error( 588 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'regex', 'cookie', "+ 589 "'deviceCharacteristics', 'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy'", (&m).MatchType))), 590 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 591 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 592 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 593 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 594 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 595 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 596 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 597 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrObjectValidation)), 598 }.Filter() 599 } 600 601 // Validate validates MatchCriteriaRC 602 func (m MatchCriteriaRC) Validate() error { 603 return validation.Errors{ 604 "MatchType": validation.Validate(m.MatchType, validation.Required, validation.In("header", "hostname", "path", "extension", "query", "cookie", 605 "deviceCharacteristics", "clientip", "continent", "countrycode", "regioncode", "protocol", "method", "proxy").Error( 606 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'cookie', 'deviceCharacteristics', "+ 607 "'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy'", (&m).MatchType))), 608 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 609 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 610 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 611 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 612 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 613 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 614 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 615 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrObjectValidation)), 616 }.Filter() 617 } 618 619 // Validate validates MatchCriteriaVP 620 func (m MatchCriteriaVP) Validate() error { 621 return validation.Errors{ 622 "MatchType": validation.Validate(m.MatchType, validation.In("header", "hostname", "path", "extension", "query", 623 "cookie", "deviceCharacteristics", "clientip", "continent", "countrycode", "regioncode", "protocol", "method", "proxy").Error( 624 fmt.Sprintf("value '%s' is invalid. Must be one of: 'header', 'hostname', 'path', 'extension', 'query', 'cookie', "+ 625 "'deviceCharacteristics', 'clientip', 'continent', 'countrycode', 'regioncode', 'protocol', 'method', 'proxy'", (&m).MatchType))), 626 "MatchValue": validation.Validate(m.MatchValue, validation.Length(1, 8192), validation.Required.When(m.ObjectMatchValue == nil).Error("cannot be blank when ObjectMatchValue is blank"), 627 validation.Empty.When(m.ObjectMatchValue != nil).Error("must be blank when ObjectMatchValue is set")), 628 "MatchOperator": validation.Validate(m.MatchOperator, validation.In(MatchOperatorContains, MatchOperatorExists, MatchOperatorEquals).Error( 629 fmt.Sprintf("value '%s' is invalid. Must be one of: 'contains', 'exists', 'equals' or '' (empty)", (&m).MatchOperator))), 630 "CheckIPs": validation.Validate(m.CheckIPs, validation.In(CheckIPsConnectingIP, CheckIPsXFFHeaders, CheckIPsConnectingIPXFFHeaders).Error( 631 fmt.Sprintf("value '%s' is invalid. Must be one of: 'CONNECTING_IP', 'XFF_HEADERS', 'CONNECTING_IP XFF_HEADERS' or '' (empty)", (&m).CheckIPs))), 632 "ObjectMatchValue": validation.Validate(m.ObjectMatchValue, validation.Required.When(m.MatchValue == "").Error("cannot be blank when MatchValue is blank"), 633 validation.Empty.When(m.MatchValue != "").Error("must be blank when MatchValue is set"), validation.By(objectMatchValueSimpleOrObjectValidation)), 634 }.Filter() 635 } 636 637 func objectMatchValueSimpleOrObjectValidation(value interface{}) error { 638 if value == nil { 639 return nil 640 } 641 switch value.(type) { 642 case *ObjectMatchValueObject, *ObjectMatchValueSimple: 643 return nil 644 default: 645 return fmt.Errorf("type %T is invalid. Must be one of: 'simple' or 'object'", value) 646 } 647 } 648 649 func objectMatchValueSimpleOrRangeOrObjectValidation(value interface{}) error { 650 if value == nil { 651 return nil 652 } 653 switch value.(type) { 654 case *ObjectMatchValueObject, *ObjectMatchValueSimple, *ObjectMatchValueRange: 655 return nil 656 default: 657 return fmt.Errorf("type %T is invalid. Must be one of: 'simple', 'range' or 'object'", value) 658 } 659 } 660 661 func passThroughPercentValidation(value interface{}) error { 662 v, ok := value.(*float64) 663 if !ok { 664 return fmt.Errorf("type %T is invalid. Must be *float64", value) 665 } 666 if v == nil { 667 return fmt.Errorf("cannot be blank") 668 } 669 if *v < -1 { 670 return fmt.Errorf("must be no less than -1") 671 } 672 if *v > 100 { 673 return fmt.Errorf("must be no greater than 100") 674 } 675 return nil 676 } 677 678 // Validate validates ObjectMatchValueRange 679 func (o ObjectMatchValueRange) Validate() error { 680 return validation.Errors{ 681 "Type": validation.Validate(o.Type, validation.In(Range).Error( 682 fmt.Sprintf("value '%s' is invalid. Must be: 'range'", (&o).Type))), 683 }.Filter() 684 } 685 686 // Validate validates ObjectMatchValueSimple 687 func (o ObjectMatchValueSimple) Validate() error { 688 return validation.Errors{ 689 "Type": validation.Validate(o.Type, validation.In(Simple).Error( 690 fmt.Sprintf("value '%s' is invalid. Must be: 'simple'", (&o).Type))), 691 }.Filter() 692 } 693 694 // Validate validates ObjectMatchValueObject 695 func (o ObjectMatchValueObject) Validate() error { 696 return validation.Errors{ 697 "Name": validation.Validate(o.Name, validation.Required, validation.Length(0, 8192)), 698 "Type": validation.Validate(o.Type, validation.Required, validation.In(Object).Error( 699 fmt.Sprintf("value '%s' is invalid. Must be: 'object'", (&o).Type))), 700 }.Filter() 701 } 702 703 func (m MatchRuleALB) cloudletType() string { 704 return "albMatchRule" 705 } 706 707 func (m MatchRuleAP) cloudletType() string { 708 return "apMatchRule" 709 } 710 711 func (m MatchRuleAS) cloudletType() string { 712 return "asMatchRule" 713 } 714 715 func (m MatchRulePR) cloudletType() string { 716 return "cdMatchRule" 717 } 718 719 func (m MatchRuleER) cloudletType() string { 720 return "erMatchRule" 721 } 722 723 func (m MatchRuleFR) cloudletType() string { 724 return "frMatchRule" 725 } 726 727 func (m MatchRuleRC) cloudletType() string { 728 return "igMatchRule" 729 } 730 731 func (m MatchRuleVP) cloudletType() string { 732 return "vpMatchRule" 733 } 734 735 // UnmarshalJSON helps to un-marshall items of MatchRules array as proper instances of *MatchRuleALB or *MatchRuleER 736 func (m *MatchRules) UnmarshalJSON(b []byte) error { 737 data := make([]map[string]interface{}, 0) 738 if err := json.Unmarshal(b, &data); err != nil { 739 return fmt.Errorf("%w: %s", ErrUnmarshallMatchRules, err) 740 } 741 for _, matchRule := range data { 742 cloudletType, ok := matchRule["type"] 743 if !ok { 744 return fmt.Errorf("%w: match rule entry should contain 'type' field", ErrUnmarshallMatchRules) 745 } 746 cloudletTypeName, ok := cloudletType.(string) 747 if !ok { 748 return fmt.Errorf("%w: 'type' field on match rule entry should be a string", ErrUnmarshallMatchRules) 749 } 750 byteArr, err := json.Marshal(matchRule) 751 if err != nil { 752 return fmt.Errorf("%w: %s", ErrUnmarshallMatchRules, err) 753 } 754 755 matchRuleType, ok := matchRuleHandlers[cloudletTypeName] 756 if !ok { 757 return fmt.Errorf("%w: unsupported match rule type: %s", ErrUnmarshallMatchRules, cloudletTypeName) 758 } 759 dst := matchRuleType() 760 err = json.Unmarshal(byteArr, dst) 761 if err != nil { 762 return fmt.Errorf("%w: %s", ErrUnmarshallMatchRules, err) 763 } 764 *m = append(*m, dst) 765 } 766 return nil 767 } 768 769 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaALB as proper instance of *ObjectMatchValueObject, *ObjectMatchValueSimple or *ObjectMatchValueRange 770 func (m *MatchCriteriaALB) UnmarshalJSON(b []byte) error { 771 // matchCriteriaALB is an alias for MatchCriteriaALB for un-marshalling purposes 772 type matchCriteriaALB MatchCriteriaALB 773 774 // populate common attributes using default json unmarshaler using aliased type 775 err := json.Unmarshal(b, (*matchCriteriaALB)(m)) 776 if err != nil { 777 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaALB, err) 778 } 779 if m.ObjectMatchValue == nil { 780 return nil 781 } 782 783 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 784 if err != nil { 785 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaALB, err) 786 } 787 788 createObjectMatchValue, ok := objectOrRangeOrSimpleMatchValueHandlers[objectMatchValueTypeName] 789 if !ok { 790 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaALB, objectMatchValueTypeName) 791 } 792 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 793 if err != nil { 794 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaALB, err) 795 } 796 m.ObjectMatchValue = convertedObjectMatchValue 797 798 return nil 799 } 800 801 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaAP as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple 802 func (m *MatchCriteriaAP) UnmarshalJSON(b []byte) error { 803 // matchCriteriaER is an alias for MatchCriteriaER for un-marshalling purposes 804 type matchCriteriaAP MatchCriteriaAP 805 806 // populate common attributes using default json unmarshaler using aliased type 807 err := json.Unmarshal(b, (*matchCriteriaAP)(m)) 808 if err != nil { 809 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaAP, err) 810 } 811 if m.ObjectMatchValue == nil { 812 return nil 813 } 814 815 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 816 if err != nil { 817 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaAP, err) 818 } 819 820 createObjectMatchValue, ok := simpleObjectMatchValueHandlers[objectMatchValueTypeName] 821 if !ok { 822 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaAP, objectMatchValueTypeName) 823 } 824 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 825 if err != nil { 826 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaAP, err) 827 } 828 m.ObjectMatchValue = convertedObjectMatchValue 829 830 return nil 831 } 832 833 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaAS as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple or *ObjectMatchValueRange 834 func (m *MatchCriteriaAS) UnmarshalJSON(b []byte) error { 835 // matchCriteriaAS is an alias for MatchCriteriaAS for un-marshalling purposes 836 type matchCriteriaAS MatchCriteriaAS 837 838 // populate common attributes using default json unmarshaler using aliased type 839 err := json.Unmarshal(b, (*matchCriteriaAS)(m)) 840 if err != nil { 841 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaAS, err) 842 } 843 if m.ObjectMatchValue == nil { 844 return nil 845 } 846 847 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 848 if err != nil { 849 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaAS, err) 850 } 851 852 createObjectMatchValue, ok := objectOrRangeOrSimpleMatchValueHandlers[objectMatchValueTypeName] 853 if !ok { 854 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaAS, objectMatchValueTypeName) 855 } 856 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 857 if err != nil { 858 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaAS, err) 859 } 860 m.ObjectMatchValue = convertedObjectMatchValue 861 862 return nil 863 } 864 865 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaPR as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple 866 func (m *MatchCriteriaPR) UnmarshalJSON(b []byte) error { 867 // matchCriteriaPR is an alias for MatchCriteriaPR for un-marshalling purposes 868 type matchCriteriaPR MatchCriteriaPR 869 870 // populate common attributes using default json unmarshaler using aliased type 871 err := json.Unmarshal(b, (*matchCriteriaPR)(m)) 872 if err != nil { 873 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaPR, err) 874 } 875 if m.ObjectMatchValue == nil { 876 return nil 877 } 878 879 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 880 if err != nil { 881 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaPR, err) 882 } 883 884 createObjectMatchValue, ok := simpleObjectMatchValueHandlers[objectMatchValueTypeName] 885 if !ok { 886 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaPR, objectMatchValueTypeName) 887 } 888 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 889 if err != nil { 890 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaPR, err) 891 } 892 m.ObjectMatchValue = convertedObjectMatchValue 893 894 return nil 895 } 896 897 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaER as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple 898 func (m *MatchCriteriaER) UnmarshalJSON(b []byte) error { 899 // matchCriteriaER is an alias for MatchCriteriaER for un-marshalling purposes 900 type matchCriteriaER MatchCriteriaER 901 902 // populate common attributes using default json unmarshaler using aliased type 903 err := json.Unmarshal(b, (*matchCriteriaER)(m)) 904 if err != nil { 905 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaER, err) 906 } 907 if m.ObjectMatchValue == nil { 908 return nil 909 } 910 911 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 912 if err != nil { 913 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaER, err) 914 } 915 916 createObjectMatchValue, ok := simpleObjectMatchValueHandlers[objectMatchValueTypeName] 917 if !ok { 918 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaER, objectMatchValueTypeName) 919 } 920 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 921 if err != nil { 922 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaER, err) 923 } 924 m.ObjectMatchValue = convertedObjectMatchValue 925 926 return nil 927 } 928 929 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaFR as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple 930 func (m *MatchCriteriaFR) UnmarshalJSON(b []byte) error { 931 // matchCriteriaFR is an alias for MatchCriteriaFR for un-marshalling purposes 932 type matchCriteriaFR MatchCriteriaFR 933 934 // populate common attributes using default json unmarshaler using aliased type 935 err := json.Unmarshal(b, (*matchCriteriaFR)(m)) 936 if err != nil { 937 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaFR, err) 938 } 939 if m.ObjectMatchValue == nil { 940 return nil 941 } 942 943 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 944 if err != nil { 945 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaFR, err) 946 } 947 948 createObjectMatchValue, ok := simpleObjectMatchValueHandlers[objectMatchValueTypeName] 949 if !ok { 950 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaFR, objectMatchValueTypeName) 951 } 952 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 953 if err != nil { 954 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaFR, err) 955 } 956 m.ObjectMatchValue = convertedObjectMatchValue 957 958 return nil 959 } 960 961 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaRC as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple 962 func (m *MatchCriteriaRC) UnmarshalJSON(b []byte) error { 963 // matchCriteriaRC is an alias for MatchCriteriaRC for un-marshalling purposes 964 type matchCriteriaRC MatchCriteriaRC 965 966 // populate common attributes using default json unmarshaler using aliased type 967 err := json.Unmarshal(b, (*matchCriteriaRC)(m)) 968 if err != nil { 969 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaRC, err) 970 } 971 if m.ObjectMatchValue == nil { 972 return nil 973 } 974 975 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 976 if err != nil { 977 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaRC, err) 978 } 979 980 createObjectMatchValue, ok := simpleObjectMatchValueHandlers[objectMatchValueTypeName] 981 if !ok { 982 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaRC, objectMatchValueTypeName) 983 } 984 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 985 if err != nil { 986 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaRC, err) 987 } 988 m.ObjectMatchValue = convertedObjectMatchValue 989 990 return nil 991 } 992 993 // UnmarshalJSON helps to un-marshall field ObjectMatchValue of MatchCriteriaVP as proper instance of *ObjectMatchValueObject or *ObjectMatchValueSimple 994 func (m *MatchCriteriaVP) UnmarshalJSON(b []byte) error { 995 // matchCriteriaVP is an alias for MatchCriteriaVP for un-marshalling purposes 996 type matchCriteriaVP MatchCriteriaVP 997 998 // populate common attributes using default json unmarshaler using aliased type 999 err := json.Unmarshal(b, (*matchCriteriaVP)(m)) 1000 if err != nil { 1001 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaVP, err) 1002 } 1003 if m.ObjectMatchValue == nil { 1004 return nil 1005 } 1006 1007 objectMatchValueTypeName, err := getObjectMatchValueType(m.ObjectMatchValue) 1008 if err != nil { 1009 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaVP, err) 1010 } 1011 1012 createObjectMatchValue, ok := simpleObjectMatchValueHandlers[objectMatchValueTypeName] 1013 if !ok { 1014 return fmt.Errorf("%w: objectMatchValue has unexpected type: '%s'", ErrUnmarshallMatchCriteriaVP, objectMatchValueTypeName) 1015 } 1016 convertedObjectMatchValue, err := convertObjectMatchValue(m.ObjectMatchValue, createObjectMatchValue()) 1017 if err != nil { 1018 return fmt.Errorf("%w: %s", ErrUnmarshallMatchCriteriaVP, err) 1019 } 1020 m.ObjectMatchValue = convertedObjectMatchValue 1021 1022 return nil 1023 } 1024 1025 func getObjectMatchValueType(omv interface{}) (string, error) { 1026 objectMatchValueMap, ok := omv.(map[string]interface{}) 1027 if !ok { 1028 return "", fmt.Errorf("structure of objectMatchValue should be 'map', but was '%T'", omv) 1029 } 1030 objectMatchValueType, ok := objectMatchValueMap["type"] 1031 if !ok { 1032 return "", fmt.Errorf("objectMatchValue should contain 'type' field") 1033 } 1034 objectMatchValueTypeName, ok := objectMatchValueType.(string) 1035 if !ok { 1036 return "", fmt.Errorf("'type' should be a string") 1037 } 1038 return objectMatchValueTypeName, nil 1039 } 1040 1041 func convertObjectMatchValue(in, out interface{}) (interface{}, error) { 1042 marshal, err := json.Marshal(in) 1043 if err != nil { 1044 return nil, fmt.Errorf("%s", err) 1045 } 1046 err = json.Unmarshal(marshal, out) 1047 if err != nil { 1048 return nil, fmt.Errorf("%s", err) 1049 } 1050 1051 return out, nil 1052 }