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  }