summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorYaron Yogev <yaronyogev@gmail.com>2017-07-31 08:02:26 +0300
committerYaron Yogev <yaronyogev@gmail.com>2017-07-31 08:59:46 +0300
commit6f42e246e99aa390e9b55c62bb47ef2ef556c2e6 (patch)
treead79ee9e4712953be6da134987da7383557ce15b /app
parentc22d277cf90c31b54e5b9f94cee38f7cddedcdc1 (diff)
US2765 ACI scanning:
Added spine switches and pnics fetching functionality Change-Id: Ifc090b31e3821303b94d7a4efe8f887c47458071 Signed-off-by: Yaron Yogev <yaronyogev@gmail.com>
Diffstat (limited to 'app')
-rw-r--r--app/config/scanners.json9
-rw-r--r--app/discover/fetchers/aci/aci_fetch_switch_pnic.py58
-rw-r--r--app/utils/util.py4
3 files changed, 45 insertions, 26 deletions
diff --git a/app/config/scanners.json b/app/config/scanners.json
index 3c17918..feaafcb 100644
--- a/app/config/scanners.json
+++ b/app/config/scanners.json
@@ -225,7 +225,14 @@
"ScanHostPnic": [
{
"type": "pnic",
- "fetcher": "AciFetchSwitchPnic"
+ "fetcher": "AciFetchSwitchPnic",
+ "children_scanner": "ScanSpines"
+ }
+ ],
+ "ScanSpines": [
+ {
+ "type": "pnic",
+ "fetcher": "AciFetchLeafToSpinePnics"
}
],
"ScanProject": [
diff --git a/app/discover/fetchers/aci/aci_fetch_switch_pnic.py b/app/discover/fetchers/aci/aci_fetch_switch_pnic.py
index a4216ea..965fc79 100644
--- a/app/discover/fetchers/aci/aci_fetch_switch_pnic.py
+++ b/app/discover/fetchers/aci/aci_fetch_switch_pnic.py
@@ -14,6 +14,12 @@ from utils.inventory_mgr import InventoryMgr
from utils.util import encode_aci_dn, get_object_path_part
+# Fetches and adds to database:
+# 1. ACI Switch
+#
+# Returns:
+# 1. ACI Switch pnic that belongs to the ACI Switch (mentioned above)
+# and is connected to Calipso host pnic.
class AciFetchSwitchPnic(AciAccess):
def __init__(self):
@@ -22,6 +28,7 @@ class AciFetchSwitchPnic(AciAccess):
def fetch_pnics_by_mac_address(self, mac_address):
mac_filter = "eq(epmMacEp.addr,\"{}\")".format(mac_address)
+ # We are only interested in Ethernet interfaces
pnic_filter = "wcard(epmMacEp.ifId, \"eth\")"
query_filter = "and({},{})".format(mac_filter, pnic_filter)
@@ -33,6 +40,7 @@ class AciFetchSwitchPnic(AciAccess):
def fetch_switch_by_id(self, switch_id):
dn = "/".join((switch_id, "sys"))
response = self.fetch_mo_data(dn)
+ # Unwrap switches
switch_data = self.get_objects_by_field_names(response, "topSystem", "attributes")
return switch_data[0] if switch_data else None
@@ -46,46 +54,50 @@ class AciFetchSwitchPnic(AciAccess):
if not mac_address:
return []
- switch_pnics = self.fetch_pnics_by_mac_address(mac_address)
- if not switch_pnics:
+ # Query ACI for related switch pnic
+ leaf_pnics = self.fetch_pnics_by_mac_address(mac_address)
+ if not leaf_pnics:
return []
- switch_pnic = switch_pnics[0]
+ leaf_pnic = leaf_pnics[0]
# Prepare and save switch data in inventory
- aci_id_match = re.match("topology/(.+)/sys", switch_pnic["dn"])
- if not aci_id_match:
- raise ValueError("Failed to fetch switch id from pnic dn: {}"
- .format(switch_pnic["dn"]))
+ leaf_id_match = re.match("topology/(.+)/sys", leaf_pnic["dn"])
+ if not leaf_id_match:
+ raise ValueError("Failed to fetch leaf switch id from pnic dn: {}"
+ .format(leaf_pnic["dn"]))
- aci_switch_id = aci_id_match.group(1)
- db_switch_id = encode_aci_dn(aci_switch_id)
- if not self.inv.get_by_id(environment, db_switch_id):
- switch_data = self.fetch_switch_by_id(aci_switch_id)
- if not switch_data:
- self.log.warning("No switch found for switch pnic dn: {}"
- .format(switch_pnic["dn"]))
- return []
+ aci_leaf_id = leaf_id_match.group(1)
+ leaf_data = self.fetch_switch_by_id(aci_leaf_id)
+ if not leaf_data:
+ self.log.warning("No switch found for switch pnic dn: {}"
+ .format(leaf_pnic["dn"]))
+ return []
- switch_json = {
- "id": db_switch_id,
- "ip_address": switch_data["address"],
+ db_leaf_id = "-".join(("switch", encode_aci_dn(aci_leaf_id), leaf_data["role"]))
+ if not self.inv.get_by_id(environment, db_leaf_id):
+ leaf_json = {
+ "id": db_leaf_id,
+ "ip_address": leaf_data["address"],
"type": "switch",
- "aci_document": switch_data
+ "host": db_leaf_id,
+ "aci_document": leaf_data
}
# Region name is the same as region id
region_id = get_object_path_part(pnic["name_path"], "Regions")
region = self.inv.get_by_id(environment, region_id)
- self.inv.save_inventory_object(o=switch_json, parent=region, environment=environment)
+ self.inv.save_inventory_object(o=leaf_json, parent=region, environment=environment)
- db_pnic_id = "-".join((db_switch_id,
- encode_aci_dn(switch_pnic["ifId"]),
+ # Prepare pnic json for results list
+ db_pnic_id = "-".join((db_leaf_id,
+ encode_aci_dn(leaf_pnic["ifId"]),
mac_address))
pnic_json = {
"id": db_pnic_id,
"type": "pnic",
"pnic_type": "switch",
"mac_address": mac_address,
- "aci_document": switch_pnic
+ "host": db_leaf_id,
+ "aci_document": leaf_pnic
}
return [pnic_json]
diff --git a/app/utils/util.py b/app/utils/util.py
index 4695879..385dea7 100644
--- a/app/utils/util.py
+++ b/app/utils/util.py
@@ -160,11 +160,11 @@ def get_extension(file_path: str) -> str:
def encode_aci_dn(object_id):
- return object_id.replace("topology/", "").replace("/", "___").replace("-", "__")
+ return object_id.replace("topology/", "").replace("/", "__")
def decode_aci_dn(object_id):
- return object_id.replace("___", "/").replace("__", "-")
+ return object_id.replace("__", "/")
def get_object_path_part(path: str, part_name: str):