WIP - netbox integration in CI #112
8 changed files with 134 additions and 17 deletions
|
@ -5,3 +5,5 @@ pytest-cov
|
||||||
flake8
|
flake8
|
||||||
flake8-isort
|
flake8-isort
|
||||||
tox
|
tox
|
||||||
|
mock
|
||||||
|
pyfakefs
|
||||||
|
|
|
@ -37,7 +37,12 @@ class IPMI():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
try:
|
||||||
self.ret, self.output = subprocess.getstatusoutput('ipmitool lan print')
|
self.ret, self.output = subprocess.getstatusoutput('ipmitool lan print')
|
||||||
|
except Exception as e:
|
||||||
|
self.ret = 42
|
||||||
|
self.output = str(e)
|
||||||
|
|
||||||
if self.ret != 0:
|
if self.ret != 0:
|
||||||
logging.error('Cannot get ipmi info: {}'.format(self.output))
|
logging.error('Cannot get ipmi info: {}'.format(self.output))
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ def get_fixture_paths(path):
|
||||||
|
|
||||||
|
|
||||||
def parametrize_with_fixtures(path, base_path='tests/fixtures',
|
def parametrize_with_fixtures(path, base_path='tests/fixtures',
|
||||||
argname='fixture', only_filenames=None):
|
argname='dmi_fixture', only_filenames=None):
|
||||||
path = os.path.join(base_path, path)
|
path = os.path.join(base_path, path)
|
||||||
fixture_paths = get_fixture_paths(path)
|
fixture_paths = get_fixture_paths(path)
|
||||||
argvalues = []
|
argvalues = []
|
||||||
|
|
1
tests/constants.py
Normal file
1
tests/constants.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
DEFAULT_DATACENTER = 'DC1'
|
6
tests/fixtures/dmidecode/HP_SL4540_Gen8
vendored
6
tests/fixtures/dmidecode/HP_SL4540_Gen8
vendored
|
@ -829,7 +829,7 @@ System Power Supply
|
||||||
Location: Not Specified
|
Location: Not Specified
|
||||||
Name: Power Supply 2
|
Name: Power Supply 2
|
||||||
Manufacturer: HP
|
Manufacturer: HP
|
||||||
Serial Number: 4242
|
Serial Number: 4243
|
||||||
Asset Tag: Not Specified
|
Asset Tag: Not Specified
|
||||||
Model Part Number: 656364-B21
|
Model Part Number: 656364-B21
|
||||||
Revision: Not Specified
|
Revision: Not Specified
|
||||||
|
@ -846,7 +846,7 @@ System Power Supply
|
||||||
Location: Not Specified
|
Location: Not Specified
|
||||||
Name: Power Supply 3
|
Name: Power Supply 3
|
||||||
Manufacturer: HP
|
Manufacturer: HP
|
||||||
Serial Number: 4242
|
Serial Number: 4244
|
||||||
Asset Tag: Not Specified
|
Asset Tag: Not Specified
|
||||||
Model Part Number: 656364-B21
|
Model Part Number: 656364-B21
|
||||||
Revision: Not Specified
|
Revision: Not Specified
|
||||||
|
@ -863,7 +863,7 @@ System Power Supply
|
||||||
Location: Not Specified
|
Location: Not Specified
|
||||||
Name: Power Supply 4
|
Name: Power Supply 4
|
||||||
Manufacturer: HP
|
Manufacturer: HP
|
||||||
Serial Number: 4242
|
Serial Number: 4245
|
||||||
Asset Tag: Not Specified
|
Asset Tag: Not Specified
|
||||||
Model Part Number: 656364-B21
|
Model Part Number: 656364-B21
|
||||||
Revision: Not Specified
|
Revision: Not Specified
|
||||||
|
|
|
@ -6,8 +6,8 @@ from tests.conftest import parametrize_with_fixtures
|
||||||
'lldp/', only_filenames=[
|
'lldp/', only_filenames=[
|
||||||
'dedibox1.txt',
|
'dedibox1.txt',
|
||||||
])
|
])
|
||||||
def test_lldp_parse_with_port_desc(fixture):
|
def test_lldp_parse_with_port_desc(dmi_fixture):
|
||||||
lldp = LLDP(fixture)
|
lldp = LLDP(dmi_fixture)
|
||||||
assert lldp.get_switch_port('enp1s0f0') == 'RJ-9'
|
assert lldp.get_switch_port('enp1s0f0') == 'RJ-9'
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,6 @@ def test_lldp_parse_with_port_desc(fixture):
|
||||||
'lldp/', only_filenames=[
|
'lldp/', only_filenames=[
|
||||||
'qfx.txt',
|
'qfx.txt',
|
||||||
])
|
])
|
||||||
def test_lldp_parse_without_ifname(fixture):
|
def test_lldp_parse_without_ifname(dmi_fixture):
|
||||||
lldp = LLDP(fixture)
|
lldp = LLDP(dmi_fixture)
|
||||||
assert lldp.get_switch_port('eth0') == 'xe-0/0/1'
|
assert lldp.get_switch_port('eth0') == 'xe-0/0/1'
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import netifaces
|
||||||
|
|
||||||
|
from netbox_agent.config import config
|
||||||
|
from netbox_agent.config import netbox_instance as nb
|
||||||
from netbox_agent.dmidecode import parse
|
from netbox_agent.dmidecode import parse
|
||||||
from netbox_agent.server import ServerBase
|
from netbox_agent.server import ServerBase
|
||||||
|
from netbox_agent.vendors.hp import HPHost
|
||||||
from tests.conftest import parametrize_with_fixtures
|
from tests.conftest import parametrize_with_fixtures
|
||||||
|
from tests.constants import DEFAULT_DATACENTER
|
||||||
|
from tests.utils import setup_netbox
|
||||||
|
|
||||||
|
|
||||||
@parametrize_with_fixtures('dmidecode/')
|
@parametrize_with_fixtures('dmidecode/')
|
||||||
def test_init(fixture):
|
def test_init(dmi_fixture):
|
||||||
dmi = parse(fixture)
|
dmi = parse(dmi_fixture)
|
||||||
server = ServerBase(dmi)
|
server = ServerBase(dmi)
|
||||||
assert server
|
assert server
|
||||||
|
|
||||||
|
@ -17,8 +26,8 @@ def test_init(fixture):
|
||||||
'HP_DL380p_Gen8',
|
'HP_DL380p_Gen8',
|
||||||
'HP_SL4540_Gen8'
|
'HP_SL4540_Gen8'
|
||||||
])
|
])
|
||||||
def test_hp_service_tag(fixture):
|
def test_hp_service_tag(dmi_fixture):
|
||||||
dmi = parse(fixture)
|
dmi = parse(dmi_fixture)
|
||||||
server = ServerBase(dmi)
|
server = ServerBase(dmi)
|
||||||
assert server.get_service_tag() == '4242'
|
assert server.get_service_tag() == '4242'
|
||||||
|
|
||||||
|
@ -27,8 +36,8 @@ def test_hp_service_tag(fixture):
|
||||||
'dmidecode/', only_filenames=[
|
'dmidecode/', only_filenames=[
|
||||||
'unknown.txt'
|
'unknown.txt'
|
||||||
])
|
])
|
||||||
def test_generic_host_service_tag(fixture):
|
def test_generic_host_service_tag(dmi_fixture):
|
||||||
dmi = parse(fixture)
|
dmi = parse(dmi_fixture)
|
||||||
server = ServerBase(dmi)
|
server = ServerBase(dmi)
|
||||||
assert server.get_service_tag() == '42'
|
assert server.get_service_tag() == '42'
|
||||||
|
|
||||||
|
@ -37,7 +46,56 @@ def test_generic_host_service_tag(fixture):
|
||||||
'dmidecode/', only_filenames=[
|
'dmidecode/', only_filenames=[
|
||||||
'unknown.txt'
|
'unknown.txt'
|
||||||
])
|
])
|
||||||
def test_generic_host_product_name(fixture):
|
def test_generic_host_product_name(dmi_fixture):
|
||||||
dmi = parse(fixture)
|
dmi = parse(dmi_fixture)
|
||||||
server = ServerBase(dmi)
|
server = ServerBase(dmi)
|
||||||
assert server.get_product_name() == 'SR'
|
assert server.get_product_name() == 'SR'
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('netifaces.ifaddresses')
|
||||||
|
@mock.patch('netifaces.interfaces')
|
||||||
|
@parametrize_with_fixtures(
|
||||||
|
'dmidecode/', only_filenames=[
|
||||||
|
'HP_SL4540_Gen8',
|
||||||
|
], argname='dmi_fixture')
|
||||||
|
def test_create_server(
|
||||||
|
mock_interfaces,
|
||||||
|
mock_ifaddresses,
|
||||||
|
fs,
|
||||||
|
dmi_fixture,
|
||||||
|
):
|
||||||
|
fake_addresses = {}
|
||||||
|
fake_addresses[netifaces.AF_INET] = [{'addr': '42.42.42.42', 'netmask': '255.255.255.0'}]
|
||||||
|
fake_addresses[netifaces.AF_LINK] = [{'addr': 'a8:1e:84:f2:9e:69'}]
|
||||||
|
|
||||||
|
mock_interfaces.return_value = ['enp1s0f0']
|
||||||
|
mock_ifaddresses.return_value = fake_addresses
|
||||||
|
|
||||||
|
dmi = parse(dmi_fixture)
|
||||||
|
server = HPHost(dmi)
|
||||||
|
|
||||||
|
setup_netbox(
|
||||||
|
DEFAULT_DATACENTER,
|
||||||
|
'Server',
|
||||||
|
'HP',
|
||||||
|
server.get_product_name(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create fake /sys/class/net directory with fake interface and MAC addr
|
||||||
|
fs.create_file('/tmp/enp1s0f0/address', contents='a8:1e:84:f2:9e:69')
|
||||||
|
fs.create_symlink('/sys/class/net/enp1s0f0', '/tmp/enp1s0f0')
|
||||||
|
|
||||||
|
server.netbox_create(config)
|
||||||
|
|
||||||
|
# Check serial tag is correct
|
||||||
|
assert server.get_service_tag() == '4242'
|
||||||
|
network_card = server.network.get_netbox_network_card({'name': 'enp1s0f0', 'mac': None})
|
||||||
|
|
||||||
|
# Check network card is correct
|
||||||
|
assert network_card.name == 'enp1s0f0'
|
||||||
|
|
||||||
|
# Check IP on network card
|
||||||
|
ips = nb.ipam.ip_addresses.filter(
|
||||||
|
interface_id=network_card.id
|
||||||
|
)
|
||||||
|
assert ips[0].address == '42.42.42.42/24'
|
||||||
|
|
51
tests/utils.py
Normal file
51
tests/utils.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
import pynetbox
|
||||||
|
|
||||||
|
from netbox_agent.config import netbox_instance as nb
|
||||||
|
|
||||||
|
|
||||||
|
def setup_netbox(dc, device_role, manufacturer, model):
|
||||||
|
try:
|
||||||
|
nb_dc = nb.dcim.sites.create(
|
||||||
|
name=dc,
|
||||||
|
slug=dc.lower(),
|
||||||
|
)
|
||||||
|
except pynetbox.RequestError:
|
||||||
|
nb_dc = nb.dcim.sites.get(
|
||||||
|
slug=dc.lower()
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
nb_manufacturer = nb.dcim.manufacturers.create(
|
||||||
|
name=manufacturer,
|
||||||
|
slug=manufacturer.lower(),
|
||||||
|
)
|
||||||
|
except pynetbox.RequestError:
|
||||||
|
nb_manufacturer = nb.dcim.manufacturers.get(
|
||||||
|
slug=manufacturer.lower()
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
nb_device_role = nb.dcim.device_roles.create(
|
||||||
|
name=device_role,
|
||||||
|
slug=device_role.lower(),
|
||||||
|
color='f44336',
|
||||||
|
)
|
||||||
|
except pynetbox.RequestError:
|
||||||
|
nb_device_role = nb.dcim.device_roles.get(
|
||||||
|
slug=device_role.lower(),
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
nb_device_type = nb.dcim.device_types.create(
|
||||||
|
model=model,
|
||||||
|
slug=model.lower().replace(' ', '_'),
|
||||||
|
device_role=nb_device_role.id,
|
||||||
|
manufacturer=nb_manufacturer.id,
|
||||||
|
)
|
||||||
|
except pynetbox.RequestError:
|
||||||
|
nb_device_type = nb.dcim.device_types.get(
|
||||||
|
slug=model.lower().replace(' ', '_'),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nb_dc, nb_manufacturer, nb_device_role, nb_device_type
|
Loading…
Reference in a new issue