feat: generate fields validation and use it when sending requests to API (#7)

* feat: generate fields validation and use it when issuing requests to API with soft (default) or hard modes

* chore: apply linter fixes

* feat: enable field validation on int fields

* feat: add validation for ^[\w]+$ fields

* feat: add validation for MAC address fields

* fix: trim wrappers for all comments

* feat: add validation for IPv4, IPv6 and IP(IPv4/IPv6) fields

* feat: add validation for numeric, non-zero based fields

* fix: one of validation can contain dot (.) sign in values

* feat: add second notation of MAC address validation

* fix: one of validation can start with ^( and end with )$

* feat: add option to disable validation and use soft validation by default

* chore: fix test

* docs: add readme about client-side validation
This commit is contained in:
Mateusz Filipowicz
2025-02-09 21:08:21 +01:00
committed by GitHub
parent 9f4fe33d07
commit 53bb1a13b9
55 changed files with 1326 additions and 588 deletions

View File

@@ -116,6 +116,47 @@ c, err := unifi.NewClient(&unifi.ClientConfig{
})
```
### Client-side validation
The SDK provides basic validation for the API models. It is recommended to use it to ensure that the data you are sending
to the UniFi Controller is correct. The validation is based on the regex and validation rules provided in
the UniFi Controller API specs extracted from the JAR files.
Client supports 3 modes of validation:
- `soft`, `unifi.SoftValidation` (_default_) - will log a warning if any of the fields are invalid before sending the request, but will not stop the request
- `hard`, `unifi.HardValidation` - will return an error if any of the fields are invalid before sending the request
- `disable`, `unifi.DisableValidation` - will disable validation completely
To change the validation mode, you can use the `ValidationMode` field in the client configuration:
```go
c, err := unifi.NewClient(&unifi.ClientConfig{
...
ValidationMode: unifi.HardValidation,
})
```
If you use hard validation, you can get access to `unifi.ValidationError` struct, which contains information about the validation errors:
```go
n := &unifi.Network{
Name: "my-network",
Purpose: "invalid-purpose",
IPSubnet: "10.0.0.10/24",
}
_, err = c.CreateNetwork(ctx, "default", n)
if err != nil {
validationError := &unifi.ValidationError{}
errors.As(err, &validationError)
fmt.Printf("Error: %v\n", validationError)
fmt.Printf("Root: %v\n", validationError.Root)
}
```
`Root` error is `validator.ValidationErrors` struct from [go-playground/validator](https://pkg.go.dev/github.com/go-playground/validator/v10#ValidationErrors),
which contains detailed information about the validation errors.
### Examples
List all available networks:
@@ -141,7 +182,8 @@ user, err := c.CreateUser(ctx, "site-name", &unifi.User{
- [x] Support API Key authentication
- [ ] Generate client code for currently generated API structures, for use within or outside the Terraform provider
- [ ] Increase test coverage
- [ ] Implement validation for fields and structures
- [x] Implement validation for fields and structures
- [ ] Extend validators for more complex cases
- [ ] Add more documentation and examples
- [ ] Bugfixing...

View File

@@ -1,7 +1,7 @@
{{- $structName := .StructName }}
{{ define "field" }}
{{ .FieldName }} {{ if .IsArray }}[]{{end}}{{ .FieldType }} `json:"{{ .JSONName }}{{ if .OmitEmpty }},omitempty{{ end }}"` {{ if .FieldValidation }}// {{ .FieldValidation }}{{ end }} {{- end }}
{{ .FieldName }} {{ if .IsArray }}[]{{end}}{{ .FieldType }} `json:"{{ .JSONName }}{{ if .OmitEmpty }},omitempty{{ end }}"{{if .FieldValidation }} {{ .FieldValidation }}{{ end }}` {{ if .FieldValidationComment }}// {{ .FieldValidationComment }}{{ end }} {{- end }}
{{ define "field-customUnmarshalType" }}
{{- if eq .CustomUnmarshalType "" }}{{else}}
{{ .FieldName }} {{ if .IsArray }}[]{{end}}{{ .CustomUnmarshalType }} `json:"{{ .JSONName }}"`{{ end }} {{- end }}

View File

@@ -94,19 +94,20 @@ type Resource struct {
}
type FieldInfo struct {
FieldName string
JSONName string
FieldType string
FieldValidation string
OmitEmpty bool
IsArray bool
Fields map[string]*FieldInfo
CustomUnmarshalType string
CustomUnmarshalFunc string
FieldName string
JSONName string
FieldType string
FieldValidation string
FieldValidationComment string
OmitEmpty bool
IsArray bool
Fields map[string]*FieldInfo
CustomUnmarshalType string
CustomUnmarshalFunc string
}
func NewResource(structName string, resourcePath string) *Resource {
baseType := NewFieldInfo(structName, resourcePath, "struct", "", false, false, "")
baseType := NewFieldInfo(structName, resourcePath, "struct", "", "", false, false, "")
resource := &Resource{
StructName: structName,
ResourcePath: resourcePath,
@@ -122,14 +123,14 @@ func NewResource(structName string, resourcePath string) *Resource {
//
// This hack is here for stability of the generated code, but can be removed if desired.
baseType.Fields = map[string]*FieldInfo{
" ID": NewFieldInfo("ID", "_id", "string", "", true, false, ""),
" SiteID": NewFieldInfo("SiteID", "site_id", "string", "", true, false, ""),
" ID": NewFieldInfo("ID", "_id", "string", "", "", true, false, ""),
" SiteID": NewFieldInfo("SiteID", "site_id", "string", "", "", true, false, ""),
" _Spacer": nil,
" Hidden": NewFieldInfo("Hidden", "attr_hidden", "bool", "", true, false, ""),
" HiddenID": NewFieldInfo("HiddenID", "attr_hidden_id", "string", "", true, false, ""),
" NoDelete": NewFieldInfo("NoDelete", "attr_no_delete", "bool", "", true, false, ""),
" NoEdit": NewFieldInfo("NoEdit", "attr_no_edit", "bool", "", true, false, ""),
" Hidden": NewFieldInfo("Hidden", "attr_hidden", "bool", "", "", true, false, ""),
" HiddenID": NewFieldInfo("HiddenID", "attr_hidden_id", "string", "", "", true, false, ""),
" NoDelete": NewFieldInfo("NoDelete", "attr_no_delete", "bool", "", "", true, false, ""),
" NoEdit": NewFieldInfo("NoEdit", "attr_no_edit", "bool", "", "", true, false, ""),
" _Spacer": nil,
" _Spacer": nil,
@@ -138,38 +139,39 @@ func NewResource(structName string, resourcePath string) *Resource {
switch {
case resource.IsSetting():
resource.ResourcePath = strcase.ToSnake(strings.TrimPrefix(structName, "Setting"))
baseType.Fields[" Key"] = NewFieldInfo("Key", "key", "string", "", false, false, "")
baseType.Fields[" Key"] = NewFieldInfo("Key", "key", "string", "", "", false, false, "")
if resource.StructName == "SettingUsg" {
// Removed in v7, retaining for backwards compatibility
baseType.Fields["MdnsEnabled"] = NewFieldInfo("MdnsEnabled", "mdns_enabled", "bool", "", false, false, "")
baseType.Fields["MdnsEnabled"] = NewFieldInfo("MdnsEnabled", "mdns_enabled", "bool", "", "", false, false, "")
}
case resource.StructName == "Device":
baseType.Fields[" MAC"] = NewFieldInfo("MAC", "mac", "string", "", true, false, "")
baseType.Fields["Adopted"] = NewFieldInfo("Adopted", "adopted", "bool", "", false, false, "")
baseType.Fields["Model"] = NewFieldInfo("Model", "model", "string", "", true, false, "")
baseType.Fields["State"] = NewFieldInfo("State", "state", "DeviceState", "", false, false, "")
baseType.Fields["Type"] = NewFieldInfo("Type", "type", "string", "", true, false, "")
baseType.Fields[" MAC"] = NewFieldInfo("MAC", "mac", "string", createValidations(validation{v: mac}), "", true, false, "")
baseType.Fields["Adopted"] = NewFieldInfo("Adopted", "adopted", "bool", "", "", false, false, "")
baseType.Fields["Model"] = NewFieldInfo("Model", "model", "string", "", "", true, false, "")
baseType.Fields["State"] = NewFieldInfo("State", "state", "DeviceState", "", "", false, false, "")
baseType.Fields["Type"] = NewFieldInfo("Type", "type", "string", "", "", true, false, "")
case resource.StructName == "User":
baseType.Fields[" IP"] = NewFieldInfo("IP", "ip", "string", "non-generated field", true, false, "")
baseType.Fields[" DevIdOverride"] = NewFieldInfo("DevIdOverride", "dev_id_override", "int", "non-generated field", true, false, "")
baseType.Fields[" IP"] = NewFieldInfo("IP", "ip", "string", createValidations(validation{v: ip}), "non-generated field", true, false, "")
baseType.Fields[" DevIdOverride"] = NewFieldInfo("DevIdOverride", "dev_id_override", "int", "", "non-generated field", true, false, "")
case resource.StructName == "WLAN":
// this field removed in v6, retaining for backwards compatibility
baseType.Fields["WLANGroupID"] = NewFieldInfo("WLANGroupID", "wlangroup_id", "string", "", false, false, "")
baseType.Fields["WLANGroupID"] = NewFieldInfo("WLANGroupID", "wlangroup_id", "string", "", "", false, false, "")
}
return resource
}
func NewFieldInfo(fieldName string, jsonName string, fieldType string, fieldValidation string, omitempty bool, isArray bool, customUnmarshalType string) *FieldInfo {
func NewFieldInfo(fieldName, jsonName, fieldType, fieldValidation, fieldValidationComment string, omitempty bool, isArray bool, customUnmarshalType string) *FieldInfo {
return &FieldInfo{
FieldName: fieldName,
JSONName: jsonName,
FieldType: fieldType,
FieldValidation: fieldValidation,
OmitEmpty: omitempty,
IsArray: isArray,
CustomUnmarshalType: customUnmarshalType,
FieldName: fieldName,
JSONName: jsonName,
FieldType: fieldType,
FieldValidation: fieldValidation,
FieldValidationComment: fieldValidationComment,
OmitEmpty: omitempty,
IsArray: isArray,
CustomUnmarshalType: customUnmarshalType,
}
}
@@ -207,7 +209,7 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{})
switch validation := validation.(type) {
case []interface{}:
if len(validation) == 0 {
fieldInfo = NewFieldInfo(fieldName, name, "string", "", false, true, "")
fieldInfo = NewFieldInfo(fieldName, name, "string", "", "", false, true, "")
err := r.FieldProcessor(fieldName, fieldInfo)
return fieldInfo, err
}
@@ -229,7 +231,7 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{})
case map[string]interface{}:
typeName := r.StructName + fieldName
result := NewFieldInfo(fieldName, name, typeName, "", true, false, "")
result := NewFieldInfo(fieldName, name, typeName, "", "", true, false, "")
result.Fields = make(map[string]*FieldInfo)
for name, fv := range validation {
@@ -246,19 +248,19 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{})
return result, err
case string:
fieldValidation := validation
fieldValidationComment := validation
normalized := normalizeValidation(validation)
omitEmpty := false
switch {
case normalized == "falsetrue" || normalized == "truefalse":
fieldInfo = NewFieldInfo(fieldName, name, "bool", "", omitEmpty, false, "")
fieldInfo = NewFieldInfo(fieldName, name, "bool", "", "", omitEmpty, false, "")
return fieldInfo, r.FieldProcessor(fieldName, fieldInfo)
default:
if _, err := strconv.ParseFloat(normalized, 64); err == nil {
if normalized == "09" || normalized == "09.09" {
fieldValidation = ""
fieldValidationComment = ""
}
if strings.Contains(normalized, ".") {
@@ -267,12 +269,13 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{})
}
omitEmpty = true
fieldInfo = NewFieldInfo(fieldName, name, "float64", fieldValidation, omitEmpty, false, "")
fieldInfo = NewFieldInfo(fieldName, name, "float64", "", fieldValidationComment, omitEmpty, false, "")
return fieldInfo, r.FieldProcessor(fieldName, fieldInfo)
}
fieldValidation := defineFieldValidation(fieldValidationComment)
omitEmpty = true
fieldInfo = NewFieldInfo(fieldName, name, "int", fieldValidation, omitEmpty, false, "")
fieldInfo = NewFieldInfo(fieldName, name, "int", fieldValidation, fieldValidationComment, omitEmpty, false, "")
fieldInfo.CustomUnmarshalType = "emptyStringInt"
return fieldInfo, r.FieldProcessor(fieldName, fieldInfo)
}
@@ -281,8 +284,9 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{})
log.Tracef("normalize %q to %q", validation, normalized)
}
fieldValidation := defineFieldValidation(fieldValidationComment)
omitEmpty = omitEmpty || (!strings.Contains(validation, "^$") && !strings.HasSuffix(fieldName, "ID"))
fieldInfo = NewFieldInfo(fieldName, name, "string", fieldValidation, omitEmpty, false, "")
fieldInfo = NewFieldInfo(fieldName, name, "string", fieldValidation, fieldValidationComment, omitEmpty, false, "")
return fieldInfo, r.FieldProcessor(fieldName, fieldInfo)
}
@@ -444,14 +448,14 @@ func generateCode(fieldsDir string, outDir string) error {
return nil
}
case "SettingMgmt":
sshKeyField := NewFieldInfo(resource.StructName+"XSshKeys", "x_ssh_keys", "struct", "", false, false, "")
sshKeyField := NewFieldInfo(resource.StructName+"XSshKeys", "x_ssh_keys", "struct", "", "", false, false, "")
sshKeyField.Fields = map[string]*FieldInfo{
"name": NewFieldInfo("Name", "name", "string", "", false, false, ""),
"keyType": NewFieldInfo("KeyType", "type", "string", "", false, false, ""),
"key": NewFieldInfo("Key", "key", "string", "", false, false, ""),
"comment": NewFieldInfo("Comment", "comment", "string", "", false, false, ""),
"date": NewFieldInfo("Date", "date", "string", "", false, false, ""),
"fingerprint": NewFieldInfo("Fingerprint", "fingerprint", "string", "", false, false, ""),
"name": NewFieldInfo("Name", "name", "string", "", "", false, false, ""),
"keyType": NewFieldInfo("KeyType", "type", "string", "", "", false, false, ""),
"key": NewFieldInfo("Key", "key", "string", "", "", false, false, ""),
"comment": NewFieldInfo("Comment", "comment", "string", "", "", false, false, ""),
"date": NewFieldInfo("Date", "date", "string", "", "", false, false, ""),
"fingerprint": NewFieldInfo("Fingerprint", "fingerprint", "string", "", "", false, false, ""),
}
resource.Types[sshKeyField.FieldName] = sshKeyField

View File

@@ -50,8 +50,8 @@ func TestFieldInfoFromValidation(t *testing.T) {
if fieldInfo.FieldType != c.expectedType {
t.Fatalf("expected type %q got %q", c.expectedType, fieldInfo.FieldType)
}
if fieldInfo.FieldValidation != c.expectedComment {
t.Fatalf("expected comment %q got %q", c.expectedComment, fieldInfo.FieldValidation)
if fieldInfo.FieldValidationComment != c.expectedComment {
t.Fatalf("expected comment %q got %q", c.expectedComment, fieldInfo.FieldValidationComment)
}
if fieldInfo.OmitEmpty != c.expectedOmitEmpty {
t.Fatalf("expected omitempty %t got %t", c.expectedOmitEmpty, fieldInfo.OmitEmpty)
@@ -79,51 +79,51 @@ func TestResourceTypes(t *testing.T) {
}
`
expectedFields := map[string]*FieldInfo{
"Note": NewFieldInfo("Note", "note", "string", ".{0,1024}", true, false, ""),
"Date": NewFieldInfo("Date", "date", "string", "^$|^(20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])Z?$", false, false, ""),
"MAC": NewFieldInfo("MAC", "mac", "string", "^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$", true, false, ""),
"Number": NewFieldInfo("Number", "number", "int", "", true, false, "emptyStringInt"),
"Boolean": NewFieldInfo("Boolean", "boolean", "bool", "", false, false, ""),
"Note": NewFieldInfo("Note", "note", "string", "validate:\"omitempty,gte=0,lte=1024\"", ".{0,1024}", true, false, ""),
"Date": NewFieldInfo("Date", "date", "string", "", "^$|^(20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])Z?$", false, false, ""),
"MAC": NewFieldInfo("MAC", "mac", "string", "validate:\"omitempty,mac\"", "^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$", true, false, ""),
"Number": NewFieldInfo("Number", "number", "int", "", "", true, false, "emptyStringInt"),
"Boolean": NewFieldInfo("Boolean", "boolean", "bool", "", "", false, false, ""),
"NestedType": {
FieldName: "NestedType",
JSONName: "nested_type",
FieldType: "StructNestedType",
FieldValidation: "",
OmitEmpty: true,
IsArray: false,
FieldName: "NestedType",
JSONName: "nested_type",
FieldType: "StructNestedType",
FieldValidationComment: "",
OmitEmpty: true,
IsArray: false,
Fields: map[string]*FieldInfo{
"NestedFieldModified": NewFieldInfo("NestedFieldModified", "nested_field", "string", "^$", false, false, ""),
"NestedFieldModified": NewFieldInfo("NestedFieldModified", "nested_field", "string", "", "^$", false, false, ""),
},
},
"NestedTypeArray": {
FieldName: "NestedTypeArray",
JSONName: "nested_type_array",
FieldType: "StructNestedTypeArray",
FieldValidation: "",
OmitEmpty: true,
IsArray: true,
FieldName: "NestedTypeArray",
JSONName: "nested_type_array",
FieldType: "StructNestedTypeArray",
FieldValidationComment: "",
OmitEmpty: true,
IsArray: true,
Fields: map[string]*FieldInfo{
"NestedFieldModified": NewFieldInfo("NestedFieldModified", "nested_field", "string", "^$", false, false, ""),
"NestedFieldModified": NewFieldInfo("NestedFieldModified", "nested_field", "string", "", "^$", false, false, ""),
},
},
}
expectedStruct := map[string]*FieldInfo{
"Struct": {
FieldName: "Struct",
JSONName: "path",
FieldType: "struct",
FieldValidation: "",
OmitEmpty: false,
IsArray: false,
FieldName: "Struct",
JSONName: "path",
FieldType: "struct",
FieldValidationComment: "",
OmitEmpty: false,
IsArray: false,
Fields: map[string]*FieldInfo{
" ID": NewFieldInfo("ID", "_id", "string", "", true, false, ""),
" SiteID": NewFieldInfo("SiteID", "site_id", "string", "", true, false, ""),
" ID": NewFieldInfo("ID", "_id", "string", "", "", true, false, ""),
" SiteID": NewFieldInfo("SiteID", "site_id", "string", "", "", true, false, ""),
" _Spacer": nil,
" Hidden": NewFieldInfo("Hidden", "attr_hidden", "bool", "", true, false, ""),
" HiddenID": NewFieldInfo("HiddenID", "attr_hidden_id", "string", "", true, false, ""),
" NoDelete": NewFieldInfo("NoDelete", "attr_no_delete", "bool", "", true, false, ""),
" NoEdit": NewFieldInfo("NoEdit", "attr_no_edit", "bool", "", true, false, ""),
" Hidden": NewFieldInfo("Hidden", "attr_hidden", "bool", "", "", true, false, ""),
" HiddenID": NewFieldInfo("HiddenID", "attr_hidden_id", "string", "", "", true, false, ""),
" NoDelete": NewFieldInfo("NoDelete", "attr_no_delete", "bool", "", "", true, false, ""),
" NoEdit": NewFieldInfo("NoEdit", "attr_no_edit", "bool", "", "", true, false, ""),
" _Spacer": nil,
" _Spacer": nil,
},

182
codegen/validation.go Normal file
View File

@@ -0,0 +1,182 @@
package main
import (
"fmt"
"slices"
"strconv"
"strings"
)
type validator string
type validation struct {
v validator
params []string
}
type validationComment string
type regexSpecialChars string
const (
validateTag = "validate"
mac validator = "mac"
ip validator = "ip"
ipv4 validator = "ipv4"
ipv6 validator = "ipv6"
httpUrl validator = "http_url"
oneOf validator = "oneof"
cidr validator = "cidr"
omitempty validator = "omitempty"
length validator = "len"
gte validator = "gte"
lte validator = "lte"
w_regex validator = "w_regex"
numeric_nonzero validator = "numeric_nonzero"
regexChars regexSpecialChars = "^$*+?()[]{}\\|."
)
func createValidations(validations ...validation) string {
if len(validations) == 0 {
return ""
}
validators := make([]string, len(validations)+1)
validators[0] = createValidator(omitempty)
for i, v := range validations {
validators[i+1] = createValidator(v.v, v.params...)
}
joinedValidators := strings.Join(validators, ",")
return fmt.Sprintf("%s:\"%s\"", validateTag, joinedValidators)
}
func createValidator(v validator, params ...string) string {
var filteredParams []string
for _, p := range params {
if p != "" {
filteredParams = append(filteredParams, p)
}
}
if len(filteredParams) == 0 {
return string(v)
}
return fmt.Sprintf("%s=%s", v, strings.Join(filteredParams, " "))
}
func (r regexSpecialChars) In(s string, excludedChars string) bool {
for _, c := range r {
if strings.ContainsRune(s, c) && !strings.ContainsRune(excludedChars, c) {
return true
}
}
return false
}
func (r regexSpecialChars) NotIn(s string, excludedChars string) bool {
return !r.In(s, excludedChars)
}
func (vc validationComment) HasDefinedLength() bool {
s := string(vc)
formatOk := strings.HasPrefix(s, ".{") && strings.HasSuffix(s, "}") && regexChars.NotIn(s, ".{}")
if formatOk {
sub := s[2 : len(s)-1]
bounds := strings.Split(sub, ",")
if len(bounds) < 1 || len(bounds) > 2 {
return false
}
for _, b := range bounds {
if _, err := strconv.Atoi(b); err != nil {
return false
}
}
return true
}
return false
}
func (vc validationComment) IsOneOf() bool {
s := string(vc)
trimmed := strings.TrimPrefix(strings.TrimSuffix(s, ")$"), "^(")
return strings.Contains(trimmed, "|") && regexChars.NotIn(trimmed, "|.")
}
func (vc validationComment) IsWRegex() bool {
s := string(vc)
return slices.Contains([]string{"[\\d\\w]+", "[\\d\\w]*", "[\\w]+", "[\\w]*"}, s)
}
func (vc validationComment) IsMAC() bool {
s := string(vc)
// there are validations present in both notations, so we need to check for both
return (strings.Contains(s, "([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})") || strings.Contains(s, "([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})")) && regexChars.NotIn(s, "(){}[]^$")
}
func (vc validationComment) IsIPv4() bool {
s := string(vc)
return strings.Contains(s, ipv4Regex) && strings.Count(s, "|") == ipv4RegexGroupsCount // last is sanity check if there are no more validation groups than expected
}
func (vc validationComment) IsIPv6() bool {
s := string(vc)
return strings.Contains(s, ipv6Regex) && strings.Count(s, "|") == ipv6RegexGroupsCount // last is sanity check if there are no more validation groups than expected
}
func (vc validationComment) IsIP() bool {
s := string(vc)
return strings.Contains(s, ipv4Regex) && strings.Contains(s, ipv6Regex) && strings.Count(s, "|") == (ipv4RegexGroupsCount+ipv6RegexGroupsCount+1)
}
func (vc validationComment) IsNumericNonZeroBased() bool {
s := string(vc)
return s == numericNonZeroRegex
}
func trimWrappers(s string) string {
trimmed := strings.TrimSuffix(strings.TrimPrefix(s, "(^$|"), "|^$)") // remove wrapping parenthesis
trimmed = strings.TrimSuffix(strings.TrimPrefix(trimmed, "^$|"), "|^$") // remove ^$ which allows for empty string and is not needed
return trimmed
}
const (
ipv4Regex = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
ipv6Regex = "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
numericNonZeroRegex = "^[1-9][0-9]*$"
)
var (
ipv4RegexGroupsCount = strings.Count(ipv4Regex, "|")
ipv6RegexGroupsCount = strings.Count(ipv6Regex, "|")
)
func defineFieldValidation(rawValidation string) string {
if rawValidation == "" {
return ""
}
rawValidation = trimWrappers(rawValidation)
vc := validationComment(rawValidation)
if vc.IsOneOf() {
trimmed := strings.TrimPrefix(strings.TrimSuffix(rawValidation, ")$"), "^(")
return createValidations(validation{v: oneOf, params: strings.Split(trimmed, "|")})
} else if vc.HasDefinedLength() {
sub := rawValidation[2 : len(rawValidation)-1]
bounds := strings.Split(sub, ",")
if len(bounds) == 1 {
return createValidations(validation{v: length, params: []string{bounds[0]}})
}
return createValidations(validation{v: gte, params: []string{bounds[0]}}, validation{v: lte, params: []string{bounds[1]}})
} else if vc.IsWRegex() {
return createValidations(validation{v: w_regex})
} else if vc.IsMAC() {
return createValidations(validation{v: mac})
} else if vc.IsIPv4() {
return createValidations(validation{v: ipv4})
} else if vc.IsIPv6() {
return createValidations(validation{v: ipv6})
} else if vc.IsIP() {
return createValidations(validation{v: ip})
} else if vc.IsNumericNonZeroBased() {
return createValidations(validation{v: numeric_nonzero})
}
return ""
}

360
codegen/validation_test.go Normal file
View File

@@ -0,0 +1,360 @@
package main
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCreateValidator(t *testing.T) {
t.Parallel()
var testValidator validator = "test"
testCases := []struct {
params []string
expectedValidation string
}{
{[]string{"vpn", "802.1x", "custom"}, "test=vpn 802.1x custom"},
{[]string{"vpn"}, "test=vpn"},
{[]string{}, "test"},
{[]string{"0"}, "test=0"},
{[]string{"2-2"}, "test=2-2"},
{[]string{""}, "test"},
}
for _, tc := range testCases {
t.Run(tc.expectedValidation, func(t *testing.T) {
t.Parallel()
a := assert.New(t)
v := validation{testValidator, tc.params}
result := createValidator(v.v, v.params...)
a.Equal(tc.expectedValidation, result)
})
}
}
func TestCreateValidations(t *testing.T) {
t.Parallel()
var testValidator validator = "test"
testCases := []struct {
params [][]string
expectedValidations string
}{
{[][]string{{"1", "2", "3"}}, "test=1 2 3"},
{[][]string{{"1", "2", "3"}, {"4", "5", "6"}}, "test=1 2 3,test=4 5 6"},
{[][]string{{}}, "test"},
{[][]string{{}, {}}, "test,test"},
{[][]string{{}, {"1"}, {}}, "test,test=1,test"},
{[][]string{}, ""},
}
for _, c := range testCases {
var expectedValidationTag string
if len(c.params) == 0 {
expectedValidationTag = ""
} else {
expectedValidationTag = fmt.Sprintf("validate:\"omitempty,%s\"", c.expectedValidations)
}
t.Run(expectedValidationTag, func(t *testing.T) {
t.Parallel()
a := assert.New(t)
var validations []validation
for _, params := range c.params {
validations = append(validations, validation{testValidator, params})
}
result := createValidations(validations...)
a.Equal(expectedValidationTag, result)
})
}
}
func TestDefineValidation(t *testing.T) {
t.Parallel()
testCases := []struct {
validationComment, expected string
}{
{"a|b", "oneof=a b"},
{"1|2", "oneof=1 2"},
{".{1,2}", "gte=1,lte=2"},
{".{1}", "len=1"},
{".{1}", "len=1"},
{"[\\d\\w]+", "w_regex"},
{"[\\d\\w]*", "w_regex"},
{"[\\w]+", "w_regex"},
{"[\\w]*", "w_regex"},
{"a", ""},
{".{1}|.{5,6}", ""},
{"a|.{5,6}", ""},
}
for _, c := range testCases {
var fullExpected string
if c.expected == "" {
fullExpected = ""
} else {
fullExpected = fmt.Sprintf("validate:\"omitempty,%s\"", c.expected)
}
t.Run(c.expected, func(t *testing.T) {
t.Parallel()
a := assert.New(t)
result := defineFieldValidation(c.validationComment)
a.Equal(fullExpected, result)
})
}
}
func testValidationCommentCheck(t *testing.T, testCases []struct {
validationComment validationComment
expected bool
}, fn func(validationComment) bool,
) {
t.Helper()
for _, c := range testCases {
t.Run(fmt.Sprintf("%s-%t", c.validationComment, c.expected), func(t *testing.T) {
t.Parallel()
a := assert.New(t)
trimmed := trimWrappers(string(c.validationComment))
// trimmed := string(c.validationComment) //trimWrappers(string(c.validationComment))
result := fn(validationComment(trimmed))
a.Equal(c.expected, result)
})
}
}
func TestIsOneOfValidation(t *testing.T) {
t.Parallel()
testCases := []struct {
validationComment validationComment
expected bool
}{
{"", false},
{"a", false},
{"a|b", true},
{"^(a|b)$", true},
{"1-2|2-3", true},
{"1_2|2_3", true},
{"1|2", true},
{"%|#", true},
{".|b", true},
{".|.", true},
{"a|.", true},
{"a|.", true},
{"^a|b", false},
{"a|b$", false},
{"(a)|b", false},
{"[a]|b", false},
{"[a]|b", false},
{"a+|b", false},
{"a*|b", false},
{"[a]*|b", false},
{"a?|b", false},
{"\\w|b", false},
{"{a}|b", false},
{".{0,32}", false},
}
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsOneOf() })
}
func TestStringLengthValidation(t *testing.T) {
t.Parallel()
testCases := []struct {
validationComment validationComment
expected bool
}{
{"", false},
{".{1,2}", true},
{".{0,9999}", true},
{".{9999}", true},
{"{9999}", false},
{"{9999", false},
{"9999}", false},
{".{}", false},
{".{1,2,3}", false},
{"a", false},
{"a,b", false},
{"1,2", false},
{"1", false},
{".{1,b}", false},
{".{a,2}", false},
{".{a,b}", false},
{".{1-2}", false},
{".{1_2,2_3}", false},
{".{%,#}", false},
{".{^1,2}", false},
{".{1,2$", false},
{".{(1),2}", false},
{".{[1],2}", false},
{".{[1],2}", false},
{".{1+,2}", false},
{".{1*,2}", false},
{".{[1]*,2}", false},
{".{1?,2}", false},
{".{\\w,2}", false},
{".{{1},2}", false},
{".{.,2}", false},
}
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.HasDefinedLength() })
}
func TestIsWRegexValidation(t *testing.T) {
t.Parallel()
testCases := []struct {
validationComment validationComment
expected bool
}{
{"[\\d\\w]+", true},
{"[\\d\\w]*", true},
{"[\\w]+", true},
{"[\\w]*", true},
{"", false},
{"a", false},
{"[\\d]+", false},
{"[\\d]*", false},
{"[\\s]+", false},
{"[\\s]*", false},
}
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsWRegex() })
}
func TestIsMACValidation(t *testing.T) {
t.Parallel()
testCases := []struct {
validationComment validationComment
expected bool
}{
{"([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", true},
{"([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$", true},
{"^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$", true},
{"^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$", true},
{"^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", true},
{"^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", true},
{"^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$", true},
{"^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$", true},
{"^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", true},
{"(^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$)", true},
{"[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2}", false},
{"[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", false},
{"([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2}", false},
{"^[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2}$", false},
{"^$|[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", false},
{"^$|[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$", false},
{"(^$|[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$)", false},
{"^$|[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$)", false},
{"(^$|[0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|^$", false},
{"", false},
{"a", false},
{"([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})|(0-9)", false},
{"[0-9]|([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})", false},
{"[0-9]|([0-9A-Fa-f]{2}:){5}", false},
}
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsMAC() })
}
func (vc validationComment) mutate(prefix, suffix string) validationComment {
return validationComment(fmt.Sprintf("%s%s%s", prefix, string(vc), suffix))
}
func generateTestCasesForFixedRegex(regex string) []struct {
validationComment validationComment
expected bool
} {
base := validationComment(regex)
return []struct {
validationComment validationComment
expected bool
}{
{base, true},
{base.mutate("^", "$"), true},
{base.mutate("^", ""), true},
{base.mutate("", "$"), true},
{base.mutate("(^", "$)"), true},
{base.mutate("^", "$)"), true},
{base.mutate("^(", "$"), true},
{base.mutate("^$|", "|^$"), true},
{base.mutate("^$|", ""), true},
{base.mutate("", "|^$"), true},
{base.mutate("(^$|", "|^$)"), true},
{base.mutate("(^$|", ""), true},
{base.mutate("", "|^$)"), true},
// FIXME how to handle these cases? current implementation is dumb and quick, and might fail..
//{base.mutate("^test", ""), false},
//{base.mutate("^test", "test$"), false},
//{base.mutate("", "test$"), false},
//{base.mutate("test", "test"), false},
//{base.mutate("", "test"), false},
//{base.mutate("test", ""), false},
{base.mutate("^test$|", "|^test$"), false},
{base.mutate("^test|", "|^test$"), false},
{base.mutate("test$|", "|^test$"), false},
{base.mutate("test$|", "|^test$"), false},
{base.mutate("^test$|", "|test$"), false},
{base.mutate("^test|", "|^test"), false},
{base.mutate("test|", "|test"), false},
{base.mutate("(test|", "|test)"), false},
{"test", false},
{"", false},
}
}
func TestIsIPv4Validation(t *testing.T) {
t.Parallel()
testCases := generateTestCasesForFixedRegex(ipv4Regex)
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsIPv4() })
}
func TestIsIPv6Validation(t *testing.T) {
t.Parallel()
testCases := generateTestCasesForFixedRegex(ipv6Regex)
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsIPv6() })
}
func TestIsIPValidation(t *testing.T) {
t.Parallel()
testCases := generateTestCasesForFixedRegex(ipv4Regex + "|" + ipv6Regex)
testCases = append(testCases, generateTestCasesForFixedRegex(ipv6Regex+"|"+ipv4Regex)...)
testCases = append(testCases, generateTestCasesForFixedRegex("("+ipv6Regex+")|("+ipv4Regex+")")...)
testCases = append(testCases, generateTestCasesForFixedRegex("("+ipv4Regex+")|("+ipv6Regex+")")...)
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsIP() })
}
func TestIsNumericNonZeroValidation(t *testing.T) {
t.Parallel()
base := validationComment(numericNonZeroRegex)
testCases := []struct {
validationComment validationComment
expected bool
}{
{base, true},
{base.mutate("^$|", "|^$"), true},
{base.mutate("^$|", ""), true},
{base.mutate("", "|^$"), true},
{base.mutate("(^$|", "|^$)"), true},
{base.mutate("(^$|", ""), true},
{base.mutate("", "|^$)"), true},
{base.mutate("(^", "$)"), false},
{base.mutate("^", "$)"), false},
{base.mutate("^(", "$"), false},
{base.mutate("^test", ""), false},
{base.mutate("^test", "test$"), false},
{base.mutate("", "test$"), false},
{base.mutate("test", "test"), false},
{base.mutate("", "test"), false},
{base.mutate("test", ""), false},
{base.mutate("^test$|", "|^test$"), false},
{base.mutate("^test|", "|^test$"), false},
{base.mutate("test$|", "|^test$"), false},
{base.mutate("test$|", "|^test$"), false},
{base.mutate("^test$|", "|test$"), false},
{base.mutate("^test|", "|^test"), false},
{base.mutate("test|", "|test"), false},
{base.mutate("(test|", "|test)"), false},
{"test", false},
{"", false},
}
testValidationCommentCheck(t, testCases, func(v validationComment) bool { return v.IsNumericNonZeroBased() })
}

View File

@@ -26,12 +26,12 @@ type Account struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
FilterIDs []string `json:"filter_ids,omitempty"`
IP string `json:"ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
Name string `json:"name,omitempty"` // ^[^"' ]+$
IP string `json:"ip,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
Name string `json:"name,omitempty"` // ^[^"' ]+$
NetworkID string `json:"networkconf_id,omitempty"`
TunnelConfigType string `json:"tunnel_config_type,omitempty"` // vpn|802.1x|custom
TunnelMediumType int `json:"tunnel_medium_type,omitempty"` // [1-9]|1[0-5]|^$
TunnelType int `json:"tunnel_type,omitempty"` // [1-9]|1[0-3]|^$
TunnelConfigType string `json:"tunnel_config_type,omitempty" validate:"omitempty,oneof=vpn 802.1x custom"` // vpn|802.1x|custom
TunnelMediumType int `json:"tunnel_medium_type,omitempty"` // [1-9]|1[0-5]|^$
TunnelType int `json:"tunnel_type,omitempty"` // [1-9]|1[0-3]|^$
UlpUserID string `json:"ulp_user_id"`
VLAN int `json:"vlan,omitempty"` // [2-9]|[1-9][0-9]{1,2}|[1-3][0-9]{3}|400[0-9]|^$
XPassword string `json:"x_password,omitempty"`

View File

@@ -26,12 +26,12 @@ type ChannelPlan struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
ApBlacklistedChannels []ChannelPlanApBlacklistedChannels `json:"ap_blacklisted_channels,omitempty"`
ConfSource string `json:"conf_source,omitempty"` // manual|radio-ai
ConfSource string `json:"conf_source,omitempty" validate:"omitempty,oneof=manual radio-ai"` // manual|radio-ai
Coupling []ChannelPlanCoupling `json:"coupling,omitempty"`
Date string `json:"date"` // ^$|^(20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])Z?$
Fitness float64 `json:"fitness,omitempty"`
Note string `json:"note,omitempty"` // .{0,1024}
Radio string `json:"radio,omitempty"` // na|ng|ng\+na
Note string `json:"note,omitempty" validate:"omitempty,gte=0,lte=1024"` // .{0,1024}
Radio string `json:"radio,omitempty"` // na|ng|ng\+na
RadioTable []ChannelPlanRadioTable `json:"radio_table,omitempty"`
Satisfaction float64 `json:"satisfaction,omitempty"`
SatisfactionTable []ChannelPlanSatisfactionTable `json:"satisfaction_table,omitempty"`
@@ -55,9 +55,9 @@ func (dst *ChannelPlan) UnmarshalJSON(b []byte) error {
}
type ChannelPlanApBlacklistedChannels struct {
Channel int `json:"channel,omitempty"` // 36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196
MAC string `json:"mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Timestamp int `json:"timestamp,omitempty"` // [1-9][0-9]{12}
Channel int `json:"channel,omitempty" validate:"omitempty,oneof=36 38 40 42 44 46 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 144 149 153 157 161 165 183 184 185 187 188 189 192 196"` // 36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196
MAC string `json:"mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Timestamp int `json:"timestamp,omitempty"` // [1-9][0-9]{12}
}
func (dst *ChannelPlanApBlacklistedChannels) UnmarshalJSON(b []byte) error {
@@ -107,13 +107,13 @@ func (dst *ChannelPlanCoupling) UnmarshalJSON(b []byte) error {
}
type ChannelPlanRadioTable struct {
BackupChannel string `json:"backup_channel,omitempty"` // [0-9]|[1][0-4]|16|34|36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196|auto
Channel string `json:"channel,omitempty"` // [0-9]|[1][0-4]|16|34|36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196|auto
DeviceMAC string `json:"device_mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Name string `json:"name,omitempty"` // [a-z]*[0-9]*
TxPower string `json:"tx_power,omitempty"` // [\d]+|auto
TxPowerMode string `json:"tx_power_mode,omitempty"` // auto|medium|high|low|custom
Width int `json:"width,omitempty"` // 20|40|80|160
BackupChannel string `json:"backup_channel,omitempty"` // [0-9]|[1][0-4]|16|34|36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196|auto
Channel string `json:"channel,omitempty"` // [0-9]|[1][0-4]|16|34|36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196|auto
DeviceMAC string `json:"device_mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Name string `json:"name,omitempty"` // [a-z]*[0-9]*
TxPower string `json:"tx_power,omitempty"` // [\d]+|auto
TxPowerMode string `json:"tx_power_mode,omitempty" validate:"omitempty,oneof=auto medium high low custom"` // auto|medium|high|low|custom
Width int `json:"width,omitempty" validate:"omitempty,oneof=20 40 80 160"` // 20|40|80|160
}
func (dst *ChannelPlanRadioTable) UnmarshalJSON(b []byte) error {
@@ -142,7 +142,7 @@ func (dst *ChannelPlanRadioTable) UnmarshalJSON(b []byte) error {
}
type ChannelPlanSatisfactionTable struct {
DeviceMAC string `json:"device_mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
DeviceMAC string `json:"device_mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Satisfaction float64 `json:"satisfaction,omitempty"`
}
@@ -163,8 +163,8 @@ func (dst *ChannelPlanSatisfactionTable) UnmarshalJSON(b []byte) error {
}
type ChannelPlanSiteBlacklistedChannels struct {
Channel int `json:"channel,omitempty"` // 36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196
Timestamp int `json:"timestamp,omitempty"` // [1-9][0-9]{12}
Channel int `json:"channel,omitempty" validate:"omitempty,oneof=36 38 40 42 44 46 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 144 149 153 157 161 165 183 184 185 187 188 189 192 196"` // 36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|183|184|185|187|188|189|192|196
Timestamp int `json:"timestamp,omitempty"` // [1-9][0-9]{12}
}
func (dst *ChannelPlanSiteBlacklistedChannels) UnmarshalJSON(b []byte) error {

View File

@@ -25,13 +25,13 @@ type Device struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
MAC string `json:"mac,omitempty"`
MAC string `json:"mac,omitempty" validate:"omitempty,mac"`
Adopted bool `json:"adopted"`
AfcEnabled bool `json:"afc_enabled,omitempty"`
AtfEnabled bool `json:"atf_enabled,omitempty"`
BandsteeringMode string `json:"bandsteering_mode,omitempty"` // off|equal|prefer_5g
BaresipAuthUser string `json:"baresip_auth_user,omitempty"` // ^\+?[a-zA-Z0-9_.\-!~*'()]*
BandsteeringMode string `json:"bandsteering_mode,omitempty" validate:"omitempty,oneof=off equal prefer_5g"` // off|equal|prefer_5g
BaresipAuthUser string `json:"baresip_auth_user,omitempty"` // ^\+?[a-zA-Z0-9_.\-!~*'()]*
BaresipEnabled bool `json:"baresip_enabled,omitempty"`
BaresipExtension string `json:"baresip_extension,omitempty"` // ^\+?[a-zA-Z0-9_.\-!~*'()]*
ConfigNetwork DeviceConfigNetwork `json:"config_network,omitempty"`
@@ -42,29 +42,29 @@ type Device struct {
EtherLighting DeviceEtherLighting `json:"ether_lighting,omitempty"`
EthernetOverrides []DeviceEthernetOverrides `json:"ethernet_overrides,omitempty"`
FlowctrlEnabled bool `json:"flowctrl_enabled,omitempty"`
GatewayVrrpMode string `json:"gateway_vrrp_mode,omitempty"` // primary|secondary
GatewayVrrpPriority int `json:"gateway_vrrp_priority,omitempty"` // [1-9][0-9]|[1-9][0-9][0-9]
GatewayVrrpMode string `json:"gateway_vrrp_mode,omitempty" validate:"omitempty,oneof=primary secondary"` // primary|secondary
GatewayVrrpPriority int `json:"gateway_vrrp_priority,omitempty"` // [1-9][0-9]|[1-9][0-9][0-9]
GreenApEnabled bool `json:"green_ap_enabled,omitempty"`
HeightInMeters float64 `json:"heightInMeters,omitempty"`
Hostname string `json:"hostname,omitempty"` // .{1,128}
Hostname string `json:"hostname,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
JumboframeEnabled bool `json:"jumboframe_enabled,omitempty"`
LcmBrightness int `json:"lcm_brightness,omitempty"` // [1-9]|[1-9][0-9]|100
LcmBrightnessOverride bool `json:"lcm_brightness_override,omitempty"`
LcmIDleTimeout int `json:"lcm_idle_timeout,omitempty"` // [1-9][0-9]|[1-9][0-9][0-9]|[1-2][0-9][0-9][0-9]|3[0-5][0-9][0-9]|3600
LcmIDleTimeoutOverride bool `json:"lcm_idle_timeout_override,omitempty"`
LcmNightModeBegins string `json:"lcm_night_mode_begins,omitempty"` // (^$)|(^(0[1-9])|(1[0-9])|(2[0-3])):([0-5][0-9]$)
LcmNightModeEnds string `json:"lcm_night_mode_ends,omitempty"` // (^$)|(^(0[1-9])|(1[0-9])|(2[0-3])):([0-5][0-9]$)
LcmOrientationOverride int `json:"lcm_orientation_override,omitempty"` // 0|90|180|270
LcmNightModeBegins string `json:"lcm_night_mode_begins,omitempty"` // (^$)|(^(0[1-9])|(1[0-9])|(2[0-3])):([0-5][0-9]$)
LcmNightModeEnds string `json:"lcm_night_mode_ends,omitempty"` // (^$)|(^(0[1-9])|(1[0-9])|(2[0-3])):([0-5][0-9]$)
LcmOrientationOverride int `json:"lcm_orientation_override,omitempty" validate:"omitempty,oneof=0 90 180 270"` // 0|90|180|270
LcmSettingsRestrictedAccess bool `json:"lcm_settings_restricted_access,omitempty"`
LcmTrackerEnabled bool `json:"lcm_tracker_enabled,omitempty"`
LcmTrackerSeed string `json:"lcm_tracker_seed,omitempty"` // .{0,50}
LedOverride string `json:"led_override,omitempty"` // default|on|off
LedOverrideColor string `json:"led_override_color,omitempty"` // ^#(?:[0-9a-fA-F]{3}){1,2}$
LedOverrideColorBrightness int `json:"led_override_color_brightness,omitempty"` // ^[0-9][0-9]?$|^100$
LcmTrackerSeed string `json:"lcm_tracker_seed,omitempty" validate:"omitempty,gte=0,lte=50"` // .{0,50}
LedOverride string `json:"led_override,omitempty" validate:"omitempty,oneof=default on off"` // default|on|off
LedOverrideColor string `json:"led_override_color,omitempty"` // ^#(?:[0-9a-fA-F]{3}){1,2}$
LedOverrideColorBrightness int `json:"led_override_color_brightness,omitempty"` // ^[0-9][0-9]?$|^100$
Locked bool `json:"locked,omitempty"`
LowpfmodeOverride bool `json:"lowpfmode_override,omitempty"`
LteApn string `json:"lte_apn,omitempty"` // .{1,128}
LteAuthType string `json:"lte_auth_type,omitempty"` // PAP|CHAP|PAP-CHAP|NONE
LteApn string `json:"lte_apn,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
LteAuthType string `json:"lte_auth_type,omitempty" validate:"omitempty,oneof=PAP CHAP PAP-CHAP NONE"` // PAP|CHAP|PAP-CHAP|NONE
LteDataLimitEnabled bool `json:"lte_data_limit_enabled,omitempty"`
LteDataWarningEnabled bool `json:"lte_data_warning_enabled,omitempty"`
LteExtAnt bool `json:"lte_ext_ant,omitempty"`
@@ -77,35 +77,35 @@ type Device struct {
LteUsername string `json:"lte_username,omitempty"`
MapID string `json:"map_id,omitempty"`
MeshStaVapEnabled bool `json:"mesh_sta_vap_enabled,omitempty"`
MgmtNetworkID string `json:"mgmt_network_id,omitempty"` // [\d\w]+
MgmtNetworkID string `json:"mgmt_network_id,omitempty" validate:"omitempty,w_regex"` // [\d\w]+
Model string `json:"model,omitempty"`
Name string `json:"name,omitempty"` // .{0,128}
OutdoorModeOverride string `json:"outdoor_mode_override,omitempty"` // default|on|off
Name string `json:"name,omitempty" validate:"omitempty,gte=0,lte=128"` // .{0,128}
OutdoorModeOverride string `json:"outdoor_mode_override,omitempty" validate:"omitempty,oneof=default on off"` // default|on|off
OutletEnabled bool `json:"outlet_enabled,omitempty"`
OutletOverrides []DeviceOutletOverrides `json:"outlet_overrides,omitempty"`
OutletPowerCycleEnabled bool `json:"outlet_power_cycle_enabled,omitempty"`
PeerToPeerMode string `json:"peer_to_peer_mode,omitempty"` // ap|sta
PoeMode string `json:"poe_mode,omitempty"` // auto|pasv24|passthrough|off
PeerToPeerMode string `json:"peer_to_peer_mode,omitempty" validate:"omitempty,oneof=ap sta"` // ap|sta
PoeMode string `json:"poe_mode,omitempty" validate:"omitempty,oneof=auto pasv24 passthrough off"` // auto|pasv24|passthrough|off
PortOverrides []DevicePortOverrides `json:"port_overrides"`
PowerSourceCtrl string `json:"power_source_ctrl,omitempty"` // auto|8023af|8023at|8023bt-type3|8023bt-type4|pasv24|poe-injector|ac|adapter|dc|rps
PowerSourceCtrlBudget int `json:"power_source_ctrl_budget,omitempty"` // [0-9]|[1-9][0-9]|[1-9][0-9][0-9]
PowerSourceCtrl string `json:"power_source_ctrl,omitempty" validate:"omitempty,oneof=auto 8023af 8023at 8023bt-type3 8023bt-type4 pasv24 poe-injector ac adapter dc rps"` // auto|8023af|8023at|8023bt-type3|8023bt-type4|pasv24|poe-injector|ac|adapter|dc|rps
PowerSourceCtrlBudget int `json:"power_source_ctrl_budget,omitempty"` // [0-9]|[1-9][0-9]|[1-9][0-9][0-9]
PowerSourceCtrlEnabled bool `json:"power_source_ctrl_enabled,omitempty"`
PtmpApMAC string `json:"ptmp_ap_mac,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PtpApMAC string `json:"ptp_ap_mac,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PtmpApMAC string `json:"ptmp_ap_mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PtpApMAC string `json:"ptp_ap_mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
RADIUSProfileID string `json:"radiusprofile_id,omitempty"`
RadioTable []DeviceRadioTable `json:"radio_table,omitempty"`
ResetbtnEnabled string `json:"resetbtn_enabled,omitempty"` // on|off
ResetbtnEnabled string `json:"resetbtn_enabled,omitempty" validate:"omitempty,oneof=on off"` // on|off
RpsOverride DeviceRpsOverride `json:"rps_override,omitempty"`
SnmpContact string `json:"snmp_contact,omitempty"` // .{0,255}
SnmpLocation string `json:"snmp_location,omitempty"` // .{0,255}
SnmpContact string `json:"snmp_contact,omitempty" validate:"omitempty,gte=0,lte=255"` // .{0,255}
SnmpLocation string `json:"snmp_location,omitempty" validate:"omitempty,gte=0,lte=255"` // .{0,255}
State DeviceState `json:"state"`
StationMode string `json:"station_mode,omitempty"` // ptp|ptmp|wifi
StpPriority string `json:"stp_priority,omitempty"` // 0|4096|8192|12288|16384|20480|24576|28672|32768|36864|40960|45056|49152|53248|57344|61440
StpVersion string `json:"stp_version,omitempty"` // stp|rstp|disabled
StationMode string `json:"station_mode,omitempty" validate:"omitempty,oneof=ptp ptmp wifi"` // ptp|ptmp|wifi
StpPriority string `json:"stp_priority,omitempty" validate:"omitempty,oneof=0 4096 8192 12288 16384 20480 24576 28672 32768 36864 40960 45056 49152 53248 57344 61440"` // 0|4096|8192|12288|16384|20480|24576|28672|32768|36864|40960|45056|49152|53248|57344|61440
StpVersion string `json:"stp_version,omitempty" validate:"omitempty,oneof=stp rstp disabled"` // stp|rstp|disabled
SwitchVLANEnabled bool `json:"switch_vlan_enabled,omitempty"`
Type string `json:"type,omitempty"`
UbbPairName string `json:"ubb_pair_name,omitempty"` // .{1,128}
Volume int `json:"volume,omitempty"` // [0-9]|[1-9][0-9]|100
UbbPairName string `json:"ubb_pair_name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
Volume int `json:"volume,omitempty"` // [0-9]|[1-9][0-9]|100
X float64 `json:"x,omitempty"`
XBaresipPassword string `json:"x_baresip_password,omitempty"` // ^[a-zA-Z0-9_.\-!~*'()]*
Y float64 `json:"y,omitempty"`
@@ -156,13 +156,13 @@ func (dst *Device) UnmarshalJSON(b []byte) error {
type DeviceConfigNetwork struct {
BondingEnabled bool `json:"bonding_enabled,omitempty"`
DNS1 string `json:"dns1,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
DNS2 string `json:"dns2,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
DNS1 string `json:"dns1,omitempty" validate:"omitempty,ip"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
DNS2 string `json:"dns2,omitempty" validate:"omitempty,ip"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
DNSsuffix string `json:"dnssuffix,omitempty"`
Gateway string `json:"gateway,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
IP string `json:"ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Netmask string `json:"netmask,omitempty"` // ^((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))$
Type string `json:"type,omitempty"` // dhcp|static
Gateway string `json:"gateway,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
IP string `json:"ip,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Netmask string `json:"netmask,omitempty"` // ^((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))$
Type string `json:"type,omitempty" validate:"omitempty,oneof=dhcp static"` // dhcp|static
}
func (dst *DeviceConfigNetwork) UnmarshalJSON(b []byte) error {
@@ -182,10 +182,10 @@ func (dst *DeviceConfigNetwork) UnmarshalJSON(b []byte) error {
}
type DeviceEtherLighting struct {
Behavior string `json:"behavior,omitempty"` // breath|steady
Brightness int `json:"brightness,omitempty"` // [1-9]|[1-9][0-9]|100
LedMode string `json:"led_mode,omitempty"` // standard|etherlighting
Mode string `json:"mode,omitempty"` // speed|network
Behavior string `json:"behavior,omitempty" validate:"omitempty,oneof=breath steady"` // breath|steady
Brightness int `json:"brightness,omitempty"` // [1-9]|[1-9][0-9]|100
LedMode string `json:"led_mode,omitempty" validate:"omitempty,oneof=standard etherlighting"` // standard|etherlighting
Mode string `json:"mode,omitempty" validate:"omitempty,oneof=speed network"` // speed|network
}
func (dst *DeviceEtherLighting) UnmarshalJSON(b []byte) error {
@@ -231,7 +231,7 @@ func (dst *DeviceEthernetOverrides) UnmarshalJSON(b []byte) error {
type DeviceOutletOverrides struct {
CycleEnabled bool `json:"cycle_enabled,omitempty"`
Index int `json:"index,omitempty"`
Name string `json:"name,omitempty"` // .{0,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=0,lte=128"` // .{0,128}
RelayState bool `json:"relay_state,omitempty"`
}
@@ -257,13 +257,13 @@ func (dst *DeviceOutletOverrides) UnmarshalJSON(b []byte) error {
type DevicePortOverrides struct {
AggregateNumPorts int `json:"aggregate_num_ports,omitempty"` // [1-8]
Autoneg bool `json:"autoneg,omitempty"`
Dot1XCtrl string `json:"dot1x_ctrl,omitempty"` // auto|force_authorized|force_unauthorized|mac_based|multi_host
Dot1XIDleTimeout int `json:"dot1x_idle_timeout,omitempty"` // [0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]
EgressRateLimitKbps int `json:"egress_rate_limit_kbps,omitempty"` // 6[4-9]|[7-9][0-9]|[1-9][0-9]{2,6}
Dot1XCtrl string `json:"dot1x_ctrl,omitempty" validate:"omitempty,oneof=auto force_authorized force_unauthorized mac_based multi_host"` // auto|force_authorized|force_unauthorized|mac_based|multi_host
Dot1XIDleTimeout int `json:"dot1x_idle_timeout,omitempty"` // [0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]
EgressRateLimitKbps int `json:"egress_rate_limit_kbps,omitempty"` // 6[4-9]|[7-9][0-9]|[1-9][0-9]{2,6}
EgressRateLimitKbpsEnabled bool `json:"egress_rate_limit_kbps_enabled,omitempty"`
ExcludedNetworkIDs []string `json:"excluded_networkconf_ids,omitempty"`
FecMode string `json:"fec_mode,omitempty"` // rs-fec|fc-fec|default|disabled
Forward string `json:"forward,omitempty"` // all|native|customize|disabled
FecMode string `json:"fec_mode,omitempty" validate:"omitempty,oneof=rs-fec fc-fec default disabled"` // rs-fec|fc-fec|default|disabled
Forward string `json:"forward,omitempty" validate:"omitempty,oneof=all native customize disabled"` // all|native|customize|disabled
FullDuplex bool `json:"full_duplex,omitempty"`
Isolation bool `json:"isolation,omitempty"`
LldpmedEnabled bool `json:"lldpmed_enabled,omitempty"`
@@ -271,33 +271,33 @@ type DevicePortOverrides struct {
MirrorPortIDX int `json:"mirror_port_idx,omitempty"` // [1-9]|[1-4][0-9]|5[0-6]
MulticastRouterNetworkIDs []string `json:"multicast_router_networkconf_ids,omitempty"`
NATiveNetworkID string `json:"native_networkconf_id,omitempty"`
Name string `json:"name,omitempty"` // .{0,128}
OpMode string `json:"op_mode,omitempty"` // switch|mirror|aggregate
PoeMode string `json:"poe_mode,omitempty"` // auto|pasv24|passthrough|off
PortIDX int `json:"port_idx,omitempty"` // [1-9]|[1-4][0-9]|5[0-6]
Name string `json:"name,omitempty" validate:"omitempty,gte=0,lte=128"` // .{0,128}
OpMode string `json:"op_mode,omitempty" validate:"omitempty,oneof=switch mirror aggregate"` // switch|mirror|aggregate
PoeMode string `json:"poe_mode,omitempty" validate:"omitempty,oneof=auto pasv24 passthrough off"` // auto|pasv24|passthrough|off
PortIDX int `json:"port_idx,omitempty"` // [1-9]|[1-4][0-9]|5[0-6]
PortKeepaliveEnabled bool `json:"port_keepalive_enabled,omitempty"`
PortProfileID string `json:"portconf_id,omitempty"` // [\d\w]+
PortProfileID string `json:"portconf_id,omitempty" validate:"omitempty,w_regex"` // [\d\w]+
PortSecurityEnabled bool `json:"port_security_enabled,omitempty"`
PortSecurityMACAddress []string `json:"port_security_mac_address,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PriorityQueue1Level int `json:"priority_queue1_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue2Level int `json:"priority_queue2_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue3Level int `json:"priority_queue3_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue4Level int `json:"priority_queue4_level,omitempty"` // [0-9]|[1-9][0-9]|100
PortSecurityMACAddress []string `json:"port_security_mac_address,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PriorityQueue1Level int `json:"priority_queue1_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue2Level int `json:"priority_queue2_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue3Level int `json:"priority_queue3_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue4Level int `json:"priority_queue4_level,omitempty"` // [0-9]|[1-9][0-9]|100
QOSProfile DeviceQOSProfile `json:"qos_profile,omitempty"`
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
Speed int `json:"speed,omitempty"` // 10|100|1000|2500|5000|10000|20000|25000|40000|50000|100000
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
Speed int `json:"speed,omitempty" validate:"omitempty,oneof=10 100 1000 2500 5000 10000 20000 25000 40000 50000 100000"` // 10|100|1000|2500|5000|10000|20000|25000|40000|50000|100000
StormctrlBroadcastastEnabled bool `json:"stormctrl_bcast_enabled,omitempty"`
StormctrlBroadcastastLevel int `json:"stormctrl_bcast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlBroadcastastRate int `json:"stormctrl_bcast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StormctrlMcastEnabled bool `json:"stormctrl_mcast_enabled,omitempty"`
StormctrlMcastLevel int `json:"stormctrl_mcast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlMcastRate int `json:"stormctrl_mcast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StormctrlType string `json:"stormctrl_type,omitempty"` // level|rate
StormctrlMcastLevel int `json:"stormctrl_mcast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlMcastRate int `json:"stormctrl_mcast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StormctrlType string `json:"stormctrl_type,omitempty" validate:"omitempty,oneof=level rate"` // level|rate
StormctrlUcastEnabled bool `json:"stormctrl_ucast_enabled,omitempty"`
StormctrlUcastLevel int `json:"stormctrl_ucast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlUcastRate int `json:"stormctrl_ucast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StpPortMode bool `json:"stp_port_mode,omitempty"`
TaggedVLANMgmt string `json:"tagged_vlan_mgmt,omitempty"` // auto|block_all|custom
TaggedVLANMgmt string `json:"tagged_vlan_mgmt,omitempty" validate:"omitempty,oneof=auto block_all custom"` // auto|block_all|custom
VoiceNetworkID string `json:"voice_networkconf_id,omitempty"`
}
@@ -351,10 +351,10 @@ func (dst *DevicePortOverrides) UnmarshalJSON(b []byte) error {
}
type DeviceQOSMarking struct {
CosCode int `json:"cos_code,omitempty"` // [0-7]
DscpCode int `json:"dscp_code,omitempty"` // 0|8|16|24|32|40|48|56|10|12|14|18|20|22|26|28|30|34|36|38|44|46
IPPrecedenceCode int `json:"ip_precedence_code,omitempty"` // [0-7]
Queue int `json:"queue,omitempty"` // [0-7]
CosCode int `json:"cos_code,omitempty"` // [0-7]
DscpCode int `json:"dscp_code,omitempty" validate:"omitempty,oneof=0 8 16 24 32 40 48 56 10 12 14 18 20 22 26 28 30 34 36 38 44 46"` // 0|8|16|24|32|40|48|56|10|12|14|18|20|22|26|28|30|34|36|38|44|46
IPPrecedenceCode int `json:"ip_precedence_code,omitempty"` // [0-7]
Queue int `json:"queue,omitempty"` // [0-7]
}
func (dst *DeviceQOSMarking) UnmarshalJSON(b []byte) error {
@@ -441,7 +441,7 @@ func (dst *DeviceQOSPolicies) UnmarshalJSON(b []byte) error {
type DeviceQOSProfile struct {
QOSPolicies []DeviceQOSPolicies `json:"qos_policies,omitempty"`
QOSProfileMode string `json:"qos_profile_mode,omitempty"` // custom|unifi_play|aes67_audio|crestron_audio_video|dante_audio|ndi_aes67_audio|ndi_dante_audio|qsys_audio_video|qsys_video_dante_audio|sdvoe_aes67_audio|sdvoe_dante_audio|shure_audio
QOSProfileMode string `json:"qos_profile_mode,omitempty" validate:"omitempty,oneof=custom unifi_play aes67_audio crestron_audio_video dante_audio ndi_aes67_audio ndi_dante_audio qsys_audio_video qsys_video_dante_audio sdvoe_aes67_audio sdvoe_dante_audio shure_audio"` // custom|unifi_play|aes67_audio|crestron_audio_video|dante_audio|ndi_aes67_audio|ndi_dante_audio|qsys_audio_video|qsys_video_dante_audio|sdvoe_aes67_audio|sdvoe_dante_audio|shure_audio
}
func (dst *DeviceQOSProfile) UnmarshalJSON(b []byte) error {
@@ -488,18 +488,18 @@ type DeviceRadioTable struct {
Channel string `json:"channel,omitempty"` // [0-9]|[1][0-4]|4.5|5|16|17|21|25|29|33|34|36|37|38|40|41|42|44|45|46|48|49|52|53|56|57|60|61|64|65|69|73|77|81|85|89|93|97|100|101|104|105|108|109|112|113|117|116|120|121|124|125|128|129|132|133|136|137|140|141|144|145|149|153|157|161|165|169|173|177|181|183|184|185|187|188|189|192|193|196|197|201|205|209|213|217|221|225|229|233|auto
ChannelOptimizationEnabled bool `json:"channel_optimization_enabled,omitempty"`
HardNoiseFloorEnabled bool `json:"hard_noise_floor_enabled,omitempty"`
Ht int `json:"ht,omitempty"` // 20|40|80|160|240|320|1080|2160|4320
Ht int `json:"ht,omitempty" validate:"omitempty,oneof=20 40 80 160 240 320 1080 2160 4320"` // 20|40|80|160|240|320|1080|2160|4320
LoadbalanceEnabled bool `json:"loadbalance_enabled,omitempty"`
Maxsta int `json:"maxsta,omitempty"` // [1-9]|[1-9][0-9]|1[0-9]{2}|200|^$
MinRssi int `json:"min_rssi,omitempty"` // ^-(6[7-9]|[7-8][0-9]|90)$
MinRssiEnabled bool `json:"min_rssi_enabled,omitempty"`
Name string `json:"name,omitempty"`
Radio string `json:"radio,omitempty"` // ng|na|ad|6e
Radio string `json:"radio,omitempty" validate:"omitempty,oneof=ng na ad 6e"` // ng|na|ad|6e
RadioIDentifiers []DeviceRadioIDentifiers `json:"radio_identifiers,omitempty"`
SensLevel int `json:"sens_level,omitempty"` // ^-([5-8][0-9]|90)$
SensLevelEnabled bool `json:"sens_level_enabled,omitempty"`
TxPower string `json:"tx_power,omitempty"` // [\d]+|auto
TxPowerMode string `json:"tx_power_mode,omitempty"` // auto|medium|high|low|custom
TxPower string `json:"tx_power,omitempty"` // [\d]+|auto
TxPowerMode string `json:"tx_power_mode,omitempty" validate:"omitempty,oneof=auto medium high low custom"` // auto|medium|high|low|custom
VwireEnabled bool `json:"vwire_enabled,omitempty"`
}
@@ -539,7 +539,7 @@ func (dst *DeviceRadioTable) UnmarshalJSON(b []byte) error {
}
type DeviceRpsOverride struct {
PowerManagementMode string `json:"power_management_mode,omitempty"` // dynamic|static
PowerManagementMode string `json:"power_management_mode,omitempty" validate:"omitempty,oneof=dynamic static"` // dynamic|static
RpsPortTable []DeviceRpsPortTable `json:"rps_port_table,omitempty"`
}
@@ -560,9 +560,9 @@ func (dst *DeviceRpsOverride) UnmarshalJSON(b []byte) error {
}
type DeviceRpsPortTable struct {
Name string `json:"name,omitempty"` // .{0,32}
PortIDX int `json:"port_idx,omitempty"` // [1-8]
PortMode string `json:"port_mode,omitempty"` // auto|force_active|manual|disabled
Name string `json:"name,omitempty" validate:"omitempty,gte=0,lte=32"` // .{0,32}
PortIDX int `json:"port_idx,omitempty"` // [1-8]
PortMode string `json:"port_mode,omitempty" validate:"omitempty,oneof=auto force_active manual disabled"` // auto|force_active|manual|disabled
}
func (dst *DeviceRpsPortTable) UnmarshalJSON(b []byte) error {

View File

@@ -28,8 +28,8 @@ type DHCPOption struct {
Code string `json:"code,omitempty"` // ^(?!(?:15|42|43|44|51|66|67|252)$)([7-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])$
Name string `json:"name,omitempty"` // ^[A-Za-z0-9-_]{1,25}$
Signed bool `json:"signed"`
Type string `json:"type,omitempty"` // ^(boolean|hexarray|integer|ipaddress|macaddress|text)$
Width int `json:"width,omitempty"` // ^(8|16|32)$
Type string `json:"type,omitempty" validate:"omitempty,oneof=boolean hexarray integer ipaddress macaddress text"` // ^(boolean|hexarray|integer|ipaddress|macaddress|text)$
Width int `json:"width,omitempty" validate:"omitempty,oneof=8 16 32"` // ^(8|16|32)$
}
func (dst *DHCPOption) UnmarshalJSON(b []byte) error {

View File

@@ -18,12 +18,12 @@ type DNSRecord struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
Enabled bool `json:"enabled"`
Key string `json:"key,omitempty"` // .{1,128}
Key string `json:"key,omitempty" validate:"required,gte=1,lte=128"` // .{1,128}
Port int `json:"port,omitempty"`
Priority int `json:"priority,omitempty"` // .{1,128}
RecordType string `json:"record_type,omitempty"` // A|AAAA|CNAME|MX|NS|PTR|SOA|SRV|TXT
Priority int `json:"priority,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
RecordType string `json:"record_type,omitempty" validate:"required,oneof=A AAAA MX NS PTR SOA SRV TXT"` // A|AAAA|CNAME|MX|NS|PTR|SOA|SRV|TXT
Ttl int `json:"ttl,omitempty"`
Value string `json:"value,omitempty"` // .{1,256}
Value string `json:"value,omitempty" validate:"required,gte=1,lte=256"` // .{1,256}
Weight int `json:"weight,omitempty"`
}

View File

@@ -30,9 +30,9 @@ type DpiApp struct {
Cats []int `json:"cats,omitempty"`
Enabled bool `json:"enabled"`
Log bool `json:"log"`
Name string `json:"name,omitempty"` // .{1,128}
QOSRateMaxDown int `json:"qos_rate_max_down,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000|10[0-1][0-9]{3}|102[0-3][0-9]{2}|102400
QOSRateMaxUp int `json:"qos_rate_max_up,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000|10[0-1][0-9]{3}|102[0-3][0-9]{2}|102400
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
QOSRateMaxDown int `json:"qos_rate_max_down,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000|10[0-1][0-9]{3}|102[0-3][0-9]{2}|102400
QOSRateMaxUp int `json:"qos_rate_max_up,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000|10[0-1][0-9]{3}|102[0-3][0-9]{2}|102400
}
func (dst *DpiApp) UnmarshalJSON(b []byte) error {

View File

@@ -25,9 +25,9 @@ type DpiGroup struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
DPIappIDs []string `json:"dpiapp_ids,omitempty"` // [\d\w]+
DPIappIDs []string `json:"dpiapp_ids,omitempty" validate:"omitempty,w_regex"` // [\d\w]+
Enabled bool `json:"enabled"`
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *DpiGroup) UnmarshalJSON(b []byte) error {

View File

@@ -25,14 +25,14 @@ type DynamicDNS struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
CustomService string `json:"custom_service,omitempty"` // ^[^"' ]+$
HostName string `json:"host_name,omitempty"` // ^[^"' ]+$
Interface string `json:"interface,omitempty"` // wan|wan2
Login string `json:"login,omitempty"` // ^[^"' ]+$
Options []string `json:"options,omitempty"` // ^[^"' ]+$
Server string `json:"server"` // ^[^"' ]+$|^$
Service string `json:"service,omitempty"` // afraid|changeip|cloudflare|cloudxns|ddnss|dhis|dnsexit|dnsomatic|dnspark|dnspod|dslreports|dtdns|duckdns|duiadns|dyn|dyndns|dynv6|easydns|freemyip|googledomains|loopia|namecheap|noip|nsupdate|ovh|sitelutions|spdyn|strato|tunnelbroker|zoneedit|custom
XPassword string `json:"x_password,omitempty"` // ^[^"' ]+$
CustomService string `json:"custom_service,omitempty"` // ^[^"' ]+$
HostName string `json:"host_name,omitempty"` // ^[^"' ]+$
Interface string `json:"interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
Login string `json:"login,omitempty"` // ^[^"' ]+$
Options []string `json:"options,omitempty"` // ^[^"' ]+$
Server string `json:"server"` // ^[^"' ]+$|^$
Service string `json:"service,omitempty" validate:"omitempty,oneof=afraid changeip cloudflare cloudxns ddnss dhis dnsexit dnsomatic dnspark dnspod dslreports dtdns duckdns duiadns dyn dyndns dynv6 easydns freemyip googledomains loopia namecheap noip nsupdate ovh sitelutions spdyn strato tunnelbroker zoneedit custom"` // afraid|changeip|cloudflare|cloudxns|ddnss|dhis|dnsexit|dnsomatic|dnspark|dnspod|dslreports|dtdns|duckdns|duiadns|dyn|dyndns|dynv6|easydns|freemyip|googledomains|loopia|namecheap|noip|nsupdate|ovh|sitelutions|spdyn|strato|tunnelbroker|zoneedit|custom
XPassword string `json:"x_password,omitempty"` // ^[^"' ]+$
}
func (dst *DynamicDNS) UnmarshalJSON(b []byte) error {

View File

@@ -26,8 +26,8 @@ type FirewallGroup struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
GroupMembers []string `json:"group_members,omitempty"`
GroupType string `json:"group_type,omitempty"` // address-group|port-group|ipv6-address-group
Name string `json:"name,omitempty"` // .{1,64}
GroupType string `json:"group_type,omitempty" validate:"omitempty,oneof=address-group port-group ipv6-address-group"` // address-group|port-group|ipv6-address-group
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=64"` // .{1,64}
}
func (dst *FirewallGroup) UnmarshalJSON(b []byte) error {

View File

@@ -25,31 +25,31 @@ type FirewallRule struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
Action string `json:"action,omitempty"` // drop|reject|accept
Action string `json:"action,omitempty" validate:"omitempty,oneof=drop reject accept"` // drop|reject|accept
DstAddress string `json:"dst_address,omitempty"`
DstAddressIPV6 string `json:"dst_address_ipv6,omitempty"`
DstFirewallGroupIDs []string `json:"dst_firewallgroup_ids,omitempty"` // [\d\w]+
DstNetworkID string `json:"dst_networkconf_id"` // [\d\w]+|^$
DstNetworkType string `json:"dst_networkconf_type,omitempty"` // ADDRv4|NETv4
DstFirewallGroupIDs []string `json:"dst_firewallgroup_ids,omitempty" validate:"omitempty,w_regex"` // [\d\w]+
DstNetworkID string `json:"dst_networkconf_id" validate:"omitempty,w_regex"` // [\d\w]+|^$
DstNetworkType string `json:"dst_networkconf_type,omitempty" validate:"omitempty,oneof=ADDRv4 NETv4"` // ADDRv4|NETv4
DstPort string `json:"dst_port,omitempty"`
Enabled bool `json:"enabled"`
ICMPTypename string `json:"icmp_typename"` // ^$|address-mask-reply|address-mask-request|any|communication-prohibited|destination-unreachable|echo-reply|echo-request|fragmentation-needed|host-precedence-violation|host-prohibited|host-redirect|host-unknown|host-unreachable|ip-header-bad|network-prohibited|network-redirect|network-unknown|network-unreachable|parameter-problem|port-unreachable|precedence-cutoff|protocol-unreachable|redirect|required-option-missing|router-advertisement|router-solicitation|source-quench|source-route-failed|time-exceeded|timestamp-reply|timestamp-request|TOS-host-redirect|TOS-host-unreachable|TOS-network-redirect|TOS-network-unreachable|ttl-zero-during-reassembly|ttl-zero-during-transit
ICMPv6Typename string `json:"icmpv6_typename"` // ^$|address-unreachable|bad-header|beyond-scope|communication-prohibited|destination-unreachable|echo-reply|echo-request|failed-policy|neighbor-advertisement|neighbor-solicitation|no-route|packet-too-big|parameter-problem|port-unreachable|redirect|reject-route|router-advertisement|router-solicitation|time-exceeded|ttl-zero-during-reassembly|ttl-zero-during-transit|unknown-header-type|unknown-option
IPSec string `json:"ipsec"` // match-ipsec|match-none|^$
ICMPTypename string `json:"icmp_typename" validate:"omitempty,oneof=address-mask-reply address-mask-request any communication-prohibited destination-unreachable echo-reply echo-request fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable ip-header-bad network-prohibited network-redirect network-unknown network-unreachable parameter-problem port-unreachable precedence-cutoff protocol-unreachable redirect required-option-missing router-advertisement router-solicitation source-quench source-route-failed time-exceeded timestamp-reply timestamp-request TOS-host-redirect TOS-host-unreachable TOS-network-redirect TOS-network-unreachable ttl-zero-during-reassembly ttl-zero-during-transit"` // ^$|address-mask-reply|address-mask-request|any|communication-prohibited|destination-unreachable|echo-reply|echo-request|fragmentation-needed|host-precedence-violation|host-prohibited|host-redirect|host-unknown|host-unreachable|ip-header-bad|network-prohibited|network-redirect|network-unknown|network-unreachable|parameter-problem|port-unreachable|precedence-cutoff|protocol-unreachable|redirect|required-option-missing|router-advertisement|router-solicitation|source-quench|source-route-failed|time-exceeded|timestamp-reply|timestamp-request|TOS-host-redirect|TOS-host-unreachable|TOS-network-redirect|TOS-network-unreachable|ttl-zero-during-reassembly|ttl-zero-during-transit
ICMPv6Typename string `json:"icmpv6_typename" validate:"omitempty,oneof=address-unreachable bad-header beyond-scope communication-prohibited destination-unreachable echo-reply echo-request failed-policy neighbor-advertisement neighbor-solicitation no-route packet-too-big parameter-problem port-unreachable redirect reject-route router-advertisement router-solicitation time-exceeded ttl-zero-during-reassembly ttl-zero-during-transit unknown-header-type unknown-option"` // ^$|address-unreachable|bad-header|beyond-scope|communication-prohibited|destination-unreachable|echo-reply|echo-request|failed-policy|neighbor-advertisement|neighbor-solicitation|no-route|packet-too-big|parameter-problem|port-unreachable|redirect|reject-route|router-advertisement|router-solicitation|time-exceeded|ttl-zero-during-reassembly|ttl-zero-during-transit|unknown-header-type|unknown-option
IPSec string `json:"ipsec" validate:"omitempty,oneof=match-ipsec match-none"` // match-ipsec|match-none|^$
Logging bool `json:"logging"`
Name string `json:"name,omitempty"` // .{1,128}
Protocol string `json:"protocol"` // ^$|all|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|tcp_udp|ah|ax.25|dccp|ddp|egp|eigrp|encap|esp|etherip|fc|ggp|gre|hip|hmp|icmp|idpr-cmtp|idrp|igmp|igp|ip|ipcomp|ipencap|ipip|ipv6|ipv6-frag|ipv6-icmp|ipv6-nonxt|ipv6-opts|ipv6-route|isis|iso-tp4|l2tp|manet|mobility-header|mpls-in-ip|ospf|pim|pup|rdp|rohc|rspf|rsvp|sctp|shim6|skip|st|tcp|udp|udplite|vmtp|vrrp|wesp|xns-idp|xtp
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
Protocol string `json:"protocol"` // ^$|all|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|tcp_udp|ah|ax.25|dccp|ddp|egp|eigrp|encap|esp|etherip|fc|ggp|gre|hip|hmp|icmp|idpr-cmtp|idrp|igmp|igp|ip|ipcomp|ipencap|ipip|ipv6|ipv6-frag|ipv6-icmp|ipv6-nonxt|ipv6-opts|ipv6-route|isis|iso-tp4|l2tp|manet|mobility-header|mpls-in-ip|ospf|pim|pup|rdp|rohc|rspf|rsvp|sctp|shim6|skip|st|tcp|udp|udplite|vmtp|vrrp|wesp|xns-idp|xtp
ProtocolMatchExcepted bool `json:"protocol_match_excepted"`
ProtocolV6 string `json:"protocol_v6"` // ^$|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|ah|all|dccp|eigrp|esp|gre|icmpv6|ipcomp|ipv6|ipv6-frag|ipv6-icmp|ipv6-nonxt|ipv6-opts|ipv6-route|isis|l2tp|manet|mobility-header|mpls-in-ip|ospf|pim|rsvp|sctp|shim6|tcp|tcp_udp|udp|vrrp
RuleIndex int `json:"rule_index,omitempty"` // 2[0-9]{3,4}|4[0-9]{3,4}
Ruleset string `json:"ruleset,omitempty"` // WAN_IN|WAN_OUT|WAN_LOCAL|LAN_IN|LAN_OUT|LAN_LOCAL|GUEST_IN|GUEST_OUT|GUEST_LOCAL|WANv6_IN|WANv6_OUT|WANv6_LOCAL|LANv6_IN|LANv6_OUT|LANv6_LOCAL|GUESTv6_IN|GUESTv6_OUT|GUESTv6_LOCAL
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
ProtocolV6 string `json:"protocol_v6"` // ^$|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|ah|all|dccp|eigrp|esp|gre|icmpv6|ipcomp|ipv6|ipv6-frag|ipv6-icmp|ipv6-nonxt|ipv6-opts|ipv6-route|isis|l2tp|manet|mobility-header|mpls-in-ip|ospf|pim|rsvp|sctp|shim6|tcp|tcp_udp|udp|vrrp
RuleIndex int `json:"rule_index,omitempty"` // 2[0-9]{3,4}|4[0-9]{3,4}
Ruleset string `json:"ruleset,omitempty" validate:"omitempty,oneof=WAN_IN WAN_OUT WAN_LOCAL LAN_IN LAN_OUT LAN_LOCAL GUEST_IN GUEST_OUT GUEST_LOCAL WANv6_IN WANv6_OUT WANv6_LOCAL LANv6_IN LANv6_OUT LANv6_LOCAL GUESTv6_IN GUESTv6_OUT GUESTv6_LOCAL"` // WAN_IN|WAN_OUT|WAN_LOCAL|LAN_IN|LAN_OUT|LAN_LOCAL|GUEST_IN|GUEST_OUT|GUEST_LOCAL|WANv6_IN|WANv6_OUT|WANv6_LOCAL|LANv6_IN|LANv6_OUT|LANv6_LOCAL|GUESTv6_IN|GUESTv6_OUT|GUESTv6_LOCAL
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
SrcAddress string `json:"src_address,omitempty"`
SrcAddressIPV6 string `json:"src_address_ipv6,omitempty"`
SrcFirewallGroupIDs []string `json:"src_firewallgroup_ids,omitempty"` // [\d\w]+
SrcMACAddress string `json:"src_mac_address"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$|^$
SrcNetworkID string `json:"src_networkconf_id"` // [\d\w]+|^$
SrcNetworkType string `json:"src_networkconf_type,omitempty"` // ADDRv4|NETv4
SrcFirewallGroupIDs []string `json:"src_firewallgroup_ids,omitempty" validate:"omitempty,w_regex"` // [\d\w]+
SrcMACAddress string `json:"src_mac_address" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$|^$
SrcNetworkID string `json:"src_networkconf_id" validate:"omitempty,w_regex"` // [\d\w]+|^$
SrcNetworkType string `json:"src_networkconf_type,omitempty" validate:"omitempty,oneof=ADDRv4 NETv4"` // ADDRv4|NETv4
SrcPort string `json:"src_port,omitempty"`
StateEstablished bool `json:"state_established"`
StateInvalid bool `json:"state_invalid"`

View File

@@ -27,8 +27,8 @@ type HeatMap struct {
Description string `json:"description,omitempty"`
MapID string `json:"map_id"`
Name string `json:"name,omitempty"` // .*[^\s]+.*
Type string `json:"type,omitempty"` // download|upload
Name string `json:"name,omitempty"` // .*[^\s]+.*
Type string `json:"type,omitempty" validate:"omitempty,oneof=download upload"` // download|upload
}
func (dst *HeatMap) UnmarshalJSON(b []byte) error {

View File

@@ -30,22 +30,22 @@ type Hotspot2Conf struct {
CellularNetworkList []Hotspot2ConfCellularNetworkList `json:"cellular_network_list,omitempty"`
DeauthReqTimeout int `json:"deauth_req_timeout,omitempty"` // [1-9][0-9]|[1-9][0-9][0-9]|[1-2][0-9][0-9][0-9]|3[0-5][0-9][0-9]|3600
DisableDgaf bool `json:"disable_dgaf"`
DomainNameList []string `json:"domain_name_list,omitempty"` // .{1,128}
DomainNameList []string `json:"domain_name_list,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
FriendlyName []Hotspot2ConfFriendlyName `json:"friendly_name,omitempty"`
GasAdvanced bool `json:"gas_advanced"`
GasComebackDelay int `json:"gas_comeback_delay,omitempty"`
GasFragLimit int `json:"gas_frag_limit,omitempty"`
Hessid string `json:"hessid"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$|^$
Hessid string `json:"hessid" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$|^$
HessidUsed bool `json:"hessid_used"`
IPaddrTypeAvailV4 int `json:"ipaddr_type_avail_v4,omitempty"` // 0|1|2|3|4|5|6|7
IPaddrTypeAvailV6 int `json:"ipaddr_type_avail_v6,omitempty"` // 0|1|2
IPaddrTypeAvailV4 int `json:"ipaddr_type_avail_v4,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7"` // 0|1|2|3|4|5|6|7
IPaddrTypeAvailV6 int `json:"ipaddr_type_avail_v6,omitempty" validate:"omitempty,oneof=0 1 2"` // 0|1|2
Icons []Hotspot2ConfIcons `json:"icons,omitempty"`
MetricsDownlinkLoad int `json:"metrics_downlink_load,omitempty"`
MetricsDownlinkLoadSet bool `json:"metrics_downlink_load_set"`
MetricsDownlinkSpeed int `json:"metrics_downlink_speed,omitempty"`
MetricsDownlinkSpeedSet bool `json:"metrics_downlink_speed_set"`
MetricsInfoAtCapacity bool `json:"metrics_info_at_capacity"`
MetricsInfoLinkStatus string `json:"metrics_info_link_status,omitempty"` // up|down|test
MetricsInfoLinkStatus string `json:"metrics_info_link_status,omitempty" validate:"omitempty,oneof=up down test"` // up|down|test
MetricsInfoSymmetric bool `json:"metrics_info_symmetric"`
MetricsMeasurement int `json:"metrics_measurement,omitempty"`
MetricsMeasurementSet bool `json:"metrics_measurement_set"`
@@ -55,14 +55,14 @@ type Hotspot2Conf struct {
MetricsUplinkSpeed int `json:"metrics_uplink_speed,omitempty"`
MetricsUplinkSpeedSet bool `json:"metrics_uplink_speed_set"`
NaiRealmList []Hotspot2ConfNaiRealmList `json:"nai_realm_list,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
NetworkAccessAsra bool `json:"network_access_asra"`
NetworkAccessEsr bool `json:"network_access_esr"`
NetworkAccessInternet bool `json:"network_access_internet"`
NetworkAccessUesa bool `json:"network_access_uesa"`
NetworkAuthType int `json:"network_auth_type,omitempty"` // -1|0|1|2|3
NetworkAuthType int `json:"network_auth_type,omitempty" validate:"omitempty,oneof=-1 0 1 2 3"` // -1|0|1|2|3
NetworkAuthUrl string `json:"network_auth_url,omitempty"`
NetworkType int `json:"network_type,omitempty"` // 0|1|2|3|4|5|14|15
NetworkType int `json:"network_type,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 14 15"` // 0|1|2|3|4|5|14|15
Osu []Hotspot2ConfOsu `json:"osu,omitempty"`
OsuSSID string `json:"osu_ssid"`
QOSMapDcsp []Hotspot2ConfQOSMapDcsp `json:"qos_map_dcsp,omitempty"`
@@ -70,11 +70,11 @@ type Hotspot2Conf struct {
QOSMapStatus bool `json:"qos_map_status"`
RoamingConsortiumList []Hotspot2ConfRoamingConsortiumList `json:"roaming_consortium_list,omitempty"`
SaveTimestamp string `json:"save_timestamp,omitempty"`
TCFilename string `json:"t_c_filename,omitempty"` // .{1,256}
TCFilename string `json:"t_c_filename,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
TCTimestamp int `json:"t_c_timestamp,omitempty"`
VenueGroup int `json:"venue_group,omitempty"` // 0|1|2|3|4|5|6|7|8|9|10|11
VenueGroup int `json:"venue_group,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7 8 9 10 11"` // 0|1|2|3|4|5|6|7|8|9|10|11
VenueName []Hotspot2ConfVenueName `json:"venue_name,omitempty"`
VenueType int `json:"venue_type,omitempty"` // 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15
VenueType int `json:"venue_type,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"` // 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15
}
func (dst *Hotspot2Conf) UnmarshalJSON(b []byte) error {
@@ -127,9 +127,9 @@ func (dst *Hotspot2Conf) UnmarshalJSON(b []byte) error {
}
type Hotspot2ConfCapab struct {
Port int `json:"port,omitempty"` // ^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])|$
Protocol string `json:"protocol,omitempty"` // icmp|tcp_udp|tcp|udp|esp
Status string `json:"status,omitempty"` // closed|open|unknown
Port int `json:"port,omitempty"` // ^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])|$
Protocol string `json:"protocol,omitempty" validate:"omitempty,oneof=icmp tcp_udp tcp udp esp"` // icmp|tcp_udp|tcp|udp|esp
Status string `json:"status,omitempty" validate:"omitempty,oneof=closed open unknown"` // closed|open|unknown
}
func (dst *Hotspot2ConfCapab) UnmarshalJSON(b []byte) error {
@@ -154,7 +154,7 @@ func (dst *Hotspot2ConfCapab) UnmarshalJSON(b []byte) error {
type Hotspot2ConfCellularNetworkList struct {
Mcc int `json:"mcc,omitempty"`
Mnc int `json:"mnc,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *Hotspot2ConfCellularNetworkList) UnmarshalJSON(b []byte) error {
@@ -179,8 +179,8 @@ func (dst *Hotspot2ConfCellularNetworkList) UnmarshalJSON(b []byte) error {
}
type Hotspot2ConfDescription struct {
Language string `json:"language,omitempty"` // [a-z]{3}
Text string `json:"text,omitempty"` // .{1,128}
Language string `json:"language,omitempty"` // [a-z]{3}
Text string `json:"text,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *Hotspot2ConfDescription) UnmarshalJSON(b []byte) error {
@@ -200,8 +200,8 @@ func (dst *Hotspot2ConfDescription) UnmarshalJSON(b []byte) error {
}
type Hotspot2ConfFriendlyName struct {
Language string `json:"language,omitempty"` // [a-z]{3}
Text string `json:"text,omitempty"` // .{1,128}
Language string `json:"language,omitempty"` // [a-z]{3}
Text string `json:"text,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *Hotspot2ConfFriendlyName) UnmarshalJSON(b []byte) error {
@@ -221,7 +221,7 @@ func (dst *Hotspot2ConfFriendlyName) UnmarshalJSON(b []byte) error {
}
type Hotspot2ConfIcon struct {
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *Hotspot2ConfIcon) UnmarshalJSON(b []byte) error {
@@ -242,11 +242,11 @@ func (dst *Hotspot2ConfIcon) UnmarshalJSON(b []byte) error {
type Hotspot2ConfIcons struct {
Data string `json:"data,omitempty"`
Filename string `json:"filename,omitempty"` // .{1,256}
Filename string `json:"filename,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
Height int `json:"height,omitempty"`
Language string `json:"language,omitempty"` // [a-z]{3}
Media string `json:"media,omitempty"` // .{1,256}
Name string `json:"name,omitempty"` // .{1,256}
Language string `json:"language,omitempty"` // [a-z]{3}
Media string `json:"media,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
Size int `json:"size,omitempty"`
Width int `json:"width,omitempty"`
}
@@ -277,9 +277,9 @@ func (dst *Hotspot2ConfIcons) UnmarshalJSON(b []byte) error {
type Hotspot2ConfNaiRealmList struct {
AuthIDs string `json:"auth_ids,omitempty"`
AuthVals string `json:"auth_vals,omitempty"`
EapMethod int `json:"eap_method,omitempty"` // 13|21|18|23|50
Encoding int `json:"encoding,omitempty"` // 0|1
Name string `json:"name,omitempty"` // .{1,128}
EapMethod int `json:"eap_method,omitempty" validate:"omitempty,oneof=13 21 18 23 50"` // 13|21|18|23|50
Encoding int `json:"encoding,omitempty" validate:"omitempty,oneof=0 1"` // 0|1
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
Status bool `json:"status"`
}
@@ -385,8 +385,8 @@ func (dst *Hotspot2ConfQOSMapExceptions) UnmarshalJSON(b []byte) error {
}
type Hotspot2ConfRoamingConsortiumList struct {
Name string `json:"name,omitempty"` // .{1,128}
Oid string `json:"oid,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
Oid string `json:"oid,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *Hotspot2ConfRoamingConsortiumList) UnmarshalJSON(b []byte) error {

View File

@@ -25,9 +25,9 @@ type HotspotOp struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
Name string `json:"name,omitempty"` // .{1,256}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
Note string `json:"note,omitempty"`
XPassword string `json:"x_password,omitempty"` // .{1,256}
XPassword string `json:"x_password,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
}
func (dst *HotspotOp) UnmarshalJSON(b []byte) error {

10
unifi/map.generated.go generated
View File

@@ -25,17 +25,17 @@ type Map struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
Lat string `json:"lat,omitempty"` // ^([-]?[\d]+[.]?[\d]*([eE][-+]?[\d]+)?)$
Lng string `json:"lng,omitempty"` // ^([-]?[\d]+[.]?[\d]*([eE][-+]?[\d]+)?)$
MapTypeID string `json:"mapTypeId"` // satellite|roadmap|hybrid|terrain
Lat string `json:"lat,omitempty"` // ^([-]?[\d]+[.]?[\d]*([eE][-+]?[\d]+)?)$
Lng string `json:"lng,omitempty"` // ^([-]?[\d]+[.]?[\d]*([eE][-+]?[\d]+)?)$
MapTypeID string `json:"mapTypeId" validate:"omitempty,oneof=satellite roadmap hybrid terrain"` // satellite|roadmap|hybrid|terrain
Name string `json:"name,omitempty"`
OffsetLeft float64 `json:"offset_left,omitempty"`
OffsetTop float64 `json:"offset_top,omitempty"`
Opacity float64 `json:"opacity,omitempty"` // ^(0(\.[\d]{1,2})?|1)$|^$
Selected bool `json:"selected"`
Tilt int `json:"tilt,omitempty"`
Type string `json:"type,omitempty"` // designerMap|imageMap|googleMap
Unit string `json:"unit,omitempty"` // m|f
Type string `json:"type,omitempty" validate:"omitempty,oneof=designerMap imageMap googleMap"` // designerMap|imageMap|googleMap
Unit string `json:"unit,omitempty" validate:"omitempty,oneof=m f"` // m|f
Upp float64 `json:"upp,omitempty"`
Zoom int `json:"zoom,omitempty"`
}

View File

@@ -27,33 +27,33 @@ type Network struct {
AutoScaleEnabled bool `json:"auto_scale_enabled"`
DHCPDBootEnabled bool `json:"dhcpd_boot_enabled"`
DHCPDBootFilename string `json:"dhcpd_boot_filename,omitempty"` // .{1,256}
DHCPDBootServer string `json:"dhcpd_boot_server"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$|(?=^.{3,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)|[a-zA-Z0-9-]{1,63}|^$
DHCPDBootFilename string `json:"dhcpd_boot_filename,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
DHCPDBootServer string `json:"dhcpd_boot_server"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$|(?=^.{3,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)|[a-zA-Z0-9-]{1,63}|^$
DHCPDConflictChecking bool `json:"dhcpd_conflict_checking"`
DHCPDDNS1 string `json:"dhcpd_dns_1"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS2 string `json:"dhcpd_dns_2"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS3 string `json:"dhcpd_dns_3"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS4 string `json:"dhcpd_dns_4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS1 string `json:"dhcpd_dns_1" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS2 string `json:"dhcpd_dns_2" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS3 string `json:"dhcpd_dns_3" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNS4 string `json:"dhcpd_dns_4" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDDNSEnabled bool `json:"dhcpd_dns_enabled"`
DHCPDEnabled bool `json:"dhcpd_enabled"`
DHCPDGateway string `json:"dhcpd_gateway"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDGateway string `json:"dhcpd_gateway" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDGatewayEnabled bool `json:"dhcpd_gateway_enabled"`
DHCPDIP1 string `json:"dhcpd_ip_1"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDIP2 string `json:"dhcpd_ip_2"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDIP3 string `json:"dhcpd_ip_3"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDIP1 string `json:"dhcpd_ip_1" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDIP2 string `json:"dhcpd_ip_2" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDIP3 string `json:"dhcpd_ip_3" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDLeaseTime int `json:"dhcpd_leasetime,omitempty"`
DHCPDMAC1 string `json:"dhcpd_mac_1"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
DHCPDMAC2 string `json:"dhcpd_mac_2"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
DHCPDMAC3 string `json:"dhcpd_mac_3"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
DHCPDNtp1 string `json:"dhcpd_ntp_1"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDNtp2 string `json:"dhcpd_ntp_2"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDMAC1 string `json:"dhcpd_mac_1" validate:"omitempty,mac"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
DHCPDMAC2 string `json:"dhcpd_mac_2" validate:"omitempty,mac"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
DHCPDMAC3 string `json:"dhcpd_mac_3" validate:"omitempty,mac"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
DHCPDNtp1 string `json:"dhcpd_ntp_1" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDNtp2 string `json:"dhcpd_ntp_2" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDNtpEnabled bool `json:"dhcpd_ntp_enabled"`
DHCPDStart string `json:"dhcpd_start"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDStop string `json:"dhcpd_stop"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDStart string `json:"dhcpd_start" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDStop string `json:"dhcpd_stop" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDTFTPServer string `json:"dhcpd_tftp_server,omitempty"`
DHCPDTimeOffset int `json:"dhcpd_time_offset,omitempty"` // ^0$|^-?([1-9]([0-9]{1,3})?|[1-7][0-9]{4}|[8][0-5][0-9]{3}|86[0-3][0-9]{2}|86400)$
DHCPDTimeOffsetEnabled bool `json:"dhcpd_time_offset_enabled"`
DHCPDUnifiController string `json:"dhcpd_unifi_controller"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDUnifiController string `json:"dhcpd_unifi_controller" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDV6AllowSlaac bool `json:"dhcpdv6_allow_slaac"`
DHCPDV6DNS1 string `json:"dhcpdv6_dns_1,omitempty"`
DHCPDV6DNS2 string `json:"dhcpdv6_dns_2,omitempty"`
@@ -65,105 +65,105 @@ type Network struct {
DHCPDV6Start string `json:"dhcpdv6_start,omitempty"`
DHCPDV6Stop string `json:"dhcpdv6_stop,omitempty"`
DHCPDWPAdUrl string `json:"dhcpd_wpad_url,omitempty"`
DHCPDWins1 string `json:"dhcpd_wins_1"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDWins2 string `json:"dhcpd_wins_2"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDWins1 string `json:"dhcpd_wins_1" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDWins2 string `json:"dhcpd_wins_2" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPDWinsEnabled bool `json:"dhcpd_wins_enabled"`
DHCPRelayEnabled bool `json:"dhcp_relay_enabled"`
DHCPguardEnabled bool `json:"dhcpguard_enabled"`
DPIEnabled bool `json:"dpi_enabled"`
DPIgroupID string `json:"dpigroup_id"` // [\d\w]+|^$
DomainName string `json:"domain_name"` // (?=^.{3,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)|^$|[a-zA-Z0-9-]{1,63}
DPIgroupID string `json:"dpigroup_id" validate:"omitempty,w_regex"` // [\d\w]+|^$
DomainName string `json:"domain_name"` // (?=^.{3,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)|^$|[a-zA-Z0-9-]{1,63}
Enabled bool `json:"enabled"`
ExposedToSiteVPN bool `json:"exposed_to_site_vpn"`
FirewallZoneID string `json:"firewall_zone_id"`
GatewayDevice string `json:"gateway_device"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
GatewayType string `json:"gateway_type,omitempty"` // default|switch
GatewayDevice string `json:"gateway_device" validate:"omitempty,mac"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
GatewayType string `json:"gateway_type,omitempty" validate:"omitempty,oneof=default switch"` // default|switch
IGMPFastleave bool `json:"igmp_fastleave"`
IGMPForwardUnknownMulticast bool `json:"igmp_forward_unknown_multicast"`
IGMPGroupmembership int `json:"igmp_groupmembership,omitempty"` // [2-9]|[1-9][0-9]{1,2}|[1-2][0-9]{3}|3[0-5][0-9]{2}|3600|^$
IGMPMaxresponse int `json:"igmp_maxresponse,omitempty"` // [1-9]|1[0-9]|2[0-5]|^$
IGMPMcrtrexpiretime int `json:"igmp_mcrtrexpiretime,omitempty"` // [0-9]|[1-9][0-9]{1,2}|[1-2][0-9]{3}|3[0-5][0-9]{2}|3600|^$
IGMPProxyDownstreamNetworkIDs []string `json:"igmp_proxy_downstream_networkconf_ids,omitempty"`
IGMPProxyFor string `json:"igmp_proxy_for,omitempty"` // all|some|none
IGMPProxyFor string `json:"igmp_proxy_for,omitempty" validate:"omitempty,oneof=all some none"` // all|some|none
IGMPProxyUpstream bool `json:"igmp_proxy_upstream"`
IGMPQuerierSwitches []NetworkIGMPQuerierSwitches `json:"igmp_querier_switches,omitempty"`
IGMPSnooping bool `json:"igmp_snooping"`
IGMPSupression bool `json:"igmp_supression"`
IPSecDhGroup int `json:"ipsec_dh_group,omitempty"` // 2|5|14|15|16|19|20|21|25|26
IPSecDhGroup int `json:"ipsec_dh_group,omitempty" validate:"omitempty,oneof=2 5 14 15 16 19 20 21 25 26"` // 2|5|14|15|16|19|20|21|25|26
IPSecDynamicRouting bool `json:"ipsec_dynamic_routing"`
IPSecEncryption string `json:"ipsec_encryption,omitempty"` // aes128|aes192|aes256|3des
IPSecEspDhGroup int `json:"ipsec_esp_dh_group,omitempty"` // 1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32
IPSecEspEncryption string `json:"ipsec_esp_encryption,omitempty"` // aes128|aes192|aes256|3des
IPSecEspHash string `json:"ipsec_esp_hash,omitempty"` // sha1|md5|sha256|sha384|sha512
IPSecEspLifetime string `json:"ipsec_esp_lifetime,omitempty"` // ^(?:3[0-9]|[4-9][0-9]|[1-9][0-9]{2,3}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)$
IPSecHash string `json:"ipsec_hash,omitempty"` // sha1|md5|sha256|sha384|sha512
IPSecIkeDhGroup int `json:"ipsec_ike_dh_group,omitempty"` // 1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32
IPSecIkeEncryption string `json:"ipsec_ike_encryption,omitempty"` // aes128|aes192|aes256|3des
IPSecIkeHash string `json:"ipsec_ike_hash,omitempty"` // sha1|md5|sha256|sha384|sha512
IPSecIkeLifetime string `json:"ipsec_ike_lifetime,omitempty"` // ^(?:3[0-9]|[4-9][0-9]|[1-9][0-9]{2,3}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)$
IPSecInterface string `json:"ipsec_interface,omitempty"` // wan|wan2
IPSecKeyExchange string `json:"ipsec_key_exchange,omitempty"` // ikev1|ikev2
IPSecEncryption string `json:"ipsec_encryption,omitempty" validate:"omitempty,oneof=aes128 aes192 aes256 3des"` // aes128|aes192|aes256|3des
IPSecEspDhGroup int `json:"ipsec_esp_dh_group,omitempty" validate:"omitempty,oneof=1 2 5 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"` // 1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32
IPSecEspEncryption string `json:"ipsec_esp_encryption,omitempty" validate:"omitempty,oneof=aes128 aes192 aes256 3des"` // aes128|aes192|aes256|3des
IPSecEspHash string `json:"ipsec_esp_hash,omitempty" validate:"omitempty,oneof=sha1 md5 sha256 sha384 sha512"` // sha1|md5|sha256|sha384|sha512
IPSecEspLifetime string `json:"ipsec_esp_lifetime,omitempty"` // ^(?:3[0-9]|[4-9][0-9]|[1-9][0-9]{2,3}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)$
IPSecHash string `json:"ipsec_hash,omitempty" validate:"omitempty,oneof=sha1 md5 sha256 sha384 sha512"` // sha1|md5|sha256|sha384|sha512
IPSecIkeDhGroup int `json:"ipsec_ike_dh_group,omitempty" validate:"omitempty,oneof=1 2 5 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"` // 1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32
IPSecIkeEncryption string `json:"ipsec_ike_encryption,omitempty" validate:"omitempty,oneof=aes128 aes192 aes256 3des"` // aes128|aes192|aes256|3des
IPSecIkeHash string `json:"ipsec_ike_hash,omitempty" validate:"omitempty,oneof=sha1 md5 sha256 sha384 sha512"` // sha1|md5|sha256|sha384|sha512
IPSecIkeLifetime string `json:"ipsec_ike_lifetime,omitempty"` // ^(?:3[0-9]|[4-9][0-9]|[1-9][0-9]{2,3}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)$
IPSecInterface string `json:"ipsec_interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
IPSecKeyExchange string `json:"ipsec_key_exchange,omitempty" validate:"omitempty,oneof=ikev1 ikev2"` // ikev1|ikev2
IPSecLocalIDentifier string `json:"ipsec_local_identifier,omitempty"`
IPSecLocalIDentifierEnabled bool `json:"ipsec_local_identifier_enabled"`
IPSecLocalIP string `json:"ipsec_local_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
IPSecPeerIP string `json:"ipsec_peer_ip,omitempty"`
IPSecPfs bool `json:"ipsec_pfs"`
IPSecProfile string `json:"ipsec_profile,omitempty"` // customized|azure_dynamic|azure_static
IPSecProfile string `json:"ipsec_profile,omitempty" validate:"omitempty,oneof=customized azure_dynamic azure_static"` // customized|azure_dynamic|azure_static
IPSecRemoteIDentifier string `json:"ipsec_remote_identifier,omitempty"`
IPSecRemoteIDentifierEnabled bool `json:"ipsec_remote_identifier_enabled"`
IPSecSeparateIkev2Networks bool `json:"ipsec_separate_ikev2_networks"`
IPSecTunnelIP string `json:"ipsec_tunnel_ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$
IPSecTunnelIPEnabled bool `json:"ipsec_tunnel_ip_enabled"`
IPSubnet string `json:"ip_subnet,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$
IPV6ClientAddressAssignment string `json:"ipv6_client_address_assignment,omitempty"` // slaac|dhcpv6
IPV6InterfaceType string `json:"ipv6_interface_type,omitempty"` // static|pd|single_network|none
IPSubnet string `json:"ip_subnet,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$
IPV6ClientAddressAssignment string `json:"ipv6_client_address_assignment,omitempty" validate:"omitempty,oneof=slaac dhcpv6"` // slaac|dhcpv6
IPV6InterfaceType string `json:"ipv6_interface_type,omitempty" validate:"omitempty,oneof=static pd single_network none"` // static|pd|single_network|none
IPV6PDAutoPrefixidEnabled bool `json:"ipv6_pd_auto_prefixid_enabled"`
IPV6PDInterface string `json:"ipv6_pd_interface,omitempty"` // wan|wan2
IPV6PDPrefixid string `json:"ipv6_pd_prefixid"` // ^$|[a-fA-F0-9]{1,4}
IPV6PDInterface string `json:"ipv6_pd_interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
IPV6PDPrefixid string `json:"ipv6_pd_prefixid"` // ^$|[a-fA-F0-9]{1,4}
IPV6PDStart string `json:"ipv6_pd_start,omitempty"`
IPV6PDStop string `json:"ipv6_pd_stop,omitempty"`
IPV6RaEnabled bool `json:"ipv6_ra_enabled"`
IPV6RaPreferredLifetime int `json:"ipv6_ra_preferred_lifetime,omitempty"` // ^([0-9]|[1-8][0-9]|9[0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|[1-8][0-9]{3}|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9]|[1-8][0-9]{4}|9[0-8][0-9]{3}|99[0-8][0-9]{2}|999[0-8][0-9]|9999[0-9]|[1-8][0-9]{5}|9[0-8][0-9]{4}|99[0-8][0-9]{3}|999[0-8][0-9]{2}|9999[0-8][0-9]|99999[0-9]|[1-8][0-9]{6}|9[0-8][0-9]{5}|99[0-8][0-9]{4}|999[0-8][0-9]{3}|9999[0-8][0-9]{2}|99999[0-8][0-9]|999999[0-9]|[12][0-9]{7}|30[0-9]{6}|31[0-4][0-9]{5}|315[0-2][0-9]{4}|3153[0-5][0-9]{3}|31536000)$|^$
IPV6RaPriority string `json:"ipv6_ra_priority,omitempty"` // high|medium|low
IPV6RaValidLifetime int `json:"ipv6_ra_valid_lifetime,omitempty"` // ^([0-9]|[1-8][0-9]|9[0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|[1-8][0-9]{3}|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9]|[1-8][0-9]{4}|9[0-8][0-9]{3}|99[0-8][0-9]{2}|999[0-8][0-9]|9999[0-9]|[1-8][0-9]{5}|9[0-8][0-9]{4}|99[0-8][0-9]{3}|999[0-8][0-9]{2}|9999[0-8][0-9]|99999[0-9]|[1-8][0-9]{6}|9[0-8][0-9]{5}|99[0-8][0-9]{4}|999[0-8][0-9]{3}|9999[0-8][0-9]{2}|99999[0-8][0-9]|999999[0-9]|[12][0-9]{7}|30[0-9]{6}|31[0-4][0-9]{5}|315[0-2][0-9]{4}|3153[0-5][0-9]{3}|31536000)$|^$
IPV6SettingPreference string `json:"ipv6_setting_preference,omitempty"` // auto|manual
IPV6RaPreferredLifetime int `json:"ipv6_ra_preferred_lifetime,omitempty"` // ^([0-9]|[1-8][0-9]|9[0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|[1-8][0-9]{3}|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9]|[1-8][0-9]{4}|9[0-8][0-9]{3}|99[0-8][0-9]{2}|999[0-8][0-9]|9999[0-9]|[1-8][0-9]{5}|9[0-8][0-9]{4}|99[0-8][0-9]{3}|999[0-8][0-9]{2}|9999[0-8][0-9]|99999[0-9]|[1-8][0-9]{6}|9[0-8][0-9]{5}|99[0-8][0-9]{4}|999[0-8][0-9]{3}|9999[0-8][0-9]{2}|99999[0-8][0-9]|999999[0-9]|[12][0-9]{7}|30[0-9]{6}|31[0-4][0-9]{5}|315[0-2][0-9]{4}|3153[0-5][0-9]{3}|31536000)$|^$
IPV6RaPriority string `json:"ipv6_ra_priority,omitempty" validate:"omitempty,oneof=high medium low"` // high|medium|low
IPV6RaValidLifetime int `json:"ipv6_ra_valid_lifetime,omitempty"` // ^([0-9]|[1-8][0-9]|9[0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|[1-8][0-9]{3}|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9]|[1-8][0-9]{4}|9[0-8][0-9]{3}|99[0-8][0-9]{2}|999[0-8][0-9]|9999[0-9]|[1-8][0-9]{5}|9[0-8][0-9]{4}|99[0-8][0-9]{3}|999[0-8][0-9]{2}|9999[0-8][0-9]|99999[0-9]|[1-8][0-9]{6}|9[0-8][0-9]{5}|99[0-8][0-9]{4}|999[0-8][0-9]{3}|9999[0-8][0-9]{2}|99999[0-8][0-9]|999999[0-9]|[12][0-9]{7}|30[0-9]{6}|31[0-4][0-9]{5}|315[0-2][0-9]{4}|3153[0-5][0-9]{3}|31536000)$|^$
IPV6SettingPreference string `json:"ipv6_setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
IPV6SingleNetworkInterface string `json:"ipv6_single_network_interface,omitempty"`
IPV6Subnet string `json:"ipv6_subnet,omitempty"`
IPV6WANDelegationType string `json:"ipv6_wan_delegation_type,omitempty"` // pd|single_network|none
InterfaceMtu int `json:"interface_mtu,omitempty"` // ^(6[89]|[7-9][0-9]|[1-9][0-9]{2,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|65500)$
IPV6WANDelegationType string `json:"ipv6_wan_delegation_type,omitempty" validate:"omitempty,oneof=pd single_network none"` // pd|single_network|none
InterfaceMtu int `json:"interface_mtu,omitempty"` // ^(6[89]|[7-9][0-9]|[1-9][0-9]{2,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|65500)$
InterfaceMtuEnabled bool `json:"interface_mtu_enabled"`
InternetAccessEnabled bool `json:"internet_access_enabled"`
IsNAT bool `json:"is_nat"`
L2TpAllowWeakCiphers bool `json:"l2tp_allow_weak_ciphers"`
L2TpInterface string `json:"l2tp_interface,omitempty"` // wan|wan2
L2TpLocalWANIP string `json:"l2tp_local_wan_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
LocalPort int `json:"local_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
L2TpInterface string `json:"l2tp_interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
L2TpLocalWANIP string `json:"l2tp_local_wan_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
LocalPort int `json:"local_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
LteLanEnabled bool `json:"lte_lan_enabled"`
MACOverride string `json:"mac_override"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
MACOverride string `json:"mac_override" validate:"omitempty,mac"` // (^$|^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$)
MACOverrideEnabled bool `json:"mac_override_enabled"`
MdnsEnabled bool `json:"mdns_enabled"`
NATOutboundIPAddresses []NetworkNATOutboundIPAddresses `json:"nat_outbound_ip_addresses,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
NetworkGroup string `json:"networkgroup,omitempty"` // LAN[2-8]?
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
NetworkGroup string `json:"networkgroup,omitempty"` // LAN[2-8]?
NetworkIsolationEnabled bool `json:"network_isolation_enabled"`
OpenVPNConfiguration string `json:"openvpn_configuration,omitempty"`
OpenVPNConfigurationFilename string `json:"openvpn_configuration_filename,omitempty"`
OpenVPNEncryptionCipher string `json:"openvpn_encryption_cipher,omitempty"` // AES_256_GCM|AES_256_CBC|BF_CBC
OpenVPNInterface string `json:"openvpn_interface,omitempty"` // wan|wan2
OpenVPNLocalAddress string `json:"openvpn_local_address,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNLocalPort int `json:"openvpn_local_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
OpenVPNLocalWANIP string `json:"openvpn_local_wan_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNMode string `json:"openvpn_mode,omitempty"` // site-to-site|client|server
OpenVPNRemoteAddress string `json:"openvpn_remote_address,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNRemoteHost string `json:"openvpn_remote_host,omitempty"` // [^\"\' ]+|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNRemotePort int `json:"openvpn_remote_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
OpenVPNEncryptionCipher string `json:"openvpn_encryption_cipher,omitempty" validate:"omitempty,oneof=AES_256_GCM AES_256_CBC BF_CBC"` // AES_256_GCM|AES_256_CBC|BF_CBC
OpenVPNInterface string `json:"openvpn_interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
OpenVPNLocalAddress string `json:"openvpn_local_address,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNLocalPort int `json:"openvpn_local_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
OpenVPNLocalWANIP string `json:"openvpn_local_wan_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNMode string `json:"openvpn_mode,omitempty" validate:"omitempty,oneof=site-to-site client server"` // site-to-site|client|server
OpenVPNRemoteAddress string `json:"openvpn_remote_address,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNRemoteHost string `json:"openvpn_remote_host,omitempty"` // [^\"\' ]+|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
OpenVPNRemotePort int `json:"openvpn_remote_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
OpenVPNUsername string `json:"openvpn_username,omitempty"`
PptpcRequireMppe bool `json:"pptpc_require_mppe"`
PptpcRouteDistance int `json:"pptpc_route_distance,omitempty"` // ^[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]$|^$
PptpcServerIP string `json:"pptpc_server_ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|(?=^.{3,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)|^[a-zA-Z0-9-]{1,63}$
PptpcUsername string `json:"pptpc_username,omitempty"` // [^\"\' ]+
Priority int `json:"priority,omitempty"` // [1-4]
Purpose string `json:"purpose,omitempty"` // corporate|guest|remote-user-vpn|site-vpn|vlan-only|vpn-client|wan
PptpcRouteDistance int `json:"pptpc_route_distance,omitempty"` // ^[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]$|^$
PptpcServerIP string `json:"pptpc_server_ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|(?=^.{3,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)|^[a-zA-Z0-9-]{1,63}$
PptpcUsername string `json:"pptpc_username,omitempty"` // [^\"\' ]+
Priority int `json:"priority,omitempty"` // [1-4]
Purpose string `json:"purpose,omitempty" validate:"omitempty,oneof=corporate guest remote-user-vpn site-vpn vlan-only vpn-client wan"` // corporate|guest|remote-user-vpn|site-vpn|vlan-only|vpn-client|wan
RADIUSProfileID string `json:"radiusprofile_id"`
RemoteSiteID string `json:"remote_site_id"`
RemoteSiteSubnets []string `json:"remote_site_subnets,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|30)$|^$
@@ -173,7 +173,7 @@ type Network struct {
RequireMschapv2 bool `json:"require_mschapv2"`
RouteDistance int `json:"route_distance,omitempty"` // ^[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]$|^$
SdwanRemoteSiteID string `json:"sdwan_remote_site_id"`
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
SingleNetworkLan string `json:"single_network_lan,omitempty"`
UidPolicyEnabled bool `json:"uid_policy_enabled"`
UidPolicyName string `json:"uid_policy_name,omitempty"`
@@ -183,9 +183,9 @@ type Network struct {
UidVPNCustomRouting []string `json:"uid_vpn_custom_routing,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$
UidVPNDefaultDNSSuffix string `json:"uid_vpn_default_dns_suffix,omitempty"`
UidVPNMasqueradeEnabled bool `json:"uid_vpn_masquerade_enabled"`
UidVPNMaxConnectionTimeSeconds int `json:"uid_vpn_max_connection_time_seconds,omitempty"` // ^[1-9][0-9]*$
UidVPNMaxConnectionTimeSeconds int `json:"uid_vpn_max_connection_time_seconds,omitempty" validate:"omitempty,numeric_nonzero"` // ^[1-9][0-9]*$
UidVPNSyncPublicIP bool `json:"uid_vpn_sync_public_ip"`
UidVPNType string `json:"uid_vpn_type,omitempty"` // openvpn|wireguard
UidVPNType string `json:"uid_vpn_type,omitempty" validate:"omitempty,oneof=openvpn wireguard"` // openvpn|wireguard
UidWorkspaceUrl string `json:"uid_workspace_url,omitempty"`
UpnpLanEnabled bool `json:"upnp_lan_enabled"`
UserGroupID string `json:"usergroup_id"`
@@ -195,55 +195,55 @@ type Network struct {
VPNClientConfigurationRemoteIPOverrideEnabled bool `json:"vpn_client_configuration_remote_ip_override_enabled"`
VPNClientDefaultRoute bool `json:"vpn_client_default_route"`
VPNClientPullDNS bool `json:"vpn_client_pull_dns"`
VPNProtocol string `json:"vpn_protocol,omitempty"` // TCP|UDP
VPNType string `json:"vpn_type,omitempty"` // auto|ipsec-vpn|openvpn-client|openvpn-server|openvpn-vpn|pptp-client|l2tp-server|pptp-server|sdwan-hub-spoke-tunnel|sdwan-mesh-tunnel|uid-server|wireguard-server|wireguard-client
VrrpIPSubnetGw1 string `json:"vrrp_ip_subnet_gw1,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|30)$
VrrpIPSubnetGw2 string `json:"vrrp_ip_subnet_gw2,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|30)$
VrrpVrid int `json:"vrrp_vrid,omitempty"` // [1-9]|[1-9][0-9]
WANDHCPCos int `json:"wan_dhcp_cos,omitempty"` // [0-7]|^$
VPNProtocol string `json:"vpn_protocol,omitempty" validate:"omitempty,oneof=TCP UDP"` // TCP|UDP
VPNType string `json:"vpn_type,omitempty" validate:"omitempty,oneof=auto ipsec-vpn openvpn-client openvpn-server openvpn-vpn pptp-client l2tp-server pptp-server sdwan-hub-spoke-tunnel sdwan-mesh-tunnel uid-server wireguard-server wireguard-client"` // auto|ipsec-vpn|openvpn-client|openvpn-server|openvpn-vpn|pptp-client|l2tp-server|pptp-server|sdwan-hub-spoke-tunnel|sdwan-mesh-tunnel|uid-server|wireguard-server|wireguard-client
VrrpIPSubnetGw1 string `json:"vrrp_ip_subnet_gw1,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|30)$
VrrpIPSubnetGw2 string `json:"vrrp_ip_subnet_gw2,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|30)$
VrrpVrid int `json:"vrrp_vrid,omitempty"` // [1-9]|[1-9][0-9]
WANDHCPCos int `json:"wan_dhcp_cos,omitempty"` // [0-7]|^$
WANDHCPOptions []NetworkWANDHCPOptions `json:"wan_dhcp_options,omitempty"`
WANDHCPv6PDSize int `json:"wan_dhcpv6_pd_size,omitempty"` // ^(4[89]|5[0-9]|6[0-4])$|^$
WANDNS1 string `json:"wan_dns1"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNS2 string `json:"wan_dns2"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNS3 string `json:"wan_dns3"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNS4 string `json:"wan_dns4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNSPreference string `json:"wan_dns_preference,omitempty"` // auto|manual
WANDHCPv6PDSize int `json:"wan_dhcpv6_pd_size,omitempty"` // ^(4[89]|5[0-9]|6[0-4])$|^$
WANDNS1 string `json:"wan_dns1" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNS2 string `json:"wan_dns2" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNS3 string `json:"wan_dns3" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNS4 string `json:"wan_dns4" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
WANDNSPreference string `json:"wan_dns_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
WANDsliteRemoteHost string `json:"wan_dslite_remote_host,omitempty"`
WANEgressQOS int `json:"wan_egress_qos,omitempty"` // [1-7]|^$
WANGateway string `json:"wan_gateway,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
WANGatewayV6 string `json:"wan_gateway_v6"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIP string `json:"wan_ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
WANIPAliases []string `json:"wan_ip_aliases,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([8-9]|[1-2][0-9]|3[0-2])$|^$
WANIPV6 string `json:"wan_ipv6"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIPV6DNS1 string `json:"wan_ipv6_dns1"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIPV6DNS2 string `json:"wan_ipv6_dns2"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIPV6DNSPreference string `json:"wan_ipv6_dns_preference,omitempty"` // auto|manual
WANLoadBalanceType string `json:"wan_load_balance_type,omitempty"` // failover-only|weighted
WANLoadBalanceWeight int `json:"wan_load_balance_weight,omitempty"` // ^$|[1-9]|[1-9][0-9]
WANNetmask string `json:"wan_netmask,omitempty"` // ^((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))$
WANNetworkGroup string `json:"wan_networkgroup,omitempty"` // WAN[2]?|WAN_LTE_FAILOVER
WANEgressQOS int `json:"wan_egress_qos,omitempty"` // [1-7]|^$
WANGateway string `json:"wan_gateway,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
WANGatewayV6 string `json:"wan_gateway_v6" validate:"omitempty,ipv6"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIP string `json:"wan_ip,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
WANIPAliases []string `json:"wan_ip_aliases,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([8-9]|[1-2][0-9]|3[0-2])$|^$
WANIPV6 string `json:"wan_ipv6" validate:"omitempty,ipv6"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIPV6DNS1 string `json:"wan_ipv6_dns1" validate:"omitempty,ipv6"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIPV6DNS2 string `json:"wan_ipv6_dns2" validate:"omitempty,ipv6"` // ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$|^$
WANIPV6DNSPreference string `json:"wan_ipv6_dns_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
WANLoadBalanceType string `json:"wan_load_balance_type,omitempty" validate:"omitempty,oneof=failover-only weighted"` // failover-only|weighted
WANLoadBalanceWeight int `json:"wan_load_balance_weight,omitempty"` // ^$|[1-9]|[1-9][0-9]
WANNetmask string `json:"wan_netmask,omitempty"` // ^((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))$
WANNetworkGroup string `json:"wan_networkgroup,omitempty"` // WAN[2]?|WAN_LTE_FAILOVER
WANPppoePasswordEnabled bool `json:"wan_pppoe_password_enabled"`
WANPppoeUsernameEnabled bool `json:"wan_pppoe_username_enabled"`
WANPrefixlen int `json:"wan_prefixlen,omitempty"` // ^([1-9]|[1-8][0-9]|9[0-9]|1[01][0-9]|12[0-8])$|^$
WANProviderCapabilities NetworkWANProviderCapabilities `json:"wan_provider_capabilities,omitempty"`
WANSmartqDownRate int `json:"wan_smartq_down_rate,omitempty"` // [0-9]{1,6}|1000000
WANSmartqEnabled bool `json:"wan_smartq_enabled"`
WANSmartqUpRate int `json:"wan_smartq_up_rate,omitempty"` // [0-9]{1,6}|1000000
WANType string `json:"wan_type,omitempty"` // disabled|dhcp|static|pppoe|dslite
WANTypeV6 string `json:"wan_type_v6,omitempty"` // disabled|slaac|dhcpv6|static
WANUsername string `json:"wan_username,omitempty"` // [^"' ]+|^$
WANVLAN int `json:"wan_vlan,omitempty"` // [0-9]|[1-9][0-9]{1,2}|[1-3][0-9]{3}|40[0-8][0-9]|409[0-4]|^$
WANSmartqUpRate int `json:"wan_smartq_up_rate,omitempty"` // [0-9]{1,6}|1000000
WANType string `json:"wan_type,omitempty" validate:"omitempty,oneof=disabled dhcp static pppoe dslite"` // disabled|dhcp|static|pppoe|dslite
WANTypeV6 string `json:"wan_type_v6,omitempty" validate:"omitempty,oneof=disabled slaac dhcpv6 static"` // disabled|slaac|dhcpv6|static
WANUsername string `json:"wan_username,omitempty"` // [^"' ]+|^$
WANVLAN int `json:"wan_vlan,omitempty"` // [0-9]|[1-9][0-9]{1,2}|[1-3][0-9]{3}|40[0-8][0-9]|409[0-4]|^$
WANVLANEnabled bool `json:"wan_vlan_enabled"`
WireguardClientConfigurationFile string `json:"wireguard_client_configuration_file,omitempty"`
WireguardClientConfigurationFilename string `json:"wireguard_client_configuration_filename,omitempty"`
WireguardClientMode string `json:"wireguard_client_mode,omitempty"` // file|manual
WireguardClientMode string `json:"wireguard_client_mode,omitempty" validate:"omitempty,oneof=file manual"` // file|manual
WireguardClientPeerIP string `json:"wireguard_client_peer_ip,omitempty"`
WireguardClientPeerPort int `json:"wireguard_client_peer_port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$
WireguardClientPeerPublicKey string `json:"wireguard_client_peer_public_key,omitempty"`
WireguardClientPresharedKey string `json:"wireguard_client_preshared_key,omitempty"`
WireguardClientPresharedKeyEnabled bool `json:"wireguard_client_preshared_key_enabled"`
WireguardInterface string `json:"wireguard_interface,omitempty"` // wan|wan2
WireguardLocalWANIP string `json:"wireguard_local_wan_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
WireguardInterface string `json:"wireguard_interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
WireguardLocalWANIP string `json:"wireguard_local_wan_ip,omitempty"` // ^any$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
WireguardPublicKey string `json:"wireguard_public_key,omitempty"`
XAuthKey string `json:"x_auth_key,omitempty"`
XCaCrt string `json:"x_ca_crt,omitempty"`
@@ -343,8 +343,8 @@ func (dst *Network) UnmarshalJSON(b []byte) error {
}
type NetworkIGMPQuerierSwitches struct {
QuerierAddress string `json:"querier_address"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
SwitchMAC string `json:"switch_mac,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
QuerierAddress string `json:"querier_address" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
SwitchMAC string `json:"switch_mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
}
func (dst *NetworkIGMPQuerierSwitches) UnmarshalJSON(b []byte) error {
@@ -364,10 +364,10 @@ func (dst *NetworkIGMPQuerierSwitches) UnmarshalJSON(b []byte) error {
}
type NetworkNATOutboundIPAddresses struct {
IPAddress string `json:"ip_address"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
IPAddressPool []string `json:"ip_address_pool,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])-(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Mode string `json:"mode,omitempty"` // all|ip_address|ip_address_pool
WANNetworkGroup string `json:"wan_network_group,omitempty"` // WAN|WAN2
IPAddress string `json:"ip_address" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
IPAddressPool []string `json:"ip_address_pool,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])-(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Mode string `json:"mode,omitempty" validate:"omitempty,oneof=all ip_address ip_address_pool"` // all|ip_address|ip_address_pool
WANNetworkGroup string `json:"wan_network_group,omitempty" validate:"omitempty,oneof=WAN WAN2"` // WAN|WAN2
}
func (dst *NetworkNATOutboundIPAddresses) UnmarshalJSON(b []byte) error {
@@ -411,8 +411,8 @@ func (dst *NetworkWANDHCPOptions) UnmarshalJSON(b []byte) error {
}
type NetworkWANProviderCapabilities struct {
DownloadKilobitsPerSecond int `json:"download_kilobits_per_second,omitempty"` // ^[1-9][0-9]*$
UploadKilobitsPerSecond int `json:"upload_kilobits_per_second,omitempty"` // ^[1-9][0-9]*$
DownloadKilobitsPerSecond int `json:"download_kilobits_per_second,omitempty" validate:"omitempty,numeric_nonzero"` // ^[1-9][0-9]*$
UploadKilobitsPerSecond int `json:"upload_kilobits_per_second,omitempty" validate:"omitempty,numeric_nonzero"` // ^[1-9][0-9]*$
}
func (dst *NetworkWANProviderCapabilities) UnmarshalJSON(b []byte) error {

View File

@@ -29,16 +29,16 @@ type PortForward struct {
DestinationIPs []PortForwardDestinationIPs `json:"destination_ips,omitempty"`
DstPort string `json:"dst_port,omitempty"` // (([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]))+(,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])){0,14}
Enabled bool `json:"enabled"`
Fwd string `json:"fwd,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
FwdPort string `json:"fwd_port,omitempty"` // (([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]))+(,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])){0,14}
Fwd string `json:"fwd,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
FwdPort string `json:"fwd_port,omitempty"` // (([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]))+(,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])){0,14}
Log bool `json:"log"`
Name string `json:"name,omitempty"` // .{1,128}
PfwdInterface string `json:"pfwd_interface,omitempty"` // wan|wan2|both|all
Proto string `json:"proto,omitempty"` // tcp_udp|tcp|udp
Src string `json:"src,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])-(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|[1-2][0-9]|3[0-2])$|^!(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^!(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])-(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^!(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|[1-2][0-9]|3[0-2])$|^any$
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
PfwdInterface string `json:"pfwd_interface,omitempty" validate:"omitempty,oneof=wan wan2 both all"` // wan|wan2|both|all
Proto string `json:"proto,omitempty" validate:"omitempty,oneof=tcp_udp tcp udp"` // tcp_udp|tcp|udp
Src string `json:"src,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])-(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|[1-2][0-9]|3[0-2])$|^!(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^!(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])-(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^!(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|[1-2][0-9]|3[0-2])$|^any$
SrcFirewallGroupID string `json:"src_firewall_group_id"`
SrcLimitingEnabled bool `json:"src_limiting_enabled"`
SrcLimitingType string `json:"src_limiting_type,omitempty"` // ip|firewall_group
SrcLimitingType string `json:"src_limiting_type,omitempty" validate:"omitempty,oneof=ip firewall_group"` // ip|firewall_group
}
func (dst *PortForward) UnmarshalJSON(b []byte) error {
@@ -58,8 +58,8 @@ func (dst *PortForward) UnmarshalJSON(b []byte) error {
}
type PortForwardDestinationIPs struct {
DestinationIP string `json:"destination_ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^any$
Interface string `json:"interface,omitempty"` // wan|wan2
DestinationIP string `json:"destination_ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^any$
Interface string `json:"interface,omitempty" validate:"omitempty,oneof=wan wan2"` // wan|wan2
}
func (dst *PortForwardDestinationIPs) UnmarshalJSON(b []byte) error {

View File

@@ -26,13 +26,13 @@ type PortProfile struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
Autoneg bool `json:"autoneg"`
Dot1XCtrl string `json:"dot1x_ctrl,omitempty"` // auto|force_authorized|force_unauthorized|mac_based|multi_host
Dot1XIDleTimeout int `json:"dot1x_idle_timeout,omitempty"` // [0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]
EgressRateLimitKbps int `json:"egress_rate_limit_kbps,omitempty"` // 6[4-9]|[7-9][0-9]|[1-9][0-9]{2,6}
Dot1XCtrl string `json:"dot1x_ctrl,omitempty" validate:"omitempty,oneof=auto force_authorized force_unauthorized mac_based multi_host"` // auto|force_authorized|force_unauthorized|mac_based|multi_host
Dot1XIDleTimeout int `json:"dot1x_idle_timeout,omitempty"` // [0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]
EgressRateLimitKbps int `json:"egress_rate_limit_kbps,omitempty"` // 6[4-9]|[7-9][0-9]|[1-9][0-9]{2,6}
EgressRateLimitKbpsEnabled bool `json:"egress_rate_limit_kbps_enabled"`
ExcludedNetworkIDs []string `json:"excluded_networkconf_ids,omitempty"`
FecMode string `json:"fec_mode,omitempty"` // rs-fec|fc-fec|default|disabled
Forward string `json:"forward,omitempty"` // all|native|customize|disabled
FecMode string `json:"fec_mode,omitempty" validate:"omitempty,oneof=rs-fec fc-fec default disabled"` // rs-fec|fc-fec|default|disabled
Forward string `json:"forward,omitempty" validate:"omitempty,oneof=all native customize disabled"` // all|native|customize|disabled
FullDuplex bool `json:"full_duplex"`
Isolation bool `json:"isolation"`
LldpmedEnabled bool `json:"lldpmed_enabled"`
@@ -40,30 +40,30 @@ type PortProfile struct {
MulticastRouterNetworkIDs []string `json:"multicast_router_networkconf_ids,omitempty"`
NATiveNetworkID string `json:"native_networkconf_id"`
Name string `json:"name,omitempty"`
OpMode string `json:"op_mode,omitempty"` // switch
PoeMode string `json:"poe_mode,omitempty"` // auto|off
OpMode string `json:"op_mode,omitempty"` // switch
PoeMode string `json:"poe_mode,omitempty" validate:"omitempty,oneof=auto off"` // auto|off
PortKeepaliveEnabled bool `json:"port_keepalive_enabled"`
PortSecurityEnabled bool `json:"port_security_enabled"`
PortSecurityMACAddress []string `json:"port_security_mac_address,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PriorityQueue1Level int `json:"priority_queue1_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue2Level int `json:"priority_queue2_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue3Level int `json:"priority_queue3_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue4Level int `json:"priority_queue4_level,omitempty"` // [0-9]|[1-9][0-9]|100
PortSecurityMACAddress []string `json:"port_security_mac_address,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
PriorityQueue1Level int `json:"priority_queue1_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue2Level int `json:"priority_queue2_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue3Level int `json:"priority_queue3_level,omitempty"` // [0-9]|[1-9][0-9]|100
PriorityQueue4Level int `json:"priority_queue4_level,omitempty"` // [0-9]|[1-9][0-9]|100
QOSProfile PortProfileQOSProfile `json:"qos_profile,omitempty"`
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
Speed int `json:"speed,omitempty"` // 10|100|1000|2500|5000|10000|20000|25000|40000|50000|100000
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
Speed int `json:"speed,omitempty" validate:"omitempty,oneof=10 100 1000 2500 5000 10000 20000 25000 40000 50000 100000"` // 10|100|1000|2500|5000|10000|20000|25000|40000|50000|100000
StormctrlBroadcastastEnabled bool `json:"stormctrl_bcast_enabled"`
StormctrlBroadcastastLevel int `json:"stormctrl_bcast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlBroadcastastRate int `json:"stormctrl_bcast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StormctrlMcastEnabled bool `json:"stormctrl_mcast_enabled"`
StormctrlMcastLevel int `json:"stormctrl_mcast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlMcastRate int `json:"stormctrl_mcast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StormctrlType string `json:"stormctrl_type,omitempty"` // level|rate
StormctrlMcastLevel int `json:"stormctrl_mcast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlMcastRate int `json:"stormctrl_mcast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StormctrlType string `json:"stormctrl_type,omitempty" validate:"omitempty,oneof=level rate"` // level|rate
StormctrlUcastEnabled bool `json:"stormctrl_ucast_enabled"`
StormctrlUcastLevel int `json:"stormctrl_ucast_level,omitempty"` // [0-9]|[1-9][0-9]|100
StormctrlUcastRate int `json:"stormctrl_ucast_rate,omitempty"` // [0-9]|[1-9][0-9]{1,6}|1[0-3][0-9]{6}|14[0-7][0-9]{5}|148[0-7][0-9]{4}|14880000
StpPortMode bool `json:"stp_port_mode"`
TaggedVLANMgmt string `json:"tagged_vlan_mgmt,omitempty"` // auto|block_all|custom
TaggedVLANMgmt string `json:"tagged_vlan_mgmt,omitempty" validate:"omitempty,oneof=auto block_all custom"` // auto|block_all|custom
VoiceNetworkID string `json:"voice_networkconf_id"`
}
@@ -111,10 +111,10 @@ func (dst *PortProfile) UnmarshalJSON(b []byte) error {
}
type PortProfileQOSMarking struct {
CosCode int `json:"cos_code,omitempty"` // [0-7]
DscpCode int `json:"dscp_code,omitempty"` // 0|8|16|24|32|40|48|56|10|12|14|18|20|22|26|28|30|34|36|38|44|46
IPPrecedenceCode int `json:"ip_precedence_code,omitempty"` // [0-7]
Queue int `json:"queue,omitempty"` // [0-7]
CosCode int `json:"cos_code,omitempty"` // [0-7]
DscpCode int `json:"dscp_code,omitempty" validate:"omitempty,oneof=0 8 16 24 32 40 48 56 10 12 14 18 20 22 26 28 30 34 36 38 44 46"` // 0|8|16|24|32|40|48|56|10|12|14|18|20|22|26|28|30|34|36|38|44|46
IPPrecedenceCode int `json:"ip_precedence_code,omitempty"` // [0-7]
Queue int `json:"queue,omitempty"` // [0-7]
}
func (dst *PortProfileQOSMarking) UnmarshalJSON(b []byte) error {
@@ -201,7 +201,7 @@ func (dst *PortProfileQOSPolicies) UnmarshalJSON(b []byte) error {
type PortProfileQOSProfile struct {
QOSPolicies []PortProfileQOSPolicies `json:"qos_policies,omitempty"`
QOSProfileMode string `json:"qos_profile_mode,omitempty"` // custom|unifi_play|aes67_audio|crestron_audio_video|dante_audio|ndi_aes67_audio|ndi_dante_audio|qsys_audio_video|qsys_video_dante_audio|sdvoe_aes67_audio|sdvoe_dante_audio|shure_audio
QOSProfileMode string `json:"qos_profile_mode,omitempty" validate:"omitempty,oneof=custom unifi_play aes67_audio crestron_audio_video dante_audio ndi_aes67_audio ndi_dante_audio qsys_audio_video qsys_video_dante_audio sdvoe_aes67_audio sdvoe_dante_audio shure_audio"` // custom|unifi_play|aes67_audio|crestron_audio_video|dante_audio|ndi_aes67_audio|ndi_dante_audio|qsys_audio_video|qsys_video_dante_audio|sdvoe_aes67_audio|sdvoe_dante_audio|shure_audio
}
func (dst *PortProfileQOSProfile) UnmarshalJSON(b []byte) error {

View File

@@ -29,13 +29,13 @@ type RADIUSProfile struct {
AcctServers []RADIUSProfileAcctServers `json:"acct_servers,omitempty"`
AuthServers []RADIUSProfileAuthServers `json:"auth_servers,omitempty"`
InterimUpdateEnabled bool `json:"interim_update_enabled"`
InterimUpdateInterval int `json:"interim_update_interval,omitempty"` // ^([6-9][0-9]|[1-9][0-9]{2,3}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9][0-9]|86400)$
Name string `json:"name,omitempty"` // .{1,128}
InterimUpdateInterval int `json:"interim_update_interval,omitempty"` // ^([6-9][0-9]|[1-9][0-9]{2,3}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9][0-9]|86400)$
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
TlsEnabled bool `json:"tls_enabled"`
UseUsgAcctServer bool `json:"use_usg_acct_server"`
UseUsgAuthServer bool `json:"use_usg_auth_server"`
VLANEnabled bool `json:"vlan_enabled"`
VLANWLANMode string `json:"vlan_wlan_mode,omitempty"` // disabled|optional|required
VLANWLANMode string `json:"vlan_wlan_mode,omitempty" validate:"omitempty,oneof=disabled optional required"` // disabled|optional|required
XCaCrts []RADIUSProfileXCaCrts `json:"x_ca_crts,omitempty"`
XClientCrt string `json:"x_client_crt,omitempty"`
XClientCrtFilename string `json:"x_client_crt_filename,omitempty"`
@@ -64,8 +64,8 @@ func (dst *RADIUSProfile) UnmarshalJSON(b []byte) error {
}
type RADIUSProfileAcctServers struct {
IP string `json:"ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Port int `json:"port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$|^$
IP string `json:"ip,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Port int `json:"port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$|^$
XSecret string `json:"x_secret,omitempty"`
}
@@ -89,8 +89,8 @@ func (dst *RADIUSProfileAcctServers) UnmarshalJSON(b []byte) error {
}
type RADIUSProfileAuthServers struct {
IP string `json:"ip,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Port int `json:"port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$|^$
IP string `json:"ip,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Port int `json:"port,omitempty"` // ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])$|^$
XSecret string `json:"x_secret,omitempty"`
}

View File

@@ -26,15 +26,15 @@ type Routing struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
Enabled bool `json:"enabled"`
GatewayDevice string `json:"gateway_device,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
GatewayType string `json:"gateway_type,omitempty"` // default|switch
Name string `json:"name,omitempty"` // .{1,128}
StaticRouteDistance int `json:"static-route_distance,omitempty"` // ^[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]$|^$
StaticRouteInterface string `json:"static-route_interface"` // WAN1|WAN2|[\d\w]+|^$
StaticRouteNetwork string `json:"static-route_network,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$|^([a-fA-F0-9:]+\/(([1-9]|[1-8][0-9]|9[0-9]|1[01][0-9]|12[0-8])))$
StaticRouteNexthop string `json:"static-route_nexthop"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^([a-fA-F0-9:]+)$|^$
StaticRouteType string `json:"static-route_type,omitempty"` // nexthop-route|interface-route|blackhole
Type string `json:"type,omitempty"` // static-route
GatewayDevice string `json:"gateway_device,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
GatewayType string `json:"gateway_type,omitempty" validate:"omitempty,oneof=default switch"` // default|switch
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
StaticRouteDistance int `json:"static-route_distance,omitempty"` // ^[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]$|^$
StaticRouteInterface string `json:"static-route_interface"` // WAN1|WAN2|[\d\w]+|^$
StaticRouteNetwork string `json:"static-route_network,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$|^([a-fA-F0-9:]+\/(([1-9]|[1-8][0-9]|9[0-9]|1[01][0-9]|12[0-8])))$
StaticRouteNexthop string `json:"static-route_nexthop"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^([a-fA-F0-9:]+)$|^$
StaticRouteType string `json:"static-route_type,omitempty" validate:"omitempty,oneof=nexthop-route interface-route blackhole"` // nexthop-route|interface-route|blackhole
Type string `json:"type,omitempty"` // static-route
}
func (dst *Routing) UnmarshalJSON(b []byte) error {

View File

@@ -49,7 +49,7 @@ func (dst *ScheduleTask) UnmarshalJSON(b []byte) error {
}
type ScheduleTaskUpgradeTargets struct {
MAC string `json:"mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
MAC string `json:"mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
}
func (dst *ScheduleTaskUpgradeTargets) UnmarshalJSON(b []byte) error {

View File

@@ -29,10 +29,10 @@ type SettingBroadcast struct {
SoundAfterEnabled bool `json:"sound_after_enabled"`
SoundAfterResource string `json:"sound_after_resource,omitempty"`
SoundAfterType string `json:"sound_after_type,omitempty"` // sample|media
SoundAfterType string `json:"sound_after_type,omitempty" validate:"omitempty,oneof=sample media"` // sample|media
SoundBeforeEnabled bool `json:"sound_before_enabled"`
SoundBeforeResource string `json:"sound_before_resource,omitempty"`
SoundBeforeType string `json:"sound_before_type,omitempty"` // sample|media
SoundBeforeType string `json:"sound_before_type,omitempty" validate:"omitempty,oneof=sample media"` // sample|media
}
func (dst *SettingBroadcast) UnmarshalJSON(b []byte) error {

View File

@@ -27,7 +27,7 @@ type SettingDashboard struct {
Key string `json:"key"`
LayoutPreference string `json:"layout_preference,omitempty"` // auto|manual
LayoutPreference string `json:"layout_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
Widgets []SettingDashboardWidgets `json:"widgets,omitempty"`
}
@@ -49,7 +49,7 @@ func (dst *SettingDashboard) UnmarshalJSON(b []byte) error {
type SettingDashboardWidgets struct {
Enabled bool `json:"enabled"`
Name string `json:"name,omitempty"` // cybersecure|traffic_identification|wifi_technology|wifi_channels|wifi_client_experience|wifi_tx_retries|most_active_apps_aps_clients|most_active_apps_clients|most_active_aps_clients|most_active_apps_aps|most_active_apps|v2_most_active_aps|v2_most_active_clients|wifi_connectivity|ap_radio_density
Name string `json:"name,omitempty" validate:"omitempty,oneof=cybersecure traffic_identification wifi_technology wifi_channels wifi_client_experience wifi_tx_retries most_active_apps_aps_clients most_active_apps_clients most_active_aps_clients most_active_apps_aps most_active_apps v2_most_active_aps v2_most_active_clients wifi_connectivity ap_radio_density"` // cybersecure|traffic_identification|wifi_technology|wifi_channels|wifi_client_experience|wifi_tx_retries|most_active_apps_aps_clients|most_active_apps_clients|most_active_aps_clients|most_active_apps_aps|most_active_apps|v2_most_active_aps|v2_most_active_clients|wifi_connectivity|ap_radio_density
}
func (dst *SettingDashboardWidgets) UnmarshalJSON(b []byte) error {

View File

@@ -29,7 +29,7 @@ type SettingDoh struct {
CustomServers []SettingDohCustomServers `json:"custom_servers,omitempty"`
ServerNames []string `json:"server_names,omitempty"`
State string `json:"state,omitempty"` // off|auto|manual|custom
State string `json:"state,omitempty" validate:"omitempty,oneof=off auto manual custom"` // off|auto|manual|custom
}
func (dst *SettingDoh) UnmarshalJSON(b []byte) error {

View File

@@ -69,8 +69,8 @@ func (dst *SettingEtherLightingNetworkOverrides) UnmarshalJSON(b []byte) error {
}
type SettingEtherLightingSpeedOverrides struct {
Key string `json:"key,omitempty"` // FE|GbE|2.5GbE|5GbE|10GbE|25GbE|40GbE|100GbE
RawColorHex string `json:"raw_color_hex,omitempty"` // [0-9A-Fa-f]{6}
Key string `json:"key,omitempty" validate:"omitempty,oneof=FE GbE 2.5GbE 5GbE 10GbE 25GbE 40GbE 100GbE"` // FE|GbE|2.5GbE|5GbE|10GbE|25GbE|40GbE|100GbE
RawColorHex string `json:"raw_color_hex,omitempty"` // [0-9A-Fa-f]{6}
}
func (dst *SettingEtherLightingSpeedOverrides) UnmarshalJSON(b []byte) error {

View File

@@ -27,16 +27,16 @@ type SettingGlobalAp struct {
Key string `json:"key"`
ApExclusions []string `json:"ap_exclusions,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
NaChannelSize int `json:"na_channel_size,omitempty"` // 20|40|80|160
NaTxPower int `json:"na_tx_power,omitempty"` // [0-9]|[1-4][0-9]
NaTxPowerMode string `json:"na_tx_power_mode,omitempty"` // auto|medium|high|low|custom
NgChannelSize int `json:"ng_channel_size,omitempty"` // 20|40
NgTxPower int `json:"ng_tx_power,omitempty"` // [0-9]|[1-4][0-9]
NgTxPowerMode string `json:"ng_tx_power_mode,omitempty"` // auto|medium|high|low|custom
SixEChannelSize int `json:"6e_channel_size,omitempty"` // 20|40|80|160
SixETxPower int `json:"6e_tx_power,omitempty"` // [0-9]|[1-4][0-9]
SixETxPowerMode string `json:"6e_tx_power_mode,omitempty"` // auto|medium|high|low|custom
ApExclusions []string `json:"ap_exclusions,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
NaChannelSize int `json:"na_channel_size,omitempty" validate:"omitempty,oneof=20 40 80 160"` // 20|40|80|160
NaTxPower int `json:"na_tx_power,omitempty"` // [0-9]|[1-4][0-9]
NaTxPowerMode string `json:"na_tx_power_mode,omitempty" validate:"omitempty,oneof=auto medium high low custom"` // auto|medium|high|low|custom
NgChannelSize int `json:"ng_channel_size,omitempty" validate:"omitempty,oneof=20 40"` // 20|40
NgTxPower int `json:"ng_tx_power,omitempty"` // [0-9]|[1-4][0-9]
NgTxPowerMode string `json:"ng_tx_power_mode,omitempty" validate:"omitempty,oneof=auto medium high low custom"` // auto|medium|high|low|custom
SixEChannelSize int `json:"6e_channel_size,omitempty" validate:"omitempty,oneof=20 40 80 160"` // 20|40|80|160
SixETxPower int `json:"6e_tx_power,omitempty"` // [0-9]|[1-4][0-9]
SixETxPowerMode string `json:"6e_tx_power_mode,omitempty" validate:"omitempty,oneof=auto medium high low custom"` // auto|medium|high|low|custom
}
func (dst *SettingGlobalAp) UnmarshalJSON(b []byte) error {

View File

@@ -28,7 +28,7 @@ type SettingGlobalNat struct {
Key string `json:"key"`
ExcludedNetworkIDs []string `json:"excluded_network_ids,omitempty"`
Mode string `json:"mode,omitempty"` // auto|custom|off
Mode string `json:"mode,omitempty" validate:"omitempty,oneof=auto custom off"` // auto|custom|off
}
func (dst *SettingGlobalNat) UnmarshalJSON(b []byte) error {

View File

@@ -35,8 +35,8 @@ type SettingGlobalSwitch struct {
FlowctrlEnabled bool `json:"flowctrl_enabled"`
JumboframeEnabled bool `json:"jumboframe_enabled"`
RADIUSProfileID string `json:"radiusprofile_id"`
StpVersion string `json:"stp_version,omitempty"` // stp|rstp|disabled
SwitchExclusions []string `json:"switch_exclusions,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
StpVersion string `json:"stp_version,omitempty" validate:"omitempty,oneof=stp rstp disabled"` // stp|rstp|disabled
SwitchExclusions []string `json:"switch_exclusions,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
}
func (dst *SettingGlobalSwitch) UnmarshalJSON(b []byte) error {

View File

@@ -28,21 +28,21 @@ type SettingGuestAccess struct {
Key string `json:"key"`
AllowedSubnet string `json:"allowed_subnet_,omitempty"`
Auth string `json:"auth,omitempty"` // none|hotspot|facebook_wifi|custom
Auth string `json:"auth,omitempty" validate:"omitempty,oneof=none hotspot facebook_wifi custom"` // none|hotspot|facebook_wifi|custom
AuthUrl string `json:"auth_url,omitempty"`
AuthorizeUseSandbox bool `json:"authorize_use_sandbox"`
CustomIP string `json:"custom_ip"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
CustomIP string `json:"custom_ip" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
EcEnabled bool `json:"ec_enabled"`
Expire string `json:"expire,omitempty"` // [\d]+|custom
ExpireNumber int `json:"expire_number,omitempty"` // ^[1-9][0-9]{0,5}|1000000$
ExpireUnit int `json:"expire_unit,omitempty"` // 1|60|1440
Expire string `json:"expire,omitempty"` // [\d]+|custom
ExpireNumber int `json:"expire_number,omitempty"` // ^[1-9][0-9]{0,5}|1000000$
ExpireUnit int `json:"expire_unit,omitempty" validate:"omitempty,oneof=1 60 1440"` // 1|60|1440
FacebookAppID string `json:"facebook_app_id"`
FacebookEnabled bool `json:"facebook_enabled"`
FacebookScopeEmail bool `json:"facebook_scope_email"`
FacebookWifiBlockHttps bool `json:"facebook_wifi_block_https"`
FacebookWifiGwID string `json:"facebook_wifi_gw_id"`
FacebookWifiGwName string `json:"facebook_wifi_gw_name,omitempty"`
Gateway string `json:"gateway,omitempty"` // paypal|stripe|authorize|quickpay|merchantwarrior|ippay
Gateway string `json:"gateway,omitempty" validate:"omitempty,oneof=paypal stripe authorize quickpay merchantwarrior ippay"` // paypal|stripe|authorize|quickpay|merchantwarrior|ippay
GoogleClientID string `json:"google_client_id"`
GoogleDomain string `json:"google_domain,omitempty"`
GoogleEnabled bool `json:"google_enabled"`
@@ -58,21 +58,21 @@ type SettingGuestAccess struct {
PortalCustomizedBgImageEnabled bool `json:"portal_customized_bg_image_enabled"`
PortalCustomizedBgImageFilename string `json:"portal_customized_bg_image_filename,omitempty"`
PortalCustomizedBgImageTile bool `json:"portal_customized_bg_image_tile"`
PortalCustomizedBgType string `json:"portal_customized_bg_type,omitempty"` // color|image|gallery
PortalCustomizedBoxColor string `json:"portal_customized_box_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedBoxLinkColor string `json:"portal_customized_box_link_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedBoxOpacity int `json:"portal_customized_box_opacity,omitempty"` // ^[1-9][0-9]?$|^100$|^$
PortalCustomizedBoxRADIUS int `json:"portal_customized_box_radius,omitempty"` // [0-9]|[1-4][0-9]|50
PortalCustomizedBoxTextColor string `json:"portal_customized_box_text_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedButtonColor string `json:"portal_customized_button_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedBgType string `json:"portal_customized_bg_type,omitempty" validate:"omitempty,oneof=color image gallery"` // color|image|gallery
PortalCustomizedBoxColor string `json:"portal_customized_box_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedBoxLinkColor string `json:"portal_customized_box_link_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedBoxOpacity int `json:"portal_customized_box_opacity,omitempty"` // ^[1-9][0-9]?$|^100$|^$
PortalCustomizedBoxRADIUS int `json:"portal_customized_box_radius,omitempty"` // [0-9]|[1-4][0-9]|50
PortalCustomizedBoxTextColor string `json:"portal_customized_box_text_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedButtonColor string `json:"portal_customized_button_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedButtonText string `json:"portal_customized_button_text,omitempty"`
PortalCustomizedButtonTextColor string `json:"portal_customized_button_text_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedLanguages []string `json:"portal_customized_languages,omitempty"` // ^[a-z]{2}([_-][a-zA-Z]{2,4})*$
PortalCustomizedLinkColor string `json:"portal_customized_link_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedLogoEnabled bool `json:"portal_customized_logo_enabled"`
PortalCustomizedLogoFilename string `json:"portal_customized_logo_filename,omitempty"`
PortalCustomizedLogoPosition string `json:"portal_customized_logo_position,omitempty"` // left|center|right
PortalCustomizedLogoSize int `json:"portal_customized_logo_size,omitempty"` // 6[4-9]|[7-9][0-9]|1[0-8][0-9]|19[0-2]
PortalCustomizedLogoPosition string `json:"portal_customized_logo_position,omitempty" validate:"omitempty,oneof=left center right"` // left|center|right
PortalCustomizedLogoSize int `json:"portal_customized_logo_size,omitempty"` // 6[4-9]|[7-9][0-9]|1[0-8][0-9]|19[0-2]
PortalCustomizedSuccessText string `json:"portal_customized_success_text,omitempty"`
PortalCustomizedTextColor string `json:"portal_customized_text_color"` // ^#[a-zA-Z0-9]{6}$|^#[a-zA-Z0-9]{3}$|^$
PortalCustomizedTitle string `json:"portal_customized_title,omitempty"`
@@ -82,12 +82,12 @@ type SettingGuestAccess struct {
PortalCustomizedUnsplashAuthorUsername string `json:"portal_customized_unsplash_author_username,omitempty"`
PortalCustomizedWelcomeText string `json:"portal_customized_welcome_text,omitempty"`
PortalCustomizedWelcomeTextEnabled bool `json:"portal_customized_welcome_text_enabled"`
PortalCustomizedWelcomeTextPosition string `json:"portal_customized_welcome_text_position,omitempty"` // under_logo|above_boxes
PortalCustomizedWelcomeTextPosition string `json:"portal_customized_welcome_text_position,omitempty" validate:"omitempty,oneof=under_logo above_boxes"` // under_logo|above_boxes
PortalEnabled bool `json:"portal_enabled"`
PortalHostname string `json:"portal_hostname"` // ^[a-zA-Z0-9.-]+$|^$
PortalUseHostname bool `json:"portal_use_hostname"`
QuickpayTestmode bool `json:"quickpay_testmode"`
RADIUSAuthType string `json:"radius_auth_type,omitempty"` // chap|mschapv2
RADIUSAuthType string `json:"radius_auth_type,omitempty" validate:"omitempty,oneof=chap mschapv2"` // chap|mschapv2
RADIUSDisconnectEnabled bool `json:"radius_disconnect_enabled"`
RADIUSDisconnectPort int `json:"radius_disconnect_port,omitempty"` // [1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]
RADIUSEnabled bool `json:"radius_enabled"`
@@ -97,9 +97,9 @@ type SettingGuestAccess struct {
RedirectToHttps bool `json:"redirect_to_https"`
RedirectUrl string `json:"redirect_url,omitempty"`
RestrictedDNSEnabled bool `json:"restricted_dns_enabled"`
RestrictedDNSServers []string `json:"restricted_dns_servers,omitempty"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
RestrictedDNSServers []string `json:"restricted_dns_servers,omitempty" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
RestrictedSubnet string `json:"restricted_subnet_,omitempty"`
TemplateEngine string `json:"template_engine,omitempty"` // jsp|angular
TemplateEngine string `json:"template_engine,omitempty" validate:"omitempty,oneof=jsp angular"` // jsp|angular
VoucherCustomized bool `json:"voucher_customized"`
VoucherEnabled bool `json:"voucher_enabled"`
WechatAppID string `json:"wechat_app_id"`

View File

@@ -29,14 +29,14 @@ type SettingIps struct {
AdBlockingConfigurations []SettingIpsAdBlockingConfigurations `json:"ad_blocking_configurations,omitempty"`
AdBlockingEnabled bool `json:"ad_blocking_enabled"`
AdvancedFilteringPreference string `json:"advanced_filtering_preference,omitempty"` // |manual|disabled
AdvancedFilteringPreference string `json:"advanced_filtering_preference,omitempty" validate:"omitempty,oneof=manual disabled"` // |manual|disabled
DNSFiltering bool `json:"dns_filtering"`
DNSFilters []SettingIpsDNSFilters `json:"dns_filters,omitempty"`
EnabledCategories []string `json:"enabled_categories,omitempty"` // emerging-activex|emerging-attackresponse|botcc|emerging-chat|ciarmy|compromised|emerging-dns|emerging-dos|dshield|emerging-exploit|emerging-ftp|emerging-games|emerging-icmp|emerging-icmpinfo|emerging-imap|emerging-inappropriate|emerging-info|emerging-malware|emerging-misc|emerging-mobile|emerging-netbios|emerging-p2p|emerging-policy|emerging-pop3|emerging-rpc|emerging-scada|emerging-scan|emerging-shellcode|emerging-smtp|emerging-snmp|emerging-sql|emerging-telnet|emerging-tftp|tor|emerging-useragent|emerging-voip|emerging-webapps|emerging-webclient|emerging-webserver|emerging-worm|exploit-kit|adware-pup|botcc-portgrouped|phishing|threatview-cs-c2|3coresec|chat|coinminer|current-events|drop|hunting|icmp-info|inappropriate|info|ja3|policy|scada|dark-web-blocker-list|malicious-hosts
EnabledCategories []string `json:"enabled_categories,omitempty" validate:"omitempty,oneof=emerging-activex emerging-attackresponse botcc emerging-chat ciarmy compromised emerging-dns emerging-dos dshield emerging-exploit emerging-ftp emerging-games emerging-icmp emerging-icmpinfo emerging-imap emerging-inappropriate emerging-info emerging-malware emerging-misc emerging-mobile emerging-netbios emerging-p2p emerging-policy emerging-pop3 emerging-rpc emerging-scada emerging-scan emerging-shellcode emerging-smtp emerging-snmp emerging-sql emerging-telnet emerging-tftp tor emerging-useragent emerging-voip emerging-webapps emerging-webclient emerging-webserver emerging-worm exploit-kit adware-pup botcc-portgrouped phishing threatview-cs-c2 3coresec chat coinminer current-events drop hunting icmp-info inappropriate info ja3 policy scada dark-web-blocker-list malicious-hosts"` // emerging-activex|emerging-attackresponse|botcc|emerging-chat|ciarmy|compromised|emerging-dns|emerging-dos|dshield|emerging-exploit|emerging-ftp|emerging-games|emerging-icmp|emerging-icmpinfo|emerging-imap|emerging-inappropriate|emerging-info|emerging-malware|emerging-misc|emerging-mobile|emerging-netbios|emerging-p2p|emerging-policy|emerging-pop3|emerging-rpc|emerging-scada|emerging-scan|emerging-shellcode|emerging-smtp|emerging-snmp|emerging-sql|emerging-telnet|emerging-tftp|tor|emerging-useragent|emerging-voip|emerging-webapps|emerging-webclient|emerging-webserver|emerging-worm|exploit-kit|adware-pup|botcc-portgrouped|phishing|threatview-cs-c2|3coresec|chat|coinminer|current-events|drop|hunting|icmp-info|inappropriate|info|ja3|policy|scada|dark-web-blocker-list|malicious-hosts
EnabledNetworks []string `json:"enabled_networks,omitempty"`
Honeypot []SettingIpsHoneypot `json:"honeypot,omitempty"`
HoneypotEnabled bool `json:"honeypot_enabled"`
IPsMode string `json:"ips_mode,omitempty"` // ids|ips|ipsInline|disabled
IPsMode string `json:"ips_mode,omitempty" validate:"omitempty,oneof=ids ips ipsInline disabled"` // ids|ips|ipsInline|disabled
MemoryOptimized bool `json:"memory_optimized"`
RestrictTorrents bool `json:"restrict_torrents"`
Suppression SettingIpsSuppression `json:"suppression,omitempty"`
@@ -84,7 +84,7 @@ type SettingIpsAlerts struct {
ID int `json:"id,omitempty"`
Signature string `json:"signature,omitempty"`
Tracking []SettingIpsTracking `json:"tracking,omitempty"`
Type string `json:"type,omitempty"` // all|track
Type string `json:"type,omitempty" validate:"omitempty,oneof=all track"` // all|track
}
func (dst *SettingIpsAlerts) UnmarshalJSON(b []byte) error {
@@ -113,10 +113,10 @@ type SettingIpsDNSFilters struct {
BlockedSites []string `json:"blocked_sites,omitempty"` // ^[a-zA-Z0-9.-]+$|^$
BlockedTld []string `json:"blocked_tld,omitempty"` // ^[a-zA-Z0-9.-]+$|^$
Description string `json:"description,omitempty"`
Filter string `json:"filter,omitempty"` // none|work|family
Filter string `json:"filter,omitempty" validate:"omitempty,oneof=none work family"` // none|work|family
Name string `json:"name,omitempty"`
NetworkID string `json:"network_id"`
Version string `json:"version,omitempty"` // v4|v6
Version string `json:"version,omitempty" validate:"omitempty,oneof=v4 v6"` // v4|v6
}
func (dst *SettingIpsDNSFilters) UnmarshalJSON(b []byte) error {
@@ -138,7 +138,7 @@ func (dst *SettingIpsDNSFilters) UnmarshalJSON(b []byte) error {
type SettingIpsHoneypot struct {
IPAddress string `json:"ip_address,omitempty"`
NetworkID string `json:"network_id"`
Version string `json:"version,omitempty"` // v4|v6
Version string `json:"version,omitempty" validate:"omitempty,oneof=v4 v6"` // v4|v6
}
func (dst *SettingIpsHoneypot) UnmarshalJSON(b []byte) error {
@@ -179,8 +179,8 @@ func (dst *SettingIpsSuppression) UnmarshalJSON(b []byte) error {
}
type SettingIpsTracking struct {
Direction string `json:"direction,omitempty"` // both|src|dest
Mode string `json:"mode,omitempty"` // ip|subnet|network
Direction string `json:"direction,omitempty" validate:"omitempty,oneof=both src dest"` // both|src|dest
Mode string `json:"mode,omitempty" validate:"omitempty,oneof=ip subnet network"` // ip|subnet|network
Value string `json:"value,omitempty"`
}
@@ -201,8 +201,8 @@ func (dst *SettingIpsTracking) UnmarshalJSON(b []byte) error {
}
type SettingIpsWhitelist struct {
Direction string `json:"direction,omitempty"` // both|src|dest
Mode string `json:"mode,omitempty"` // ip|subnet|network
Direction string `json:"direction,omitempty" validate:"omitempty,oneof=both src dest"` // both|src|dest
Mode string `json:"mode,omitempty" validate:"omitempty,oneof=ip subnet network"` // ip|subnet|network
Value string `json:"value,omitempty"`
}

View File

@@ -44,7 +44,7 @@ type SettingMgmt struct {
XSshEnabled bool `json:"x_ssh_enabled"`
XSshKeys []SettingMgmtXSshKeys `json:"x_ssh_keys,omitempty"`
XSshMd5Passwd string `json:"x_ssh_md5passwd,omitempty"`
XSshPassword string `json:"x_ssh_password,omitempty"` // .{1,128}
XSshPassword string `json:"x_ssh_password,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
XSshSha512Passwd string `json:"x_ssh_sha512passwd,omitempty"`
XSshUsername string `json:"x_ssh_username,omitempty"` // ^[_A-Za-z0-9][-_.A-Za-z0-9]{0,29}$
}

View File

@@ -34,10 +34,10 @@ type SettingNetflow struct {
NetworkIDs []string `json:"network_ids,omitempty"`
Port int `json:"port,omitempty"` // 102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]
RefreshRate int `json:"refresh_rate,omitempty"`
SamplingMode string `json:"sampling_mode,omitempty"` // off|hash|random|deterministic
SamplingRate int `json:"sampling_rate,omitempty"` // [2-9]|[1-9][0-9]{1,3}|1[0-5][0-9]{3}|16[0-2][0-9]{2}|163[0-7][0-9]|1638[0-3]|^$
Server string `json:"server,omitempty"` // .{0,252}[^\.]$
Version int `json:"version,omitempty"` // 5|9|10
SamplingMode string `json:"sampling_mode,omitempty" validate:"omitempty,oneof=off hash random deterministic"` // off|hash|random|deterministic
SamplingRate int `json:"sampling_rate,omitempty"` // [2-9]|[1-9][0-9]{1,3}|1[0-5][0-9]{3}|16[0-2][0-9]{2}|163[0-7][0-9]|1638[0-3]|^$
Server string `json:"server,omitempty"` // .{0,252}[^\.]$
Version int `json:"version,omitempty" validate:"omitempty,oneof=5 9 10"` // 5|9|10
}
func (dst *SettingNetflow) UnmarshalJSON(b []byte) error {

View File

@@ -31,7 +31,7 @@ type SettingNtp struct {
NtpServer2 string `json:"ntp_server_2,omitempty"`
NtpServer3 string `json:"ntp_server_3,omitempty"`
NtpServer4 string `json:"ntp_server_4,omitempty"`
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
}
func (dst *SettingNtp) UnmarshalJSON(b []byte) error {

View File

@@ -30,17 +30,17 @@ type SettingRadioAi struct {
AutoAdjustChannelsToCountry bool `json:"auto_adjust_channels_to_country"`
Channels6E []int `json:"channels_6e,omitempty"` // [1-9]|[1-2][0-9]|3[3-9]|[4-5][0-9]|6[0-1]|6[5-9]|[7-8][0-9]|9[0-3]|9[7-9]|1[0-1][0-9]|12[0-5]|129|1[3-4][0-9]|15[0-7]|16[1-9]|1[7-8][0-9]|19[3-9]|2[0-1][0-9]|22[0-1]|22[5-9]|233
ChannelsBlacklist []SettingRadioAiChannelsBlacklist `json:"channels_blacklist,omitempty"`
ChannelsNa []int `json:"channels_na,omitempty"` // 34|36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|169
ChannelsNg []int `json:"channels_ng,omitempty"` // 1|2|3|4|5|6|7|8|9|10|11|12|13|14
ChannelsNa []int `json:"channels_na,omitempty" validate:"omitempty,oneof=34 36 38 40 42 44 46 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 144 149 153 157 161 165 169"` // 34|36|38|40|42|44|46|48|52|56|60|64|100|104|108|112|116|120|124|128|132|136|140|144|149|153|157|161|165|169
ChannelsNg []int `json:"channels_ng,omitempty" validate:"omitempty,oneof=1 2 3 4 5 6 7 8 9 10 11 12 13 14"` // 1|2|3|4|5|6|7|8|9|10|11|12|13|14
CronExpr string `json:"cron_expr,omitempty"`
Default bool `json:"default"`
Enabled bool `json:"enabled"`
ExcludeDevices []string `json:"exclude_devices,omitempty"` // ([0-9a-z]{2}:){5}[0-9a-z]{2}
HtModesNa []int `json:"ht_modes_na,omitempty"` // ^(20|40|80|160)$
HtModesNg []int `json:"ht_modes_ng,omitempty"` // ^(20|40)$
Optimize []string `json:"optimize,omitempty"` // channel|power
Radios []string `json:"radios,omitempty"` // na|ng
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
ExcludeDevices []string `json:"exclude_devices,omitempty"` // ([0-9a-z]{2}:){5}[0-9a-z]{2}
HtModesNa []int `json:"ht_modes_na,omitempty" validate:"omitempty,oneof=20 40 80 160"` // ^(20|40|80|160)$
HtModesNg []int `json:"ht_modes_ng,omitempty" validate:"omitempty,oneof=20 40"` // ^(20|40)$
Optimize []string `json:"optimize,omitempty" validate:"omitempty,oneof=channel power"` // channel|power
Radios []string `json:"radios,omitempty" validate:"omitempty,oneof=na ng"` // na|ng
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
UseXy bool `json:"useXY"`
}
@@ -87,9 +87,9 @@ func (dst *SettingRadioAi) UnmarshalJSON(b []byte) error {
}
type SettingRadioAiChannelsBlacklist struct {
Channel int `json:"channel,omitempty"` // [1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9]|2[0-1][0-9]|22[0-1]|22[5-9]|233
ChannelWidth int `json:"channel_width,omitempty"` // 20|40|80|160|240|320
Radio string `json:"radio,omitempty"` // na|ng|6e
Channel int `json:"channel,omitempty"` // [1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9]|2[0-1][0-9]|22[0-1]|22[5-9]|233
ChannelWidth int `json:"channel_width,omitempty" validate:"omitempty,oneof=20 40 80 160 240 320"` // 20|40|80|160|240|320
Radio string `json:"radio,omitempty" validate:"omitempty,oneof=na ng 6e"` // na|ng|6e
}
func (dst *SettingRadioAiChannelsBlacklist) UnmarshalJSON(b []byte) error {

View File

@@ -27,7 +27,7 @@ type SettingRsyslogd struct {
Key string `json:"key"`
Contents []string `json:"contents,omitempty"` // device|client|firewall_default_policy|triggers|updates|admin_activity|critical|security_detections|vpn
Contents []string `json:"contents,omitempty" validate:"omitempty,oneof=device client firewall_default_policy triggers updates admin_activity critical security_detections vpn"` // device|client|firewall_default_policy|triggers|updates|admin_activity|critical|security_detections|vpn
Debug bool `json:"debug"`
Enabled bool `json:"enabled"`
IP string `json:"ip,omitempty"`

View File

@@ -27,7 +27,7 @@ type SettingSnmp struct {
Key string `json:"key"`
Community string `json:"community,omitempty"` // .{1,256}
Community string `json:"community,omitempty" validate:"omitempty,gte=1,lte=256"` // .{1,256}
Enabled bool `json:"enabled"`
EnabledV3 bool `json:"enabledV3"`
Username string `json:"username,omitempty"` // [a-zA-Z0-9_-]{1,30}

View File

@@ -27,7 +27,7 @@ type SettingSslInspection struct {
Key string `json:"key"`
State string `json:"state,omitempty"` // off|simple|advanced
State string `json:"state,omitempty" validate:"omitempty,oneof=off simple advanced"` // off|simple|advanced
}
func (dst *SettingSslInspection) UnmarshalJSON(b []byte) error {

View File

@@ -27,8 +27,8 @@ type SettingSuperFwupdate struct {
Key string `json:"key"`
ControllerChannel string `json:"controller_channel,omitempty"` // internal|alpha|beta|release-candidate|release
FirmwareChannel string `json:"firmware_channel,omitempty"` // internal|alpha|beta|release-candidate|release
ControllerChannel string `json:"controller_channel,omitempty" validate:"omitempty,oneof=internal alpha beta release-candidate release"` // internal|alpha|beta|release-candidate|release
FirmwareChannel string `json:"firmware_channel,omitempty" validate:"omitempty,oneof=internal alpha beta release-candidate release"` // internal|alpha|beta|release-candidate|release
SsoEnabled bool `json:"sso_enabled"`
}

View File

@@ -27,7 +27,7 @@ type SettingSuperMail struct {
Key string `json:"key"`
Provider string `json:"provider,omitempty"` // smtp|cloud|disabled
Provider string `json:"provider,omitempty" validate:"omitempty,oneof=smtp cloud disabled"` // smtp|cloud|disabled
}
func (dst *SettingSuperMail) UnmarshalJSON(b []byte) error {

View File

@@ -36,7 +36,7 @@ type SettingSuperMgmt struct {
AutobackupGcsCertificatePath string `json:"autobackup_gcs_certificate_path,omitempty"`
AutobackupLocalPath string `json:"autobackup_local_path,omitempty"`
AutobackupMaxFiles int `json:"autobackup_max_files,omitempty"`
AutobackupPostActions []string `json:"autobackup_post_actions,omitempty"` // copy_local|copy_s3|copy_gcs|copy_cloud
AutobackupPostActions []string `json:"autobackup_post_actions,omitempty" validate:"omitempty,oneof=copy_local copy_s3 copy_gcs copy_cloud"` // copy_local|copy_s3|copy_gcs|copy_cloud
AutobackupS3AccessKey string `json:"autobackup_s3_access_key,omitempty"`
AutobackupS3AccessSecret string `json:"autobackup_s3_access_secret,omitempty"`
AutobackupS3Bucket string `json:"autobackup_s3_bucket,omitempty"`
@@ -51,7 +51,7 @@ type SettingSuperMgmt struct {
ContactInfoShippingAddress2 string `json:"contact_info_shipping_address_2,omitempty"`
ContactInfoState string `json:"contact_info_state,omitempty"`
ContactInfoZip string `json:"contact_info_zip,omitempty"`
DataRetentionSettingPreference string `json:"data_retention_setting_preference,omitempty"` // auto|manual
DataRetentionSettingPreference string `json:"data_retention_setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
DataRetentionTimeInHoursFor5MinutesScale int `json:"data_retention_time_in_hours_for_5minutes_scale,omitempty"`
DataRetentionTimeInHoursForDailyScale int `json:"data_retention_time_in_hours_for_daily_scale,omitempty"`
DataRetentionTimeInHoursForHourlyScale int `json:"data_retention_time_in_hours_for_hourly_scale,omitempty"`
@@ -63,14 +63,14 @@ type SettingSuperMgmt struct {
GoogleMapsApiKey string `json:"google_maps_api_key,omitempty"`
ImageMapsUseGoogleEngine bool `json:"image_maps_use_google_engine"`
LedEnabled bool `json:"led_enabled"`
LiveChat string `json:"live_chat,omitempty"` // disabled|super-only|everyone
LiveUpdates string `json:"live_updates,omitempty"` // disabled|live|auto
LiveChat string `json:"live_chat,omitempty" validate:"omitempty,oneof=disabled super-only everyone"` // disabled|super-only|everyone
LiveUpdates string `json:"live_updates,omitempty" validate:"omitempty,oneof=disabled live auto"` // disabled|live|auto
MinimumUsableHdSpace int `json:"minimum_usable_hd_space,omitempty"`
MinimumUsableSdSpace int `json:"minimum_usable_sd_space,omitempty"`
MultipleSitesEnabled bool `json:"multiple_sites_enabled"`
OverrideInformHost bool `json:"override_inform_host"`
OverrideInformHostLocation string `json:"override_inform_host_location,omitempty"`
StoreEnabled string `json:"store_enabled,omitempty"` // disabled|super-only|everyone
StoreEnabled string `json:"store_enabled,omitempty" validate:"omitempty,oneof=disabled super-only everyone"` // disabled|super-only|everyone
TimeSeriesPerClientStatsEnabled bool `json:"time_series_per_client_stats_enabled"`
XSshPassword string `json:"x_ssh_password,omitempty"`
XSshUsername string `json:"x_ssh_username,omitempty"`

View File

@@ -27,35 +27,35 @@ type SettingUsg struct {
Key string `json:"key"`
ArpCacheBaseReachable int `json:"arp_cache_base_reachable,omitempty"` // ^$|^[1-9]{1}[0-9]{0,4}$
ArpCacheTimeout string `json:"arp_cache_timeout,omitempty"` // normal|min-dhcp-lease|custom
ArpCacheBaseReachable int `json:"arp_cache_base_reachable,omitempty"` // ^$|^[1-9]{1}[0-9]{0,4}$
ArpCacheTimeout string `json:"arp_cache_timeout,omitempty" validate:"omitempty,oneof=normal min-dhcp-lease custom"` // normal|min-dhcp-lease|custom
BroadcastPing bool `json:"broadcast_ping"`
DHCPDHostfileUpdate bool `json:"dhcpd_hostfile_update"`
DHCPDUseDNSmasq bool `json:"dhcpd_use_dnsmasq"`
DHCPRelayAgentsPackets string `json:"dhcp_relay_agents_packets"` // append|discard|forward|replace|^$
DHCPRelayHopCount int `json:"dhcp_relay_hop_count,omitempty"` // ([1-9]|[1-8][0-9]|9[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|^$
DHCPRelayMaxSize int `json:"dhcp_relay_max_size,omitempty"` // (6[4-9]|[7-9][0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|1[0-3][0-9]{2}|1400)|^$
DHCPRelayPort int `json:"dhcp_relay_port,omitempty"` // [1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]|^$
DHCPRelayServer1 string `json:"dhcp_relay_server_1"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer2 string `json:"dhcp_relay_server_2"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer3 string `json:"dhcp_relay_server_3"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer4 string `json:"dhcp_relay_server_4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer5 string `json:"dhcp_relay_server_5"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayAgentsPackets string `json:"dhcp_relay_agents_packets" validate:"omitempty,oneof=append discard forward replace"` // append|discard|forward|replace|^$
DHCPRelayHopCount int `json:"dhcp_relay_hop_count,omitempty"` // ([1-9]|[1-8][0-9]|9[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|^$
DHCPRelayMaxSize int `json:"dhcp_relay_max_size,omitempty"` // (6[4-9]|[7-9][0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|1[0-3][0-9]{2}|1400)|^$
DHCPRelayPort int `json:"dhcp_relay_port,omitempty"` // [1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]|^$
DHCPRelayServer1 string `json:"dhcp_relay_server_1" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer2 string `json:"dhcp_relay_server_2" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer3 string `json:"dhcp_relay_server_3" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer4 string `json:"dhcp_relay_server_4" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DHCPRelayServer5 string `json:"dhcp_relay_server_5" validate:"omitempty,ipv4"` // ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DNSVerification SettingUsgDNSVerification `json:"dns_verification,omitempty"`
DNSmasqAllServers bool `json:"dnsmasq_all_servers"`
EchoServer string `json:"echo_server,omitempty"` // [^\"\' ]{1,255}
FtpModule bool `json:"ftp_module"`
GeoIPFilteringBlock string `json:"geo_ip_filtering_block,omitempty"` // block|allow
GeoIPFilteringCountries string `json:"geo_ip_filtering_countries,omitempty"` // ^([A-Z]{2})?(,[A-Z]{2}){0,149}$
GeoIPFilteringBlock string `json:"geo_ip_filtering_block,omitempty" validate:"omitempty,oneof=block allow"` // block|allow
GeoIPFilteringCountries string `json:"geo_ip_filtering_countries,omitempty"` // ^([A-Z]{2})?(,[A-Z]{2}){0,149}$
GeoIPFilteringEnabled bool `json:"geo_ip_filtering_enabled"`
GeoIPFilteringTrafficDirection string `json:"geo_ip_filtering_traffic_direction,omitempty"` // ^(both|ingress|egress)$
GeoIPFilteringTrafficDirection string `json:"geo_ip_filtering_traffic_direction,omitempty" validate:"omitempty,oneof=both ingress egress"` // ^(both|ingress|egress)$
GreModule bool `json:"gre_module"`
H323Module bool `json:"h323_module"`
ICMPTimeout int `json:"icmp_timeout,omitempty"`
LldpEnableAll bool `json:"lldp_enable_all"`
MdnsEnabled bool `json:"mdns_enabled"`
MssClamp string `json:"mss_clamp,omitempty"` // auto|custom|disabled
MssClampMss int `json:"mss_clamp_mss,omitempty"` // [1-9][0-9]{2,3}
MssClamp string `json:"mss_clamp,omitempty" validate:"omitempty,oneof=auto custom disabled"` // auto|custom|disabled
MssClampMss int `json:"mss_clamp_mss,omitempty"` // [1-9][0-9]{2,3}
OffloadAccounting bool `json:"offload_accounting"`
OffloadL2Blocking bool `json:"offload_l2_blocking"`
OffloadSch bool `json:"offload_sch"`
@@ -74,14 +74,14 @@ type SettingUsg struct {
TCPSynSentTimeout int `json:"tcp_syn_sent_timeout,omitempty"`
TCPTimeWaitTimeout int `json:"tcp_time_wait_timeout,omitempty"`
TFTPModule bool `json:"tftp_module"`
TimeoutSettingPreference string `json:"timeout_setting_preference,omitempty"` // auto|manual
TimeoutSettingPreference string `json:"timeout_setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
UDPOtherTimeout int `json:"udp_other_timeout,omitempty"`
UDPStreamTimeout int `json:"udp_stream_timeout,omitempty"`
UnbindWANMonitors bool `json:"unbind_wan_monitors"`
UpnpEnabled bool `json:"upnp_enabled"`
UpnpNATPmpEnabled bool `json:"upnp_nat_pmp_enabled"`
UpnpSecureMode bool `json:"upnp_secure_mode"`
UpnpWANInterface string `json:"upnp_wan_interface,omitempty"` // WAN|WAN2
UpnpWANInterface string `json:"upnp_wan_interface,omitempty" validate:"omitempty,oneof=WAN WAN2"` // WAN|WAN2
}
func (dst *SettingUsg) UnmarshalJSON(b []byte) error {
@@ -139,7 +139,7 @@ type SettingUsgDNSVerification struct {
Domain string `json:"domain,omitempty"`
PrimaryDNSServer string `json:"primary_dns_server,omitempty"`
SecondaryDNSServer string `json:"secondary_dns_server,omitempty"`
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
}
func (dst *SettingUsgDNSVerification) UnmarshalJSON(b []byte) error {

View File

@@ -26,7 +26,7 @@ type SpatialRecord struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
Devices []SpatialRecordDevices `json:"devices,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *SpatialRecord) UnmarshalJSON(b []byte) error {
@@ -46,7 +46,7 @@ func (dst *SpatialRecord) UnmarshalJSON(b []byte) error {
}
type SpatialRecordDevices struct {
MAC string `json:"mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
MAC string `json:"mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Position SpatialRecordPosition `json:"position,omitempty"`
}

View File

@@ -84,6 +84,15 @@ func (m *Meta) error() error {
return nil
}
type validationMode string
const (
SoftValidation validationMode = "soft"
HardValidation validationMode = "hard"
DisableValidation validationMode = "disable"
DefaultValidation validationMode = SoftValidation // TODO: change to hard in next major version
)
type ClientConfig struct {
URL string `validate:"required,http_url"`
APIKey string `validate:"required_without_all=User Pass"`
@@ -96,6 +105,7 @@ type ClientConfig struct {
UserAgent string
ErrorHandler ResponseErrorHandler
UseLocking bool
ValidationMode validationMode `validate:"omitempty,oneof=soft hard disable"`
}
type Client struct {
@@ -248,6 +258,9 @@ func NewClient(config *ClientConfig) (*Client, error) {
if err := v.Validate(config); err != nil {
return nil, fmt.Errorf("failed validating config: %w", err)
}
if config.ValidationMode == "" {
config.ValidationMode = DefaultValidation
}
u, err := newUnifi(config, v)
if err != nil {
return nil, fmt.Errorf("failed creating unifi client: %w", err)
@@ -491,8 +504,25 @@ func (c *Client) createRequestURL(apiPath string) (*url.URL, error) {
return c.BaseURL.ResolveReference(reqURL), nil
}
func (c *Client) validateRequestBody(reqBody interface{}) error {
if reqBody != nil && c.config.ValidationMode != DisableValidation {
if err := c.validator.Validate(reqBody); err != nil {
err = fmt.Errorf("failed validating request body: %w", err)
if c.config.ValidationMode == HardValidation {
return err
} else {
fmt.Println(err)
}
}
}
return nil
}
// Do performs a request to the given API path with the given method.
func (c *Client) Do(ctx context.Context, method, apiPath string, reqBody interface{}, respBody interface{}) error {
if err := c.validateRequestBody(reqBody); err != nil {
return err
}
reqReader, err := marshalRequest(reqBody)
if err != nil {
return fmt.Errorf("unable to marshal request: %w", err)

View File

@@ -579,3 +579,46 @@ func TestUrlValidation(t *testing.T) {
})
}
}
type validateableBody struct {
Data string `json:"data" validate:"required"`
}
func TestValidationModes(t *testing.T) {
t.Parallel()
testCases := []struct {
validationMode validationMode
expectedError string
expectRequest bool
}{
{SoftValidation, "dial tcp", true},
{HardValidation, "validation failed", false},
{DisableValidation, "dial tcp", true},
}
for _, tc := range testCases {
t.Run(string(tc.validationMode), func(t *testing.T) {
t.Parallel()
a := assert.New(t)
// given
interceptor := NewTestInterceptor()
c, _ := NewClient(&ClientConfig{
URL: testUrl,
APIKey: "test-key",
Interceptors: []ClientInterceptor{interceptor},
ValidationMode: tc.validationMode,
})
c.apiPaths = &NewStyleAPI
// when
err := c.Get(context.Background(), "", validateableBody{}, nil)
// then
require.ErrorContains(t, err, tc.expectedError)
if tc.expectRequest {
a.NotNil(interceptor.request)
} else {
a.Nil(interceptor.request)
}
})
}
}

View File

@@ -25,18 +25,18 @@ type User struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
DevIdOverride int `json:"dev_id_override,omitempty"` // non-generated field
IP string `json:"ip,omitempty"` // non-generated field
DevIdOverride int `json:"dev_id_override,omitempty"` // non-generated field
IP string `json:"ip,omitempty" validate:"omitempty,ip"` // non-generated field
Blocked bool `json:"blocked,omitempty"`
FixedApEnabled bool `json:"fixed_ap_enabled"`
FixedApMAC string `json:"fixed_ap_mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
FixedApMAC string `json:"fixed_ap_mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
FixedIP string `json:"fixed_ip,omitempty"`
Hostname string `json:"hostname,omitempty"`
LastSeen int `json:"last_seen,omitempty"`
LocalDNSRecord string `json:"local_dns_record,omitempty"`
LocalDNSRecordEnabled bool `json:"local_dns_record_enabled"`
MAC string `json:"mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
MAC string `json:"mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Name string `json:"name,omitempty"`
NetworkID string `json:"network_id"`
Note string `json:"note,omitempty"`

View File

@@ -25,9 +25,9 @@ type UserGroup struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
QOSRateMaxDown int `json:"qos_rate_max_down,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000
QOSRateMaxUp int `json:"qos_rate_max_up,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
QOSRateMaxDown int `json:"qos_rate_max_down,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000
QOSRateMaxUp int `json:"qos_rate_max_up,omitempty"` // -1|[2-9]|[1-9][0-9]{1,4}|100000
}
func (dst *UserGroup) UnmarshalJSON(b []byte) error {

View File

@@ -3,6 +3,8 @@ package unifi
import (
"errors"
"fmt"
"regexp"
"sync"
"github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
@@ -34,6 +36,8 @@ type Validator interface {
RegisterStructValidation(fn vd.StructLevelFunc, i interface{})
// RegisterTranslation registers a custom translation for a given tag.
RegisterTranslation(tag string, registerFn vd.RegisterTranslationsFunc, translationFn vd.TranslationFunc) (err error)
// RegisterCustomValidator registers a custom validator function with own tag and error message.
RegisterCustomValidator(cv CustomValidator) error
}
type validator struct {
@@ -60,6 +64,23 @@ func (v *validator) RegisterTranslation(tag string, registerFn vd.RegisterTransl
return v.validate.RegisterTranslation(tag, v.trans, registerFn, translationFn)
}
func (v *validator) RegisterCustomValidator(cv CustomValidator) error {
var err error
if err = v.validate.RegisterValidation(cv.tag, cv.fn, false); err != nil {
return fmt.Errorf("failed to register custom validation '%s': %w", cv.tag, err)
}
err = v.RegisterTranslation(cv.tag, func(ut ut.Translator) error {
return ut.Add(cv.tag, cv.messageText, true)
}, func(ut ut.Translator, fe vd.FieldError) string {
t, _ := ut.T(cv.tag, append([]string{fe.Field()}, cv.params...)...)
return t
})
if err != nil {
return fmt.Errorf("failed to register custom validation '%s' translation: %w", cv.tag, err)
}
return nil
}
func newValidator() (*validator, error) {
validate := vd.New(vd.WithRequiredStructEnabled())
enLocale := en.New()
@@ -70,8 +91,64 @@ func newValidator() (*validator, error) {
return nil, err
}
return &validator{
v := &validator{
validate: validate,
trans: trans,
}, nil
}
for _, customValidator := range customValidators {
if err = v.RegisterCustomValidator(customValidator); err != nil {
return nil, err
}
}
return v, nil
}
type CustomValidator struct {
tag string
fn vd.Func
messageText string
params []string
}
func NewCustomRegexValidator(tag string, regex string) CustomValidator {
cv := &CustomValidator{
tag: tag,
messageText: regexValidatorMessage,
params: []string{regex},
}
crv := CustomRegexValidator{
CustomValidator: cv,
regex: lazyRegexCompile(regex),
}
crv.fn = func(fl vd.FieldLevel) bool {
return crv.regex().MatchString(fl.Field().String())
}
return *crv.CustomValidator
}
type CustomRegexValidator struct {
*CustomValidator
regex func() *regexp.Regexp
}
var customValidators = []CustomValidator{
NewCustomRegexValidator("w_regex", wRegexString),
NewCustomRegexValidator("numeric_nonzero", `^[1-9][0-9]*$`),
}
func lazyRegexCompile(str string) func() *regexp.Regexp {
var regex *regexp.Regexp
var once sync.Once
return func() *regexp.Regexp {
once.Do(func() {
regex = regexp.MustCompile(str)
})
return regex
}
}
const (
regexValidatorMessage = "{0} must comply with the regular expression pattern '{1}'"
wRegexString = `^[\w]+$`
)

View File

@@ -28,7 +28,7 @@ type VirtualDevice struct {
HeightInMeters float64 `json:"heightInMeters,omitempty"`
Locked bool `json:"locked"`
MapID string `json:"map_id"`
Type string `json:"type,omitempty"` // uap|usg|usw
Type string `json:"type,omitempty" validate:"omitempty,oneof=uap usg usw"` // uap|usg|usw
X string `json:"x,omitempty"`
Y string `json:"y,omitempty"`
}

114
unifi/wlan.generated.go generated
View File

@@ -26,19 +26,19 @@ type WLAN struct {
NoEdit bool `json:"attr_no_edit,omitempty"`
ApGroupIDs []string `json:"ap_group_ids,omitempty"`
ApGroupMode string `json:"ap_group_mode,omitempty"` // all|groups|devices
ApGroupMode string `json:"ap_group_mode,omitempty" validate:"omitempty,oneof=all groups devices"` // all|groups|devices
AuthCache bool `json:"auth_cache"`
BSupported bool `json:"b_supported"`
BroadcastFilterEnabled bool `json:"bc_filter_enabled"`
BroadcastFilterList []string `json:"bc_filter_list,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
BroadcastFilterList []string `json:"bc_filter_list,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
BssTransition bool `json:"bss_transition"`
CountryBeacon bool `json:"country_beacon"`
DPIEnabled bool `json:"dpi_enabled"`
DPIgroupID string `json:"dpigroup_id"` // [\d\w]+|^$
DTIM6E int `json:"dtim_6e,omitempty"` // ^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DTIMMode string `json:"dtim_mode,omitempty"` // default|custom
DTIMNa int `json:"dtim_na,omitempty"` // ^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DTIMNg int `json:"dtim_ng,omitempty"` // ^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DPIgroupID string `json:"dpigroup_id" validate:"omitempty,w_regex"` // [\d\w]+|^$
DTIM6E int `json:"dtim_6e,omitempty"` // ^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DTIMMode string `json:"dtim_mode,omitempty" validate:"omitempty,oneof=default custom"` // default|custom
DTIMNa int `json:"dtim_na,omitempty"` // ^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
DTIMNg int `json:"dtim_ng,omitempty"` // ^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^$
ElementAdopt bool `json:"element_adopt"`
Enabled bool `json:"enabled"`
EnhancedIot bool `json:"enhanced_iot"`
@@ -52,37 +52,37 @@ type WLAN struct {
L2Isolation bool `json:"l2_isolation"`
LogLevel string `json:"log_level,omitempty"`
MACFilterEnabled bool `json:"mac_filter_enabled"`
MACFilterList []string `json:"mac_filter_list,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
MACFilterPolicy string `json:"mac_filter_policy,omitempty"` // allow|deny
MACFilterList []string `json:"mac_filter_list,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
MACFilterPolicy string `json:"mac_filter_policy,omitempty" validate:"omitempty,oneof=allow deny"` // allow|deny
MinrateNaAdvertisingRates bool `json:"minrate_na_advertising_rates"`
MinrateNaDataRateKbps int `json:"minrate_na_data_rate_kbps,omitempty"`
MinrateNaEnabled bool `json:"minrate_na_enabled"`
MinrateNgAdvertisingRates bool `json:"minrate_ng_advertising_rates"`
MinrateNgDataRateKbps int `json:"minrate_ng_data_rate_kbps,omitempty"`
MinrateNgEnabled bool `json:"minrate_ng_enabled"`
MinrateSettingPreference string `json:"minrate_setting_preference,omitempty"` // auto|manual
MinrateSettingPreference string `json:"minrate_setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
MloEnabled bool `json:"mlo_enabled"`
MulticastEnhanceEnabled bool `json:"mcastenhance_enabled"`
Name string `json:"name,omitempty"` // .{1,32}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=32"` // .{1,32}
NameCombineEnabled bool `json:"name_combine_enabled"`
NameCombineSuffix string `json:"name_combine_suffix,omitempty"` // .{0,8}
NasIDentifier string `json:"nas_identifier,omitempty"` // .{0,48}
NasIDentifierType string `json:"nas_identifier_type,omitempty"` // ap_name|ap_mac|bssid|site_name|custom
NameCombineSuffix string `json:"name_combine_suffix,omitempty" validate:"omitempty,gte=0,lte=8"` // .{0,8}
NasIDentifier string `json:"nas_identifier,omitempty" validate:"omitempty,gte=0,lte=48"` // .{0,48}
NasIDentifierType string `json:"nas_identifier_type,omitempty" validate:"omitempty,oneof=ap_name ap_mac bssid site_name custom"` // ap_name|ap_mac|bssid|site_name|custom
NetworkID string `json:"networkconf_id"`
No2GhzOui bool `json:"no2ghz_oui"`
OptimizeIotWifiConnectivity bool `json:"optimize_iot_wifi_connectivity"`
P2P bool `json:"p2p"`
P2PCrossConnect bool `json:"p2p_cross_connect"`
PMFCipher string `json:"pmf_cipher,omitempty"` // auto|aes-128-cmac|bip-gmac-256
PMFMode string `json:"pmf_mode,omitempty"` // disabled|optional|required
Priority string `json:"priority,omitempty"` // medium|high|low
PMFCipher string `json:"pmf_cipher,omitempty" validate:"omitempty,oneof=auto aes-128-cmac bip-gmac-256"` // auto|aes-128-cmac|bip-gmac-256
PMFMode string `json:"pmf_mode,omitempty" validate:"omitempty,oneof=disabled optional required"` // disabled|optional|required
Priority string `json:"priority,omitempty" validate:"omitempty,oneof=medium high low"` // medium|high|low
PrivatePresharedKeys []WLANPrivatePresharedKeys `json:"private_preshared_keys,omitempty"`
PrivatePresharedKeysEnabled bool `json:"private_preshared_keys_enabled"`
ProxyArp bool `json:"proxy_arp"`
RADIUSDasEnabled bool `json:"radius_das_enabled"`
RADIUSMACAuthEnabled bool `json:"radius_mac_auth_enabled"`
RADIUSMACaclEmptyPassword bool `json:"radius_macacl_empty_password"`
RADIUSMACaclFormat string `json:"radius_macacl_format,omitempty"` // none_lower|hyphen_lower|colon_lower|none_upper|hyphen_upper|colon_upper
RADIUSMACaclFormat string `json:"radius_macacl_format,omitempty" validate:"omitempty,oneof=none_lower hyphen_lower colon_lower none_upper hyphen_upper colon_upper"` // none_lower|hyphen_lower|colon_lower|none_upper|hyphen_upper|colon_upper
RADIUSProfileID string `json:"radiusprofile_id"`
RoamClusterID int `json:"roam_cluster_id,omitempty"` // [0-9]|[1-2][0-9]|[3][0-1]|^$
RrmEnabled bool `json:"rrm_enabled"`
@@ -95,27 +95,27 @@ type WLAN struct {
ScheduleEnabled bool `json:"schedule_enabled"`
ScheduleReversed bool `json:"schedule_reversed"`
ScheduleWithDuration []WLANScheduleWithDuration `json:"schedule_with_duration"`
Security string `json:"security,omitempty"` // open|wpapsk|wep|wpaeap|osen
SettingPreference string `json:"setting_preference,omitempty"` // auto|manual
Security string `json:"security,omitempty" validate:"omitempty,oneof=open wpapsk wep wpaeap osen"` // open|wpapsk|wep|wpaeap|osen
SettingPreference string `json:"setting_preference,omitempty" validate:"omitempty,oneof=auto manual"` // auto|manual
TdlsProhibit bool `json:"tdls_prohibit"`
UapsdEnabled bool `json:"uapsd_enabled"`
UidWorkspaceUrl string `json:"uid_workspace_url,omitempty"`
UserGroupID string `json:"usergroup_id"`
VLAN int `json:"vlan,omitempty"` // [2-9]|[1-9][0-9]{1,2}|[1-3][0-9]{3}|40[0-8][0-9]|409[0-5]|^$
VLANEnabled bool `json:"vlan_enabled"`
WEPIDX int `json:"wep_idx,omitempty"` // [1-4]
WLANBand string `json:"wlan_band,omitempty"` // 2g|5g|both
WLANBands []string `json:"wlan_bands,omitempty"` // 2g|5g|6g
WEPIDX int `json:"wep_idx,omitempty"` // [1-4]
WLANBand string `json:"wlan_band,omitempty" validate:"omitempty,oneof=2g 5g both"` // 2g|5g|both
WLANBands []string `json:"wlan_bands,omitempty" validate:"omitempty,oneof=2g 5g 6g"` // 2g|5g|6g
WLANGroupID string `json:"wlangroup_id"`
WPA3Enhanced192 bool `json:"wpa3_enhanced_192"`
WPA3FastRoaming bool `json:"wpa3_fast_roaming"`
WPA3Support bool `json:"wpa3_support"`
WPA3Transition bool `json:"wpa3_transition"`
WPAEnc string `json:"wpa_enc,omitempty"` // auto|ccmp|gcmp|ccmp-256|gcmp-256
WPAMode string `json:"wpa_mode,omitempty"` // auto|wpa1|wpa2
WPAPskRADIUS string `json:"wpa_psk_radius,omitempty"` // disabled|optional|required
XIappKey string `json:"x_iapp_key,omitempty"` // [0-9A-Fa-f]{32}
XPassphrase string `json:"x_passphrase,omitempty"` // [\x20-\x7E]{8,255}|[0-9a-fA-F]{64}
WPAEnc string `json:"wpa_enc,omitempty" validate:"omitempty,oneof=auto ccmp gcmp ccmp-256 gcmp-256"` // auto|ccmp|gcmp|ccmp-256|gcmp-256
WPAMode string `json:"wpa_mode,omitempty" validate:"omitempty,oneof=auto wpa1 wpa2"` // auto|wpa1|wpa2
WPAPskRADIUS string `json:"wpa_psk_radius,omitempty" validate:"omitempty,oneof=disabled optional required"` // disabled|optional|required
XIappKey string `json:"x_iapp_key,omitempty"` // [0-9A-Fa-f]{32}
XPassphrase string `json:"x_passphrase,omitempty"` // [\x20-\x7E]{8,255}|[0-9a-fA-F]{64}
XWEP string `json:"x_wep,omitempty"`
}
@@ -164,9 +164,9 @@ func (dst *WLAN) UnmarshalJSON(b []byte) error {
}
type WLANCapab struct {
Port int `json:"port,omitempty"` // ^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])|$
Protocol string `json:"protocol,omitempty"` // icmp|tcp_udp|tcp|udp|esp
Status string `json:"status,omitempty"` // closed|open|unknown
Port int `json:"port,omitempty"` // ^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])|$
Protocol string `json:"protocol,omitempty" validate:"omitempty,oneof=icmp tcp_udp tcp udp esp"` // icmp|tcp_udp|tcp|udp|esp
Status string `json:"status,omitempty" validate:"omitempty,oneof=closed open unknown"` // closed|open|unknown
}
func (dst *WLANCapab) UnmarshalJSON(b []byte) error {
@@ -192,7 +192,7 @@ type WLANCellularNetworkList struct {
CountryCode int `json:"country_code,omitempty"` // [1-9]{1}[0-9]{0,3}
Mcc int `json:"mcc,omitempty"`
Mnc int `json:"mnc,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *WLANCellularNetworkList) UnmarshalJSON(b []byte) error {
@@ -219,8 +219,8 @@ func (dst *WLANCellularNetworkList) UnmarshalJSON(b []byte) error {
}
type WLANFriendlyName struct {
Language string `json:"language,omitempty"` // [a-z]{3}
Text string `json:"text,omitempty"` // .{1,128}
Language string `json:"language,omitempty"` // [a-z]{3}
Text string `json:"text,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *WLANFriendlyName) UnmarshalJSON(b []byte) error {
@@ -242,16 +242,16 @@ func (dst *WLANFriendlyName) UnmarshalJSON(b []byte) error {
type WLANHotspot2 struct {
Capab []WLANCapab `json:"capab,omitempty"`
CellularNetworkList []WLANCellularNetworkList `json:"cellular_network_list,omitempty"`
DomainNameList []string `json:"domain_name_list,omitempty"` // .{1,128}
DomainNameList []string `json:"domain_name_list,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
FriendlyName []WLANFriendlyName `json:"friendly_name,omitempty"`
IPaddrTypeAvailV4 int `json:"ipaddr_type_avail_v4,omitempty"` // 0|1|2|3|4|5|6|7
IPaddrTypeAvailV6 int `json:"ipaddr_type_avail_v6,omitempty"` // 0|1|2
IPaddrTypeAvailV4 int `json:"ipaddr_type_avail_v4,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7"` // 0|1|2|3|4|5|6|7
IPaddrTypeAvailV6 int `json:"ipaddr_type_avail_v6,omitempty" validate:"omitempty,oneof=0 1 2"` // 0|1|2
MetricsDownlinkLoad int `json:"metrics_downlink_load,omitempty"`
MetricsDownlinkLoadSet bool `json:"metrics_downlink_load_set"`
MetricsDownlinkSpeed int `json:"metrics_downlink_speed,omitempty"`
MetricsDownlinkSpeedSet bool `json:"metrics_downlink_speed_set"`
MetricsInfoAtCapacity bool `json:"metrics_info_at_capacity"`
MetricsInfoLinkStatus string `json:"metrics_info_link_status,omitempty"` // up|down|test
MetricsInfoLinkStatus string `json:"metrics_info_link_status,omitempty" validate:"omitempty,oneof=up down test"` // up|down|test
MetricsInfoSymmetric bool `json:"metrics_info_symmetric"`
MetricsMeasurement int `json:"metrics_measurement,omitempty"`
MetricsMeasurementSet bool `json:"metrics_measurement_set"`
@@ -261,11 +261,11 @@ type WLANHotspot2 struct {
MetricsUplinkSpeed int `json:"metrics_uplink_speed,omitempty"`
MetricsUplinkSpeedSet bool `json:"metrics_uplink_speed_set"`
NaiRealmList []WLANNaiRealmList `json:"nai_realm_list,omitempty"`
NetworkType int `json:"network_type,omitempty"` // 0|1|2|3|4|5|14|15
NetworkType int `json:"network_type,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 14 15"` // 0|1|2|3|4|5|14|15
RoamingConsortiumList []WLANRoamingConsortiumList `json:"roaming_consortium_list,omitempty"`
VenueGroup int `json:"venue_group,omitempty"` // 0|1|2|3|4|5|6|7|8|9|10|11
VenueGroup int `json:"venue_group,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7 8 9 10 11"` // 0|1|2|3|4|5|6|7|8|9|10|11
VenueName []WLANVenueName `json:"venue_name,omitempty"`
VenueType int `json:"venue_type,omitempty"` // 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15
VenueType int `json:"venue_type,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"` // 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15
}
func (dst *WLANHotspot2) UnmarshalJSON(b []byte) error {
@@ -306,11 +306,11 @@ func (dst *WLANHotspot2) UnmarshalJSON(b []byte) error {
}
type WLANNaiRealmList struct {
AuthIDs []int `json:"auth_ids,omitempty"` // 0|1|2|3|4|5
AuthVals []int `json:"auth_vals,omitempty"` // 0|1|2|3|4|5|6|7|8|9|10
EapMethod int `json:"eap_method,omitempty"` // 13|21|18|23|50
Encoding int `json:"encoding,omitempty"` // 0|1
Name string `json:"name,omitempty"` // .{1,128}
AuthIDs []int `json:"auth_ids,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5"` // 0|1|2|3|4|5
AuthVals []int `json:"auth_vals,omitempty" validate:"omitempty,oneof=0 1 2 3 4 5 6 7 8 9 10"` // 0|1|2|3|4|5|6|7|8|9|10
EapMethod int `json:"eap_method,omitempty" validate:"omitempty,oneof=13 21 18 23 50"` // 13|21|18|23|50
Encoding int `json:"encoding,omitempty" validate:"omitempty,oneof=0 1"` // 0|1
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
Status bool `json:"status"`
}
@@ -367,8 +367,8 @@ func (dst *WLANPrivatePresharedKeys) UnmarshalJSON(b []byte) error {
}
type WLANRoamingConsortiumList struct {
Name string `json:"name,omitempty"` // .{1,128}
Oid string `json:"oid,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
Oid string `json:"oid,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *WLANRoamingConsortiumList) UnmarshalJSON(b []byte) error {
@@ -388,10 +388,10 @@ func (dst *WLANRoamingConsortiumList) UnmarshalJSON(b []byte) error {
}
type WLANSaePsk struct {
ID string `json:"id"` // .{0,128}
MAC string `json:"mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Psk string `json:"psk,omitempty"` // [\x20-\x7E]{8,255}
VLAN int `json:"vlan,omitempty"` // [0-9]|[1-9][0-9]{1,2}|[1-3][0-9]{3}|40[0-8][0-9]|409[0-5]|^$
ID string `json:"id" validate:"omitempty,gte=0,lte=128"` // .{0,128}
MAC string `json:"mac,omitempty" validate:"omitempty,mac"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
Psk string `json:"psk,omitempty"` // [\x20-\x7E]{8,255}
VLAN int `json:"vlan,omitempty"` // [0-9]|[1-9][0-9]{1,2}|[1-3][0-9]{3}|40[0-8][0-9]|409[0-5]|^$
}
func (dst *WLANSaePsk) UnmarshalJSON(b []byte) error {
@@ -414,11 +414,11 @@ func (dst *WLANSaePsk) UnmarshalJSON(b []byte) error {
}
type WLANScheduleWithDuration struct {
DurationMinutes int `json:"duration_minutes,omitempty"` // ^[1-9][0-9]*$
Name string `json:"name,omitempty"` // .*
StartDaysOfWeek []string `json:"start_days_of_week,omitempty"` // ^(sun|mon|tue|wed|thu|fri|sat)$
StartHour int `json:"start_hour,omitempty"` // ^(1?[0-9])|(2[0-3])$
StartMinute int `json:"start_minute,omitempty"` // ^[0-5]?[0-9]$
DurationMinutes int `json:"duration_minutes,omitempty" validate:"omitempty,numeric_nonzero"` // ^[1-9][0-9]*$
Name string `json:"name,omitempty"` // .*
StartDaysOfWeek []string `json:"start_days_of_week,omitempty" validate:"omitempty,oneof=sun mon tue wed thu fri sat"` // ^(sun|mon|tue|wed|thu|fri|sat)$
StartHour int `json:"start_hour,omitempty"` // ^(1?[0-9])|(2[0-3])$
StartMinute int `json:"start_minute,omitempty"` // ^[0-5]?[0-9]$
}
func (dst *WLANScheduleWithDuration) UnmarshalJSON(b []byte) error {

View File

@@ -25,7 +25,7 @@ type WLANGroup struct {
NoDelete bool `json:"attr_no_delete,omitempty"`
NoEdit bool `json:"attr_no_edit,omitempty"`
Name string `json:"name,omitempty"` // .{1,128}
Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=128"` // .{1,128}
}
func (dst *WLANGroup) UnmarshalJSON(b []byte) error {