Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Switch from MAC address stored in Nautobot asset_tag to custom field #502

Merged
merged 3 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions python/understack-workflows/tests/test_nautobot_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ def update(self, *_):
pass

class Graphql:
def query(self, graphql):
if "61:80" in graphql:
def query(self, graphql, variables: dict):
if "pattern" in variables:
return FakeNautobot.SwitchResponse()
if "33GSW04" in graphql:
if "serial" in variables:
return FakeNautobot.GraphqlResponse(
"json_samples/bmc_chassis_info/R7615/nautobot_graphql_response_server_device_33GSW04.json"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ def update_nautobot_for_provisioning(


def vlan_group_id_for(device_id, nautobot):
result = nautobot.session.graphql.query(
f'{{device(id: "{device_id}") {{ rel_vlan_group_to_devices {{id}}}}}}'
)
query = """
query($device_id: ID!){
device(id: $device_id) {
rel_vlan_group_to_devices {id}
}
}
"""
variables = {"device_id": device_id}
result = nautobot.session.graphql.query(query=query, variables=variables)
if not result.json or result.json.get("errors"):
raise Exception(f"Nautobot vlan_group graphql query failed: {result}")
return result.json["data"]["device"]["rel_vlan_group_to_devices"]["id"]
Expand Down
87 changes: 43 additions & 44 deletions python/understack-workflows/understack_workflows/nautobot_device.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
import re
from dataclasses import dataclass
from ipaddress import IPv4Interface
Expand Down Expand Up @@ -139,29 +138,28 @@ def switches_for(nautobot, chassis_info: ChassisInfo) -> dict:
def nautobot_switches(nautobot, mac_addresses: set[str]) -> dict[str, dict]:
"""Get switches by MAC address.

Assumes switch MAC addresses are present in Nautobot in a custom field on
Device called chassis_mac_address.

Assumes that MAC addresses in Nautobot are normalized to upcase
AA:BB:CC:DD:EE:FF form.

We store the MAC address in the nautobot device "asset tag" field because
there was nowhere else to put it.

returns a dict[mac_address] -> dict switch information indexed by mac
"""
formatted_list = json.dumps(list(mac_addresses))

query = (
"""{
devices(asset_tag: %s){
id name
mac: asset_tag
location { id name }
rack { id name }
pattern = "|".join(mac_addresses)

query = """
query($pattern: [String!]){
devices(cf_chassis_mac_address__re: $pattern){
id name
mac: cf_chassis_mac_address
location { id name }
rack { id name }
}
}
}"""
% formatted_list
)
"""

result = nautobot.graphql.query(query)
result = nautobot.graphql.query(query, variables={"pattern": pattern})
if not result.json or result.json.get("errors"):
raise Exception(f"Nautobot switch graphql query failed: {result}")
switches = result.json["data"]["devices"]
Expand All @@ -177,9 +175,8 @@ def nautobot_switch(all_switches, interface):
raise Exception(
f"Looking for a switch in nautobot that matches the LLDP "
f"info reported by server BMC - "
f"No device found in nautobot with asset_tag {mac_address} "
f"nor the calculated base mac address {base_mac_address}"
f"{all_switches}"
f"No device in nautobot with chassis_mac_address {mac_address}, "
f"nor the calculated base mac address {base_mac_address}."
)
return switch

Expand Down Expand Up @@ -225,33 +222,35 @@ def _parse_manufacturer(name: str) -> str:


def nautobot_server(nautobot, serial: str) -> NautobotDevice | None:
query = f"""{{
devices(serial: ["{serial}"]){{
id name
location {{ id name }}
rack {{ id name }}
interfaces {{
query = """
query($serial: String!){
devices(serial: [$serial]){
id name
type description mac_address
status {{ name }}
connected_interface {{
location { id name }
rack { id name }
interfaces {
id name
device {{
type description mac_address
status { name }
connected_interface {
id name
mac: asset_tag
location {{ id name }}
rack {{ id name }}
}}
}}
ip_addresses {{
id host
parent {{ prefix }}
}}
}}
}}
}}"""

result = nautobot.graphql.query(query)
device {
id name
mac: cf_chassis_mac_address
location { id name }
rack { id name }
}
}
ip_addresses {
id host
parent { prefix }
}
}
}
}
"""

result = nautobot.graphql.query(query, variables={"serial": serial})
if not result.json or result.json.get("errors"):
raise Exception(f"Nautobot server graphql query failed: {result}")

Expand Down