зеркало из https://github.com/Azure/ipam.git
Added subscription name to planner, visualize, and peering components
This commit is contained in:
Родитель
e673ec6ec9
Коммит
a4fd136052
|
@ -299,6 +299,8 @@ async def subscription(
|
|||
|
||||
subscription_list = await get_subscriptions_sdk(creds)
|
||||
|
||||
await creds.close()
|
||||
|
||||
return subscription_list
|
||||
|
||||
@router.get(
|
||||
|
|
|
@ -16,6 +16,7 @@ import RestoreIcon from '@mui/icons-material/Restore';
|
|||
import { cloneDeep, isEmpty } from "lodash";
|
||||
|
||||
import {
|
||||
selectSubscriptions,
|
||||
selectNetworks
|
||||
} from "../ipam/ipamSlice";
|
||||
|
||||
|
@ -84,46 +85,6 @@ const opt = {
|
|||
},
|
||||
formatter: function (d) {
|
||||
if(d.dataType === "edge") {
|
||||
const source = d.data.source;
|
||||
const target = d.data.target;
|
||||
const lineColor = d.data.lineStyle.color;
|
||||
|
||||
const colorMap = {
|
||||
'#00FF00': 'Connected',
|
||||
'#FF0000': 'Disconnected'
|
||||
};
|
||||
|
||||
const vNetPattern = "/Microsoft.Network/virtualNetworks/";
|
||||
const vHubPattern = "/Microsoft.Network/virtualHubs/";
|
||||
|
||||
const resourceGroupPattern = "(?<=/resourceGroups/).+?(?=/)";
|
||||
const subscriptionPattern = "(?<=/subscriptions/).+?(?=/)";
|
||||
|
||||
var sourceVnetName = '';
|
||||
var targetVnetName = '';
|
||||
|
||||
if(source.includes(vNetPattern)) {
|
||||
sourceVnetName = source.substr(source.indexOf(vNetPattern) + vNetPattern.length, source.length);
|
||||
}
|
||||
|
||||
if(source.includes(vHubPattern)) {
|
||||
sourceVnetName = source.substr(source.indexOf(vHubPattern) + vHubPattern.length, source.length);
|
||||
}
|
||||
|
||||
if(target.includes(vNetPattern)) {
|
||||
targetVnetName = target.substr(source.indexOf(vNetPattern) + vNetPattern.length, target.length);
|
||||
}
|
||||
|
||||
if(target.includes(vHubPattern)) {
|
||||
targetVnetName = target.substr(source.indexOf(vHubPattern) + vHubPattern.length, target.length);
|
||||
}
|
||||
|
||||
const sourceResourceGroup = source.match(resourceGroupPattern)[0];
|
||||
const targetResourceGroup = target.match(resourceGroupPattern)[0];
|
||||
|
||||
const sourceSubscription = source.match(subscriptionPattern)[0];
|
||||
const targetSubscription = target.match(subscriptionPattern)[0];
|
||||
|
||||
const x = `
|
||||
<style>
|
||||
.wrapper {
|
||||
|
@ -186,7 +147,7 @@ const opt = {
|
|||
left: calc(50% - 6px);
|
||||
border-width: 0px 12px 12px;
|
||||
border-style: solid;
|
||||
border-color: ${lineColor} transparent;
|
||||
border-color: ${d.data.lineStyle.color} transparent;
|
||||
}
|
||||
|
||||
.wrapper::after {
|
||||
|
@ -208,15 +169,19 @@ const opt = {
|
|||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Network Name: </span>
|
||||
${sourceVnetName}
|
||||
${d.data.detail.sourceVnetName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${sourceResourceGroup}
|
||||
${d.data.detail.sourceResourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription: </span>
|
||||
${sourceSubscription}
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.data.detail.sourceSubscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.data.detail.sourceSubscriptionId}
|
||||
</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
|
@ -228,22 +193,26 @@ const opt = {
|
|||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Network Name: </span>
|
||||
${targetVnetName}
|
||||
${d.data.detail.targetVnetName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${targetResourceGroup}
|
||||
${d.data.detail.targetResourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription: </span>
|
||||
${targetSubscription}
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.data.detail.targetSubscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.data.detail.targetSubscriptionId}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="dot" style="background-color: ${lineColor}"></div>
|
||||
<div class="dot" style="background-color: ${d.data.lineStyle.color}"></div>
|
||||
<span style="font-weight: bold">
|
||||
${colorMap[lineColor]}
|
||||
${d.data.detail.state}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -251,30 +220,30 @@ const opt = {
|
|||
|
||||
return x;
|
||||
} else {
|
||||
const name = d.name;
|
||||
const peers = d.value;
|
||||
const color = d.color;
|
||||
// const name = d.name;
|
||||
// const peers = d.value;
|
||||
// const color = d.color;
|
||||
|
||||
const display = d.data.category !== 'error' && 'none';
|
||||
|
||||
const vNetPattern = "/Microsoft.Network/virtualNetworks/";
|
||||
const vHubPattern = "/Microsoft.Network/virtualHubs/";
|
||||
// const vNetPattern = "/Microsoft.Network/virtualNetworks/";
|
||||
// const vHubPattern = "/Microsoft.Network/virtualHubs/";
|
||||
|
||||
const resourceGroupPattern = "(?<=/resourceGroups/).+?(?=/)";
|
||||
const subscriptionPattern = "(?<=/subscriptions/).+?(?=/)";
|
||||
// const resourceGroupPattern = "(?<=/resourceGroups/).+?(?=/)";
|
||||
// const subscriptionPattern = "(?<=/subscriptions/).+?(?=/)";
|
||||
|
||||
var vNetName = '';
|
||||
// var vNetName = '';
|
||||
|
||||
if(name.includes(vNetPattern)) {
|
||||
vNetName = name.substr(name.indexOf(vNetPattern) + vNetPattern.length, name.length);
|
||||
}
|
||||
// if(name.includes(vNetPattern)) {
|
||||
// vNetName = name.substr(name.indexOf(vNetPattern) + vNetPattern.length, name.length);
|
||||
// }
|
||||
|
||||
if(name.includes(vHubPattern)) {
|
||||
vNetName = name.substr(name.indexOf(vHubPattern) + vHubPattern.length, name.length);
|
||||
}
|
||||
// if(name.includes(vHubPattern)) {
|
||||
// vNetName = name.substr(name.indexOf(vHubPattern) + vHubPattern.length, name.length);
|
||||
// }
|
||||
|
||||
const resourceGroup = name.match(resourceGroupPattern)[0];
|
||||
const subscription = name.match(subscriptionPattern)[0];
|
||||
// const resourceGroup = name.match(resourceGroupPattern)[0];
|
||||
// const subscription = name.match(subscriptionPattern)[0];
|
||||
|
||||
const y = `
|
||||
<style>
|
||||
|
@ -323,7 +292,7 @@ const opt = {
|
|||
left: calc(50% - 6px);
|
||||
border-width: 0px 12px 12px;
|
||||
border-style: solid;
|
||||
border-color: ${color} transparent;
|
||||
border-color: ${d.color} transparent;
|
||||
}
|
||||
|
||||
.outer::after {
|
||||
|
@ -345,20 +314,24 @@ const opt = {
|
|||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Network Name: </span>
|
||||
${vNetName}
|
||||
${d.data.detail.vNetName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${resourceGroup}
|
||||
${d.data.detail.resourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription: </span>
|
||||
${subscription}
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.data.detail.subscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.data.detail.subscriptionId}
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="dot" style="background-color: ${color}"></div>
|
||||
<div class="dot" style="background-color: ${d.color}"></div>
|
||||
<span style="font-weight: bold">Peerings: </span>
|
||||
${peers}
|
||||
${d.value}
|
||||
<span style="margin-left: auto; color: crimson; font-weight: bold; display: ${display}">vNET Missing</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -373,7 +346,7 @@ const opt = {
|
|||
series: []
|
||||
};
|
||||
|
||||
function parseNets(data) {
|
||||
function parseNets(data, subscriptions) {
|
||||
const factor = 3;
|
||||
|
||||
const stateMap = {
|
||||
|
@ -394,13 +367,38 @@ function parseNets(data) {
|
|||
var visibleNets = [];
|
||||
|
||||
const nodes = data.map(vnet => {
|
||||
const vNetPattern = "/Microsoft.Network/virtualNetworks/";
|
||||
const vHubPattern = "/Microsoft.Network/virtualHubs/";
|
||||
|
||||
const resourceGroupPattern = "(?<=/resourceGroups/).+?(?=/)";
|
||||
const subscriptionPattern = "(?<=/subscriptions/).+?(?=/)";
|
||||
|
||||
var vNetName = '';
|
||||
|
||||
if(vnet.id.includes(vNetPattern)) {
|
||||
vNetName = vnet.id.substr(vnet.id.indexOf(vNetPattern) + vNetPattern.length, vnet.id.length);
|
||||
}
|
||||
|
||||
if(vnet.id.includes(vHubPattern)) {
|
||||
vNetName = vnet.id.substr(vnet.id.indexOf(vHubPattern) + vHubPattern.length, vnet.id.length);
|
||||
}
|
||||
|
||||
const resourceGroup = vnet.id.match(resourceGroupPattern)[0];
|
||||
const subscriptionId = vnet.id.match(subscriptionPattern)[0];
|
||||
|
||||
const subscriptionName = subscriptions.find(sub => sub.subscription_id === subscriptionId)?.name || 'Unknown';
|
||||
|
||||
visibleNets.push(vnet.id);
|
||||
|
||||
let node = {
|
||||
name: vnet.id,
|
||||
value: vnet.peerings.length, //vnet.id
|
||||
detail: {
|
||||
vNetName: vNetName,
|
||||
resourceGroup: resourceGroup,
|
||||
subscriptionId: subscriptionId,
|
||||
subscriptionName: subscriptionName
|
||||
},
|
||||
symbolSize: (vnet.peerings.length * factor) + factor,
|
||||
category: vnet.id,
|
||||
label: {
|
||||
|
@ -421,9 +419,36 @@ function parseNets(data) {
|
|||
|
||||
uniqueMissing.forEach((peer) => {
|
||||
if(!visibleNets.includes(peer.remote_network)) {
|
||||
const vNetPattern = "/Microsoft.Network/virtualNetworks/";
|
||||
const vHubPattern = "/Microsoft.Network/virtualHubs/";
|
||||
|
||||
const resourceGroupPattern = "(?<=/resourceGroups/).+?(?=/)";
|
||||
const subscriptionPattern = "(?<=/subscriptions/).+?(?=/)";
|
||||
|
||||
var vNetName = '';
|
||||
|
||||
if(peer.remote_network.includes(vNetPattern)) {
|
||||
vNetName = peer.remote_network.substr(peer.remote_network.indexOf(vNetPattern) + vNetPattern.length, peer.remote_network.length);
|
||||
}
|
||||
|
||||
if(peer.remote_network.includes(vHubPattern)) {
|
||||
vNetName = peer.remote_network.substr(peer.remote_network.indexOf(vHubPattern) + vHubPattern.length, peer.remote_network.length);
|
||||
}
|
||||
|
||||
const resourceGroup = peer.remote_network.match(resourceGroupPattern)[0];
|
||||
const subscriptionId = peer.remote_network.match(subscriptionPattern)[0];
|
||||
|
||||
const subscriptionName = subscriptions.find(sub => sub.subscription_id === subscriptionId)?.name || 'Unknown';
|
||||
|
||||
let node = {
|
||||
name: peer.remote_network,
|
||||
value: 1,
|
||||
detail: {
|
||||
vNetName: vNetName,
|
||||
resourceGroup: resourceGroup,
|
||||
subscriptionId: subscriptionId,
|
||||
subscriptionName: subscriptionName
|
||||
},
|
||||
symbol: 'image:///warning.png',
|
||||
symbolSize: (1 * factor) + factor,
|
||||
category: 'error',
|
||||
|
@ -444,9 +469,54 @@ function parseNets(data) {
|
|||
let peerArr = [];
|
||||
|
||||
item.peerings.forEach((peer) => {
|
||||
const vNetPattern = "/Microsoft.Network/virtualNetworks/";
|
||||
const vHubPattern = "/Microsoft.Network/virtualHubs/";
|
||||
|
||||
const resourceGroupPattern = "(?<=/resourceGroups/).+?(?=/)";
|
||||
const subscriptionPattern = "(?<=/subscriptions/).+?(?=/)";
|
||||
|
||||
var sourceVnetName = '';
|
||||
var targetVnetName = '';
|
||||
|
||||
if(item.id.includes(vNetPattern)) {
|
||||
sourceVnetName = item.id.substr(item.id.indexOf(vNetPattern) + vNetPattern.length, item.id.length);
|
||||
}
|
||||
|
||||
if(item.id.includes(vHubPattern)) {
|
||||
sourceVnetName = item.id.substr(item.id.indexOf(vHubPattern) + vHubPattern.length, item.id.length);
|
||||
}
|
||||
|
||||
if(peer.remote_network.includes(vNetPattern)) {
|
||||
targetVnetName = peer.remote_network.substr(peer.remote_network.indexOf(vNetPattern) + vNetPattern.length, peer.remote_network.length);
|
||||
}
|
||||
|
||||
if(peer.remote_network.includes(vHubPattern)) {
|
||||
targetVnetName = peer.remote_network.substr(peer.remote_network.indexOf(vHubPattern) + vHubPattern.length, peer.remote_network.length);
|
||||
}
|
||||
|
||||
const sourceResourceGroup = item.id.match(resourceGroupPattern)[0];
|
||||
const targetResourceGroup = peer.remote_network.match(resourceGroupPattern)[0];
|
||||
|
||||
const sourceSubscriptionId = item.id.match(subscriptionPattern)[0];
|
||||
const targetSubscriptionId = peer.remote_network.match(subscriptionPattern)[0];
|
||||
|
||||
const sourceSubscriptionName = subscriptions.find(sub => sub.subscription_id === sourceSubscriptionId)?.name || 'Unknown';
|
||||
const targetSubscriptionName = subscriptions.find(sub => sub.subscription_id === targetSubscriptionId)?.name || 'Unknown';
|
||||
|
||||
const data = {
|
||||
source: item.id,
|
||||
target: peer.remote_network,
|
||||
detail: {
|
||||
sourceVnetName: sourceVnetName,
|
||||
targetVnetName: targetVnetName,
|
||||
sourceResourceGroup: sourceResourceGroup,
|
||||
targetResourceGroup: targetResourceGroup,
|
||||
sourceSubscriptionId: sourceSubscriptionId,
|
||||
targetSubscriptionId: targetSubscriptionId,
|
||||
sourceSubscriptionName: sourceSubscriptionName,
|
||||
targetSubscriptionName: targetSubscriptionName,
|
||||
state: peer.state
|
||||
},
|
||||
lineStyle: {
|
||||
color: stateMap[peer.state].color,
|
||||
type: stateMap[peer.state].lineStyle,
|
||||
|
@ -674,6 +744,7 @@ const Peering = () => {
|
|||
|
||||
const searchRef = React.useRef(null);
|
||||
|
||||
const subscriptions = useSelector(selectSubscriptions);
|
||||
const networks = useSelector(selectNetworks);
|
||||
|
||||
const theme = useTheme();
|
||||
|
@ -688,14 +759,14 @@ const Peering = () => {
|
|||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if(networks) {
|
||||
let vnetOptions = parseNets(networks);
|
||||
if(subscriptions && networks) {
|
||||
let vnetOptions = parseNets(networks, subscriptions);
|
||||
|
||||
vnetOptions.darkMode = theme.palette.mode === "dark" ? true : false;
|
||||
|
||||
setOptions(vnetOptions);
|
||||
}
|
||||
}, [networks, theme]);
|
||||
}, [subscriptions, networks, theme]);
|
||||
|
||||
function filterByVnet(options, target, previousTarget, currentMembers) {
|
||||
const members = [];
|
||||
|
|
|
@ -19,6 +19,7 @@ import { cloneDeep, isEmpty } from "lodash";
|
|||
|
||||
import {
|
||||
selectSpaces,
|
||||
selectSubscriptions,
|
||||
selectVNets,
|
||||
selectVHubs,
|
||||
selectEndpoints
|
||||
|
@ -169,6 +170,10 @@ const opt = {
|
|||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${d.value.resourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.value.subscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.value.subscriptionId}
|
||||
|
@ -205,6 +210,10 @@ const opt = {
|
|||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${d.value.resourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.value.subscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.value.subscriptionId}
|
||||
|
@ -229,6 +238,10 @@ const opt = {
|
|||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${d.value.resourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.value.subscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.value.subscriptionId}
|
||||
|
@ -265,6 +278,10 @@ const opt = {
|
|||
<span style="font-weight: bold">Resource Group: </span>
|
||||
${d.value.resourceGroup}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription Name: </span>
|
||||
${d.value.subscriptionName}
|
||||
</div>
|
||||
<div class="data">
|
||||
<span style="font-weight: bold">Subscription ID: </span>
|
||||
${d.value.subscriptionId}
|
||||
|
@ -343,7 +360,7 @@ const opt = {
|
|||
series: []
|
||||
};
|
||||
|
||||
function parseTree(spaces, vnets, vhubs, endpoints) {
|
||||
function parseTree(spaces, subscriptions, vnets, vhubs, endpoints) {
|
||||
const series = spaces.map((space) => {
|
||||
const data = {
|
||||
name: space.name,
|
||||
|
@ -368,6 +385,7 @@ function parseTree(spaces, vnets, vhubs, endpoints) {
|
|||
parentVWan: target.vwan_name,
|
||||
resourceGroup: target.resource_group,
|
||||
subscriptionId: target.subscription_id,
|
||||
subscriptionName: subscriptions.find((sub) => sub.subscription_id === target.subscription_id)?.name || 'Unknown',
|
||||
tentantId: target.tenant_id,
|
||||
prefix: target.prefixes.toString(),
|
||||
size: target.size
|
||||
|
@ -389,6 +407,7 @@ function parseTree(spaces, vnets, vhubs, endpoints) {
|
|||
name: target.name,
|
||||
resourceGroup: target.resource_group,
|
||||
subscriptionId: target.subscription_id,
|
||||
subscriptionName: subscriptions.find((sub) => sub.subscription_id === target.subscription_id)?.name || 'Unknown',
|
||||
tentantId: target.tenant_id,
|
||||
prefixes: target.prefixes,
|
||||
size: target.size,
|
||||
|
@ -404,6 +423,7 @@ function parseTree(spaces, vnets, vhubs, endpoints) {
|
|||
name: subnet.name,
|
||||
resourceGroup: target.resource_group,
|
||||
subscriptionId: target.subscription_id,
|
||||
subscriptionName: subscriptions.find((sub) => sub.subscription_id === target.subscription_id)?.name || 'Unknown',
|
||||
tentantId: target.tenant_id,
|
||||
prefix: subnet.prefix,
|
||||
size: subnet.size,
|
||||
|
@ -419,6 +439,7 @@ function parseTree(spaces, vnets, vhubs, endpoints) {
|
|||
privateIp: endpoint.private_ip,
|
||||
resourceGroup: endpoint.resource_group,
|
||||
subscriptionId: endpoint.subscription_id,
|
||||
subscriptionName: subscriptions.find((sub) => sub.subscription_id === target.subscription_id)?.name || 'Unknown',
|
||||
tentantId: endpoint.tenant_id
|
||||
}
|
||||
};
|
||||
|
@ -594,6 +615,7 @@ const Visualize = () => {
|
|||
const searchRef = React.useRef(null);
|
||||
|
||||
const spaces = useSelector(selectSpaces);
|
||||
const subscriptions = useSelector(selectSubscriptions);
|
||||
const vnets = useSelector(selectVNets);
|
||||
const vhubs = useSelector(selectVHubs);
|
||||
const endpoints = useSelector(selectEndpoints);
|
||||
|
@ -607,12 +629,12 @@ const Visualize = () => {
|
|||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if(spaces && vnets && vhubs && endpoints) {
|
||||
if(spaces && subscriptions && vnets && vhubs && endpoints) {
|
||||
var newOptions = cloneDeep(opt);
|
||||
|
||||
delete newOptions.graphic;
|
||||
newOptions.darkMode = theme.palette.mode === 'dark' ? true : false;
|
||||
newOptions.series = parseTree(spaces, vnets, vhubs, endpoints);
|
||||
newOptions.series = parseTree(spaces, subscriptions, vnets, vhubs, endpoints);
|
||||
newOptions.legend.data = newOptions.series.map((option) => {
|
||||
return {
|
||||
name: option.name,
|
||||
|
@ -627,7 +649,7 @@ const Visualize = () => {
|
|||
})
|
||||
);
|
||||
}
|
||||
}, [spaces, vnets, vhubs, endpoints, theme]);
|
||||
}, [spaces, subscriptions, vnets, vhubs, endpoints, theme]);
|
||||
|
||||
function setDataFocus(target) {
|
||||
if(eChartsRef && !isEmpty(options.series)) {
|
||||
|
|
|
@ -313,6 +313,7 @@ export default function EditReservations(props) {
|
|||
showActiveRowIndicator={false}
|
||||
enableColumnAutosize={false}
|
||||
showColumnMenuGroupOptions={false}
|
||||
showColumnMenuLockOptions={false}
|
||||
columns={columns}
|
||||
loading={loading}
|
||||
loadingText={sending ? <Update>Updating</Update> : "Loading"}
|
||||
|
|
|
@ -60,7 +60,7 @@ const gridStyle = {
|
|||
|
||||
const columns = [
|
||||
{ name: "name", header: "Name", defaultFlex: 1 },
|
||||
{ name: "subscription_id", header: "Subscription", defaultFlex: 1 },
|
||||
{ name: "subscription_id", header: "Subscription", defaultFlex: 1, defaultVisible: false },
|
||||
{ name: "resource_group", header: "Resource Group", defaultFlex: 1 },
|
||||
{ name: "prefixes", header: "Prefixes", defaultFlex: 0.75, render: ({value}) => value.join(", ") },
|
||||
];
|
||||
|
@ -76,6 +76,8 @@ export default function EditVnets(props) {
|
|||
const [sending, setSending] = React.useState(false);
|
||||
const [refreshing, setRefreshing] = React.useState(false);
|
||||
|
||||
const gridRef = React.createRef();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const theme = useTheme();
|
||||
|
@ -197,8 +199,8 @@ export default function EditVnets(props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<div sx={{ height: "300px", width: "100%" }}>
|
||||
<Dialog open={open} onClose={handleClose} maxWidth="md" fullWidth>
|
||||
<div sx={{ height: "400px", width: "100%" }}>
|
||||
<Dialog open={open} onClose={handleClose} maxWidth="lg" fullWidth>
|
||||
<DialogTitle>
|
||||
<Box sx={{ display: "flex", flexDirection: "row" }}>
|
||||
<Box>
|
||||
|
@ -223,7 +225,7 @@ export default function EditVnets(props) {
|
|||
<Box
|
||||
sx={{
|
||||
pt: 4,
|
||||
height: "300px",
|
||||
height: "400px",
|
||||
'& .ipam-block-vnet-stale': {
|
||||
background: theme.palette.mode === 'dark' ? 'rgb(220, 20, 20) !important' : 'rgb(255, 230, 230) !important',
|
||||
'.InovuaReactDataGrid__row-hover-target': {
|
||||
|
@ -243,6 +245,7 @@ export default function EditVnets(props) {
|
|||
}}
|
||||
>
|
||||
<ReactDataGrid
|
||||
ref={gridRef}
|
||||
theme={theme.palette.mode === 'dark' ? "default-dark" : "default-light"}
|
||||
idProperty="id"
|
||||
showCellBorders="horizontal"
|
||||
|
@ -254,6 +257,10 @@ export default function EditVnets(props) {
|
|||
showActiveRowIndicator={false}
|
||||
enableColumnAutosize={false}
|
||||
showColumnMenuGroupOptions={false}
|
||||
showColumnMenuLockOptions={false}
|
||||
columnContextMenuConstrainTo={gridRef.current?.getBoundingClientRect()}
|
||||
// columnContextMenuPosition={"fixed"}
|
||||
// updateMenuPositionOnColumnsChange={true}
|
||||
columns={columns}
|
||||
loading={sending || refreshing || refreshingState}
|
||||
loadingText={sending ? <Update>Updating</Update> : "Loading"}
|
||||
|
|
|
@ -310,6 +310,7 @@ export function fetchNetworks(token) {
|
|||
export function refreshAll(token) {
|
||||
const stack = [
|
||||
(async () => await fetchSpaces(token, true))(),
|
||||
(async () => await fetchSubscriptions(token, true))(),
|
||||
(async () => await fetchNetworks(token))(),
|
||||
(async () => await fetchEndpoints(token))()
|
||||
];
|
||||
|
|
|
@ -25,6 +25,7 @@ const initialState = {
|
|||
isAdmin: false,
|
||||
spaces: null,
|
||||
blocks: null,
|
||||
subscriptions: null,
|
||||
vNets: null,
|
||||
vHubs: null,
|
||||
subnets: null,
|
||||
|
@ -278,11 +279,17 @@ export const ipamSlice = createSlice({
|
|||
});
|
||||
|
||||
return space.blocks;
|
||||
}).flat();
|
||||
}).flat();
|
||||
|
||||
if(action.payload[1].status === 'fulfilled') {
|
||||
const vNetData = action.payload[1].value.filter((x) => x.id.toLowerCase().includes(vNetProvider.toLowerCase()));
|
||||
const vHubData = action.payload[1].value.filter((x) => x.id.toLowerCase().includes(vHubProvider.toLowerCase()));
|
||||
state.subscriptions = action.payload[1].value;
|
||||
} else {
|
||||
state.subscriptions = [];
|
||||
}
|
||||
|
||||
if(action.payload[2].status === 'fulfilled') {
|
||||
const vNetData = action.payload[2].value.filter((x) => x.id.toLowerCase().includes(vNetProvider.toLowerCase()));
|
||||
const vHubData = action.payload[2].value.filter((x) => x.id.toLowerCase().includes(vHubProvider.toLowerCase()));
|
||||
|
||||
const vnets = vNetData.map((vnet) => {
|
||||
vnet.available = (vnet.size - vnet.used);
|
||||
|
@ -329,8 +336,8 @@ export const ipamSlice = createSlice({
|
|||
state.vHubs = [];
|
||||
}
|
||||
|
||||
if(action.payload[2].status === 'fulfilled') {
|
||||
const endpoints = action.payload[2].value.map((endpoint) => {
|
||||
if(action.payload[3].status === 'fulfilled') {
|
||||
const endpoints = action.payload[3].value.map((endpoint) => {
|
||||
endpoint.uniqueId = `${endpoint.id}@$${endpoint.private_ip}`
|
||||
|
||||
return endpoint;
|
||||
|
@ -385,8 +392,19 @@ export const getRefreshing = (state) => state.ipam.refreshing;
|
|||
export const getDarkMode = (state) => state.ipam.darkMode;
|
||||
export const getMeLoaded = (state) => state.ipam.meLoaded;
|
||||
|
||||
// const subFixup = (data, state) => {
|
||||
// data?.forEach((item) => {
|
||||
// let target = state.subscriptions?.find((x) => x.subscription_id === item.subcription_id);
|
||||
|
||||
// item['subscription_name'] = target ? target.name : 'Unknown';
|
||||
// });
|
||||
|
||||
// return data;
|
||||
// };
|
||||
|
||||
export const selectSpaces = (state) => state.ipam.spaces;
|
||||
export const selectBlocks = (state) => state.ipam.blocks;
|
||||
export const selectSubscriptions = (state) => state.ipam.subscriptions;
|
||||
export const selectVNets = (state) => state.ipam.vNets;
|
||||
export const selectVHubs = (state) => state.ipam.vHubs;
|
||||
export const selectSubnets = (state) => state.ipam.subnets;
|
||||
|
|
|
@ -2,11 +2,6 @@ import * as React from 'react';
|
|||
import { useSelector } from 'react-redux';
|
||||
import { ThemeProvider, createTheme, styled } from '@mui/material/styles';
|
||||
|
||||
import { useMsal } from "@azure/msal-react";
|
||||
import { InteractionRequiredAuthError } from "@azure/msal-browser";
|
||||
|
||||
import { useSnackbar } from 'notistack';
|
||||
|
||||
import { find } from 'lodash';
|
||||
|
||||
import {
|
||||
|
@ -33,15 +28,10 @@ import {
|
|||
} from '@mui/icons-material';
|
||||
|
||||
import {
|
||||
selectSubscriptions,
|
||||
selectVNets
|
||||
} from "../ipam/ipamSlice";
|
||||
|
||||
import {
|
||||
fetchSubscriptions
|
||||
} from "../ipam/ipamAPI";
|
||||
|
||||
import { apiRequest } from "../../msal/authConfig";
|
||||
|
||||
import { availableSubnets } from './utils/iputils';
|
||||
|
||||
const plannerTheme = (theme) => createTheme({
|
||||
|
@ -115,12 +105,7 @@ const Separator = (props) => {
|
|||
};
|
||||
|
||||
const Planner = () => {
|
||||
const { instance, accounts } = useMsal();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const [subscriptions, setSubscriptions] = React.useState(null);
|
||||
const [newVNets, setNewVNets] = React.useState([]);
|
||||
|
||||
const [subnetData, setSubnetData] = React.useState(null);
|
||||
|
||||
const [vNetInput, setVNetInput] = React.useState('');
|
||||
|
@ -137,43 +122,10 @@ const Planner = () => {
|
|||
|
||||
const [showAll, setShowAll] = React.useState(false);
|
||||
|
||||
const subsLoadingRef = React.useRef(false);
|
||||
|
||||
const subscriptions = useSelector(selectSubscriptions);
|
||||
const vNets = useSelector(selectVNets);
|
||||
|
||||
const loading = !vNets || subsLoadingRef.current;
|
||||
|
||||
const refreshSubscriptions = React.useCallback(() => {
|
||||
const request = {
|
||||
scopes: apiRequest.scopes,
|
||||
account: accounts[0],
|
||||
};
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
subsLoadingRef.current = true;
|
||||
const response = await instance.acquireTokenSilent(request);
|
||||
const data = await fetchSubscriptions(response.accessToken);
|
||||
setSubscriptions(data);
|
||||
} catch (e) {
|
||||
if (e instanceof InteractionRequiredAuthError) {
|
||||
instance.acquireTokenRedirect(request);
|
||||
} else {
|
||||
console.log("ERROR");
|
||||
console.log("------------------");
|
||||
console.log(e);
|
||||
console.log("------------------");
|
||||
enqueueSnackbar("Error fetching subnets", { variant: "error" });
|
||||
}
|
||||
} finally {
|
||||
subsLoadingRef.current = false;
|
||||
}
|
||||
})();
|
||||
}, [accounts, enqueueSnackbar, instance]);
|
||||
|
||||
React.useEffect(() => {
|
||||
!subsLoadingRef.current && refreshSubscriptions();
|
||||
}, [vNets, refreshSubscriptions]);
|
||||
const loading = !vNets || !subscriptions;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (vNets && subscriptions) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче