From 16c246525bd5d3c0cec4bc569b4d5dbf17cd0899 Mon Sep 17 00:00:00 2001 From: James Stephenson Date: Sun, 6 Sep 2020 16:10:45 -0400 Subject: [PATCH] Refactored field processing in generator. * Allows for specifying more customizations per field in each type. Previously, the switch clause didn't allow sub-types to be modified, but that became a problem with some of the more complex types. * Fixed several problematic fields in the Device resource * Removed the underscore separator from generated type names --- fields/main.go | 105 +++++++---- fields/main_test.go | 34 +++- unifi/channel_plan.generated.go | 32 ++-- unifi/dashboard.generated.go | 12 +- unifi/device.generated.go | 138 +++++++-------- unifi/hotspot_2_conf.generated.go | 142 +++++++-------- unifi/network.generated.go | 280 +++++++++++++++--------------- unifi/radius_profile.generated.go | 24 +-- unifi/schedule_task.generated.go | 22 +-- unifi/setting_ips.generated.go | 50 +++--- unifi/spatial_record.generated.go | 12 +- 11 files changed, 455 insertions(+), 396 deletions(-) diff --git a/fields/main.go b/fields/main.go index 14756af..428e2a0 100644 --- a/fields/main.go +++ b/fields/main.go @@ -86,9 +86,10 @@ var fileReps = []replacement{ var embedTypes bool type Resource struct { - StructName string - ResourcePath string - Types map[string]*FieldInfo + StructName string + ResourcePath string + Types map[string]*FieldInfo + FieldProcessor func(name string, f *FieldInfo) error } type FieldInfo struct { @@ -109,6 +110,7 @@ func NewResource(structName string, resourcePath string) *Resource { Types: map[string]*FieldInfo{ structName: baseType, }, + FieldProcessor: func(name string, f *FieldInfo) error { return nil }, } // Since template files iterate through map keys in sorted order, these initial fields @@ -135,6 +137,10 @@ func NewResource(structName string, resourcePath string) *Resource { baseType.Fields[" Key"] = NewFieldInfo("Key", "key", "string", "", false, false) } + if resource.StructName == "Device" { + baseType.Fields[" MAC"] = NewFieldInfo("MAC", "mac", "string", "", false, false) + } + if resource.StructName == "User" { baseType.Fields[" IP"] = NewFieldInfo("IP", "ip", "string", "non-generated field", true, false) } @@ -229,6 +235,48 @@ func main() { } resource := NewResource(structName, urlPath) + + switch resource.StructName { + case "Account": + resource.FieldProcessor = func(name string, f *FieldInfo) error { + if name == "IP" { + f.OmitEmpty = true + } + return nil + } + case "Device": + resource.FieldProcessor = func(name string, f *FieldInfo) error { + switch name { + case "X", "Y": + f.FieldType = "float64" + case "Channel", "BackupChannel", "TxPower": + f.FieldType = "int" + case "StpPriority", "Ht": + f.FieldType = "string" + } + + f.OmitEmpty = true + return nil + } + case "SettingUsg": + resource.FieldProcessor = func(name string, f *FieldInfo) error { + if strings.HasSuffix(name, "Timeout") && name != "ArpCacheTimeout" { + f.FieldType = "int" + } + return nil + } + case "User": + resource.FieldProcessor = func(name string, f *FieldInfo) error { + switch name { + case "Blocked": + f.FieldType = "bool" + case "LastSeen": + f.FieldType = "int" + } + return nil + } + } + err = resource.processJSON(b) if err != nil { fmt.Printf("skipping file %s: %s", fieldsFile.Name(), err) @@ -256,30 +304,11 @@ func (r *Resource) processFields(fields map[string]interface{}) { continue } - switch { - case r.StructName == "Account" && name == "ip": - fieldInfo.OmitEmpty = true - case r.StructName == "Device" && name == "stp_priority": - fieldInfo.OmitEmpty = true - fieldInfo.FieldType = "string" - case r.StructName == "Device" && (name == "x" || name == "y"): - fieldInfo.OmitEmpty = true - fieldInfo.FieldType = "int" - case r.StructName == "Device": - fieldInfo.OmitEmpty = true - case r.StructName == "SettingUsg" && strings.HasSuffix(name, "_timeout") && name != "arp_cache_timeout": - fieldInfo.FieldType = "int" - case r.StructName == "User" && name == "blocked": - fieldInfo.FieldType = "bool" - case r.StructName == "User" && name == "last_seen": - fieldInfo.FieldType = "int" - } - t.Fields[fieldInfo.FieldName] = fieldInfo } } -func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) (f *FieldInfo, err error) { +func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) (fieldInfo *FieldInfo, err error) { fieldName := strcase.ToCamel(name) fieldName = cleanName(fieldName, fieldReps) @@ -288,7 +317,9 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) switch validation := validation.(type) { case []interface{}: if len(validation) == 0 { - return NewFieldInfo(fieldName, name, "string", "", false, true), nil + fieldInfo, err = NewFieldInfo(fieldName, name, "string", "", false, true), nil + err = r.FieldProcessor(fieldName, fieldInfo) + return fieldInfo, err } if len(validation) > 1 { return empty, fmt.Errorf("unknown validation %#v", validation) @@ -302,9 +333,11 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) fieldInfo.OmitEmpty = true fieldInfo.IsArray = true - return fieldInfo, nil + err = r.FieldProcessor(fieldName, fieldInfo) + return fieldInfo, err + case map[string]interface{}: - typeName := r.StructName + "_" + fieldName + typeName := r.StructName + fieldName result := NewFieldInfo(fieldName, name, typeName, "", true, false) result.Fields = make(map[string]*FieldInfo) @@ -318,20 +351,23 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) result.Fields[child.FieldName] = child } + err = r.FieldProcessor(fieldName, result) r.Types[typeName] = result - return result, nil + return result, err case string: fieldValidation := validation normalized := normalizeValidation(validation) - omitEmpty := r.StructName == "Device" + omitEmpty := false switch { case normalized == "falsetrue" || normalized == "truefalse": - return NewFieldInfo(fieldName, name, "bool", "", omitEmpty, false), nil + fieldInfo, err = NewFieldInfo(fieldName, name, "bool", "", omitEmpty, false), nil + return fieldInfo, r.FieldProcessor(fieldName, fieldInfo) default: if _, err := strconv.ParseFloat(normalized, 64); err == nil { + if normalized == "09" || normalized == "09.09" { fieldValidation = "" } @@ -341,10 +377,14 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) break } - return NewFieldInfo(fieldName, name, "float64", fieldValidation, true, false), nil + omitEmpty = true + fieldInfo, err = NewFieldInfo(fieldName, name, "float64", fieldValidation, omitEmpty, false), nil + return fieldInfo, r.FieldProcessor(fieldName, fieldInfo) } - return NewFieldInfo(fieldName, name, "int", fieldValidation, true, false), nil + omitEmpty = true + fieldInfo, err = NewFieldInfo(fieldName, name, "int", fieldValidation, omitEmpty, false), nil + return fieldInfo, r.FieldProcessor(fieldName, fieldInfo) } } if validation != "" && normalized != "" { @@ -352,7 +392,8 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{}) } omitEmpty = omitEmpty || (!strings.Contains(validation, "^$") && !strings.HasSuffix(fieldName, "ID")) - return NewFieldInfo(fieldName, name, "string", fieldValidation, omitEmpty, false), nil + fieldInfo, err = NewFieldInfo(fieldName, name, "string", fieldValidation, omitEmpty, false), nil + return fieldInfo, r.FieldProcessor(fieldName, fieldInfo) } return empty, fmt.Errorf("unable to determine type from validation %q", validation) diff --git a/fields/main_test.go b/fields/main_test.go index 31d5040..8917520 100644 --- a/fields/main_test.go +++ b/fields/main_test.go @@ -30,7 +30,12 @@ func TestFieldInfoFromValidation(t *testing.T) { {"bool", "", false, "true|false"}, } { t.Run(fmt.Sprintf("%d %s %s", i, c.expectedType, c.validation), func(t *testing.T) { - resource := &Resource{StructName: "TestType", Types: make(map[string]*FieldInfo)} + resource := &Resource{ + StructName: "TestType", + Types: make(map[string]*FieldInfo), + FieldProcessor: func(name string, f *FieldInfo) error { return nil }, + } + fieldInfo, err := resource.fieldInfoFromValidation("fieldName", c.validation) //actualType, actualComment, actualOmitEmpty, err := fieldInfoFromValidation(c.validation) if err != nil { @@ -74,23 +79,23 @@ func TestResourceTypes(t *testing.T) { "NestedType": &FieldInfo{ FieldName: "NestedType", JSONName: "nested_type", - FieldType: "Struct_NestedType", + FieldType: "StructNestedType", FieldValidation: "", OmitEmpty: true, IsArray: false, Fields: map[string]*FieldInfo{ - "NestedField": NewFieldInfo("NestedField", "nested_field", "string", "^$", false, false), + "NestedFieldModified": NewFieldInfo("NestedFieldModified", "nested_field", "string", "^$", false, false), }, }, "NestedTypeArray": &FieldInfo{ FieldName: "NestedTypeArray", JSONName: "nested_type_array", - FieldType: "Struct_NestedTypeArray", + FieldType: "StructNestedTypeArray", FieldValidation: "", OmitEmpty: true, IsArray: true, Fields: map[string]*FieldInfo{ - "NestedField": NewFieldInfo("NestedField", "nested_field", "string", "^$", false, false), + "NestedFieldModified": NewFieldInfo("NestedFieldModified", "nested_field", "string", "^$", false, false), }, }, } @@ -126,17 +131,28 @@ func TestResourceTypes(t *testing.T) { ResourcePath: "path", Types: map[string]*FieldInfo{ - "Struct": expectedStruct["Struct"], - "Struct_NestedType": expectedStruct["Struct"].Fields["NestedType"], - "Struct_NestedTypeArray": expectedStruct["Struct"].Fields["NestedTypeArray"], + "Struct": expectedStruct["Struct"], + "StructNestedType": expectedStruct["Struct"].Fields["NestedType"], + "StructNestedTypeArray": expectedStruct["Struct"].Fields["NestedTypeArray"], + }, + + FieldProcessor: func(name string, f *FieldInfo) error { + if name == "NestedField" { + f.FieldName = "NestedFieldModified" + } + return nil }, } t.Run("structural test", func(t *testing.T) { resource := NewResource("Struct", "path") + resource.FieldProcessor = expectation.FieldProcessor + err := resource.processJSON(([]byte)(testData)) assert.Empty(t, err, "No error processing JSON") - assert.Equal(t, expectation, resource) + assert.Equal(t, expectation.StructName, resource.StructName) + assert.Equal(t, expectation.ResourcePath, resource.ResourcePath) + assert.Equal(t, expectation.Types, resource.Types) }) } diff --git a/unifi/channel_plan.generated.go b/unifi/channel_plan.generated.go index 3e5c0a0..3e9386f 100644 --- a/unifi/channel_plan.generated.go +++ b/unifi/channel_plan.generated.go @@ -23,32 +23,32 @@ type ChannelPlan struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,omitempty"` - ApBlacklistedChannels []ChannelPlan_ApBlacklistedChannels `json:"ap_blacklisted_channels,omitempty"` - ConfSource string `json:"conf_source,omitempty"` // manual|radio-ai - Coupling []ChannelPlan_Coupling `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 - RadioTable []ChannelPlan_RadioTable `json:"radio_table,omitempty"` - Satisfaction float64 `json:"satisfaction,omitempty"` - SatisfactionTable []ChannelPlan_SatisfactionTable `json:"satisfaction_table,omitempty"` - SiteBlacklistedChannels []ChannelPlan_SiteBlacklistedChannels `json:"site_blacklisted_channels,omitempty"` + ApBlacklistedChannels []ChannelPlanApBlacklistedChannels `json:"ap_blacklisted_channels,omitempty"` + ConfSource string `json:"conf_source,omitempty"` // 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 + RadioTable []ChannelPlanRadioTable `json:"radio_table,omitempty"` + Satisfaction float64 `json:"satisfaction,omitempty"` + SatisfactionTable []ChannelPlanSatisfactionTable `json:"satisfaction_table,omitempty"` + SiteBlacklistedChannels []ChannelPlanSiteBlacklistedChannels `json:"site_blacklisted_channels,omitempty"` } -type ChannelPlan_ApBlacklistedChannels struct { +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} } -type ChannelPlan_Coupling struct { +type ChannelPlanCoupling struct { Rssi int `json:"rssi,omitempty"` Source string `json:"source,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2}).*$ Target string `json:"target,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2}).*$ } -type ChannelPlan_RadioTable struct { +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})$ @@ -58,12 +58,12 @@ type ChannelPlan_RadioTable struct { Width int `json:"width,omitempty"` // 20|40|80|160 } -type ChannelPlan_SatisfactionTable struct { +type ChannelPlanSatisfactionTable struct { DeviceMAC string `json:"device_mac,omitempty"` // ^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$ Satisfaction float64 `json:"satisfaction,omitempty"` } -type ChannelPlan_SiteBlacklistedChannels struct { +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} } diff --git a/unifi/dashboard.generated.go b/unifi/dashboard.generated.go index 464c20a..bcb5ee2 100644 --- a/unifi/dashboard.generated.go +++ b/unifi/dashboard.generated.go @@ -23,14 +23,14 @@ type Dashboard struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,omitempty"` - ControllerVersion string `json:"controller_version,omitempty"` - Desc string `json:"desc,omitempty"` - IsPublic bool `json:"is_public"` - Modules []Dashboard_Modules `json:"modules,omitempty"` - Name string `json:"name,omitempty"` + ControllerVersion string `json:"controller_version,omitempty"` + Desc string `json:"desc,omitempty"` + IsPublic bool `json:"is_public"` + Modules []DashboardModules `json:"modules,omitempty"` + Name string `json:"name,omitempty"` } -type Dashboard_Modules struct { +type DashboardModules struct { Config string `json:"config,omitempty"` ID string `json:"id"` ModuleID string `json:"module_id"` diff --git a/unifi/device.generated.go b/unifi/device.generated.go index 270cbb9..906c4fd 100644 --- a/unifi/device.generated.go +++ b/unifi/device.generated.go @@ -23,63 +23,65 @@ type Device struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,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_.\-!~*'()]* - BaresipEnabled bool `json:"baresip_enabled,omitempty"` - BaresipExtension string `json:"baresip_extension,omitempty"` // ^\+?[a-zA-Z0-9_.\-!~*'()]* - ConfigNetwork Device_ConfigNetwork `json:"config_network,omitempty"` - DPIEnabled bool `json:"dpi_enabled,omitempty"` - Disabled bool `json:"disabled,omitempty"` - Dot1XFallbackNetworkID string `json:"dot1x_fallback_networkconf_id,omitempty"` // [\d\w]+| - Dot1XPortctrlEnabled bool `json:"dot1x_portctrl_enabled,omitempty"` - EthernetOverrides []Device_EthernetOverrides `json:"ethernet_overrides,omitempty"` - FlowctrlEnabled bool `json:"flowctrl_enabled,omitempty"` - HeightInMeters float64 `json:"heightInMeters,omitempty"` - 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"` - 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$ - Locked bool `json:"locked,omitempty"` - LteApn string `json:"lte_apn,omitempty"` // .{1,128} - LteExtAnt bool `json:"lte_ext_ant,omitempty"` - LtePoe bool `json:"lte_poe,omitempty"` - LteSimPin int `json:"lte_sim_pin,omitempty"` - LteSoftLimit int `json:"lte_soft_limit,omitempty"` - MapID string `json:"map_id,omitempty"` - MeshStaVapEnabled bool `json:"mesh_sta_vap_enabled,omitempty"` - MgmtNetworkID string `json:"mgmt_network_id,omitempty"` // [\d\w]+ - Name string `json:"name,omitempty"` // .{1,128} - OutdoorModeOverride string `json:"outdoor_mode_override,omitempty"` // default|on|off - OutletEnabled bool `json:"outlet_enabled,omitempty"` - OutletOverrides []Device_OutletOverrides `json:"outlet_overrides,omitempty"` - PortOverrides []Device_PortOverrides `json:"port_overrides,omitempty"` - PowerSourceCtrl string `json:"power_source_ctrl,omitempty"` // auto|8023af|8023at|8023bt-type3|8023bt-type4|pasv24|poe-injector|ac|adapter|dc|rps - PowerSourceCtrlEnabled bool `json:"power_source_ctrl_enabled,omitempty"` - RADIUSProfileID string `json:"radiusprofile_id,omitempty"` - RadioTable []Device_RadioTable `json:"radio_table,omitempty"` - ResetbtnEnabled string `json:"resetbtn_enabled,omitempty"` // on|off - RpsOverride Device_RpsOverride `json:"rps_override,omitempty"` - SnmpContact string `json:"snmp_contact,omitempty"` // .{0,255} - SnmpLocation string `json:"snmp_location,omitempty"` // .{0,255} - 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 - SwitchVLANEnabled bool `json:"switch_vlan_enabled,omitempty"` - UbbPairName string `json:"ubb_pair_name,omitempty"` // .{1,128} - Volume int `json:"volume,omitempty"` // [0-9]|[1-9][0-9]|100 - WLANOverrides []Device_WLANOverrides `json:"wlan_overrides,omitempty"` - X int `json:"x,omitempty"` - XBaresipPassword string `json:"x_baresip_password,omitempty"` // ^[a-zA-Z0-9_.\-!~*'()]* - Y int `json:"y,omitempty"` + MAC string `json:"mac"` + + 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_.\-!~*'()]* + BaresipEnabled bool `json:"baresip_enabled,omitempty"` + BaresipExtension string `json:"baresip_extension,omitempty"` // ^\+?[a-zA-Z0-9_.\-!~*'()]* + ConfigNetwork DeviceConfigNetwork `json:"config_network,omitempty"` + DPIEnabled bool `json:"dpi_enabled,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Dot1XFallbackNetworkID string `json:"dot1x_fallback_networkconf_id,omitempty"` // [\d\w]+| + Dot1XPortctrlEnabled bool `json:"dot1x_portctrl_enabled,omitempty"` + EthernetOverrides []DeviceEthernetOverrides `json:"ethernet_overrides,omitempty"` + FlowctrlEnabled bool `json:"flowctrl_enabled,omitempty"` + HeightInMeters float64 `json:"heightInMeters,omitempty"` + 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"` + 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$ + Locked bool `json:"locked,omitempty"` + LteApn string `json:"lte_apn,omitempty"` // .{1,128} + LteExtAnt bool `json:"lte_ext_ant,omitempty"` + LtePoe bool `json:"lte_poe,omitempty"` + LteSimPin int `json:"lte_sim_pin,omitempty"` + LteSoftLimit int `json:"lte_soft_limit,omitempty"` + MapID string `json:"map_id,omitempty"` + MeshStaVapEnabled bool `json:"mesh_sta_vap_enabled,omitempty"` + MgmtNetworkID string `json:"mgmt_network_id,omitempty"` // [\d\w]+ + Name string `json:"name,omitempty"` // .{1,128} + OutdoorModeOverride string `json:"outdoor_mode_override,omitempty"` // default|on|off + OutletEnabled bool `json:"outlet_enabled,omitempty"` + OutletOverrides []DeviceOutletOverrides `json:"outlet_overrides,omitempty"` + PortOverrides []DevicePortOverrides `json:"port_overrides,omitempty"` + PowerSourceCtrl string `json:"power_source_ctrl,omitempty"` // auto|8023af|8023at|8023bt-type3|8023bt-type4|pasv24|poe-injector|ac|adapter|dc|rps + PowerSourceCtrlEnabled bool `json:"power_source_ctrl_enabled,omitempty"` + RADIUSProfileID string `json:"radiusprofile_id,omitempty"` + RadioTable []DeviceRadioTable `json:"radio_table,omitempty"` + ResetbtnEnabled string `json:"resetbtn_enabled,omitempty"` // on|off + RpsOverride DeviceRpsOverride `json:"rps_override,omitempty"` + SnmpContact string `json:"snmp_contact,omitempty"` // .{0,255} + SnmpLocation string `json:"snmp_location,omitempty"` // .{0,255} + 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 + SwitchVLANEnabled bool `json:"switch_vlan_enabled,omitempty"` + UbbPairName string `json:"ubb_pair_name,omitempty"` // .{1,128} + Volume int `json:"volume,omitempty"` // [0-9]|[1-9][0-9]|100 + WLANOverrides []DeviceWLANOverrides `json:"wlan_overrides,omitempty"` + X float64 `json:"x,omitempty"` + XBaresipPassword string `json:"x_baresip_password,omitempty"` // ^[a-zA-Z0-9_.\-!~*'()]* + Y float64 `json:"y,omitempty"` } -type Device_ConfigNetwork struct { +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]))$|^$ @@ -90,19 +92,19 @@ type Device_ConfigNetwork struct { Type string `json:"type,omitempty"` // dhcp|static } -type Device_EthernetOverrides struct { +type DeviceEthernetOverrides struct { Ifname string `json:"ifname,omitempty"` // eth[0-9]{1,2} NetworkGroup string `json:"networkgroup,omitempty"` // LAN[2-8]?|WAN[2]? } -type Device_OutletOverrides struct { +type DeviceOutletOverrides struct { CycleEnabled bool `json:"cycle_enabled,omitempty"` Index int `json:"index,omitempty"` Name string `json:"name,omitempty"` // .{0,128} RelayState bool `json:"relay_state,omitempty"` } -type Device_PortOverrides struct { +type DevicePortOverrides struct { AggregateNumPorts int `json:"aggregate_num_ports,omitempty"` // [2-6] Autoneg bool `json:"autoneg,omitempty"` Dot1XCtrl string `json:"dot1x_ctrl,omitempty"` // auto|force_authorized|force_unauthorized|mac_based|multi_host @@ -139,37 +141,37 @@ type Device_PortOverrides struct { StpPortMode bool `json:"stp_port_mode,omitempty"` } -type Device_RadioTable struct { +type DeviceRadioTable struct { AntennaGain int `json:"antenna_gain,omitempty"` // ^-?([0-9]|[1-9][0-9]) AntennaID int `json:"antenna_id,omitempty"` // -1|[0-9] - 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]|4.5|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 + BackupChannel int `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 int `json:"channel,omitempty"` // [0-9]|[1][0-4]|4.5|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 HardNoiseFloorEnabled bool `json:"hard_noise_floor_enabled,omitempty"` - Ht int `json:"ht,omitempty"` // 20|40|80|160|1080|2160 + Ht string `json:"ht,omitempty"` // 20|40|80|160|1080|2160 MinRssi int `json:"min_rssi,omitempty"` // ^-([1-9]|[1-8][0-9]|9[0-4])$ MinRssiEnabled bool `json:"min_rssi_enabled,omitempty"` Name string `json:"name,omitempty"` Radio string `json:"radio,omitempty"` // ng|na|ad 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 + TxPower int `json:"tx_power,omitempty"` // [\d]+|auto TxPowerMode string `json:"tx_power_mode,omitempty"` // auto|medium|high|low|custom VwireEnabled bool `json:"vwire_enabled,omitempty"` WLANGroupID string `json:"wlangroup_id,omitempty"` // [\d\w]+ } -type Device_RpsOverride struct { - PowerManagementMode string `json:"power_management_mode,omitempty"` // dynamic|static - RpsPortTable []Device_RpsPortTable `json:"rps_port_table,omitempty"` +type DeviceRpsOverride struct { + PowerManagementMode string `json:"power_management_mode,omitempty"` // dynamic|static + RpsPortTable []DeviceRpsPortTable `json:"rps_port_table,omitempty"` } -type Device_RpsPortTable struct { +type DeviceRpsPortTable struct { Name string `json:"name,omitempty"` // .{0,32} PortIDX int `json:"port_idx,omitempty"` // [1-6] PortMode string `json:"port_mode,omitempty"` // auto|force_active|manual|disabled } -type Device_WLANOverrides struct { +type DeviceWLANOverrides struct { Enabled bool `json:"enabled,omitempty"` Name string `json:"name,omitempty"` // .{1,32} NameCombineEnabled bool `json:"name_combine_enabled,omitempty"` diff --git a/unifi/hotspot_2_conf.generated.go b/unifi/hotspot_2_conf.generated.go index a783ea8..3037751 100644 --- a/unifi/hotspot_2_conf.generated.go +++ b/unifi/hotspot_2_conf.generated.go @@ -23,85 +23,85 @@ type Hotspot2Conf struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,omitempty"` - AnqpDomainID int `json:"anqp_domain_id,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]|$ - Capab []Hotspot2Conf_Capab `json:"capab,omitempty"` - CellularNetworkList []Hotspot2Conf_CellularNetworkList `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} - FriendlyName []Hotspot2Conf_FriendlyName `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})$|^$ - 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 - Icons []Hotspot2Conf_Icons `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 - MetricsInfoSymmetric bool `json:"metrics_info_symmetric"` - MetricsMeasurement int `json:"metrics_measurement,omitempty"` - MetricsMeasurementSet bool `json:"metrics_measurement_set"` - MetricsStatus bool `json:"metrics_status"` - MetricsUplinkLoad int `json:"metrics_uplink_load,omitempty"` - MetricsUplinkLoadSet bool `json:"metrics_uplink_load_set"` - MetricsUplinkSpeed int `json:"metrics_uplink_speed,omitempty"` - MetricsUplinkSpeedSet bool `json:"metrics_uplink_speed_set"` - NaiRealmList []Hotspot2Conf_NaiRealmList `json:"nai_realm_list,omitempty"` - Name string `json:"name,omitempty"` // .{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 - NetworkAuthUrl string `json:"network_auth_url,omitempty"` - NetworkType int `json:"network_type,omitempty"` // 0|1|2|3|4|5|14|15 - Osu []Hotspot2Conf_Osu `json:"osu,omitempty"` - OsuSSID string `json:"osu_ssid"` - QOSMapDcsp []Hotspot2Conf_QOSMapDcsp `json:"qos_map_dcsp,omitempty"` - QOSMapExceptions []Hotspot2Conf_QOSMapExceptions `json:"qos_map_exceptions,omitempty"` - QOSMapStatus bool `json:"qos_map_status"` - RoamingConsortiumList []Hotspot2Conf_RoamingConsortiumList `json:"roaming_consortium_list,omitempty"` - SaveTimestamp string `json:"save_timestamp,omitempty"` - TCFilename string `json:"t_c_filename,omitempty"` // .{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 - VenueName []Hotspot2Conf_VenueName `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 + AnqpDomainID int `json:"anqp_domain_id,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]|$ + Capab []Hotspot2ConfCapab `json:"capab,omitempty"` + 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} + 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})$|^$ + 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 + 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 + MetricsInfoSymmetric bool `json:"metrics_info_symmetric"` + MetricsMeasurement int `json:"metrics_measurement,omitempty"` + MetricsMeasurementSet bool `json:"metrics_measurement_set"` + MetricsStatus bool `json:"metrics_status"` + MetricsUplinkLoad int `json:"metrics_uplink_load,omitempty"` + MetricsUplinkLoadSet bool `json:"metrics_uplink_load_set"` + 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} + 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 + NetworkAuthUrl string `json:"network_auth_url,omitempty"` + NetworkType int `json:"network_type,omitempty"` // 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"` + QOSMapExceptions []Hotspot2ConfQOSMapExceptions `json:"qos_map_exceptions,omitempty"` + 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} + 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 + 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 } -type Hotspot2Conf_Capab struct { +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 } -type Hotspot2Conf_CellularNetworkList struct { +type Hotspot2ConfCellularNetworkList struct { Mcc int `json:"mcc,omitempty"` Mnc int `json:"mnc,omitempty"` Name string `json:"name,omitempty"` // .{1,128} } -type Hotspot2Conf_Description struct { +type Hotspot2ConfDescription struct { Language string `json:"language,omitempty"` // [a-z]{3} Text string `json:"text,omitempty"` // .{1,128} } -type Hotspot2Conf_FriendlyName struct { +type Hotspot2ConfFriendlyName struct { Language string `json:"language,omitempty"` // [a-z]{3} Text string `json:"text,omitempty"` // .{1,128} } -type Hotspot2Conf_Icon struct { +type Hotspot2ConfIcon struct { Name string `json:"name,omitempty"` // .{1,128} } -type Hotspot2Conf_Icons struct { +type Hotspot2ConfIcons struct { Data string `json:"data,omitempty"` Filename string `json:"filename,omitempty"` // .{1,256} Height int `json:"height,omitempty"` @@ -112,7 +112,7 @@ type Hotspot2Conf_Icons struct { Width int `json:"width,omitempty"` } -type Hotspot2Conf_NaiRealmList struct { +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 @@ -121,34 +121,34 @@ type Hotspot2Conf_NaiRealmList struct { Status bool `json:"status"` } -type Hotspot2Conf_Osu struct { - Description []Hotspot2Conf_Description `json:"description,omitempty"` - FriendlyName []Hotspot2Conf_FriendlyName `json:"friendly_name,omitempty"` - Icon []Hotspot2Conf_Icon `json:"icon,omitempty"` - MethodOmaDm bool `json:"method_oma_dm"` - MethodSoapXmlSpp bool `json:"method_soap_xml_spp"` - Nai string `json:"nai,omitempty"` - Nai2 string `json:"nai2,omitempty"` - OperatingClass string `json:"operating_class,omitempty"` // [0-9A-Fa-f]{12} - ServerUri string `json:"server_uri,omitempty"` +type Hotspot2ConfOsu struct { + Description []Hotspot2ConfDescription `json:"description,omitempty"` + FriendlyName []Hotspot2ConfFriendlyName `json:"friendly_name,omitempty"` + Icon []Hotspot2ConfIcon `json:"icon,omitempty"` + MethodOmaDm bool `json:"method_oma_dm"` + MethodSoapXmlSpp bool `json:"method_soap_xml_spp"` + Nai string `json:"nai,omitempty"` + Nai2 string `json:"nai2,omitempty"` + OperatingClass string `json:"operating_class,omitempty"` // [0-9A-Fa-f]{12} + ServerUri string `json:"server_uri,omitempty"` } -type Hotspot2Conf_QOSMapDcsp struct { +type Hotspot2ConfQOSMapDcsp struct { High int `json:"high,omitempty"` Low int `json:"low,omitempty"` } -type Hotspot2Conf_QOSMapExceptions struct { +type Hotspot2ConfQOSMapExceptions struct { Dcsp int `json:"dcsp,omitempty"` Up int `json:"up,omitempty"` // [0-7] } -type Hotspot2Conf_RoamingConsortiumList struct { +type Hotspot2ConfRoamingConsortiumList struct { Name string `json:"name,omitempty"` // .{1,128} Oid string `json:"oid,omitempty"` // .{1,128} } -type Hotspot2Conf_VenueName struct { +type Hotspot2ConfVenueName struct { Language string `json:"language,omitempty"` // [a-z]{3} Name string `json:"name,omitempty"` Url string `json:"url,omitempty"` diff --git a/unifi/network.generated.go b/unifi/network.generated.go index 395a090..4a60092 100644 --- a/unifi/network.generated.go +++ b/unifi/network.generated.go @@ -23,148 +23,148 @@ type Network struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,omitempty"` - 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}(?