From 11779f248b1a849fbdb5ba1e065a113cfee2ec33 Mon Sep 17 00:00:00 2001 From: Jamie Wark Date: Tue, 24 Mar 2026 00:37:15 +1300 Subject: [PATCH] Update to UniFi Network Application 10.1.89 Field definitions moved from ace.jar to internal-dependencies.jar in newer versions. Updated the extractor to check both JARs, maintaining backward compatibility with older versions. Regenerated all types from 10.1.89 field definitions. --- fields/extract.go | 130 +-- fields/main.go | 4 +- unifi/account.generated.go | 18 +- unifi/account_test.go | 4 +- unifi/channel_plan.generated.go | 133 +-- unifi/device.generated.go | 830 +++++++++++++++---- unifi/dynamic_dns.generated.go | 4 +- unifi/firewall_rule.generated.go | 12 +- unifi/network.generated.go | 544 +++++++----- unifi/port_forward.generated.go | 45 +- unifi/port_profile.generated.go | 186 ++++- unifi/radius_profile.generated.go | 48 +- unifi/routing.generated.go | 2 +- unifi/setting_dashboard.generated.go | 109 +++ unifi/setting_doh.generated.go | 111 +++ unifi/setting_ether_lighting.generated.go | 130 +++ unifi/setting_evaluation_score.generated.go | 87 ++ unifi/setting_global_nat.generated.go | 88 ++ unifi/setting_global_switch.generated.go | 41 +- unifi/setting_guest_access.generated.go | 1 + unifi/setting_ips.generated.go | 69 +- unifi/setting_mdns.generated.go | 130 +++ unifi/setting_netflow.generated.go | 110 +++ unifi/setting_radio_ai.generated.go | 88 +- unifi/setting_radius.generated.go | 2 +- unifi/setting_roaming_assistant.generated.go | 91 ++ unifi/setting_rsyslogd.generated.go | 20 +- unifi/setting_ssl_inspection.generated.go | 87 ++ unifi/setting_super_mgmt.generated.go | 11 +- unifi/setting_traffic_flow.generated.go | 90 ++ unifi/setting_usg.generated.go | 129 +-- unifi/user.generated.go | 33 +- unifi/version.generated.go | 2 +- unifi/wlan.generated.go | 327 +++++++- 34 files changed, 2898 insertions(+), 818 deletions(-) create mode 100644 unifi/setting_dashboard.generated.go create mode 100644 unifi/setting_doh.generated.go create mode 100644 unifi/setting_ether_lighting.generated.go create mode 100644 unifi/setting_evaluation_score.generated.go create mode 100644 unifi/setting_global_nat.generated.go create mode 100644 unifi/setting_mdns.generated.go create mode 100644 unifi/setting_netflow.generated.go create mode 100644 unifi/setting_roaming_assistant.generated.go create mode 100644 unifi/setting_ssl_inspection.generated.go create mode 100644 unifi/setting_traffic_flow.generated.go diff --git a/fields/extract.go b/fields/extract.go index 4481ebfc..bc4044df 100644 --- a/fields/extract.go +++ b/fields/extract.go @@ -20,15 +20,20 @@ import ( "github.com/xor-gate/ar" ) -func downloadJar(url *url.URL, outputDir string) (string, error) { +var jarPaths = map[string]string{ + "./usr/lib/unifi/lib/ace.jar": "ace.jar", + "./usr/lib/unifi/lib/internal/internal-dependencies.jar": "internal-dependencies.jar", +} + +func downloadJars(url *url.URL, outputDir string) ([]string, error) { req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url.String(), nil) if err != nil { - return "", fmt.Errorf("unable to download deb: %w", err) + return nil, fmt.Errorf("unable to download deb: %w", err) } debResp, err := http.DefaultClient.Do(req) if err != nil { - return "", fmt.Errorf("unable to download deb: %w", err) + return nil, fmt.Errorf("unable to download deb: %w", err) } defer debResp.Body.Close() @@ -41,25 +46,24 @@ func downloadJar(url *url.URL, outputDir string) (string, error) { break } if err != nil { - return "", fmt.Errorf("in ar next: %w", err) + return nil, fmt.Errorf("in ar next: %w", err) } - // read the data file if header.Name == "data.tar.xz" { uncompressedReader, err = xz.NewReader(arReader) if err != nil { - return "", fmt.Errorf("in xz reader: %w", err) + return nil, fmt.Errorf("in xz reader: %w", err) } break } } if uncompressedReader == nil { - return "", fmt.Errorf("unable to find .deb data file") + return nil, fmt.Errorf("unable to find .deb data file") } tarReader := tar.NewReader(uncompressedReader) - var aceJar *os.File + var extracted []string for { header, err := tarReader.Next() @@ -67,70 +71,52 @@ func downloadJar(url *url.URL, outputDir string) (string, error) { break } if err != nil { - return "", fmt.Errorf("in next: %w", err) + return nil, fmt.Errorf("in next: %w", err) } - if header.Typeflag != tar.TypeReg || header.Name != "./usr/lib/unifi/lib/ace.jar" { - // skipping + localName, ok := jarPaths[header.Name] + if !ok || header.Typeflag != tar.TypeReg { continue } - aceJar, err = os.Create(filepath.Join(outputDir, "ace.jar")) + outPath := filepath.Join(outputDir, localName) + f, err := os.Create(outPath) if err != nil { - return "", fmt.Errorf("unable to create temp file: %w", err) + return nil, fmt.Errorf("unable to create %s: %w", localName, err) } - _, err = io.Copy(aceJar, tarReader) + _, err = io.Copy(f, tarReader) + f.Close() if err != nil { - return "", fmt.Errorf("unable to write ace.jar temp file: %w", err) + return nil, fmt.Errorf("unable to write %s: %w", localName, err) } - } - if aceJar == nil { - return "", fmt.Errorf("unable to find ace.jar") + extracted = append(extracted, outPath) } - defer aceJar.Close() - - return aceJar.Name(), nil -} - -func extractJSON(jarFile, fieldsDir string) error { - jarZip, err := zip.OpenReader(jarFile) - if err != nil { - return fmt.Errorf("unable to open jar: %w", err) + if len(extracted) == 0 { + return nil, fmt.Errorf("unable to find any known jar files in deb") } - defer jarZip.Close() - for _, f := range jarZip.File { - if !strings.HasPrefix(f.Name, "api/fields/") || path.Ext(f.Name) != ".json" { - // skip file - continue - } - - err = func() error { - src, err := f.Open() - if err != nil { - return err - } - - dst, err := os.Create(filepath.Join(fieldsDir, filepath.Base(f.Name))) - if err != nil { - return err - } - defer dst.Close() - - _, err = io.Copy(dst, src) - if err != nil { - return err - } + return extracted, nil +} - return nil - }() +func extractJSON(jarFiles []string, fieldsDir string) error { + found := false + for _, jarFile := range jarFiles { + n, err := extractFieldsFromJar(jarFile, fieldsDir) if err != nil { - return fmt.Errorf("unable to write JSON file: %w", err) + return err + } + if n > 0 { + found = true + break } } + if !found { + return fmt.Errorf("no api/fields/*.json found in any jar") + } + settingsData, err := os.ReadFile(filepath.Join(fieldsDir, "Setting.json")) if errors.Is(err, os.ErrNotExist) { return nil @@ -159,6 +145,42 @@ func extractJSON(jarFile, fieldsDir string) error { } } - // TODO: cleanup JSON return nil } + +func extractFieldsFromJar(jarFile, fieldsDir string) (int, error) { + jarZip, err := zip.OpenReader(jarFile) + if err != nil { + return 0, fmt.Errorf("unable to open jar %s: %w", jarFile, err) + } + defer jarZip.Close() + + count := 0 + for _, f := range jarZip.File { + if !strings.HasPrefix(f.Name, "api/fields/") || path.Ext(f.Name) != ".json" { + continue + } + + err = func() error { + src, err := f.Open() + if err != nil { + return err + } + + dst, err := os.Create(filepath.Join(fieldsDir, filepath.Base(f.Name))) + if err != nil { + return err + } + defer dst.Close() + + _, err = io.Copy(dst, src) + return err + }() + if err != nil { + return 0, fmt.Errorf("unable to write JSON file: %w", err) + } + count++ + } + + return count, nil +} diff --git a/fields/main.go b/fields/main.go index e777041a..4784b42a 100644 --- a/fields/main.go +++ b/fields/main.go @@ -253,12 +253,12 @@ func main() { } // download fields, create - jarFile, err := downloadJar(unifiDownloadUrl, fieldsDir) + jarFiles, err := downloadJars(unifiDownloadUrl, fieldsDir) if err != nil { panic(err) } - err = extractJSON(jarFile, fieldsDir) + err = extractJSON(jarFiles, fieldsDir) if err != nil { panic(err) } diff --git a/unifi/account.generated.go b/unifi/account.generated.go index 24051a7d..55ee76c1 100644 --- a/unifi/account.generated.go +++ b/unifi/account.generated.go @@ -25,14 +25,16 @@ type Account struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,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"` // ^[^"' ]+$ - 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]|^$ - 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"` + 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"` // ^[^"' ]+$ + 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]|^$ + 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"` } func (dst *Account) UnmarshalJSON(b []byte) error { diff --git a/unifi/account_test.go b/unifi/account_test.go index 6c1b4d61..54c2f10c 100644 --- a/unifi/account_test.go +++ b/unifi/account_test.go @@ -14,11 +14,11 @@ func TestAccountMarshalJSON(t *testing.T) { acc unifi.Account }{ "empty strings": { - `{"vlan":"","tunnel_type":"","tunnel_medium_type":""}`, + `{"vlan":"","tunnel_type":"","tunnel_medium_type":"","ulp_user_id":""}`, unifi.Account{}, }, "response": { - `{"vlan":10,"tunnel_type":1,"tunnel_medium_type":1}`, + `{"vlan":10,"tunnel_type":1,"tunnel_medium_type":1,"ulp_user_id":""}`, unifi.Account{ VLAN: 10, TunnelType: 1, diff --git a/unifi/channel_plan.generated.go b/unifi/channel_plan.generated.go index ccb29297..98fa2ab2 100644 --- a/unifi/channel_plan.generated.go +++ b/unifi/channel_plan.generated.go @@ -25,17 +25,8 @@ type ChannelPlan struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,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"` + 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?$ + RadioTable []ChannelPlanRadioTable `json:"radio_table,omitempty"` } func (dst *ChannelPlan) UnmarshalJSON(b []byte) error { @@ -54,75 +45,21 @@ func (dst *ChannelPlan) UnmarshalJSON(b []byte) error { return nil } -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} -} - -func (dst *ChannelPlanApBlacklistedChannels) UnmarshalJSON(b []byte) error { - type Alias ChannelPlanApBlacklistedChannels - aux := &struct { - Channel emptyStringInt `json:"channel"` - Timestamp emptyStringInt `json:"timestamp"` - - *Alias - }{ - Alias: (*Alias)(dst), - } - - err := json.Unmarshal(b, &aux) - if err != nil { - return fmt.Errorf("unable to unmarshal alias: %w", err) - } - dst.Channel = int(aux.Channel) - dst.Timestamp = int(aux.Timestamp) - - return nil -} - -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}).*$ -} - -func (dst *ChannelPlanCoupling) UnmarshalJSON(b []byte) error { - type Alias ChannelPlanCoupling - aux := &struct { - Rssi emptyStringInt `json:"rssi"` - - *Alias - }{ - Alias: (*Alias)(dst), - } - - err := json.Unmarshal(b, &aux) - if err != nil { - return fmt.Errorf("unable to unmarshal alias: %w", err) - } - dst.Rssi = int(aux.Rssi) - - return nil -} - 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 + 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 } func (dst *ChannelPlanRadioTable) UnmarshalJSON(b []byte) error { type Alias ChannelPlanRadioTable aux := &struct { - BackupChannel numberOrString `json:"backup_channel"` - Channel numberOrString `json:"channel"` - TxPower numberOrString `json:"tx_power"` - Width emptyStringInt `json:"width"` + Channel numberOrString `json:"channel"` + TxPower numberOrString `json:"tx_power"` + Width emptyStringInt `json:"width"` *Alias }{ @@ -133,7 +70,6 @@ func (dst *ChannelPlanRadioTable) UnmarshalJSON(b []byte) error { if err != nil { return fmt.Errorf("unable to unmarshal alias: %w", err) } - dst.BackupChannel = string(aux.BackupChannel) dst.Channel = string(aux.Channel) dst.TxPower = string(aux.TxPower) dst.Width = int(aux.Width) @@ -141,53 +77,6 @@ func (dst *ChannelPlanRadioTable) UnmarshalJSON(b []byte) error { return nil } -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"` -} - -func (dst *ChannelPlanSatisfactionTable) UnmarshalJSON(b []byte) error { - type Alias ChannelPlanSatisfactionTable - aux := &struct { - *Alias - }{ - Alias: (*Alias)(dst), - } - - err := json.Unmarshal(b, &aux) - if err != nil { - return fmt.Errorf("unable to unmarshal alias: %w", err) - } - - return nil -} - -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} -} - -func (dst *ChannelPlanSiteBlacklistedChannels) UnmarshalJSON(b []byte) error { - type Alias ChannelPlanSiteBlacklistedChannels - aux := &struct { - Channel emptyStringInt `json:"channel"` - Timestamp emptyStringInt `json:"timestamp"` - - *Alias - }{ - Alias: (*Alias)(dst), - } - - err := json.Unmarshal(b, &aux) - if err != nil { - return fmt.Errorf("unable to unmarshal alias: %w", err) - } - dst.Channel = int(aux.Channel) - dst.Timestamp = int(aux.Timestamp) - - return nil -} - func (c *Client) listChannelPlan(ctx context.Context, site string) ([]ChannelPlan, error) { var respBody struct { Meta meta `json:"meta"` diff --git a/unifi/device.generated.go b/unifi/device.generated.go index 4ffd88c5..ee8367a7 100644 --- a/unifi/device.generated.go +++ b/unifi/device.generated.go @@ -27,80 +27,101 @@ type Device struct { MAC string `json:"mac,omitempty"` - Adopted bool `json:"adopted"` - 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"` - ConnectedBatteryOverrides []DeviceConnectedBatteryOverrides `json:"connected_battery_overrides,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"` - 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] - HeightInMeters float64 `json:"heightInMeters,omitempty"` - Hostname string `json:"hostname,omitempty"` // .{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]$) - 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$ - 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 - LteDataLimitEnabled bool `json:"lte_data_limit_enabled,omitempty"` - LteDataWarningEnabled bool `json:"lte_data_warning_enabled,omitempty"` - LteExtAnt bool `json:"lte_ext_ant,omitempty"` - LteHardLimit int `json:"lte_hard_limit,omitempty"` - LtePassword string `json:"lte_password,omitempty"` - LtePoe bool `json:"lte_poe,omitempty"` - LteRoamingAllowed bool `json:"lte_roaming_allowed,omitempty"` - LteSimPin int `json:"lte_sim_pin,omitempty"` - LteSoftLimit int `json:"lte_soft_limit,omitempty"` - 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]+ - Model string `json:"model,omitempty"` - Name string `json:"name,omitempty"` // .{0,128} - OutdoorModeOverride string `json:"outdoor_mode_override,omitempty"` // default|on|off - OutletEnabled bool `json:"outlet_enabled,omitempty"` - OutletOverrides []DeviceOutletOverrides `json:"outlet_overrides,omitempty"` - OutletPowerCycleEnabled bool `json:"outlet_power_cycle_enabled,omitempty"` - 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 - 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} - State DeviceState `json:"state"` - 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"` - 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 - 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"` + Adopted bool `json:"adopted"` + AfcEnabled bool `json:"afc_enabled,omitempty"` + AtfEnabled bool `json:"atf_enabled,omitempty"` + AudioInfo DeviceAudioInfo `json:"audio_info,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"` + EavBridgeRole string `json:"eav_bridge_role,omitempty"` // host|client + EtherLighting DeviceEtherLighting `json:"ether_lighting,omitempty"` + EthernetOverrides []DeviceEthernetOverrides `json:"ethernet_overrides,omitempty"` + FanModeOverride string `json:"fan_mode_override,omitempty"` // default|quiet + 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] + GreenApEnabled bool `json:"green_ap_enabled,omitempty"` + HardwareOffload bool `json:"hardware_offload,omitempty"` + HeightInMeters float64 `json:"heightInMeters,omitempty"` + Hostname string `json:"hostname,omitempty"` // .{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 + 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$ + Locked bool `json:"locked,omitempty"` + LoopbackOverride bool `json:"loopback_override,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 + LteDataLimitEnabled bool `json:"lte_data_limit_enabled,omitempty"` + LteDataWarningEnabled bool `json:"lte_data_warning_enabled,omitempty"` + LteExtAnt bool `json:"lte_ext_ant,omitempty"` + LteHardLimit int `json:"lte_hard_limit,omitempty"` + LtePassword string `json:"lte_password,omitempty"` + LtePoe bool `json:"lte_poe,omitempty"` + LteRoamingAllowed bool `json:"lte_roaming_allowed,omitempty"` + LteSimPin int `json:"lte_sim_pin,omitempty"` + LteSoftLimit int `json:"lte_soft_limit,omitempty"` + LteUsername string `json:"lte_username,omitempty"` + MapID string `json:"map_id,omitempty"` + MbbOverrides DeviceMbbOverrides `json:"mbb_overrides,omitempty"` + MeshMloEnabled bool `json:"mesh_mlo_enabled,omitempty"` + MeshStaVapEnabled bool `json:"mesh_sta_vap_enabled,omitempty"` + MgmtNetworkID string `json:"mgmt_network_id,omitempty"` // [\d\w]+ + Model string `json:"model,omitempty"` + Name string `json:"name,omitempty"` // .{0,128} + NutServer DeviceNutServer `json:"nut_server,omitempty"` + OobPortConfig DeviceOobPortConfig `json:"oob_port_config,omitempty"` + OutdoorModeOverride string `json:"outdoor_mode_override,omitempty"` // default|on|off + OutletEnabled bool `json:"outlet_enabled,omitempty"` + OutletOverrides []DeviceOutletOverrides `json:"outlet_overrides,omitempty"` + OutletPowerCycleEnabled bool `json:"outlet_power_cycle_enabled,omitempty"` + OutletPowerCycleOnAcRecoveryEnabled bool `json:"outlet_power_cycle_on_ac_recovery_enabled,omitempty"` + PeerToPeerMode string `json:"peer_to_peer_mode,omitempty"` // ap|sta + PoeMode string `json:"poe_mode,omitempty"` // 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]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9] + PowerSourceCtrlEnabled bool `json:"power_source_ctrl_enabled,omitempty"` + PrecisionTimeProtocolConfig DevicePrecisionTimeProtocolConfig `json:"precision_time_protocol_config,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})$ + 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"` + SmaPortConfig DeviceSmaPortConfig `json:"sma_port_config,omitempty"` + SnmpContact string `json:"snmp_contact,omitempty"` // .{0,255} + SnmpLocation string `json:"snmp_location,omitempty"` // .{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 + SwitchVLANEnabled bool `json:"switch_vlan_enabled,omitempty"` + Type string `json:"type,omitempty"` + UbbPairName string `json:"ubb_pair_name,omitempty"` // .{1,128} + VideoInfo DeviceVideoInfo `json:"video_info,omitempty"` + 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"` } func (dst *Device) UnmarshalJSON(b []byte) error { @@ -109,12 +130,14 @@ func (dst *Device) UnmarshalJSON(b []byte) error { GatewayVrrpPriority emptyStringInt `json:"gateway_vrrp_priority"` LcmBrightness emptyStringInt `json:"lcm_brightness"` LcmIDleTimeout emptyStringInt `json:"lcm_idle_timeout"` + LcmOrientationOverride emptyStringInt `json:"lcm_orientation_override"` LedOverrideColorBrightness emptyStringInt `json:"led_override_color_brightness"` LteExtAnt booleanishString `json:"lte_ext_ant"` LteHardLimit emptyStringInt `json:"lte_hard_limit"` LtePoe booleanishString `json:"lte_poe"` LteSimPin emptyStringInt `json:"lte_sim_pin"` LteSoftLimit emptyStringInt `json:"lte_soft_limit"` + PowerSourceCtrlBudget emptyStringInt `json:"power_source_ctrl_budget"` StpPriority numberOrString `json:"stp_priority"` Volume emptyStringInt `json:"volume"` @@ -130,18 +153,44 @@ func (dst *Device) UnmarshalJSON(b []byte) error { dst.GatewayVrrpPriority = int(aux.GatewayVrrpPriority) dst.LcmBrightness = int(aux.LcmBrightness) dst.LcmIDleTimeout = int(aux.LcmIDleTimeout) + dst.LcmOrientationOverride = int(aux.LcmOrientationOverride) dst.LedOverrideColorBrightness = int(aux.LedOverrideColorBrightness) dst.LteExtAnt = bool(aux.LteExtAnt) dst.LteHardLimit = int(aux.LteHardLimit) dst.LtePoe = bool(aux.LtePoe) dst.LteSimPin = int(aux.LteSimPin) dst.LteSoftLimit = int(aux.LteSoftLimit) + dst.PowerSourceCtrlBudget = int(aux.PowerSourceCtrlBudget) dst.StpPriority = string(aux.StpPriority) dst.Volume = int(aux.Volume) return nil } +type DeviceAudioInfo struct { + Channel int `json:"channel,omitempty"` // [2-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9] + Role string `json:"role,omitempty"` // host|client +} + +func (dst *DeviceAudioInfo) UnmarshalJSON(b []byte) error { + type Alias DeviceAudioInfo + aux := &struct { + Channel emptyStringInt `json:"channel"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.Channel = int(aux.Channel) + + return nil +} + 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]))$|^$ @@ -169,13 +218,43 @@ func (dst *DeviceConfigNetwork) UnmarshalJSON(b []byte) error { return nil } -type DeviceConnectedBatteryOverrides struct { - MAC string `json:"mac,omitempty"` // ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$ +type DeviceCurrentApn struct { + Apn string `json:"apn,omitempty"` + AuthType string `json:"auth_type,omitempty"` // PAP|CHAP|PAP-CHAP|NONE + PDpType string `json:"pdp_type,omitempty"` // IPv4|IPv6|IPv4v6 + Password string `json:"password,omitempty"` + Roaming bool `json:"roaming,omitempty"` + Username string `json:"username,omitempty"` +} + +func (dst *DeviceCurrentApn) UnmarshalJSON(b []byte) error { + type Alias DeviceCurrentApn + aux := &struct { + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + + return nil +} + +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 } -func (dst *DeviceConnectedBatteryOverrides) UnmarshalJSON(b []byte) error { - type Alias DeviceConnectedBatteryOverrides +func (dst *DeviceEtherLighting) UnmarshalJSON(b []byte) error { + type Alias DeviceEtherLighting aux := &struct { + Brightness emptyStringInt `json:"brightness"` + *Alias }{ Alias: (*Alias)(dst), @@ -185,13 +264,15 @@ func (dst *DeviceConnectedBatteryOverrides) UnmarshalJSON(b []byte) error { if err != nil { return fmt.Errorf("unable to unmarshal alias: %w", err) } + dst.Brightness = int(aux.Brightness) return nil } type DeviceEthernetOverrides struct { + Disabled bool `json:"disabled,omitempty"` Ifname string `json:"ifname,omitempty"` // eth[0-9]{1,2} - NetworkGroup string `json:"networkgroup,omitempty"` // LAN[2-8]?|WAN[2]? + NetworkGroup string `json:"networkgroup,omitempty"` // LAN[2-8]?|WAN[2-9]? } func (dst *DeviceEthernetOverrides) UnmarshalJSON(b []byte) error { @@ -210,6 +291,130 @@ func (dst *DeviceEthernetOverrides) UnmarshalJSON(b []byte) error { return nil } +type DeviceIPV6 struct { + IP string `json:"ip,omitempty"` // ^(([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]))$|^$ + Netmask int `json:"netmask,omitempty"` // ^(0|[1-9]|[1-8][0-9]|9[0-9]|1[01][0-9]|12[0-8])$|^$ + Type string `json:"type,omitempty"` // slaac|dhcp|static|none +} + +func (dst *DeviceIPV6) UnmarshalJSON(b []byte) error { + type Alias DeviceIPV6 + aux := &struct { + Netmask emptyStringInt `json:"netmask"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.Netmask = int(aux.Netmask) + + return nil +} + +type DeviceIPv4 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])$ + Netmask int `json:"netmask,omitempty"` // ^(0|[1-9]|1[0-9]|2[0-9]|3[0-2])$|^$ + Type string `json:"type,omitempty"` // dhcp|static +} + +func (dst *DeviceIPv4) UnmarshalJSON(b []byte) error { + type Alias DeviceIPv4 + aux := &struct { + Netmask emptyStringInt `json:"netmask"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.Netmask = int(aux.Netmask) + + return nil +} + +type DeviceMbbOverrides struct { + PrimarySlot int `json:"primary_slot,omitempty"` // 1|2 + Sim []DeviceSim `json:"sim,omitempty"` +} + +func (dst *DeviceMbbOverrides) UnmarshalJSON(b []byte) error { + type Alias DeviceMbbOverrides + aux := &struct { + PrimarySlot emptyStringInt `json:"primary_slot"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.PrimarySlot = int(aux.PrimarySlot) + + return nil +} + +type DeviceNutServer struct { + CredentialRequired bool `json:"credential_required,omitempty"` + Enabled bool `json:"enabled,omitempty"` + ID string `json:"id,omitempty"` + Password string `json:"password,omitempty"` + Port int `json:"port,omitempty"` + Username string `json:"username,omitempty"` +} + +func (dst *DeviceNutServer) UnmarshalJSON(b []byte) error { + type Alias DeviceNutServer + aux := &struct { + Port emptyStringInt `json:"port"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.Port = int(aux.Port) + + return nil +} + +type DeviceOobPortConfig struct { + Enabled bool `json:"enabled,omitempty"` + IPV6 DeviceIPV6 `json:"ipv6,omitempty"` + IPv4 DeviceIPv4 `json:"ipv4,omitempty"` +} + +func (dst *DeviceOobPortConfig) UnmarshalJSON(b []byte) error { + type Alias DeviceOobPortConfig + aux := &struct { + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + + return nil +} + type DeviceOutletOverrides struct { CycleEnabled bool `json:"cycle_enabled,omitempty"` Index int `json:"index,omitempty"` @@ -237,67 +442,72 @@ func (dst *DeviceOutletOverrides) UnmarshalJSON(b []byte) error { } type DevicePortOverrides struct { - AggregateNumPorts int `json:"aggregate_num_ports,omitempty"` // [2-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} - EgressRateLimitKbpsEnabled bool `json:"egress_rate_limit_kbps_enabled,omitempty"` - ExcludedNetworkIDs []string `json:"excluded_networkconf_ids,omitempty"` - Forward string `json:"forward,omitempty"` // all|native|customize|disabled - FullDuplex bool `json:"full_duplex,omitempty"` - Isolation bool `json:"isolation,omitempty"` - LldpmedEnabled bool `json:"lldpmed_enabled,omitempty"` - LldpmedNotifyEnabled bool `json:"lldpmed_notify_enabled,omitempty"` - MirrorPortIDX int `json:"mirror_port_idx,omitempty"` // [1-9]|[1-4][0-9]|5[0-2] - 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-2] - PortProfileID string `json:"portconf_id,omitempty"` // [\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 - SettingPreference string `json:"setting_preference,omitempty"` // auto|manual - ShowTrafficRestrictionAsAllowlist bool `json:"show_traffic_restriction_as_allowlist,omitempty"` - Speed int `json:"speed,omitempty"` // 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 - 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"` - VoiceNetworkID string `json:"voice_networkconf_id,omitempty"` + AggregateMembers []int `json:"aggregate_members,omitempty"` // [1-9]|[1-4][0-9]|5[0-6] + 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} + 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 + FlowControlEnabled bool `json:"flow_control_enabled,omitempty"` + Forward string `json:"forward,omitempty"` // all|native|customize|disabled + FullDuplex bool `json:"full_duplex,omitempty"` + Isolation bool `json:"isolation,omitempty"` + LldpmedEnabled bool `json:"lldpmed_enabled,omitempty"` + LldpmedNotifyEnabled bool `json:"lldpmed_notify_enabled,omitempty"` + 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] + PortKeepaliveEnabled bool `json:"port_keepalive_enabled,omitempty"` + PortProfileID string `json:"portconf_id,omitempty"` // [\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 + 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 + 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 + 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 + VoiceNetworkID string `json:"voice_networkconf_id,omitempty"` } func (dst *DevicePortOverrides) UnmarshalJSON(b []byte) error { type Alias DevicePortOverrides aux := &struct { - AggregateNumPorts emptyStringInt `json:"aggregate_num_ports"` - Dot1XIDleTimeout emptyStringInt `json:"dot1x_idle_timeout"` - EgressRateLimitKbps emptyStringInt `json:"egress_rate_limit_kbps"` - MirrorPortIDX emptyStringInt `json:"mirror_port_idx"` - PortIDX emptyStringInt `json:"port_idx"` - PriorityQueue1Level emptyStringInt `json:"priority_queue1_level"` - PriorityQueue2Level emptyStringInt `json:"priority_queue2_level"` - PriorityQueue3Level emptyStringInt `json:"priority_queue3_level"` - PriorityQueue4Level emptyStringInt `json:"priority_queue4_level"` - Speed emptyStringInt `json:"speed"` - StormctrlBroadcastastLevel emptyStringInt `json:"stormctrl_bcast_level"` - StormctrlBroadcastastRate emptyStringInt `json:"stormctrl_bcast_rate"` - StormctrlMcastLevel emptyStringInt `json:"stormctrl_mcast_level"` - StormctrlMcastRate emptyStringInt `json:"stormctrl_mcast_rate"` - StormctrlUcastLevel emptyStringInt `json:"stormctrl_ucast_level"` - StormctrlUcastRate emptyStringInt `json:"stormctrl_ucast_rate"` + AggregateMembers []emptyStringInt `json:"aggregate_members"` + Dot1XIDleTimeout emptyStringInt `json:"dot1x_idle_timeout"` + EgressRateLimitKbps emptyStringInt `json:"egress_rate_limit_kbps"` + MirrorPortIDX emptyStringInt `json:"mirror_port_idx"` + PortIDX emptyStringInt `json:"port_idx"` + PriorityQueue1Level emptyStringInt `json:"priority_queue1_level"` + PriorityQueue2Level emptyStringInt `json:"priority_queue2_level"` + PriorityQueue3Level emptyStringInt `json:"priority_queue3_level"` + PriorityQueue4Level emptyStringInt `json:"priority_queue4_level"` + Speed emptyStringInt `json:"speed"` + StormctrlBroadcastastLevel emptyStringInt `json:"stormctrl_bcast_level"` + StormctrlBroadcastastRate emptyStringInt `json:"stormctrl_bcast_rate"` + StormctrlMcastLevel emptyStringInt `json:"stormctrl_mcast_level"` + StormctrlMcastRate emptyStringInt `json:"stormctrl_mcast_rate"` + StormctrlUcastLevel emptyStringInt `json:"stormctrl_ucast_level"` + StormctrlUcastRate emptyStringInt `json:"stormctrl_ucast_rate"` *Alias }{ @@ -308,7 +518,10 @@ func (dst *DevicePortOverrides) UnmarshalJSON(b []byte) error { if err != nil { return fmt.Errorf("unable to unmarshal alias: %w", err) } - dst.AggregateNumPorts = int(aux.AggregateNumPorts) + dst.AggregateMembers = make([]int, len(aux.AggregateMembers)) + for i, v := range aux.AggregateMembers { + dst.AggregateMembers[i] = int(v) + } dst.Dot1XIDleTimeout = int(aux.Dot1XIDleTimeout) dst.EgressRateLimitKbps = int(aux.EgressRateLimitKbps) dst.MirrorPortIDX = int(aux.MirrorPortIDX) @@ -328,38 +541,217 @@ func (dst *DevicePortOverrides) UnmarshalJSON(b []byte) error { return nil } +type DevicePrecisionTimeProtocolConfig struct { + ClockMode string `json:"clock_mode,omitempty"` // boundary|sma|transparent + CustomAnnounceInterval int `json:"custom_announce_interval,omitempty"` // ^(-[1-4]|[0-4])$ + CustomAnnounceTimeout int `json:"custom_announce_timeout,omitempty"` // ^([2-9]|10)$ + CustomDelayReqInterval int `json:"custom_delay_req_interval,omitempty"` // ^(-[1-7]|[0-4])$ + CustomDomain int `json:"custom_domain,omitempty"` // ^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) + CustomSyncInterval int `json:"custom_sync_interval,omitempty"` // ^(-[1-7]|[0-4])$ + Enabled bool `json:"enabled,omitempty"` + Priority1 int `json:"priority1,omitempty"` // ^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) + Priority2 int `json:"priority2,omitempty"` // ^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) + Profile string `json:"profile,omitempty"` // smpte|ieee1588|aes67|aes_r16|custom + TransportType string `json:"transport_type,omitempty"` // ipv4|layer2 +} + +func (dst *DevicePrecisionTimeProtocolConfig) UnmarshalJSON(b []byte) error { + type Alias DevicePrecisionTimeProtocolConfig + aux := &struct { + CustomAnnounceInterval emptyStringInt `json:"custom_announce_interval"` + CustomAnnounceTimeout emptyStringInt `json:"custom_announce_timeout"` + CustomDelayReqInterval emptyStringInt `json:"custom_delay_req_interval"` + CustomDomain emptyStringInt `json:"custom_domain"` + CustomSyncInterval emptyStringInt `json:"custom_sync_interval"` + Priority1 emptyStringInt `json:"priority1"` + Priority2 emptyStringInt `json:"priority2"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.CustomAnnounceInterval = int(aux.CustomAnnounceInterval) + dst.CustomAnnounceTimeout = int(aux.CustomAnnounceTimeout) + dst.CustomDelayReqInterval = int(aux.CustomDelayReqInterval) + dst.CustomDomain = int(aux.CustomDomain) + dst.CustomSyncInterval = int(aux.CustomSyncInterval) + dst.Priority1 = int(aux.Priority1) + dst.Priority2 = int(aux.Priority2) + + return nil +} + +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] +} + +func (dst *DeviceQOSMarking) UnmarshalJSON(b []byte) error { + type Alias DeviceQOSMarking + aux := &struct { + CosCode emptyStringInt `json:"cos_code"` + DscpCode emptyStringInt `json:"dscp_code"` + IPPrecedenceCode emptyStringInt `json:"ip_precedence_code"` + Queue emptyStringInt `json:"queue"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.CosCode = int(aux.CosCode) + dst.DscpCode = int(aux.DscpCode) + dst.IPPrecedenceCode = int(aux.IPPrecedenceCode) + dst.Queue = int(aux.Queue) + + return nil +} + +type DeviceQOSMatching struct { + CosCode int `json:"cos_code,omitempty"` // [0-7] + DscpCode int `json:"dscp_code,omitempty"` // [0-9]|[1-5][0-9]|6[0-3] + DstPort int `json:"dst_port,omitempty"` // [0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-4]|65535 + IPPrecedenceCode int `json:"ip_precedence_code,omitempty"` // [0-7] + Protocol string `json:"protocol,omitempty"` // ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|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 + SrcPort int `json:"src_port,omitempty"` // [0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-4]|65535 +} + +func (dst *DeviceQOSMatching) UnmarshalJSON(b []byte) error { + type Alias DeviceQOSMatching + aux := &struct { + CosCode emptyStringInt `json:"cos_code"` + DscpCode emptyStringInt `json:"dscp_code"` + DstPort emptyStringInt `json:"dst_port"` + IPPrecedenceCode emptyStringInt `json:"ip_precedence_code"` + SrcPort emptyStringInt `json:"src_port"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.CosCode = int(aux.CosCode) + dst.DscpCode = int(aux.DscpCode) + dst.DstPort = int(aux.DstPort) + dst.IPPrecedenceCode = int(aux.IPPrecedenceCode) + dst.SrcPort = int(aux.SrcPort) + + return nil +} + +type DeviceQOSPolicies struct { + QOSMarking DeviceQOSMarking `json:"qos_marking,omitempty"` + QOSMatching DeviceQOSMatching `json:"qos_matching,omitempty"` +} + +func (dst *DeviceQOSPolicies) UnmarshalJSON(b []byte) error { + type Alias DeviceQOSPolicies + aux := &struct { + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + + return nil +} + +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|smpte_st2110 +} + +func (dst *DeviceQOSProfile) UnmarshalJSON(b []byte) error { + type Alias DeviceQOSProfile + aux := &struct { + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + + return nil +} + +type DeviceRadioIDentifiers struct { + DeviceID string `json:"device_id,omitempty"` + RadioName string `json:"radio_name,omitempty"` +} + +func (dst *DeviceRadioIDentifiers) UnmarshalJSON(b []byte) error { + type Alias DeviceRadioIDentifiers + aux := &struct { + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + + return nil +} + 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]|4.5|5|16|21|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 - Channel string `json:"channel,omitempty"` // [0-9]|[1][0-4]|4.5|5|16|21|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 - HardNoiseFloorEnabled bool `json:"hard_noise_floor_enabled,omitempty"` - Ht int `json:"ht,omitempty"` // 20|40|80|160|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 - 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 - VwireEnabled bool `json:"vwire_enabled,omitempty"` + AntennaGain int `json:"antenna_gain,omitempty"` // ^-?([0-9]|[1-9][0-9]) + AntennaID int `json:"antenna_id,omitempty"` // -1|[0-9] + AssistedRoamingEnabled bool `json:"assisted_roaming_enabled,omitempty"` + AssistedRoamingRssi int `json:"assisted_roaming_rssi,omitempty"` // ^-([6-7][0-9]|80)$ + Channel string `json:"channel,omitempty"` // [0-9]|[1][0-4]|1.5|2.5|3.5|4.5|5.5|6.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 + Dfs bool `json:"dfs,omitempty"` + HardNoiseFloorEnabled bool `json:"hard_noise_floor_enabled,omitempty"` + Ht int `json:"ht,omitempty"` // 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 + 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|disabled + VwireEnabled bool `json:"vwire_enabled,omitempty"` } func (dst *DeviceRadioTable) UnmarshalJSON(b []byte) error { type Alias DeviceRadioTable aux := &struct { - AntennaGain emptyStringInt `json:"antenna_gain"` - AntennaID emptyStringInt `json:"antenna_id"` - BackupChannel numberOrString `json:"backup_channel"` - Channel numberOrString `json:"channel"` - Ht emptyStringInt `json:"ht"` - Maxsta emptyStringInt `json:"maxsta"` - MinRssi emptyStringInt `json:"min_rssi"` - SensLevel emptyStringInt `json:"sens_level"` - TxPower numberOrString `json:"tx_power"` + AntennaGain emptyStringInt `json:"antenna_gain"` + AntennaID emptyStringInt `json:"antenna_id"` + AssistedRoamingRssi emptyStringInt `json:"assisted_roaming_rssi"` + Channel numberOrString `json:"channel"` + Ht emptyStringInt `json:"ht"` + Maxsta emptyStringInt `json:"maxsta"` + MinRssi emptyStringInt `json:"min_rssi"` + SensLevel emptyStringInt `json:"sens_level"` + TxPower numberOrString `json:"tx_power"` *Alias }{ @@ -372,7 +764,7 @@ func (dst *DeviceRadioTable) UnmarshalJSON(b []byte) error { } dst.AntennaGain = int(aux.AntennaGain) dst.AntennaID = int(aux.AntennaID) - dst.BackupChannel = string(aux.BackupChannel) + dst.AssistedRoamingRssi = int(aux.AssistedRoamingRssi) dst.Channel = string(aux.Channel) dst.Ht = int(aux.Ht) dst.Maxsta = int(aux.Maxsta) @@ -429,23 +821,95 @@ func (dst *DeviceRpsPortTable) UnmarshalJSON(b []byte) error { return nil } -type DeviceWLANOverrides struct { - Enabled bool `json:"enabled,omitempty"` - Name string `json:"name,omitempty"` // .{1,32} - NameCombineEnabled bool `json:"name_combine_enabled,omitempty"` - NameCombineSuffix string `json:"name_combine_suffix,omitempty"` // .{0,8} - Radio string `json:"radio,omitempty"` // ng|na - RadioName string `json:"radio_name,omitempty"` - 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,omitempty"` - WLANID string `json:"wlan_id,omitempty"` // [\d\w]+ - XPassphrase string `json:"x_passphrase,omitempty"` // [\x20-\x7E]{8,255}|[0-9a-fA-F]{64} -} - -func (dst *DeviceWLANOverrides) UnmarshalJSON(b []byte) error { - type Alias DeviceWLANOverrides +type DeviceSim struct { + CurrentApn DeviceCurrentApn `json:"current_apn,omitempty"` + DataHardLimitBytes int `json:"data_hard_limit_bytes,omitempty"` + DataLimitEnabled bool `json:"data_limit_enabled,omitempty"` + DataSoftLimitBytes int `json:"data_soft_limit_bytes,omitempty"` + DataSoftLimitDisplayUnit string `json:"data_soft_limit_display_unit,omitempty"` // MB|GB + DataWarningThreshold int `json:"data_warning_threshold,omitempty"` // [0-9]|[1-9][0-9]|100 + ResetDate int `json:"reset_date,omitempty"` // [0-9]|[1-2][0-9]|3[0-1] + ResetPolicy string `json:"reset_policy,omitempty"` // day|week|month + Slot int `json:"slot,omitempty"` // 1|2 + UseCustomApn bool `json:"use_custom_apn,omitempty"` +} + +func (dst *DeviceSim) UnmarshalJSON(b []byte) error { + type Alias DeviceSim + aux := &struct { + DataHardLimitBytes emptyStringInt `json:"data_hard_limit_bytes"` + DataSoftLimitBytes emptyStringInt `json:"data_soft_limit_bytes"` + DataWarningThreshold emptyStringInt `json:"data_warning_threshold"` + ResetDate emptyStringInt `json:"reset_date"` + Slot emptyStringInt `json:"slot"` + + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + dst.DataHardLimitBytes = int(aux.DataHardLimitBytes) + dst.DataSoftLimitBytes = int(aux.DataSoftLimitBytes) + dst.DataWarningThreshold = int(aux.DataWarningThreshold) + dst.ResetDate = int(aux.ResetDate) + dst.Slot = int(aux.Slot) + + return nil +} + +type DeviceSmaPortConfig struct { + ClockSource string `json:"clock_source,omitempty"` // gps|external + DelayNs float64 `json:"delay_ns,omitempty"` + Display string `json:"display,omitempty"` // ns|m|ft +} + +func (dst *DeviceSmaPortConfig) UnmarshalJSON(b []byte) error { + type Alias DeviceSmaPortConfig + aux := &struct { + *Alias + }{ + Alias: (*Alias)(dst), + } + + err := json.Unmarshal(b, &aux) + if err != nil { + return fmt.Errorf("unable to unmarshal alias: %w", err) + } + + return nil +} + +type DeviceVideoInfo struct { + AudioEnabled bool `json:"audio_enabled,omitempty"` + AudioMode string `json:"audio_mode,omitempty"` // auto|pcm + Channel int `json:"channel,omitempty"` // [2-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9] + ColorFormat string `json:"color_format,omitempty"` // rgb|ycbcr444|ycbcr422 + Mode string `json:"mode,omitempty"` // unicast|multicast + RefreshRate string `json:"refresh_rate,omitempty"` + Resolution string `json:"resolution,omitempty"` // auto|1080p|1440p|4k + Role string `json:"role,omitempty"` // host|client + TvwallEndX int `json:"tvwall_end_x,omitempty"` // [2-5] + TvwallEndY int `json:"tvwall_end_y,omitempty"` // [2-5] + TvwallLayoutX int `json:"tvwall_layout_x,omitempty"` // [1-4] + TvwallLayoutY int `json:"tvwall_layout_y,omitempty"` // [1-4] + TvwallStartX int `json:"tvwall_start_x,omitempty"` // [2-5] + TvwallStartY int `json:"tvwall_start_y,omitempty"` // [2-5] +} + +func (dst *DeviceVideoInfo) UnmarshalJSON(b []byte) error { + type Alias DeviceVideoInfo aux := &struct { - VLAN emptyStringInt `json:"vlan"` + Channel emptyStringInt `json:"channel"` + TvwallEndX emptyStringInt `json:"tvwall_end_x"` + TvwallEndY emptyStringInt `json:"tvwall_end_y"` + TvwallLayoutX emptyStringInt `json:"tvwall_layout_x"` + TvwallLayoutY emptyStringInt `json:"tvwall_layout_y"` + TvwallStartX emptyStringInt `json:"tvwall_start_x"` + TvwallStartY emptyStringInt `json:"tvwall_start_y"` *Alias }{ @@ -456,7 +920,13 @@ func (dst *DeviceWLANOverrides) UnmarshalJSON(b []byte) error { if err != nil { return fmt.Errorf("unable to unmarshal alias: %w", err) } - dst.VLAN = int(aux.VLAN) + dst.Channel = int(aux.Channel) + dst.TvwallEndX = int(aux.TvwallEndX) + dst.TvwallEndY = int(aux.TvwallEndY) + dst.TvwallLayoutX = int(aux.TvwallLayoutX) + dst.TvwallLayoutY = int(aux.TvwallLayoutY) + dst.TvwallStartX = int(aux.TvwallStartX) + dst.TvwallStartY = int(aux.TvwallStartY) return nil } diff --git a/unifi/dynamic_dns.generated.go b/unifi/dynamic_dns.generated.go index 1e66ccf2..4bd18e0f 100644 --- a/unifi/dynamic_dns.generated.go +++ b/unifi/dynamic_dns.generated.go @@ -27,11 +27,11 @@ type DynamicDNS struct { CustomService string `json:"custom_service,omitempty"` // ^[^"' ]+$ HostName string `json:"host_name,omitempty"` // ^[^"' ]+$ - Interface string `json:"interface,omitempty"` // wan|wan2 + Interface string `json:"interface,omitempty"` // wan[2-9]? Login string `json:"login,omitempty"` // ^[^"' ]+$ Options []string `json:"options,omitempty"` // ^[^"' ]+$ Server string `json:"server"` // ^[^"' ]+$|^$ - Service string `json:"service,omitempty"` // afraid|changeip|cloudflare|dnspark|dslreports|dyndns|easydns|googledomains|namecheap|noip|sitelutions|zoneedit|custom + 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|cloudflare|custom XPassword string `json:"x_password,omitempty"` // ^[^"' ]+$ } diff --git a/unifi/firewall_rule.generated.go b/unifi/firewall_rule.generated.go index 412b2e7c..4e08e203 100644 --- a/unifi/firewall_rule.generated.go +++ b/unifi/firewall_rule.generated.go @@ -26,7 +26,6 @@ type FirewallRule struct { NoEdit bool `json:"attr_no_edit,omitempty"` Action string `json:"action,omitempty"` // drop|reject|accept - Contiguous bool `json:"contiguous"` DstAddress string `json:"dst_address,omitempty"` DstAddressIPV6 string `json:"dst_address_ipv6,omitempty"` DstFirewallGroupIDs []string `json:"dst_firewallgroup_ids,omitempty"` // [\d\w]+ @@ -38,13 +37,11 @@ type FirewallRule struct { 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|^$ Logging bool `json:"logging"` - MonthDays string `json:"monthdays"` // ^$|^(([1-9]|[12][0-9]|3[01])(,([1-9]|[12][0-9]|3[01])){0,30})$ - MonthDaysNegate bool `json:"monthdays_negate"` 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 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[0-9]{3} + 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 SrcAddress string `json:"src_address,omitempty"` @@ -54,17 +51,10 @@ type FirewallRule struct { SrcNetworkID string `json:"src_networkconf_id"` // [\d\w]+|^$ SrcNetworkType string `json:"src_networkconf_type,omitempty"` // ADDRv4|NETv4 SrcPort string `json:"src_port,omitempty"` - StartDate string `json:"startdate"` // ^$|^(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])$ - StartTime string `json:"starttime"` // ^$|^(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])$ StateEstablished bool `json:"state_established"` StateInvalid bool `json:"state_invalid"` StateNew bool `json:"state_new"` StateRelated bool `json:"state_related"` - StopDate string `json:"stopdate"` // ^$|^(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])$ - StopTime string `json:"stoptime"` // ^$|^(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])$ - UTC bool `json:"utc"` - Weekdays string `json:"weekdays"` // ^$|^((Mon|Tue|Wed|Thu|Fri|Sat|Sun)(,(Mon|Tue|Wed|Thu|Fri|Sat|Sun)){0,6})$ - WeekdaysNegate bool `json:"weekdays_negate"` } func (dst *FirewallRule) UnmarshalJSON(b []byte) error { diff --git a/unifi/network.generated.go b/unifi/network.generated.go index 3774c62a..6cb5e7d9 100644 --- a/unifi/network.generated.go +++ b/unifi/network.generated.go @@ -25,216 +25,292 @@ type Network struct { NoDelete bool `json:"attr_no_delete,omitempty"` NoEdit bool `json:"attr_no_edit,omitempty"` - 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}(?