os-normalizer 0.3.2__py3-none-any.whl → 0.3.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of os-normalizer might be problematic. Click here for more details.
- os_normalizer/constants.py +43 -3
- os_normalizer/parsers/__init__.py +3 -4
- os_normalizer/parsers/linux.py +15 -5
- os_normalizer/parsers/network/fortinet.py +1 -3
- os_normalizer/parsers/network/netgear.py +2 -6
- os_normalizer/parsers/windows.py +51 -14
- {os_normalizer-0.3.2.dist-info → os_normalizer-0.3.3.dist-info}/METADATA +1 -1
- {os_normalizer-0.3.2.dist-info → os_normalizer-0.3.3.dist-info}/RECORD +10 -10
- {os_normalizer-0.3.2.dist-info → os_normalizer-0.3.3.dist-info}/WHEEL +0 -0
- {os_normalizer-0.3.2.dist-info → os_normalizer-0.3.3.dist-info}/licenses/LICENSE +0 -0
os_normalizer/constants.py
CHANGED
|
@@ -17,8 +17,27 @@ ARCH_SYNONYMS = {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
# Windows build map (build number range -> product name, marketing channel)
|
|
20
|
+
# Notes:
|
|
21
|
+
# - This focuses on common client builds; server detection is handled separately
|
|
22
|
+
# and this map is not applied if a server product was already detected.
|
|
23
|
+
# - Marketing/channel labels use common public naming where applicable
|
|
24
|
+
# (e.g., 21H2/22H2 for Windows 10/11, RTM/SPx for older releases).
|
|
20
25
|
WINDOWS_BUILD_MAP = [
|
|
21
|
-
# Windows 10
|
|
26
|
+
# NT era (pre-Windows 10)
|
|
27
|
+
(1381, 1381, "Windows NT 4.0", "RTM"),
|
|
28
|
+
(2195, 2195, "Windows 2000", "RTM"),
|
|
29
|
+
(2600, 2600, "Windows XP", "RTM"),
|
|
30
|
+
# NT 5.2 builds are ambiguous (XP x64 vs Server 2003); keep consistent label
|
|
31
|
+
(3790, 3790, "Windows XP x64/Server 2003", "RTM"),
|
|
32
|
+
# Vista/7/8/8.1
|
|
33
|
+
(6000, 6000, "Windows Vista", "RTM"),
|
|
34
|
+
(6001, 6001, "Windows Vista", "SP1"),
|
|
35
|
+
(6002, 6002, "Windows Vista", "SP2"),
|
|
36
|
+
(7600, 7600, "Windows 7", "RTM"),
|
|
37
|
+
(7601, 7601, "Windows 7", "SP1"),
|
|
38
|
+
(9200, 9200, "Windows 8", "RTM"),
|
|
39
|
+
(9600, 9600, "Windows 8.1", "RTM"),
|
|
40
|
+
# Windows 10 (builds and marketing versions)
|
|
22
41
|
(10240, 10240, "Windows 10", "1507"),
|
|
23
42
|
(10586, 10586, "Windows 10", "1511"),
|
|
24
43
|
(14393, 14393, "Windows 10", "1607"),
|
|
@@ -30,7 +49,7 @@ WINDOWS_BUILD_MAP = [
|
|
|
30
49
|
(19041, 19045, "Windows 10", "2004/20H2/21H1/21H2/22H2"),
|
|
31
50
|
# Windows 11
|
|
32
51
|
(22000, 22000, "Windows 11", "21H2"),
|
|
33
|
-
(22621,
|
|
52
|
+
(22621, 22621, "Windows 11", "22H2"),
|
|
34
53
|
(22631, 25999, "Windows 11", "23H2"),
|
|
35
54
|
(26100, 26199, "Windows 11", "24H2"),
|
|
36
55
|
]
|
|
@@ -80,8 +99,29 @@ MACOS_DARWIN_MAP = {
|
|
|
80
99
|
22: ("macOS", "13", "Ventura"),
|
|
81
100
|
23: ("macOS", "14", "Sonoma"),
|
|
82
101
|
24: ("macOS", "15", "Sequoia"),
|
|
102
|
+
25: ("macOS", "26", "Tahoe"),
|
|
83
103
|
}
|
|
84
104
|
|
|
105
|
+
# Windows Server build map (build number range -> product name, marketing channel)
|
|
106
|
+
# This is consulted only when the input looks server-like or when an explicit
|
|
107
|
+
# Windows Server product is already detected. Client mapping will not override
|
|
108
|
+
# explicit server detections.
|
|
109
|
+
WINDOWS_SERVER_BUILD_MAP = [
|
|
110
|
+
# Legacy server releases aligned with Vista/7/8/8.1
|
|
111
|
+
(3790, 3790, "Windows Server 2003", "RTM"),
|
|
112
|
+
(6001, 6001, "Windows Server 2008", "RTM"), # 6001 corresponds to 2008 RTM
|
|
113
|
+
(6002, 6002, "Windows Server 2008", "SP2"),
|
|
114
|
+
(7600, 7600, "Windows Server 2008 R2", "RTM"),
|
|
115
|
+
(7601, 7601, "Windows Server 2008 R2", "SP1"),
|
|
116
|
+
(9200, 9200, "Windows Server 2012", "RTM"),
|
|
117
|
+
(9600, 9600, "Windows Server 2012 R2", "RTM"),
|
|
118
|
+
# NT 10.0 based server releases
|
|
119
|
+
(14393, 14393, "Windows Server 2016", "1607"),
|
|
120
|
+
(17763, 17763, "Windows Server 2019", "1809"),
|
|
121
|
+
(20348, 20348, "Windows Server 2022", "21H2"),
|
|
122
|
+
# Windows Server 2025 (vNext) uses the 26100 train alongside client 24H2
|
|
123
|
+
(26100, 26199, "Windows Server 2025", "24H2"),
|
|
124
|
+
]
|
|
125
|
+
|
|
85
126
|
# Cisco train names (used for codename detection)
|
|
86
127
|
CISCO_TRAIN_NAMES = {"Everest", "Fuji", "Gibraltar", "Amsterdam", "Denali"}
|
|
87
|
-
|
|
@@ -6,11 +6,10 @@ from .bsd import parse_bsd
|
|
|
6
6
|
from .network import parse_network
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
|
-
"
|
|
10
|
-
"parse_macos",
|
|
9
|
+
"parse_bsd",
|
|
11
10
|
"parse_linux",
|
|
11
|
+
"parse_macos",
|
|
12
12
|
"parse_mobile",
|
|
13
|
-
"parse_bsd",
|
|
14
13
|
"parse_network",
|
|
14
|
+
"parse_windows",
|
|
15
15
|
]
|
|
16
|
-
|
os_normalizer/parsers/linux.py
CHANGED
|
@@ -18,7 +18,7 @@ LINUX_VER_FALLBACK_RE = re.compile(
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def parse_linux(text: str, data: dict[str, Any], p: OSData) -> OSData:
|
|
21
|
-
"""Populate an OSData instance with Linux
|
|
21
|
+
"""Populate an OSData instance with Linux-specific details."""
|
|
22
22
|
p.kernel_name = "linux"
|
|
23
23
|
|
|
24
24
|
osrel = _coerce_os_release(data.get("os_release")) if isinstance(data, dict) else None
|
|
@@ -37,7 +37,7 @@ def parse_linux(text: str, data: dict[str, Any], p: OSData) -> OSData:
|
|
|
37
37
|
return p
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def _coerce_os_release(obj: Any) ->
|
|
40
|
+
def _coerce_os_release(obj: Any) -> dict[str, Any] | None:
|
|
41
41
|
if isinstance(obj, str):
|
|
42
42
|
return parse_os_release(obj)
|
|
43
43
|
if isinstance(obj, dict):
|
|
@@ -45,7 +45,7 @@ def _coerce_os_release(obj: Any) -> Optional[dict[str, Any]]:
|
|
|
45
45
|
return None
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def _extract_kernel_version(text: str) ->
|
|
48
|
+
def _extract_kernel_version(text: str) -> str | None:
|
|
49
49
|
m = KERNEL_RE.search(text)
|
|
50
50
|
if m:
|
|
51
51
|
return m.group(2)
|
|
@@ -66,6 +66,14 @@ def _apply_os_release(osrel: dict[str, Any], p: OSData) -> None:
|
|
|
66
66
|
|
|
67
67
|
p.pretty_name = osrel.get("PRETTY_NAME") or osrel.get("NAME")
|
|
68
68
|
|
|
69
|
+
if not p.codename and p.pretty_name:
|
|
70
|
+
# Fallback: try to extract codename from parenthetical in pretty name (e.g. "Debian ... (buster)")
|
|
71
|
+
m = re.search(r"\(([^)]+)\)", str(p.pretty_name))
|
|
72
|
+
if m:
|
|
73
|
+
candidate = m.group(1).strip()
|
|
74
|
+
if candidate:
|
|
75
|
+
p.codename = candidate.title()
|
|
76
|
+
|
|
69
77
|
_apply_version_id(osrel.get("VERSION_ID"), p)
|
|
70
78
|
|
|
71
79
|
vcode = osrel.get("VERSION_CODENAME")
|
|
@@ -78,7 +86,9 @@ def _apply_os_release(osrel: dict[str, Any], p: OSData) -> None:
|
|
|
78
86
|
p.vendor = _vendor_for_distro(p.distro) if p.distro else p.vendor
|
|
79
87
|
|
|
80
88
|
name = osrel.get("NAME")
|
|
81
|
-
p.product = (
|
|
89
|
+
p.product = (
|
|
90
|
+
(name if name else (p.distro or "Linux")).replace('"', "") if isinstance(name, str) else (p.distro or "Linux")
|
|
91
|
+
)
|
|
82
92
|
|
|
83
93
|
# Precision from version parts
|
|
84
94
|
if p.version_patch is not None:
|
|
@@ -103,7 +113,7 @@ def _apply_version_id(vid: Any, p: OSData) -> None:
|
|
|
103
113
|
p.version_patch = int(parts[2])
|
|
104
114
|
|
|
105
115
|
|
|
106
|
-
def _vendor_for_distro(distro:
|
|
116
|
+
def _vendor_for_distro(distro: str | None) -> str | None:
|
|
107
117
|
vendor_by_distro = {
|
|
108
118
|
"ubuntu": "Canonical",
|
|
109
119
|
"debian": "Debian",
|
|
@@ -30,9 +30,7 @@ def parse_fortinet(text: str, p: OSData) -> OSData:
|
|
|
30
30
|
if len(nums) >= 3:
|
|
31
31
|
p.version_patch = int(nums[2])
|
|
32
32
|
p.version_build = v
|
|
33
|
-
p.precision = (
|
|
34
|
-
"patch" if p.version_patch is not None else ("minor" if p.version_minor is not None else "major")
|
|
35
|
-
)
|
|
33
|
+
p.precision = "patch" if p.version_patch is not None else ("minor" if p.version_minor is not None else "major")
|
|
36
34
|
|
|
37
35
|
bld = FORTI_BUILD_RE.search(text)
|
|
38
36
|
if bld:
|
|
@@ -6,9 +6,7 @@ from os_normalizer.helpers import update_confidence
|
|
|
6
6
|
from os_normalizer.models import OSData
|
|
7
7
|
|
|
8
8
|
NETGEAR_RE = re.compile(r"\bnetgear\b|\bfirmware\b", re.IGNORECASE)
|
|
9
|
-
NETGEAR_VER_RE = re.compile(
|
|
10
|
-
r"\bV(\d+\.\d+\.\d+(?:\.\d+)?(?:_\d+\.\d+\.\d+)?)\b", re.IGNORECASE
|
|
11
|
-
)
|
|
9
|
+
NETGEAR_VER_RE = re.compile(r"\bV(\d+\.\d+\.\d+(?:\.\d+)?(?:_\d+\.\d+\.\d+)?)\b", re.IGNORECASE)
|
|
12
10
|
NETGEAR_MODEL_RE = re.compile(r"\b([RN][0-9]{3,4}[A-Z]?)\b", re.IGNORECASE)
|
|
13
11
|
|
|
14
12
|
|
|
@@ -29,9 +27,7 @@ def parse_netgear(text: str, p: OSData) -> OSData:
|
|
|
29
27
|
if len(nums) >= 3:
|
|
30
28
|
p.version_patch = int(nums[2])
|
|
31
29
|
p.version_build = v
|
|
32
|
-
p.precision = (
|
|
33
|
-
"patch" if p.version_patch is not None else ("minor" if p.version_minor is not None else "major")
|
|
34
|
-
)
|
|
30
|
+
p.precision = "patch" if p.version_patch is not None else ("minor" if p.version_minor is not None else "major")
|
|
35
31
|
|
|
36
32
|
mdl = NETGEAR_MODEL_RE.search(text)
|
|
37
33
|
if mdl:
|
os_normalizer/parsers/windows.py
CHANGED
|
@@ -10,6 +10,7 @@ from typing import Any, Optional
|
|
|
10
10
|
|
|
11
11
|
from os_normalizer.constants import (
|
|
12
12
|
WINDOWS_BUILD_MAP,
|
|
13
|
+
WINDOWS_SERVER_BUILD_MAP,
|
|
13
14
|
WINDOWS_NT_CLIENT_MAP,
|
|
14
15
|
WINDOWS_NT_SERVER_MAP,
|
|
15
16
|
)
|
|
@@ -18,14 +19,17 @@ from os_normalizer.models import OSData
|
|
|
18
19
|
|
|
19
20
|
# Regex patterns used only by the Windows parser
|
|
20
21
|
WIN_EDITION_RE = re.compile(
|
|
21
|
-
r"\b(professional|enterprise|home|education|ltsc|datacenter)\b",
|
|
22
|
+
r"\b(professional|pro|enterprise|home|education|ltsc|datacenter|standard)\b",
|
|
22
23
|
re.IGNORECASE,
|
|
23
24
|
)
|
|
24
25
|
WIN_SP_RE = re.compile(r"\bSP\s?([0-9]+)\b", re.IGNORECASE)
|
|
25
26
|
WIN_BUILD_RE = re.compile(r"\bbuild\s?(\d{4,6})\b", re.IGNORECASE)
|
|
26
27
|
WIN_NT_RE = re.compile(r"\bnt\s?(\d+)\.(\d+)\b", re.IGNORECASE)
|
|
27
28
|
WIN_FULL_NT_BUILD_RE = re.compile(r"\b(10)\.(0)\.(\d+)(?:\.(\d+))?\b")
|
|
28
|
-
WIN_CHANNEL_RE = re.compile(
|
|
29
|
+
WIN_CHANNEL_RE = re.compile(
|
|
30
|
+
r"\b(24H2|23H2|22H2|21H2|21H1|20H2|2004|1909|1903|1809|1803|1709|1703|1607|1511|1507)\b",
|
|
31
|
+
re.IGNORECASE,
|
|
32
|
+
)
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
def parse_windows(text: str, data: dict[str, Any], p: OSData) -> OSData:
|
|
@@ -47,7 +51,7 @@ def parse_windows(text: str, data: dict[str, Any], p: OSData) -> OSData:
|
|
|
47
51
|
_apply_full_kernel_and_channel(text, p)
|
|
48
52
|
|
|
49
53
|
# 5) Build number + marketing channel (fallback when only 'build 22631' is present)
|
|
50
|
-
_apply_build_mapping(text, p)
|
|
54
|
+
_apply_build_mapping(text, p, server_like)
|
|
51
55
|
|
|
52
56
|
# 6) Precision and version_major if applicable
|
|
53
57
|
_finalize_precision_and_version(p)
|
|
@@ -75,6 +79,8 @@ def _detect_product_from_text(t: str) -> str:
|
|
|
75
79
|
return "Windows 98"
|
|
76
80
|
|
|
77
81
|
# Server explicit names
|
|
82
|
+
if "windows server 2012 r2" in t:
|
|
83
|
+
return "Windows Server 2012 R2"
|
|
78
84
|
if "windows server 2022" in t or "win2k22" in t or "win2022" in t:
|
|
79
85
|
return "Windows Server 2022"
|
|
80
86
|
if "windows server 2019" in t or "win2k19" in t or "win2019" in t:
|
|
@@ -83,6 +89,8 @@ def _detect_product_from_text(t: str) -> str:
|
|
|
83
89
|
return "Windows Server 2016"
|
|
84
90
|
if "windows server 2012" in t or "win2k12" in t or "win2012" in t:
|
|
85
91
|
return "Windows Server 2012"
|
|
92
|
+
if "windows server 2008 r2" in t:
|
|
93
|
+
return "Windows Server 2008 R2"
|
|
86
94
|
if "windows server 2008" in t or "win2k8" in t or "win2008" in t:
|
|
87
95
|
return "Windows Server 2008"
|
|
88
96
|
if "windows server 2003" in t or "win2k3" in t or "win2003" in t:
|
|
@@ -97,7 +105,20 @@ def _detect_product_from_text(t: str) -> str:
|
|
|
97
105
|
|
|
98
106
|
def _detect_edition(text: str) -> str | None:
|
|
99
107
|
m = WIN_EDITION_RE.search(text)
|
|
100
|
-
|
|
108
|
+
if not m:
|
|
109
|
+
return None
|
|
110
|
+
token = m.group(1).lower()
|
|
111
|
+
norm = {
|
|
112
|
+
"pro": "Professional",
|
|
113
|
+
"professional": "Professional",
|
|
114
|
+
"enterprise": "Enterprise",
|
|
115
|
+
"home": "Home",
|
|
116
|
+
"education": "Education",
|
|
117
|
+
"ltsc": "LTSC",
|
|
118
|
+
"datacenter": "Datacenter",
|
|
119
|
+
"standard": "Standard",
|
|
120
|
+
}
|
|
121
|
+
return norm.get(token, token.title())
|
|
101
122
|
|
|
102
123
|
|
|
103
124
|
def _parse_service_pack(text: str, p: OSData) -> None:
|
|
@@ -138,26 +159,42 @@ def _apply_nt_mapping(text: str, p: OSData, server_like: bool) -> None:
|
|
|
138
159
|
p.product = product
|
|
139
160
|
|
|
140
161
|
|
|
141
|
-
def _apply_build_mapping(text: str, p: OSData) -> None:
|
|
162
|
+
def _apply_build_mapping(text: str, p: OSData, server_like: bool) -> None:
|
|
142
163
|
m = WIN_BUILD_RE.search(text)
|
|
143
164
|
if not m:
|
|
144
165
|
return
|
|
145
166
|
build_num = int(m.group(1))
|
|
146
167
|
p.version_build = str(build_num)
|
|
147
168
|
|
|
148
|
-
# Kernel version
|
|
149
|
-
if
|
|
150
|
-
p.
|
|
151
|
-
|
|
152
|
-
|
|
169
|
+
# Kernel version string
|
|
170
|
+
if not p.kernel_version:
|
|
171
|
+
if (p.product == "Windows 10/11") or ("10.0" in text):
|
|
172
|
+
p.kernel_version = f"10.0.{build_num}"
|
|
173
|
+
else:
|
|
174
|
+
nt_mm = WIN_NT_RE.search(text)
|
|
175
|
+
if nt_mm:
|
|
176
|
+
maj, minr = int(nt_mm.group(1)), int(nt_mm.group(2))
|
|
177
|
+
p.kernel_version = f"{maj}.{minr}.{build_num}"
|
|
153
178
|
|
|
154
|
-
# Only apply client build mapping if current product isn't an explicit Server
|
|
155
179
|
is_server_product = isinstance(p.product, str) and "server" in p.product.lower()
|
|
156
|
-
if
|
|
180
|
+
if is_server_product or server_like:
|
|
181
|
+
# Apply server build mapping; do not override explicit server product names
|
|
182
|
+
for lo, hi, product_name, marketing in WINDOWS_SERVER_BUILD_MAP:
|
|
183
|
+
if lo <= build_num <= hi:
|
|
184
|
+
if not p.product or p.product in ("Windows", "Windows 10/11"):
|
|
185
|
+
p.product = product_name
|
|
186
|
+
# Only set channel for modern Server (2016+)
|
|
187
|
+
if build_num >= 14393:
|
|
188
|
+
p.channel = p.channel or marketing
|
|
189
|
+
break
|
|
190
|
+
else:
|
|
191
|
+
# Apply client build mapping
|
|
157
192
|
for lo, hi, product_name, marketing in WINDOWS_BUILD_MAP:
|
|
158
193
|
if lo <= build_num <= hi:
|
|
159
|
-
|
|
160
|
-
|
|
194
|
+
# Only use build map to set product for Windows 10/11 trains
|
|
195
|
+
if build_num >= 10240:
|
|
196
|
+
p.product = product_name
|
|
197
|
+
p.channel = p.channel or marketing
|
|
161
198
|
break
|
|
162
199
|
|
|
163
200
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: os-normalizer
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Normalize raw OS strings/metadata into structured data (family, product, version, arch).
|
|
5
5
|
Project-URL: Homepage, https://github.com/johnscillieri/os-normalizer
|
|
6
6
|
Project-URL: Repository, https://github.com/johnscillieri/os-normalizer
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
os_normalizer/__init__.py,sha256=ZA2JnO3juuAn8xQBqUoUXxca10B-rE1MIuwtzDofpKs,212
|
|
2
|
-
os_normalizer/constants.py,sha256=
|
|
2
|
+
os_normalizer/constants.py,sha256=XwwPXmb9poJBHCEyHyvUIE2OaTjXLF6xVI5-dnRr9x0,4686
|
|
3
3
|
os_normalizer/cpe.py,sha256=G7hFiuVMlXM2d70ra7NA8v3a7kV7gYBt24bFunCAzk8,8742
|
|
4
4
|
os_normalizer/helpers.py,sha256=IymYS2NAJ6J8ngI_HL5PH2_6zN6zzIpWMx1-05D2O3c,3347
|
|
5
5
|
os_normalizer/models.py,sha256=_FAisDt9Pi5GDHIvzzfilEE8svvjyx6EcG2ZvMSRRJ0,5793
|
|
6
6
|
os_normalizer/os_normalizer.py,sha256=IsWxE_Yes7FQxxNhA8twNrzmeRcl8QXTxjTfn0zCTTI,10143
|
|
7
|
-
os_normalizer/parsers/__init__.py,sha256
|
|
7
|
+
os_normalizer/parsers/__init__.py,sha256=l9kx_P7FUHy--AxygZ8Q8nlyxyoSRRTREmp40M73Gxg,324
|
|
8
8
|
os_normalizer/parsers/bsd.py,sha256=Umm7RSXjQfv6pfziJ8BYlmOc80VlLRueTrYw1iR-UjY,2018
|
|
9
|
-
os_normalizer/parsers/linux.py,sha256=
|
|
9
|
+
os_normalizer/parsers/linux.py,sha256=kSIYZ_hRJxJieV21u8TRcWfAjYOIXlCLBSwyINkuyA4,3867
|
|
10
10
|
os_normalizer/parsers/macos.py,sha256=fU1YyiijzBdDAxUBSL2EQLhUu3JbOSx-N_KYvOg0XsI,3627
|
|
11
11
|
os_normalizer/parsers/mobile.py,sha256=Ca864JhrO9zW5fs0zbs2VcMypKIkFHqZtxpJDbi12q0,1033
|
|
12
|
-
os_normalizer/parsers/windows.py,sha256=
|
|
12
|
+
os_normalizer/parsers/windows.py,sha256=RQ_DJ3OjG70g_vwIaX9UrH2ADKzTEzF-R4ID2YSlAS0,7972
|
|
13
13
|
os_normalizer/parsers/network/__init__.py,sha256=TvRz08lNDZbr6yG8O3M7cLNu0hWAbtE1y7_9SwhP4g4,1596
|
|
14
14
|
os_normalizer/parsers/network/cisco.py,sha256=ivhw85IHnHVT4sW-65F-ZGCR7yvu0mMMBfXRT4EzUfc,3203
|
|
15
|
-
os_normalizer/parsers/network/fortinet.py,sha256=
|
|
15
|
+
os_normalizer/parsers/network/fortinet.py,sha256=i6PVRxzO_onaCvo3_eI4csXFwGp4ZpQY0d1y2-Wodn0,1783
|
|
16
16
|
os_normalizer/parsers/network/huawei.py,sha256=Su3eCRlmOCmpOPA_TGeH8gHY3-ZdXKFW4O3_W0SOPmk,1158
|
|
17
17
|
os_normalizer/parsers/network/juniper.py,sha256=gskbaY4-LYWauM9yrvGMuCxPrNBKmUfIRPd1zsUUY7w,1275
|
|
18
|
-
os_normalizer/parsers/network/netgear.py,sha256=
|
|
19
|
-
os_normalizer-0.3.
|
|
20
|
-
os_normalizer-0.3.
|
|
21
|
-
os_normalizer-0.3.
|
|
22
|
-
os_normalizer-0.3.
|
|
18
|
+
os_normalizer/parsers/network/netgear.py,sha256=idVD7VTxb07LdhFPwb-sT3586ARoBrd1OmWpADAZUVc,1190
|
|
19
|
+
os_normalizer-0.3.3.dist-info/METADATA,sha256=aUqJk1GKj_dHxjHRbR4C79UTNi5zc_HjnRqfzK-fVkc,6421
|
|
20
|
+
os_normalizer-0.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
21
|
+
os_normalizer-0.3.3.dist-info/licenses/LICENSE,sha256=DN0enoiHxVkJ-hxmIchPaCQWrDsZwva5LY8XvG3UK8w,1083
|
|
22
|
+
os_normalizer-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|