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