diff --git a/hyperglass/configuration/__init__.py b/hyperglass/configuration/__init__.py
index a5bc9b6..40ca3a1 100644
--- a/hyperglass/configuration/__init__.py
+++ b/hyperglass/configuration/__init__.py
@@ -293,7 +293,12 @@ def _build_frontend_devices():
"network": device.network.display_name,
"display_name": device.display_name,
"vrfs": [
- {"id": vrf.name, "display_name": vrf.display_name}
+ {
+ "id": vrf.name,
+ "display_name": vrf.display_name,
+ "ipv4": True if vrf.ipv4 else False, # noqa: IF100
+ "ipv6": True if vrf.ipv6 else False, # noqa: IF100
+ }
for vrf in device.vrfs
],
}
@@ -303,7 +308,12 @@ def _build_frontend_devices():
"network": device.network.display_name,
"display_name": device.display_name,
"vrfs": [
- {"id": vrf.name, "display_name": vrf.display_name}
+ {
+ "id": vrf.name,
+ "display_name": vrf.display_name,
+ "ipv4": True if vrf.ipv4 else False, # noqa: IF100
+ "ipv6": True if vrf.ipv6 else False, # noqa: IF100
+ }
for vrf in device.vrfs
],
}
@@ -350,9 +360,15 @@ def _build_vrfs():
vrfs = []
for device in devices.routers:
for vrf in device.vrfs:
- vrf_dict = {"id": vrf.name, "display_name": vrf.display_name}
+
+ vrf_dict = {
+ "id": vrf.name,
+ "display_name": vrf.display_name,
+ }
+
if vrf_dict not in vrfs:
vrfs.append(vrf_dict)
+
return vrfs
diff --git a/hyperglass/ui/components/HyperglassForm.js b/hyperglass/ui/components/HyperglassForm.js
index 67b1669..ec154ac 100644
--- a/hyperglass/ui/components/HyperglassForm.js
+++ b/hyperglass/ui/components/HyperglassForm.js
@@ -58,6 +58,7 @@ const HyperglassForm = React.forwardRef(
const [availVrfs, setAvailVrfs] = useState([]);
const [fqdnTarget, setFqdnTarget] = useState("");
const [displayTarget, setDisplayTarget] = useState("");
+ const [families, setFamilies] = useState([]);
const onSubmit = values => {
setFormData(values);
setSubmitting(true);
@@ -66,16 +67,44 @@ const HyperglassForm = React.forwardRef(
const handleLocChange = locObj => {
setQueryLocation(locObj.value);
const allVrfs = [];
+ const deviceVrfs = [];
locObj.value.map(loc => {
const locVrfs = [];
config.devices[loc].vrfs.map(vrf => {
- locVrfs.push({ label: vrf.display_name, value: vrf.id });
+ locVrfs.push({
+ label: vrf.display_name,
+ value: vrf.id
+ });
+ deviceVrfs.push([{ id: vrf.id, ipv4: vrf.ipv4, ipv6: vrf.ipv6 }]);
});
allVrfs.push(locVrfs);
});
+
const intersecting = lodash.intersectionWith(...allVrfs, lodash.isEqual);
setAvailVrfs(intersecting);
!intersecting.includes(queryVrf) && queryVrf !== "default" && setQueryVrf("default");
+
+ let ipv4 = 0;
+ let ipv6 = 0;
+ deviceVrfs.length !== 0 &&
+ intersecting.length !== 0 &&
+ deviceVrfs
+ .filter(v => intersecting.every(i => i.id === v.id))
+ .reduce((a, b) => a.concat(b))
+ .filter(v => v.id === "default")
+ .map(v => {
+ v.ipv4 === true && ipv4++;
+ v.ipv6 === true && ipv6++;
+ });
+ if (ipv4 !== 0 && ipv4 === ipv6) {
+ setFamilies([4, 6]);
+ } else if (ipv4 > ipv6) {
+ setFamilies([4]);
+ } else if (ipv4 < ipv6) {
+ setFamilies([6]);
+ } else {
+ setFamilies([]);
+ }
};
const handleChange = e => {
@@ -92,6 +121,7 @@ const HyperglassForm = React.forwardRef(
};
const vrfContent = config.content.vrf[queryVrf]?.[queryType];
+
const validFqdnQueryType =
["ping", "traceroute", "bgp_route"].includes(queryType) &&
fqdnTarget &&
@@ -155,11 +185,13 @@ const HyperglassForm = React.forwardRef(
name="query_target"
error={errors.query_target}
fieldAddOn={
+ queryLocation.length !== 0 &&
validFqdnQueryType && (
)
}
diff --git a/hyperglass/ui/components/ResolvedTarget.js b/hyperglass/ui/components/ResolvedTarget.js
index 42d2b17..7e1ce7e 100644
--- a/hyperglass/ui/components/ResolvedTarget.js
+++ b/hyperglass/ui/components/ResolvedTarget.js
@@ -1,38 +1,41 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect } from "react";
import { Button, Icon, Spinner, Stack, Tag, Text, Tooltip, useColorMode } from "@chakra-ui/core";
import useAxios from "axios-hooks";
import format from "string-format";
import useConfig from "~/components/HyperglassProvider";
-import useMedia from "~/components/MediaProvider";
format.extend(String.prototype, {});
const labelBg = { dark: "secondary", light: "secondary" };
const labelBgSuccess = { dark: "success", light: "success" };
-const ResolvedTarget = React.forwardRef(({ fqdnTarget, setTarget, queryTarget }, ref) => {
+const ResolvedTarget = React.forwardRef(({ fqdnTarget, setTarget, queryTarget, families }, ref) => {
const { colorMode } = useColorMode();
- const { mediaSize } = useMedia();
const config = useConfig();
const labelBgStatus = { true: labelBgSuccess[colorMode], false: labelBg[colorMode] };
const dnsUrl = config.web.dns_provider.url;
- const params4 = {
- url: dnsUrl,
- params: { name: fqdnTarget, type: "A" },
- headers: { accept: "application/dns-json" },
- crossdomain: true,
- timeout: 1000
- };
- const params6 = {
- url: dnsUrl,
- params: { name: fqdnTarget, type: "AAAA" },
- headers: { accept: "application/dns-json" },
- crossdomain: true,
- timeout: 1000
+ const query4 = families.includes(4);
+ const query6 = families.includes(6);
+ const params = {
+ 4: {
+ url: dnsUrl,
+ params: { name: fqdnTarget, type: "A" },
+ headers: { accept: "application/dns-json" },
+ crossdomain: true,
+ timeout: 1000
+ },
+ 6: {
+ url: dnsUrl,
+ params: { name: fqdnTarget, type: "AAAA" },
+ headers: { accept: "application/dns-json" },
+ crossdomain: true,
+ timeout: 1000
+ }
};
- const [{ data: data4, loading: loading4, error: error4 }] = useAxios(params4);
- const [{ data: data6, loading: loading6, error: error6 }] = useAxios(params6);
+ const [{ data: data4, loading: loading4, error: error4 }] = useAxios(params[4]);
+
+ const [{ data: data6, loading: loading6, error: error6 }] = useAxios(params[6]);
const handleOverride = overridden => {
setTarget({ field: "query_target", value: overridden });
@@ -48,23 +51,28 @@ const ResolvedTarget = React.forwardRef(({ fqdnTarget, setTarget, queryTarget },
};
useEffect(() => {
- if (data6 && data6.Answer) {
+ if (query6 && data6?.Answer) {
handleOverride(findAnswer(data6));
- } else if (data4 && data4.Answer && !data6?.Answer) {
+ } else if (query4 && data4?.Answer && !query6 && !data6?.Answer) {
+ handleOverride(findAnswer(data4));
+ } else if (query4 && data4?.Answer) {
handleOverride(findAnswer(data4));
}
}, [data4, data6]);
+
return (
{loading4 ||
error4 ||
- (findAnswer(data4) && (
+ (query4 && findAnswer(data4) && (