Skip to content

Instantly share code, notes, and snippets.

@Cheaterman
Last active July 28, 2020 12:25
Show Gist options
  • Save Cheaterman/16e306b2b56eaffe8fa298930f867620 to your computer and use it in GitHub Desktop.
Save Cheaterman/16e306b2b56eaffe8fa298930f867620 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
# Display status of VPNs terminated within NSX
# Created Jul 2020
# Tim Bowers
# Rewritten by Cheaterman (Guillaume Brun) for Smiley (Tim Bowers)
import argparse
import datetime
import contextlib
import os
import requests
from lxml import etree
URL = 'https://XXXX.local/api/4.0/edges'
DEV_MODE = False
if os.environ.get('WITH_DEV'):
DEV_MODE = True
class MockResponse:
def __init__(self, path):
with open(path) as file:
self.text = file.read()
@contextlib.contextmanager
def absorb_stderr():
with open(os.devnull, 'w') as devnull:
with contextlib.redirect_stderr(devnull):
yield
def get_vpn_status(user, password, url):
"""Login to NSX, get list of edges."""
request_args = dict(
auth=(user, password),
verify=False,
headers={
'Accept': 'application/xml',
'Content-Type': 'application/xml',
},
)
if not DEV_MODE:
with absorb_stderr():
all_edges = requests.get(url, **request_args)
else:
all_edges = MockResponse('sites.xml')
data = {}
# Convert result of call into XML object
tree = etree.fromstring(all_edges.text.encode())
# Create a dict containing all the edges
data['edges'] = {}
for edge_summary in tree[0]:
if edge_summary.tag == 'pagingInfo':
continue
current_edge = {}
for attribute_tag in edge_summary.iter('objectId', 'name'):
current_edge[attribute_tag.tag] = attribute_tag.text
data['edges'][current_edge['objectId']] = {
'name': current_edge['name'],
}
# For each edge, check for VPN and VPN status
for id, edge in data['edges'].items():
edge_url = f'{url}/{id}/ipsec/statistics'
if not DEV_MODE:
with absorb_stderr():
vpn_state = requests.get(edge_url, **request_args)
else:
vpn_state = MockResponse('site_stats.xml')
vpn_tree = etree.fromstring(vpn_state.text.encode())
# Create a dict of tunnels - keyed by network CIDR
edge['tunnels'] = tunnels = {}
if not len(vpn_tree):
continue
for site_statistics in vpn_tree:
if site_statistics.tag != 'siteStatistics':
continue
for tunnel_stats in site_statistics.iter('tunnelStats'):
current_tunnel = {}
for attribute_tag in tunnel_stats.iter(
'tunnelStatus',
'peerSubnet',
):
current_tunnel[attribute_tag.tag] = attribute_tag.text
tunnels[
current_tunnel['peerSubnet']
] = current_tunnel['tunnelStatus']
if all(tunnel == 'up' for tunnel in edge['tunnels'].values()):
edge['status'] = 'OK'
else:
edge['status'] = 'ERROR'
return data
def show_vpn_status(data, html_output=False):
if not html_output:
print(data)
return
# Lazy loading on purpose - optional dependency.
from jinja2 import Environment, FileSystemLoader, select_autoescape
env = Environment(
loader=FileSystemLoader('.'),
autoescape=select_autoescape(['html', 'xml']),
)
print(env.get_template('show_vpn_status.html').render(
data=data,
now=datetime.datetime.now(),
))
def get_nonempty_input(prompt, value_name):
value = ''
while not value:
value = input(f'{prompt}: ')
if not value:
print(f'A {value_name} must be provided to continue.')
return value
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user', help='NSX Manager username')
parser.add_argument('-p', '--password', help='NSX Manager password')
parser.add_argument(
'--html',
action='store_true',
default=False,
dest='html',
help='Enables html output formatting',
)
args = parser.parse_args()
if not args.user:
args.user = get_nonempty_input('Username for logging in', 'username')
if not args.password:
args.password = get_nonempty_input('Password', 'password')
data = get_vpn_status(args.user, args.password, URL)
show_vpn_status(data, args.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>NSX VPN Status</title>
<!-- Mobile display -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="./template_files/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Weird Smiley JS stuff... why no CDN? -->
<script
src="./template_files/jquery-3.4.1.slim.min.js.download"
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
crossorigin="anonymous"
></script>
<script
src="./template_files/popper.min.js.download"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"
></script>
<script
src="./template_files/bootstrap.min.js.download"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"
></script>
</head>
<body>
<h1>NSX VPN Status</h1>
<h2>Last updated: {{ now.isoformat() }}</h2>
<br>
<br>
<div class="container">
{%- for edge_id, edge in data.edges.items() %}
<div class="
col-12
text-white
{% if edge.status != 'OK' -%}
bg-failure
alert-failure
{% else -%}
bg-success
alert-success
{% endif -%}
">
<h4 class="alert-heading">{{ edge_id }} (name: {{ edge.name }})</h4>
{%- for address, status in edge.tunnels.items() %}
<p>VPN to peer {{ address }} is {{ status }}</p>
{%- endfor %}
</div>
{%- endfor %}
</div>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<ipsecStatusAndStats>
<siteStatistics>
<siteId>ipsecsite-33</siteId>
<ikeStatus>
<channelStatus>down</channelStatus>
<channelState>PENDING</channelState>
<lastInformationalMessage></lastInformationalMessage>
<localIpAddress>1.2.3.4</localIpAddress>
<peerId>9.10.11.12</peerId>
<peerIpAddress>9.10.11.12</peerIpAddress>
<localSubnets>
<string>1.2.3.5/24</string>
</localSubnets>
<peerSubnets>
<string>10.1.1.1/32</string>
<string>10.2.1.1/32</string>
</peerSubnets>
<channelIkeVersion> IKEv2</channelIkeVersion>
<failureMessage> Version-IKEv2 Giving UP, Peer is not responding. Check reachability or check for Configuration on peer</failureMessage>
</ikeStatus>
<tunnelStats>
<tunnelStatus>down</tunnelStatus>
<tunnelState>PENDING</tunnelState>
<lastInformationalMessage></lastInformationalMessage>
<localSubnet>1.1.1.0/28</localSubnet>
<peerSubnet>10.3.1.1/32</peerSubnet>
<failureMessage> Version-IKEv2 Giving UP, Peer is not responding. Check reachability or check for Configuration on peer</failureMessage>
</tunnelStats>
<tunnelStats>
<tunnelStatus>down</tunnelStatus>
<tunnelState>PENDING</tunnelState>
<lastInformationalMessage></lastInformationalMessage>
<localSubnet>1.1.1.0/28</localSubnet>
<peerSubnet>10.4.1.1/32</peerSubnet>
<failureMessage> Version-IKEv2 Giving UP, Peer is not responding. Check reachability or check for Configuration on peer</failureMessage>
</tunnelStats>
</siteStatistics>
<siteStatistics>
<siteId>ipsecsite-44</siteId>
<ikeStatus>
<channelStatus>down</channelStatus>
<channelState>PENDING</channelState>
<lastInformationalMessage></lastInformationalMessage>
<localIpAddress>110.100.1.1</localIpAddress>
<peerId>10.7.1.1</peerId>
<peerIpAddress>10.7.1.1</peerIpAddress>
<localSubnets>
<string>10.9.1.1/28</string>
</localSubnets>
<peerSubnets>
<string>10.10.1.2/32</string>
</peerSubnets>
<channelIkeVersion> IKEv2</channelIkeVersion>
<failureMessage> Version-IKEv2 Received Delete for IKE-SA</failureMessage>
</ikeStatus>
<tunnelStats>
<tunnelStatus>down</tunnelStatus>
<tunnelState>PENDING</tunnelState>
<lastInformationalMessage> IKE_SA deleted, received DELETE for IKE_SA (80 bytes)</lastInformationalMessage>
<localSubnet>10.99.1.1/28</localSubnet>
<peerSubnet>10.103.1.1/32</peerSubnet>
<failureMessage> Version-IKEv2 Received Delete for IKE-SA</failureMessage>
</tunnelStats>
</siteStatistics>
<timeStamp>1595937529</timeStamp>
</ipsecStatusAndStats>
<?xml version="1.0" encoding="UTF-8"?>
<pagedEdgeList>
<edgePage>
<pagingInfo>
<pageSize>256</pageSize>
<startIndex>0</startIndex>
<totalCount>35</totalCount>
<sortOrderAscending>true</sortOrderAscending>
<sortBy>id</sortBy>
</pagingInfo>
<edgeSummary>
<objectId>edge-1</objectId>
<objectTypeName>Edge</objectTypeName>
<vsmUuid>421A561D-488B-F6FD-2D11-093376E581B2</vsmUuid>
<nodeId>804b8ee7-01f2-4d1d-9b05-99b23e2ef36a</nodeId>
<revision>231</revision>
<type>
<typeName>Edge</typeName>
</type>
<name>ONE</name>
<description>blaaaaaaaa</description>
<clientHandle></clientHandle>
<extendedAttributes/>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<isTemporal>false</isTemporal>
<isUpgradeAvailable>false</isUpgradeAvailable>
<id>edge-1</id>
<state>deployed</state>
<edgeType>gatewayServices</edgeType>
<datacenterMoid>datacenter-2</datacenterMoid>
<datacenterName>Coventry</datacenterName>
<tenantId>XXX</tenantId>
<apiVersion>4.0</apiVersion>
<edgeStatus>GREEN</edgeStatus>
<numberOfConnectedVnics>6</numberOfConnectedVnics>
<appliancesSummary>
<vmVersion>6.4.1</vmVersion>
<vmBuildInfo>6.4.1-8462400</vmBuildInfo>
<applianceSize>xlarge</applianceSize>
<fqdn>sddsds</fqdn>
<numberOfDeployedVms>2</numberOfDeployedVms>
<activeVseHaIndex>0</activeVseHaIndex>
<vmMoidOfActiveVse>vm-2306</vmMoidOfActiveVse>
<vmNameOfActiveVse>sdsdsd</vmNameOfActiveVse>
<hostMoidOfActiveVse>host-1112</hostMoidOfActiveVse>
<hostNameOfActiveVse>ddddd.local</hostNameOfActiveVse>
<resourcePoolMoidOfActiveVse>resgroup-1143</resourcePoolMoidOfActiveVse>
<resourcePoolNameOfActiveVse>NSX Components</resourcePoolNameOfActiveVse>
<dataStoreMoidOfActiveVse>datastore-1608</dataStoreMoidOfActiveVse>
<dataStoreNameOfActiveVse>11111111</dataStoreNameOfActiveVse>
<statusFromVseUpdatedOn>1594223712593</statusFromVseUpdatedOn>
<communicationChannel>msgbus-msgbus</communicationChannel>
<enableFips>false</enableFips>
</appliancesSummary>
<hypervisorAssist>false</hypervisorAssist>
<allowedActions>
<string>Change Log Level</string>
<string>Add Edge Appliance</string>
<string>Delete Edge Appliance</string>
<string>Edit Edge Appliance</string>
<string>Edit CLI Credentials</string>
<string>Change FIPS mode</string>
<string>Change edge appliance size</string>
<string>Force Sync</string>
<string>Redeploy Edge</string>
<string>Change Edge Appliance Core Dump Configuration</string>
<string>Enable hypervisorAssist</string>
<string>Edit Highavailability</string>
<string>Edit Dns</string>
<string>Edit Syslog</string>
<string>Edit Automatic Rule Generation Settings</string>
<string>Disable SSH</string>
<string>Download Edge TechSupport Logs</string>
</allowedActions>
</edgeSummary>
<edgeSummary>
<objectId>edge-2</objectId>
<objectTypeName>Edge</objectTypeName>
<vsmUuid>421A561D-488B-F6FD-2D11-093376E581B2</vsmUuid>
<nodeId>804b8ee7-01f2-4d1d-9b05-99b23e2ef36a</nodeId>
<revision>46</revision>
<type>
<typeName>Edge</typeName>
</type>
<name>AAAAAAA</name>
<description>DLR</description>
<clientHandle></clientHandle>
<extendedAttributes/>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<isTemporal>false</isTemporal>
<isUpgradeAvailable>false</isUpgradeAvailable>
<id>edge-2</id>
<state>deployed</state>
<edgeType>distributedRouter</edgeType>
<datacenterMoid>datacenter-2</datacenterMoid>
<datacenterName>Coventry</datacenterName>
<tenantId>wwwwwwwwwwww</tenantId>
<apiVersion>4.0</apiVersion>
<edgeStatus>GREEN</edgeStatus>
<numberOfConnectedVnics>8</numberOfConnectedVnics>
<appliancesSummary>
<vmVersion>6.4.1</vmVersion>
<vmBuildInfo>6.4.1-8462400</vmBuildInfo>
<applianceSize>compact</applianceSize>
<fqdn>vsssdsd</fqdn>
<numberOfDeployedVms>1</numberOfDeployedVms>
<activeVseHaIndex>0</activeVseHaIndex>
<vmMoidOfActiveVse>vm-286</vmMoidOfActiveVse>
<vmNameOfActiveVse>vvvvv-0</vmNameOfActiveVse>
<hostMoidOfActiveVse>host-1118</hostMoidOfActiveVse>
<hostNameOfActiveVse>ddddddddd.local</hostNameOfActiveVse>
<resourcePoolMoidOfActiveVse>resgroup-1143</resourcePoolMoidOfActiveVse>
<resourcePoolNameOfActiveVse>NSX Components</resourcePoolNameOfActiveVse>
<dataStoreMoidOfActiveVse>datastore-1608</dataStoreMoidOfActiveVse>
<dataStoreNameOfActiveVse>sdsdsdsd</dataStoreNameOfActiveVse>
<statusFromVseUpdatedOn>1594223692351</statusFromVseUpdatedOn>
<communicationChannel>msgbus</communicationChannel>
<enableFips>false</enableFips>
</appliancesSummary>
<hypervisorAssist>false</hypervisorAssist>
<allowedActions>
<string>Change Log Level</string>
<string>Add Edge Appliance</string>
<string>Delete Edge Appliance</string>
<string>Edit Edge Appliance</string>
<string>Edit CLI Credentials</string>
<string>Change FIPS mode</string>
<string>Force Sync</string>
<string>Redeploy Edge</string>
<string>Change Edge Appliance Core Dump Configuration</string>
<string>Edit Highavailability</string>
<string>Edit Dns</string>
<string>Edit Syslog</string>
<string>Disable SSH</string>
<string>Download Edge TechSupport Logs</string>
</allowedActions>
<edgeAssistId>10000</edgeAssistId>
<edgeAssistInstanceName>edge-2</edgeAssistInstanceName>
<lrouterUuid>fafe08b0-e8dc-4115-8f68-119fae451737</lrouterUuid>
<logicalRouterScopes>
<logicalRouterScope>
<type>TransportZone</type>
<id>vdnscope-1</id>
</logicalRouterScope>
</logicalRouterScopes>
</edgeSummary>
</edgePage>
</pagedEdgeList>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment