osism 0.20250331.0__py3-none-any.whl → 0.20250425.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.
osism/utils/__init__.py CHANGED
@@ -1,13 +1,34 @@
1
1
  # SPDX-License-Identifier: Apache-2.0
2
2
 
3
3
  import keystoneauth1
4
+ from loguru import logger
4
5
  import openstack
5
6
  import pynetbox
6
7
  from redis import Redis
7
8
  import urllib3
9
+ import yaml
8
10
 
9
11
  from osism import settings
10
12
 
13
+
14
+ def get_netbox_connection(netbox_url, netbox_token, ignore_ssl_errors=False):
15
+ if netbox_url and netbox_token:
16
+ nb = pynetbox.api(netbox_url, token=netbox_token)
17
+
18
+ if ignore_ssl_errors and nb:
19
+ import requests
20
+
21
+ urllib3.disable_warnings()
22
+ session = requests.Session()
23
+ session.verify = False
24
+ nb.http_session = session
25
+
26
+ else:
27
+ nb = None
28
+
29
+ return nb
30
+
31
+
11
32
  redis = Redis(
12
33
  host=settings.REDIS_HOST,
13
34
  port=settings.REDIS_PORT,
@@ -16,19 +37,53 @@ redis = Redis(
16
37
  )
17
38
  redis.ping()
18
39
 
19
- if settings.NETBOX_URL and settings.NETBOX_TOKEN:
20
- nb = pynetbox.api(settings.NETBOX_URL, token=settings.NETBOX_TOKEN)
21
-
22
- if settings.IGNORE_SSL_ERRORS and nb:
23
- import requests
24
-
25
- urllib3.disable_warnings()
26
- session = requests.Session()
27
- session.verify = False
28
- nb.http_session = session
40
+ nb = get_netbox_connection(
41
+ settings.NETBOX_URL, settings.NETBOX_TOKEN, settings.IGNORE_SSL_ERRORS
42
+ )
29
43
 
30
- else:
31
- nb = None
44
+ try:
45
+ secondary_nb_settings_list = yaml.safe_load(settings.NETBOX_SECONDARIES)
46
+ supported_secondary_nb_keys = ["NETBOX_URL", "NETBOX_TOKEN", "IGNORE_SSL_ERRORS"]
47
+ secondary_nb_list = []
48
+ if type(secondary_nb_settings_list) is not list:
49
+ raise TypeError(
50
+ f"Setting NETBOX_SECONDARIES needs to be an array of mappings containing supported netbox API configuration: {supported_secondary_nb_keys}"
51
+ )
52
+ for secondary_nb_settings in secondary_nb_settings_list:
53
+ if type(secondary_nb_settings) is not dict:
54
+ raise TypeError(
55
+ f"Elements in setting NETBOX_SECONDARIES need to be mappings containing supported netbox API configuration: {supported_secondary_nb_keys}"
56
+ )
57
+ for key in list(secondary_nb_settings.keys()):
58
+ if key not in supported_secondary_nb_keys:
59
+ raise ValueError(
60
+ f"Unknown key in element of setting NETBOX_SECONDARIES. Supported keys: {supported_secondary_nb_keys}"
61
+ )
62
+ if (
63
+ "NETBOX_URL" not in secondary_nb_settings
64
+ or not secondary_nb_settings["NETBOX_URL"]
65
+ ):
66
+ raise ValueError(
67
+ "All NETBOX_URL values in the elements of setting NETBOX_SECONDARIES need to be valid netbox URLs"
68
+ )
69
+ if (
70
+ "NETBOX_TOKEN" not in secondary_nb_settings
71
+ or not secondary_nb_settings["NETBOX_TOKEN"]
72
+ ):
73
+ raise ValueError(
74
+ "All NETBOX_TOKEN values in the elements of setting NETBOX_SECONDARIES need to be valid netbox tokens"
75
+ )
76
+
77
+ secondary_nb_list.append(
78
+ get_netbox_connection(
79
+ secondary_nb_settings["NETBOX_URL"],
80
+ secondary_nb_settings["NETBOX_TOKEN"],
81
+ secondary_nb_settings.get("IGNORE_SSL_ERRORS", True),
82
+ )
83
+ )
84
+ except (yaml.YAMLError, TypeError, ValueError) as exc:
85
+ logger.error(f"Error parsing settings NETBOX_SECONDARIES: {exc}")
86
+ secondary_nb_list = []
32
87
 
33
88
 
34
89
  def get_openstack_connection():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osism
3
- Version: 0.20250331.0
3
+ Version: 0.20250425.0
4
4
  Summary: OSISM manager interface
5
5
  Home-page: https://github.com/osism/python-osism
6
6
  Author: OSISM GmbH
@@ -27,7 +27,7 @@ Requires-Dist: GitPython==3.1.44
27
27
  Requires-Dist: Jinja2==3.1.6
28
28
  Requires-Dist: PyYAML==6.0.2
29
29
  Requires-Dist: ara==1.7.2
30
- Requires-Dist: celery[redis]==5.4.0
30
+ Requires-Dist: celery[redis]==5.5.1
31
31
  Requires-Dist: cliff==4.9.1
32
32
  Requires-Dist: deepdiff==8.4.2
33
33
  Requires-Dist: docker==7.1.0
@@ -37,31 +37,31 @@ Requires-Dist: flower==2.0.1
37
37
  Requires-Dist: hiredis==3.1.0
38
38
  Requires-Dist: jc==1.25.4
39
39
  Requires-Dist: keystoneauth1==5.10.0
40
- Requires-Dist: kombu==5.5.2
40
+ Requires-Dist: kombu==5.5.3
41
41
  Requires-Dist: kubernetes==32.0.1
42
42
  Requires-Dist: loguru==0.7.3
43
43
  Requires-Dist: netmiko==4.5.0
44
44
  Requires-Dist: nornir-ansible==2023.12.28
45
45
  Requires-Dist: nornir==3.5.0
46
- Requires-Dist: openstacksdk==4.4.0
46
+ Requires-Dist: openstacksdk==4.5.0
47
47
  Requires-Dist: pottery==3.0.1
48
- Requires-Dist: prompt-toolkit==3.0.50
49
- Requires-Dist: pydantic==1.10.21
48
+ Requires-Dist: prompt-toolkit==3.0.51
49
+ Requires-Dist: pydantic==1.10.22
50
50
  Requires-Dist: pynetbox==7.4.1
51
51
  Requires-Dist: pytest-testinfra==10.2.2
52
52
  Requires-Dist: python-dateutil==2.9.0.post0
53
- Requires-Dist: setuptools==78.1.0
53
+ Requires-Dist: setuptools==79.0.1
54
54
  Requires-Dist: sqlmodel==0.0.24
55
55
  Requires-Dist: sushy==5.5.0
56
56
  Requires-Dist: tabulate==0.9.0
57
57
  Requires-Dist: transitions==0.9.2
58
- Requires-Dist: uvicorn[standard]==0.34.0
58
+ Requires-Dist: uvicorn[standard]==0.34.2
59
59
  Requires-Dist: watchdog==6.0.0
60
60
  Provides-Extra: ansible
61
61
  Requires-Dist: ansible-runner==2.4.1; extra == "ansible"
62
- Requires-Dist: ansible-core==2.18.4; extra == "ansible"
62
+ Requires-Dist: ansible-core==2.18.5; extra == "ansible"
63
63
  Provides-Extra: openstack-image-manager
64
- Requires-Dist: openstack-image-manager==0.20250314.0; extra == "openstack-image-manager"
64
+ Requires-Dist: openstack-image-manager==0.20250423.0; extra == "openstack-image-manager"
65
65
  Dynamic: author
66
66
  Dynamic: author-email
67
67
  Dynamic: classifier
@@ -1,11 +1,9 @@
1
1
  osism/__init__.py,sha256=1UiNTBus0V0f2AbZQzAtVtu6zkfCCrw0OTq--NwFAqY,341
2
2
  osism/__main__.py,sha256=ILe4gu61xEISiBsxanqTQIdSkV-YhpZXTRlguCYyssk,141
3
- osism/api.py,sha256=Lvkdd92tvv9RtoMs9RtvqsN3DiSKPdSll24J3wRzbBY,4793
3
+ osism/api.py,sha256=xJC6RyC1TU54PU2C06rlialh2SmTCgM1L0MSgyUlubU,4331
4
4
  osism/main.py,sha256=Dt2-9sLXcS-Ny4DAz7hrha-KRc7zd7BFUTRdfs_X8z4,893
5
- osism/settings.py,sha256=m__DltxKQo5D-vDKKwY8RNBVs5bverYdJmtyVyln_6o,1049
5
+ osism/settings.py,sha256=xzFRbf5mdl_MUAUFqPavE14vaVuTr5z6b969vJQvF2E,1306
6
6
  osism/actions/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
7
- osism/actions/manage_device.py,sha256=joQwPnwEUw5V1ZRRbdrM0FjfNlG4vPNc0r8FBRTOJiA,3541
8
- osism/actions/manage_interface.py,sha256=iDp7zY16XXtwdLk1sxa-TBAkpdPxmtbVeEvMZuP5h4s,472
9
7
  osism/commands/__init__.py,sha256=Ag4wX_DCgXRdoLn6t069jqb3DdRylsX2nyYkiyCx4uk,456
10
8
  osism/commands/apply.py,sha256=n3lLb1cS3GahQqRT0723di98hg47MjVzDzkAoeZX7qU,16780
11
9
  osism/commands/compose.py,sha256=iqzG7mS9E1VWaLNN6yQowjOqiHn3BMdj-yfXb3Dc4Ok,1200
@@ -15,11 +13,11 @@ osism/commands/console.py,sha256=8BPz1hio5Wi6kONVAWFuSqkDRrMcLEYeFIY8dbtN6e4,321
15
13
  osism/commands/container.py,sha256=Fku2GaCM3Idq_FxExUtNqjrEM0XYjpVvXmueSVO8S_c,1601
16
14
  osism/commands/get.py,sha256=ryytjtXWmlMV0NucP5tGkMZu0nIlC4xVtjRk4iMZ06c,8967
17
15
  osism/commands/log.py,sha256=2IpYuosC7FZwwLvM8HmKSU1NRNIelVVYzqjjVMCrOJk,4072
18
- osism/commands/manage.py,sha256=SDJyH3zwdaOjVWURIIjm8WMo6zSor1Y_TiTYgeMt4pI,11932
19
- osism/commands/netbox.py,sha256=FYBHcOR_cO-n7rcf4V_-DbwUCgMLFmrrPKCjd0zQOp4,4548
16
+ osism/commands/manage.py,sha256=5ypZzA91QGgWCt35rVNJSXVC9l189IntS4UnsD8LRZY,11971
17
+ osism/commands/netbox.py,sha256=_2-j6XM9JvH0DXnbct6rG9T6hT8KEpm3vazQC28Rt7I,4529
20
18
  osism/commands/noset.py,sha256=7zDFuFMyNpo7DUOKcNiYV8nodtdMOYFp5LDPcuJhlZ8,1481
21
19
  osism/commands/reconciler.py,sha256=Ja_b86gX6-_Pr3DmrUUvskmEnnJpHQ-XJNQLycMJeyc,2818
22
- osism/commands/server.py,sha256=zFXRdYoj4ZNDJNPSaGddMPEWxt8G2GyMomPOcCOaN3c,4137
20
+ osism/commands/server.py,sha256=avmoOv5rjOi-fN2A-27cPwOtiy2Q2j6UFtCh3QrfWAI,7512
23
21
  osism/commands/service.py,sha256=A1lgAlGeCJpbFFqF55DRWPcCirIgpU0dzjzVLZ0mz3k,2649
24
22
  osism/commands/set.py,sha256=xLBi2DzbVQo2jb3-cOIE9In5UB3vFxquQJkDN-EsfhM,1425
25
23
  osism/commands/status.py,sha256=X-Rcj-XuNPDBoxsGkf96NswwpmTognxz1V6E2NX2ZgY,1997
@@ -27,31 +25,31 @@ osism/commands/sync.py,sha256=Vf9k7uVQTIu-8kK1u7Gjs3et3RRBEkmnNikot_PFJIE,484
27
25
  osism/commands/task.py,sha256=mwJJ7a71Lw3o_FX7j3rR0-NbPdPwMDOjbOAiiXE4uGc,543
28
26
  osism/commands/validate.py,sha256=hIQB0zk4xIBZJORtBp_tWrXTRKKhB2qi6j-mznDxKR4,4191
29
27
  osism/commands/vault.py,sha256=Ip0IMR7zaBkPbLJenXr4ZwxM6FnozZ9wn9rwHmFHo8s,1818
30
- osism/commands/volume.py,sha256=SqD9pYgtcYnMu6sB2pG8lfrLHRq6GzOb_-RkWOOVZPo,3156
28
+ osism/commands/volume.py,sha256=l6oAk__dFM8KKdLTWOvuSiI7tLh9wAPZp8hwmYF-NX0,6595
31
29
  osism/commands/wait.py,sha256=mKFDqEXcaLlKw1T3MuBEZpNh7CeL3lpUXgubD2_f8es,6580
32
30
  osism/commands/worker.py,sha256=iraCOEhCp7WgfjfZ0-12XQYQPUjpi9rSJK5Z9JfNJk4,1651
33
31
  osism/core/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
34
- osism/core/enums.py,sha256=UDV3WoOp9kfGTPCQ94tr-2v6c07pNP2kYrxxv6pwxDI,9638
32
+ osism/core/enums.py,sha256=ldH2wM0mea7oHBSCrxEyCqkjH_R2kc8wmdI2J9eb6sM,9952
35
33
  osism/core/playbooks.py,sha256=M3T3ajV-8Lt-orsRO3jAoukhaoYFr4EZ2dzYXQjt1kg,728
36
34
  osism/data/__init__.py,sha256=izXdh0J3vPLQI7kBhJI7ibJQzPqU_nlONP0L4Cf_k6A,1504
37
35
  osism/plugins/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
38
36
  osism/services/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
39
- osism/services/listener.py,sha256=JjCdwPG5U9b_xYDpGFQeiLPP4y00GM3Me6NW1tt6Jws,11275
40
- osism/tasks/__init__.py,sha256=lrSkcZtbzhWsLS4hWadKfpP_tCd1pX1IhvrBU3EhKmM,8605
37
+ osism/services/listener.py,sha256=eEamlQsJqCuU9K2QFmk3yM9LAJZEanVcTLtGMsNCKjs,9783
38
+ osism/tasks/__init__.py,sha256=ZEu_KYsapTYp0etr-rLqie_NT_LndHDDpx53xITru5Y,8691
41
39
  osism/tasks/ansible.py,sha256=RcLxLrjzL5_X6OjNHm3H0lZlmKKlYKIANB0M4_d4chE,1109
42
40
  osism/tasks/ceph.py,sha256=eIQkah3Kj4INtOkF9kTjHbXJ3_J2lg48EWJKfHc-UYw,615
43
- osism/tasks/conductor.py,sha256=P52Avy8OgNQ4koZp3QZLXJiN9uIiBcqrmDpc3UXsPzs,3639
41
+ osism/tasks/conductor.py,sha256=JlfSMgwwiXVjVk6HGwAtoJCyZO_qbY_O4tLtz7ibHKg,21039
44
42
  osism/tasks/kolla.py,sha256=wJQpWn_01iWLkr7l7T7RNrQGfRgsgmYi4WQlTmNGvew,618
45
43
  osism/tasks/kubernetes.py,sha256=VzXq_VrYU_CLm4cOruqnE3Kq2ydfO9glZ3p0bp3OYoc,625
46
- osism/tasks/netbox.py,sha256=JTgMLp5WAGoupU5Os6xWnKHXACxfXVS33wM1rvbz6Y0,4432
47
- osism/tasks/openstack.py,sha256=nhHiEcmI_AjM-oYnqjlJ0-c9qYZRQeruOTJsLbScxKI,10258
44
+ osism/tasks/netbox.py,sha256=QVOLiTH2Su237YAS0QfXbQ86E-OA1JzrFDfyi9JBmvk,5658
45
+ osism/tasks/openstack.py,sha256=J0dvJYUWT1182LArm8UXplVpK5bNWSAdiHYR7urh2GM,7941
48
46
  osism/tasks/reconciler.py,sha256=RGUcax2gDuyVLw1nGRQn5izXclnPBo9MRl0ndLDiiYQ,2707
49
- osism/utils/__init__.py,sha256=DP2D7xyXnfWuH-c26elIwdwrMSY-oSkVsLFKsQfna9w,1477
50
- osism-0.20250331.0.dist-info/licenses/AUTHORS,sha256=EKFIR9F27AvoEXp1cA6FkGbjEOFt4Rcbipr5RJc7jSs,64
51
- osism-0.20250331.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
52
- osism-0.20250331.0.dist-info/METADATA,sha256=0iUarhckKfE774zkRlFp8Pn21wK2bW30nztf0udL2t8,2972
53
- osism-0.20250331.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
54
- osism-0.20250331.0.dist-info/entry_points.txt,sha256=DlfrvU14rI55WuTrwNRoce9FY3ric4HeZKZx_Z3NzCw,3015
55
- osism-0.20250331.0.dist-info/pbr.json,sha256=dAx-E5EYMfbySf6Y9YoFJwWMs-TE1eIlvi2JwTL12Nw,47
56
- osism-0.20250331.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
57
- osism-0.20250331.0.dist-info/RECORD,,
47
+ osism/utils/__init__.py,sha256=_uhe9ghqAJ2me0p187X-vzJ2Nh_Hpmfw3D6HU4kKa10,3759
48
+ osism-0.20250425.0.dist-info/licenses/AUTHORS,sha256=DJIRsjyrFxKjFvmpUNDRDBS04nRiJ5B6FpKcDcfnoGM,36
49
+ osism-0.20250425.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
50
+ osism-0.20250425.0.dist-info/METADATA,sha256=rofd2A8V3RZhLVaC0Y7qmKQuWCmjNSjickRtZIg5U-g,2972
51
+ osism-0.20250425.0.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
52
+ osism-0.20250425.0.dist-info/entry_points.txt,sha256=DlfrvU14rI55WuTrwNRoce9FY3ric4HeZKZx_Z3NzCw,3015
53
+ osism-0.20250425.0.dist-info/pbr.json,sha256=qcrfoQrh4nhmive5GikkS5SflAbt999idvJgP56J1JY,47
54
+ osism-0.20250425.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
55
+ osism-0.20250425.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1 @@
1
+ janhorstmann <horstmann@osism.tech>
@@ -0,0 +1 @@
1
+ {"git_version": "121615f", "is_release": false}
@@ -1,120 +0,0 @@
1
- # SPDX-License-Identifier: CC-BY-NC-4.0
2
- # Copyright OSISM GmbH, 2022-2023
3
-
4
- from loguru import logger
5
- from pottery import Redlock
6
-
7
- from osism import utils
8
-
9
-
10
- def get_state(device):
11
- """Gets the state (device_state) stored in the Netbox for a device."""
12
-
13
- result = None
14
- device_a = utils.nb.dcim.devices.get(name=device)
15
- result = device_a.custom_fields["device_state"]
16
-
17
- return result
18
-
19
-
20
- def get_states(devices):
21
- """Gets the state (device_state) stored in the Netbox for a list of devices."""
22
-
23
- result = {}
24
- for device in devices:
25
- device_a = utils.nb.dcim.devices.get(name=device)
26
- result[device] = device_a.custom_fields["device_state"]
27
-
28
- return result
29
-
30
-
31
- def set_maintenance(device, state):
32
- """Set the maintenance state for a device in the Netbox."""
33
-
34
- logger.info(f"Set maintenance state of device {device} = {state}")
35
-
36
- device_a = utils.nb.dcim.devices.get(name=device)
37
- device_a.custom_fields = {"maintenance": state}
38
- device_a.save()
39
-
40
-
41
- def set_ironic_state(device, state):
42
- """Set the ironic state (ironic_state) for a device in the Netbox."""
43
-
44
- logger.info(f"Set ironic state of device {device} = {state}")
45
-
46
- device_a = utils.nb.dcim.devices.get(name=device)
47
- device_a.custom_fields = {"ironic_state": state}
48
- device_a.save()
49
-
50
-
51
- def set_introspection_state(device, state):
52
- """Set the introspection state (introspection_state) for a device in the Netbox."""
53
-
54
- logger.info(f"Set introspection state of device {device} = {state}")
55
-
56
- device_a = utils.nb.dcim.devices.get(name=device)
57
- device_a.custom_fields = {"introspection_state": state}
58
- device_a.save()
59
-
60
-
61
- def set_deployment_state(device, state):
62
- """Set the deployment state (deployment_state) for a device in the Netbox."""
63
-
64
- logger.info(f"Set deployment state of device {device} = {state}")
65
-
66
- device_a = utils.nb.dcim.devices.get(name=device)
67
- device_a.custom_fields = {"deployment_state": state}
68
- device_a.save()
69
-
70
-
71
- def set_device_state(device, state):
72
- """Set the state (device_state) for a device in the Netbox."""
73
-
74
- logger.info(f"Set state of device {device} = {state}")
75
-
76
- device_a = utils.nb.dcim.devices.get(name=device)
77
- device_a.custom_fields = {"device_state": state}
78
- device_a.save()
79
-
80
-
81
- def set_state(device, state, state_type):
82
- """Set the state for a device in the Netbox."""
83
-
84
- lock = Redlock(key=f"lock_state_{device}", masters={utils.redis})
85
- lock.acquire()
86
-
87
- if state_type == "power":
88
- set_power_state(device, state)
89
- elif state_type == "provision":
90
- set_provision_state(device, state)
91
- elif state_type == "introspection":
92
- set_introspection_state(device, state)
93
- elif state_type == "ironic":
94
- set_ironic_state(device, state)
95
- elif state_type == "deployment":
96
- set_deployment_state(device, state)
97
- else:
98
- set_device_state(device, state)
99
-
100
- lock.release()
101
-
102
-
103
- def set_provision_state(device, state):
104
- """Set the provision state (provision_state) for a device in the Netbox."""
105
-
106
- logger.info(f"Set provision state of device {device} = {state}")
107
-
108
- device_a = utils.nb.dcim.devices.get(name=device)
109
- device_a.custom_fields = {"provision_state": state}
110
- device_a.save()
111
-
112
-
113
- def set_power_state(device, state):
114
- """Set the power state (power_state) for a device in the Netbox."""
115
-
116
- logger.info(f"Set power state of device {device} = {state}")
117
-
118
- device_a = utils.nb.dcim.devices.get(name=device)
119
- device_a.custom_fields = {"power_state": state}
120
- device_a.save()
@@ -1,13 +0,0 @@
1
- # SPDX-License-Identifier: CC-BY-NC-4.0
2
- # Copyright OSISM GmbH, 2022-2023
3
-
4
- from osism import utils
5
-
6
-
7
- def update_network_interface_name(mac_address, network_interface_name):
8
- """Sets the network interface name from a performed
9
- introspection for an interface with a given MAC address."""
10
-
11
- interface_a = utils.nb.dcim.interfaces.get(mac_address=mac_address)
12
- interface_a.custom_fields = {"network_interface_name": network_interface_name}
13
- interface_a.save()
@@ -1 +0,0 @@
1
- renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@@ -1 +0,0 @@
1
- {"git_version": "8324e98", "is_release": false}