update py files

This commit is contained in:
John Poland 2025-03-05 15:22:17 -05:00
parent 7e73217c4c
commit cdc3bda927
5 changed files with 421 additions and 0 deletions

126
code/backupviacentral.py Normal file
View File

@ -0,0 +1,126 @@
import centralauth
import requests
import contextlib
import os
import stat
import sys
import tempfile
import yaml
@contextlib.contextmanager
def atomic_write(filename, text=True, keep=True,
owner=None, group=None, perms=None,
suffix='.bak', prefix='tmp'):
"""Context manager for overwriting a file atomically.
Usage:
>>> with atomic_write("myfile.txt") as f: # doctest: +SKIP
... f.write("data")
The context manager opens a temporary file for writing in the same
directory as `filename`. On cleanly exiting the with-block, the temp
file is renamed to the given filename. If the original file already
exists, it will be overwritten and any existing contents replaced.
(On POSIX systems, the rename is atomic. Other operating systems may
not support atomic renames, in which case the function name is
misleading.)
If an uncaught exception occurs inside the with-block, the original
file is left untouched. By default the temporary file is also
preserved, for diagnosis or data recovery. To delete the temp file,
pass `keep=False`. Any errors in deleting the temp file are ignored.
By default, the temp file is opened in text mode. To use binary mode,
pass `text=False` as an argument. On some operating systems, this make
no difference.
The temporary file is readable and writable only by the creating user.
By default, the original ownership and access permissions of `filename`
are restored after a successful rename. If `owner`, `group` or `perms`
are specified and are not None, the file owner, group or permissions
are set to the given numeric value(s). If they are not specified, or
are None, the appropriate value is taken from the original file (which
must exist).
By default, the temp file will have a name starting with "tmp" and
ending with ".bak". You can vary that by passing strings as the
`suffix` and `prefix` arguments.
"""
t = (uid, gid, mod) = (owner, group, perms)
if any(x is None for x in t):
info = os.stat(filename)
if uid is None:
uid = info.st_uid
if gid is None:
gid = info.st_gid
if mod is None:
mod = stat.S_IMODE(info.st_mode)
path = os.path.dirname(filename)
fd, tmp = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=path, text=text)
try:
replace = os.replace # Python 3.3 and better.
except AttributeError:
if sys.platform == 'win32':
# FIXME This is definitely not atomic!
# But it's how (for example) Mercurial does it, as of 2016-03-23
# https://selenic.com/repo/hg/file/tip/mercurial/windows.py
def replace(source, destination):
assert sys.platform == 'win32'
try:
os.rename(source, destination)
except OSError as err:
if err.winerr != 183:
raise
os.remove(destination)
os.rename(source, destination)
else:
# Atomic on POSIX. Not sure about Cygwin, OS/2 or others.
replace = os.rename
try:
with os.fdopen(fd, 'w' if text else 'wb') as f:
yield f
# Perform an atomic rename (if possible). This will be atomic on
# POSIX systems, and Windows for Python 3.3 or higher.
replace(tmp, filename)
tmp = None
os.chown(filename, uid, gid)
os.chmod(filename, mod)
finally:
if (tmp is not None) and (not keep):
# Silently delete the temporary file. Ignore any errors.
try:
os.unlink(tmp)
except Exception:
pass
centralauth_db=centralauth.get_centralauth()
inventory = yaml.safe_load(open("centralinv.yml"))
headers = {
'Accept': 'application/json',
'Authorization': f'Bearer {centralauth_db['access_token']}',
}
for building in inventory:
for switch in inventory[building]['hosts']:
url = f"{centralauth_db['base_url']}/configuration/v1/devices/{inventory[building]['hosts'][switch]['serial_num']}/configuration"
response=requests.get(url,headers=headers)
#print(response.text)
print(f"/tmp/cfg/{building}/{switch}.cfg")
try:
with atomic_write(f"/tmp/cfg/{building}/{switch}.cfg") as f:
f.write(response.text)
except FileNotFoundError:
with open(f"/tmp/cfg/{building}/{switch}.cfg","w") as f:
f.write(response.text)
url = f"{centralauth_db['base_url']}/configuration/v1/devices/SG3AKMY253/configuration"
response=requests.get(url,headers=headers)
print(response.text)

64
code/central_devices.py Normal file
View File

@ -0,0 +1,64 @@
import centralauth
import requests
import json
DEBUG = False
centralauth_db=centralauth.get_centralauth()
all_text="""
all:
vars:
ansible_network_os: arubanetworks.aoscx.aoscx
ansible_connection: arubanetworks.aoscx.aoscx # REST API via pyaoscx connection method
ansible_aoscx_validate_certs: False
ansible_aoscx_use_proxy: False
ansible_acx_no_proxy: True
ansible_ssh_common_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
"""
headers = {
'Accept': 'application/json',
'Authorization': f'Bearer {centralauth_db['access_token']}',
}
offset=1
page_size=300
switch_dict={}
while True:
url = f"{centralauth_db['base_url']}/monitoring/v1/switches?limit={page_size}&offset={offset}"
response = requests.get(url, headers=headers)
#print(response.text)
j=json.loads(response.text)
if j['count']==0:
break
for switch in j['switches']:
if not switch['status'] == 'Down' and not switch['ip_address']=='':
switch_dict[switch['name']]=switch
#print (switch['name'],switch['serial'],switch['ip_address'])
offset+=page_size
current_building=''
for switch_name in sorted(switch_dict):
switch=switch_dict[switch_name]
building=switch_name.split("-")[0]
if not building == current_building:
print(f"{building}:")
print( " hosts:")
current_building=building
print(f" {switch_name}:")
print(f" ansible_host: {switch['ip_address']}")
print(f" building_name: {current_building}")
print(f" serial_num: {switch['serial']}")
print(f"{all_text}")

112
code/centralauth.py Normal file
View File

@ -0,0 +1,112 @@
import sqlite3
import requests
import json
def load_kvstore():
con = sqlite3.connect("centralauth.db")
cur = con.cursor()
res=cur.execute("select key,value from kvstore")
data=res.fetchall()
kvstore={}
for key,value in data:
kvstore[key]=value
con.close()
return(kvstore)
def save_kvstore(kvstore):
con = sqlite3.connect("centralauth.db")
cur = con.cursor()
for key in kvstore:
sql=f"INSERT INTO kvstore (key,value) values('{key}','{kvstore[key]}') ON CONFLICT DO update set value=excluded.value"
cur.execute(sql)
con.commit()
con.close()
return(kvstore)
def get_new_access_token(kvstore):
# step 1
url=f"{kvstore['base_url']}/oauth2/authorize/central/api/login?client_id={kvstore['client_id']}"
payload = json.dumps({
'username':kvstore['central_username'],
'password':kvstore['central_password']
})
headers = {
'Content-Type': 'application/json'
}
ses = requests.Session()
response=ses.post(url,headers=headers,data=payload)
print (response)
# step 2
payload = json.dumps({'customer_id':kvstore['customer_id']})
url = f"{kvstore['base_url']}/oauth2/authorize/central/api/?client_id={kvstore['client_id']}&response_type=code&scope=all"
response=ses.post(url,headers=headers,data=payload)
response_data=json.loads(response.text)
# step 3
payload = json.dumps({
"grant_type": "authorization_code",
'code':response_data['auth_code'],
'client_id':kvstore['client_id'],
'client_secret':kvstore['client_secret'],
})
url = f"{kvstore['base_url']}/oauth2/token"
response=ses.post(url,headers=headers,data=payload)
response_data=json.loads(response.text)
kvstore['refresh_token']=response_data['refresh_token']
kvstore['access_token']=response_data['access_token']
save_kvstore(kvstore)
return(kvstore)
def refresh_access_token(kvstore):
headers = {
'Content-Type': 'application/json'
}
url=f"{kvstore['base_url']}/oauth2/token?client_id={kvstore['client_id']}&client_secret={kvstore['client_secret']}&grant_type=refresh_token&refresh_token={kvstore['refresh_token']}"
ses = requests.Session()
response=ses.post(url,headers=headers)
response_data=json.loads(response.text)
kvstore['refresh_token']=response_data['refresh_token']
kvstore['access_token']=response_data['access_token']
save_kvstore(kvstore)
return(kvstore)
def get_centralauth():
kvstore=load_kvstore()
if 'access_token' not in kvstore:
kvstore=get_new_access_token(kvstore)
if 'access_token' in kvstore:
kvstore=refresh_access_token(kvstore)
return({'access_token':kvstore['access_token'],'base_url':kvstore['base_url']})
if __name__ == "__main__":
centralauth=get_centralauth()
headers = {
'Accept': 'application/json',
'Authorization': f'Bearer {centralauth['access_token']}',
}
url = f"{centralauth['base_url']}/configuration/v1/devices/SG3AL5K03S/configuration"
url = f"{centralauth['base_url']}/configuration/v1/devices/SG3AKMY253/configuration"
response=requests.get(url,headers=headers)
print(response.text)

View File

@ -0,0 +1,31 @@
import glob
filenames=glob.glob("../configs/*/*8360*")
for filename in filenames:
in_mgmt = False
in_vlan10 = False
vlan10_ip = None
mgmt_ip = None
with open(filename) as f:
for line in f:
if in_mgmt:
if not line[0]==" ":
in_mgmt=False
elif line.startswith(" ip static"):
mgmt_ip = line.strip().split()[2]
if line.startswith("interface mgmt"):
#print(line)
in_mgmt=True
if in_vlan10:
if not line[0]==" ":
in_vlan10=False
elif line.startswith(" ip address"):
vlan10_ip = line.strip().split()[2]
if line.strip()=="interface vlan 10":
#print(line)
in_vlan10=True
#print (line)
if vlan10_ip:
print (filename.split("/")[-1],mgmt_ip,vlan10_ip)
#sys.exit()

View File

@ -0,0 +1,88 @@
import requests
import json
DEBUG = False
url = "https://sso.common.cloud.hpe.com/as/token.oauth2"
payload = {
"grant_type": "client_credentials",
"client_id": "65098f0f-747f-4c13-a338-c13028184ecd",
"client_secret": "710067957ef344918e90f8c890655f5e"
}
headers = {
"accept": "application/json",
"content-type": "application/x-www-form-urlencoded"
}
all_text="""
all:
vars:
ansible_network_os: arubanetworks.aoscx.aoscx
ansible_connection: arubanetworks.aoscx.aoscx # REST API via pyaoscx connection method
ansible_aoscx_validate_certs: False
ansible_aoscx_use_proxy: False
ansible_acx_no_proxy: True
ansible_ssh_common_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
"""
response = requests.post(url, data=payload, headers=headers)
#print(response.text)
response_json=json.loads(response.text)
access_token=response_json['access_token']
devices={}
page_count=1
page_size=100
url_base='https://us4.api.central.arubanetworks.com'
while True:
url = f"{url_base}/network-monitoring/v1alpha1/devices?limit={page_size}&next={page_count}"
#url = f"{url_base}/network-monitoring/v1alpha1/device-inventory?limit={page_size}&next={page_count}"
headers = {
"accept": "application/json",
"authorization": f"Bearer {access_token}"
}
response = requests.get(url, headers=headers)
items = json.loads(response.text)['items']
for d in items:
#print (d['deviceName'])
if d['status']=="ONLINE":
devices[d['deviceName']]=d
if DEBUG: print(d['deviceName'])
if json.loads(response.text)['next'] is None:
break
page_count+=1
for d in devices:
if devices[d]['deployment']=='Stack':
if DEBUG: print(d,'Stack',devices[d])
headers['site-id']=devices[d]['siteId']
url = f"{url_base}/network-monitoring/v1alpha1/stack/{devices[d]['id']}/members"
response = requests.get(url, headers=headers)
if DEBUG: print(response.text)
current_building=''
#print (devices)
for d in sorted(devices):
building=devices[d]['deviceName'].split("-")[0]
if not building == current_building:
print(f"{building}:")
print( " hosts:")
current_building=building
print(f" {devices[d]['deviceName']}:")
print(f" ansible_host: {devices[d]['ipv4']}")
print(f" building_name: {current_building}")
print(f" serial_num: {devices[d]['serialNumber']}")
print(f"{all_text}")