netbox-vcenter-server 0.2.0__py3-none-any.whl → 0.3.0__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.
@@ -7,7 +7,7 @@ Supports multiple vCenter servers with per-server caching and VM import to NetBo
7
7
 
8
8
  from netbox.plugins import PluginConfig
9
9
 
10
- __version__ = "0.2.0"
10
+ __version__ = "0.3.0"
11
11
 
12
12
 
13
13
  class VcenterConfig(PluginConfig):
@@ -53,6 +53,22 @@ class VcenterConfig(PluginConfig):
53
53
  "default_role": "",
54
54
  # Optional default platform slug for imported VMs (must exist in NetBox, or leave empty)
55
55
  "default_platform": "",
56
+ # Platform mappings - auto-map vCenter guest OS to NetBox platform
57
+ # Each mapping has a "pattern" (regex to match against guest OS) and "platform" (NetBox platform slug)
58
+ # Mappings are evaluated in order; first match wins
59
+ # Example:
60
+ # "platform_mappings": [
61
+ # {"pattern": r"Microsoft Windows Server 2022", "platform": "windows-server-2022"},
62
+ # {"pattern": r"Microsoft Windows Server 2019", "platform": "windows-server-2019"},
63
+ # {"pattern": r"Microsoft Windows Server", "platform": "windows-server"},
64
+ # {"pattern": r"Microsoft Windows 1[01]", "platform": "windows-desktop"},
65
+ # {"pattern": r"Ubuntu", "platform": "ubuntu"},
66
+ # {"pattern": r"CentOS", "platform": "centos"},
67
+ # {"pattern": r"Red Hat", "platform": "rhel"},
68
+ # {"pattern": r"Debian", "platform": "debian"},
69
+ # {"pattern": r"VMware Photon", "platform": "photon"},
70
+ # ]
71
+ "platform_mappings": [],
56
72
  }
57
73
 
58
74
 
netbox_vcenter/client.py CHANGED
@@ -70,9 +70,7 @@ class VCenterClient:
70
70
 
71
71
  def _get_objects_of_type(self, obj_type):
72
72
  """Get all objects of a specific type from vCenter."""
73
- view_mgr = self.content.viewManager.CreateContainerView(
74
- self.content.rootFolder, [obj_type], True
75
- )
73
+ view_mgr = self.content.viewManager.CreateContainerView(self.content.rootFolder, [obj_type], True)
76
74
  try:
77
75
  return list(view_mgr.view)
78
76
  finally:
@@ -127,9 +125,7 @@ class VCenterClient:
127
125
 
128
126
  # Calculate total disk capacity
129
127
  disk_devices = [
130
- device
131
- for device in vm.config.hardware.device
132
- if isinstance(device, vim.vm.device.VirtualDisk)
128
+ device for device in vm.config.hardware.device if isinstance(device, vim.vm.device.VirtualDisk)
133
129
  ]
134
130
  if disk_devices:
135
131
  total_kb = sum(d.capacityInKB for d in disk_devices)
netbox_vcenter/views.py CHANGED
@@ -4,16 +4,16 @@ import json
4
4
  import logging
5
5
  import re
6
6
 
7
+ from dcim.models import Platform
7
8
  from django.conf import settings
8
9
  from django.contrib import messages
9
10
  from django.core.cache import cache
10
11
  from django.shortcuts import redirect, render
11
12
  from django.utils import timezone
12
13
  from django.views.generic import View
13
- from dcim.models import Platform
14
14
  from extras.models import Tag
15
15
  from ipam.models import IPAddress
16
- from virtualization.models import Cluster, VMInterface, VirtualMachine
16
+ from virtualization.models import Cluster, VirtualMachine, VMInterface
17
17
 
18
18
  from .client import connect_and_fetch
19
19
  from .forms import VCenterConnectForm, VMImportForm
@@ -68,9 +68,45 @@ def get_import_config() -> dict:
68
68
  "default_tag": config.get("default_tag", ""),
69
69
  "default_role": config.get("default_role", ""),
70
70
  "default_platform": config.get("default_platform", ""),
71
+ "platform_mappings": config.get("platform_mappings", []),
71
72
  }
72
73
 
73
74
 
75
+ def get_platform_for_guest_os(guest_os: str, mappings: list) -> Platform | None:
76
+ """
77
+ Match vCenter guest OS to a NetBox platform using configured mappings.
78
+
79
+ Args:
80
+ guest_os: The guest OS string from vCenter (e.g., "Microsoft Windows Server 2019 (64-bit)")
81
+ mappings: List of dicts with "pattern" (regex) and "platform" (slug) keys
82
+
83
+ Returns:
84
+ Platform object if a match is found and platform exists, None otherwise
85
+ """
86
+ if not guest_os or not mappings:
87
+ return None
88
+
89
+ for mapping in mappings:
90
+ pattern = mapping.get("pattern", "")
91
+ platform_slug = mapping.get("platform", "")
92
+
93
+ if not pattern or not platform_slug:
94
+ continue
95
+
96
+ try:
97
+ if re.search(pattern, guest_os, re.IGNORECASE):
98
+ try:
99
+ return Platform.objects.get(slug=platform_slug)
100
+ except Platform.DoesNotExist:
101
+ logger.warning(f"Platform '{platform_slug}' not found for guest OS '{guest_os}'")
102
+ return None
103
+ except re.error:
104
+ logger.warning(f"Invalid regex pattern in platform_mappings: {pattern}")
105
+ continue
106
+
107
+ return None
108
+
109
+
74
110
  def get_name_for_import(vm_name: str, normalize: bool, mode: str, pattern: str) -> str:
75
111
  """
76
112
  Get the name to use when importing a VM.
@@ -364,6 +400,7 @@ class VMImportView(View):
364
400
  default_tag_slug = import_config["default_tag"]
365
401
  default_role_slug = import_config["default_role"]
366
402
  default_platform_slug = import_config["default_platform"]
403
+ platform_mappings = import_config["platform_mappings"]
367
404
 
368
405
  # Look up default tag, role, platform if configured
369
406
  default_tag = None
@@ -379,6 +416,7 @@ class VMImportView(View):
379
416
  if default_role_slug:
380
417
  try:
381
418
  from dcim.models import DeviceRole
419
+
382
420
  default_role = DeviceRole.objects.get(slug=default_role_slug)
383
421
  except Exception:
384
422
  logger.warning(f"Default role '{default_role_slug}' not found in NetBox")
@@ -423,8 +461,15 @@ class VMImportView(View):
423
461
  # Update role and platform if configured and not already set
424
462
  if default_role and not existing_vm.role:
425
463
  existing_vm.role = default_role
426
- if default_platform and not existing_vm.platform:
427
- existing_vm.platform = default_platform
464
+ if not existing_vm.platform:
465
+ if default_platform:
466
+ existing_vm.platform = default_platform
467
+ elif platform_mappings:
468
+ # Try to map guest OS to platform
469
+ guest_os = vm_data.get("guest_os")
470
+ mapped_platform = get_platform_for_guest_os(guest_os, platform_mappings)
471
+ if mapped_platform:
472
+ existing_vm.platform = mapped_platform
428
473
 
429
474
  # Update primary IP if available
430
475
  primary_ip = vm_data.get("primary_ip")
@@ -450,6 +495,12 @@ class VMImportView(View):
450
495
  # Determine status based on power state
451
496
  status = "active" if vm_data.get("power_state") == "on" else "offline"
452
497
 
498
+ # Determine platform - use default if set, otherwise try guest OS mapping
499
+ vm_platform = default_platform
500
+ if not vm_platform and platform_mappings:
501
+ guest_os = vm_data.get("guest_os")
502
+ vm_platform = get_platform_for_guest_os(guest_os, platform_mappings)
503
+
453
504
  # Create the VM with normalized or original name
454
505
  vm = VirtualMachine(
455
506
  name=import_name,
@@ -459,7 +510,7 @@ class VMImportView(View):
459
510
  disk=vm_data.get("disk_gb"),
460
511
  status=status,
461
512
  role=default_role,
462
- platform=default_platform,
513
+ platform=vm_platform,
463
514
  comments=f"Imported from vCenter {server} on {timezone.now().strftime('%Y-%m-%d %H:%M')}",
464
515
  )
465
516
  vm.full_clean()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-vcenter-server
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: NetBox plugin for viewing and importing VMs from VMware vCenter servers
5
5
  Author-email: sieteunoseis <jeremy.worden@gmail.com>
6
6
  License: Apache-2.0
@@ -29,7 +29,7 @@ Dynamic: license-file
29
29
 
30
30
  # NetBox vCenter Server Plugin
31
31
 
32
- <img src="docs/icon.png" alt="NetBox vCenter Server Plugin" width="100" align="right">
32
+ <img src="https://raw.githubusercontent.com/sieteunoseis/netbox-vcenter-server/master/docs/icon.png" alt="NetBox vCenter Server Plugin" width="100" align="right">
33
33
 
34
34
  A NetBox plugin for viewing and importing VMs from VMware vCenter servers.
35
35
 
@@ -46,7 +46,7 @@ A NetBox plugin for viewing and importing VMs from VMware vCenter servers.
46
46
  - **VM Import** - Import VMs from vCenter into NetBox with one click
47
47
  - **Comparison View** - Compare vCenter VMs with NetBox to find differences
48
48
  - **Manual Cache Control** - Data persists until you click Refresh
49
- - **Duo MFA Support** - Works with environments requiring Duo authentication
49
+ - **MFA/2FA Support** - Works with environments requiring multi-factor authentication
50
50
 
51
51
  ## Requirements
52
52
 
@@ -102,7 +102,7 @@ PLUGINS_CONFIG = {
102
102
  'verify_ssl': False, # SSL verification (False for self-signed certs)
103
103
  # MFA/2FA settings (optional)
104
104
  'mfa_enabled': True, # Show MFA warning in UI
105
- 'mfa_label': 'Duo', # Label shown: "Duo", "2FA", "MFA"
105
+ 'mfa_label': 'MFA', # Label shown in UI (e.g., "Duo", "2FA", "MFA")
106
106
  'mfa_message': 'Check your authenticator after clicking Connect & Sync.',
107
107
  # Name matching for duplicate detection
108
108
  # Options: "exact" (full name), "hostname" (strip domain), "regex"
@@ -125,7 +125,7 @@ PLUGINS_CONFIG = {
125
125
  2. Select a vCenter server from the dropdown
126
126
  3. Enter your username and password
127
127
  4. Click **Connect & Sync**
128
- 5. If Duo MFA is enabled, approve the push notification on your phone
128
+ 5. If MFA is enabled, approve the authentication prompt
129
129
  6. VMs will be fetched and cached (data persists until you click Refresh)
130
130
 
131
131
  ### Importing VMs to NetBox
@@ -156,7 +156,7 @@ PLUGINS_CONFIG = {
156
156
  - Verify vCenter hostname is reachable from the NetBox server
157
157
  - Check that credentials are correct (use `domain\username` format)
158
158
  - For self-signed certificates, set `verify_ssl: False`
159
- - If using Duo MFA, ensure you approve the push notification promptly
159
+ - If using MFA/2FA, ensure you approve the authentication prompt promptly
160
160
 
161
161
  ### Authentication issues
162
162
 
@@ -1,9 +1,9 @@
1
- netbox_vcenter/__init__.py,sha256=-eVgcHl5sr-4vltYmpLudS1UsyFRd4CstFuqsKGzGzQ,2373
2
- netbox_vcenter/client.py,sha256=d3SNie04scmICceEWtZodIvvigOBtghoX3BKsljJ3RI,8492
1
+ netbox_vcenter/__init__.py,sha256=s28pL0-z9QdZqQ_V8SdnPcLg4Ra0dYml-8KY2bpHlTU,3386
2
+ netbox_vcenter/client.py,sha256=_zRJQpZ-zlDwvVk87At-SHF7jTHBfP6Q3Z8CTvGV7GA,8422
3
3
  netbox_vcenter/forms.py,sha256=GC1LHmzwMLziNJ0V3KO1pTDJq35SHz56lYioN-BNvpk,2763
4
4
  netbox_vcenter/navigation.py,sha256=iQ5on_klzEI5rUsT4xXNTvP9vmtitiKVPiUd0r4HyuA,757
5
5
  netbox_vcenter/urls.py,sha256=EOu8qCSq_lAkN56SmPaHMidHPTzu-Jb13_NfxlaUOfI,509
6
- netbox_vcenter/views.py,sha256=xEdFXwrgYc_rFF_HvS9BEcjsaUMiryxwh9BTZeV9dvA,27518
6
+ netbox_vcenter/views.py,sha256=j9bMK2DhlQDHzTEaSHvY-uj-0OETyy4GWbWWQmoVm5Q,29635
7
7
  netbox_vcenter/api/__init__.py,sha256=f5d-0NprTQjL9t0TC9RuDlwCvkA7974Dbm_cuPI5FBY,44
8
8
  netbox_vcenter/api/urls.py,sha256=84-OcoT5K1jzckWIsFpAfstfFn8BCuMgMwE1tH8XtMY,103
9
9
  netbox_vcenter/templates/netbox_vcenter/compare.html,sha256=5b6bGQnxKlgB5OvTeHuBf53_c4mLIahTV_OB99Soai4,10412
@@ -11,8 +11,8 @@ netbox_vcenter/templates/netbox_vcenter/dashboard.html,sha256=umeT184bPDoWgA_8t2
11
11
  netbox_vcenter/templates/netbox_vcenter/import.html,sha256=Gv_e0VOEQnUxW6wxuLNIdzAYB-JW5CLeL7Afxz7b3lo,8052
12
12
  netbox_vcenter/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  netbox_vcenter/templatetags/vcenter_tags.py,sha256=Ca6X3yyH43M-YqbEkZqapnqM_4hOqf0g-N1PikfY9xY,327
14
- netbox_vcenter_server-0.2.0.dist-info/licenses/LICENSE,sha256=8-I2jh8bMe_hkWX6XfGtHF1aA6y1oqRusoMnkdmFzNA,10761
15
- netbox_vcenter_server-0.2.0.dist-info/METADATA,sha256=ULGNef1va9tw68BBUya7yekWIeccB8SbT5nOSE_-9Uw,6286
16
- netbox_vcenter_server-0.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
17
- netbox_vcenter_server-0.2.0.dist-info/top_level.txt,sha256=jvm95otBzT6WKAfIM_UXVqOeHYYL59zgpyEcLEk3G8g,15
18
- netbox_vcenter_server-0.2.0.dist-info/RECORD,,
14
+ netbox_vcenter_server-0.3.0.dist-info/licenses/LICENSE,sha256=8-I2jh8bMe_hkWX6XfGtHF1aA6y1oqRusoMnkdmFzNA,10761
15
+ netbox_vcenter_server-0.3.0.dist-info/METADATA,sha256=0tbf9Y3ZK7SSo4dksXJ5Tz6l9j0TplHACHMo84JvBRE,6374
16
+ netbox_vcenter_server-0.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
17
+ netbox_vcenter_server-0.3.0.dist-info/top_level.txt,sha256=jvm95otBzT6WKAfIM_UXVqOeHYYL59zgpyEcLEk3G8g,15
18
+ netbox_vcenter_server-0.3.0.dist-info/RECORD,,