|
25 | 25 | from module.common.misc import grab, dump, get_string_or_none, plural |
26 | 26 | from module.common.support import normalize_mac_address, ip_valid_to_add_to_netbox |
27 | 27 | from module.netbox.object_classes import ( |
| 28 | + NetBoxObject, |
28 | 29 | NetBoxInterfaceType, |
29 | 30 | NBTag, |
30 | 31 | NBManufacturer, |
|
43 | 44 | NBPrefix, |
44 | 45 | NBTenant, |
45 | 46 | NBVRF, |
46 | | - NBVLAN |
| 47 | + NBVLAN, |
| 48 | + NBCustomField |
47 | 49 | ) |
48 | 50 |
|
49 | 51 | vsphere_automation_sdk_available = True |
@@ -82,7 +84,8 @@ class VMWareHandler(SourceBase): |
82 | 84 | NBPrefix, |
83 | 85 | NBTenant, |
84 | 86 | NBVRF, |
85 | | - NBVLAN |
| 87 | + NBVLAN, |
| 88 | + NBCustomField |
86 | 89 | ] |
87 | 90 |
|
88 | 91 | settings = { |
@@ -120,7 +123,8 @@ class VMWareHandler(SourceBase): |
120 | 123 | "strip_host_domain_name": False, |
121 | 124 | "strip_vm_domain_name": False, |
122 | 125 | "sync_tags": False, |
123 | | - "sync_parent_tags": False |
| 126 | + "sync_parent_tags": False, |
| 127 | + "sync_custom_attributes": False |
124 | 128 | } |
125 | 129 |
|
126 | 130 | deprecated_settings = {} |
@@ -772,6 +776,61 @@ def get_object_tags(self, obj, parent=False): |
772 | 776 |
|
773 | 777 | return tag_list |
774 | 778 |
|
| 779 | + def get_object_custom_fields(self, obj): |
| 780 | + """ |
| 781 | + Get custom attributes from vCenter for submitted object and as NetBox custom fields |
| 782 | +
|
| 783 | + Parameters |
| 784 | + ---------- |
| 785 | + obj |
| 786 | + pyvmomi object to retrieve custom attributes from |
| 787 | +
|
| 788 | + Returns |
| 789 | + ------- |
| 790 | + custom_fields: dict |
| 791 | + dictionary with assigned custom fields |
| 792 | + """ |
| 793 | + |
| 794 | + return_custom_fields = dict() |
| 795 | + |
| 796 | + custom_value = grab(obj, "customValue", fallback=list()) |
| 797 | + |
| 798 | + if self.sync_custom_attributes is False or len(custom_value) == 0: |
| 799 | + return return_custom_fields |
| 800 | + |
| 801 | + if grab(obj, "_wsdlName") == "VirtualMachine": |
| 802 | + content_type = "virtualization.virtualmachine" |
| 803 | + else: |
| 804 | + content_type = "dcim.device" |
| 805 | + |
| 806 | + field_definition = {grab(k, "key"): grab(k, "name") for k in grab(obj, "availableField", fallback=list())} |
| 807 | + |
| 808 | + for obj_custom_field in custom_value: |
| 809 | + key = grab(obj_custom_field, "key") |
| 810 | + value = grab(obj_custom_field, "value") |
| 811 | + |
| 812 | + if key is None or value is None: |
| 813 | + continue |
| 814 | + |
| 815 | + label = field_definition.get(key) |
| 816 | + |
| 817 | + if label is None: |
| 818 | + continue |
| 819 | + |
| 820 | + name = NetBoxObject.format_slug(f"vcsa-{label}", 50).replace("--", "-").strip("-") |
| 821 | + |
| 822 | + self.add_update_custom_field({ |
| 823 | + "name": name, |
| 824 | + "label": label, |
| 825 | + "content_types": [content_type], |
| 826 | + "type": "text", |
| 827 | + "description": f"vCenter '{self.name}' synced custom attribute '{label}'" |
| 828 | + }) |
| 829 | + |
| 830 | + return_custom_fields[name] = value |
| 831 | + |
| 832 | + return return_custom_fields |
| 833 | + |
775 | 834 | def get_object_relation(self, name, relation, fallback=None): |
776 | 835 | """ |
777 | 836 |
|
@@ -1365,6 +1424,11 @@ def add_host(self, obj): |
1365 | 1424 | if len(host_tags) > 0: |
1366 | 1425 | host_data["tags"] = host_tags |
1367 | 1426 |
|
| 1427 | + # add custom fields if present and configured |
| 1428 | + host_custom_fields = self.get_object_custom_fields(obj) |
| 1429 | + if len(host_custom_fields) > 0: |
| 1430 | + host_data["custom_fields"] = host_custom_fields |
| 1431 | + |
1368 | 1432 | # iterate over hosts virtual switches, needed to enrich data on physical interfaces |
1369 | 1433 | self.network_data["vswitch"][name] = dict() |
1370 | 1434 | for vswitch in grab(obj, "config.network.vswitch", fallback=list()): |
@@ -1824,6 +1888,11 @@ def add_virtual_machine(self, obj): |
1824 | 1888 | if len(vm_tags) > 0: |
1825 | 1889 | vm_data["tags"] = vm_tags |
1826 | 1890 |
|
| 1891 | + # add custom fields if present and configured |
| 1892 | + vm_custom_fields = self.get_object_custom_fields(obj) |
| 1893 | + if len(vm_custom_fields) > 0: |
| 1894 | + vm_data["custom_fields"] = vm_custom_fields |
| 1895 | + |
1827 | 1896 | vm_primary_ip4 = None |
1828 | 1897 | vm_primary_ip6 = None |
1829 | 1898 | vm_default_gateway_ip4 = None |
|
0 commit comments