generated from ministryofjustice/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
broken out juniperscript into more readable modules
- Loading branch information
1 parent
16dae5c
commit 1992522
Showing
6 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,7 @@ env/ | |
*.code-workspace | ||
*.sha256 | ||
terraform.tfstate | ||
|
||
test_data/**.csv | ||
./idea/* | ||
**/__pycache__/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from geopy import Nominatim | ||
from timezonefinder import TimezoneFinder | ||
|
||
def geocode(address) -> str: | ||
geolocator = Nominatim(user_agent="geocode") | ||
location = geolocator.geocode(address) | ||
try: | ||
latitude, longitude = location.latitude, location.longitude | ||
except ValueError: | ||
raise ValueError('geocode unable to find latitude & longitude for {address}'.format(address=address)) | ||
return latitude, longitude | ||
|
||
def find_country_code(gps) -> tuple: | ||
latitude = gps[0] | ||
longitude = gps[1] | ||
geolocator = Nominatim(user_agent="geocode") | ||
location = geolocator.reverse([latitude, longitude]) | ||
country_code=location.raw['address']['country_code'] | ||
|
||
return country_code.upper() | ||
|
||
def find_timezone(gps) -> tuple: | ||
tf_init = TimezoneFinder() | ||
latitude = gps[0] | ||
longitude = gps[1] | ||
try: | ||
timezone_name = tf_init.timezone_at(lat=latitude, lng=longitude) | ||
except ValueError: | ||
raise ValueError('The coordinates were out of bounds {latitude}:{longitude}'.format(lat=latitude,lng=longitude)) | ||
if timezone_name is None: | ||
raise ValueError('GPS coordinates did not match a time_zone') | ||
|
||
return timezone_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import sys, requests, json | ||
|
||
# Mist CRUD operations | ||
class Admin(object): | ||
def __init__(self, token=''): | ||
self.session = requests.Session() | ||
self.headers = { | ||
'Content-Type': 'application/json', | ||
'Authorization': 'Token ' + token | ||
} | ||
|
||
def post(self, url, payload, timeout=60): | ||
url = 'https://api.eu.mist.com{}'.format(url) | ||
session = self.session | ||
headers = self.headers | ||
|
||
print('POST {}'.format(url)) | ||
response = session.post(url, headers=headers, json=payload) | ||
|
||
if response.status_code != 200: | ||
print('Failed to POST') | ||
print('\tURL: {}'.format(url)) | ||
print('\tPayload: {}'.format(payload)) | ||
print('\tResponse: {} ({})'.format(response.text, response.status_code)) | ||
|
||
return False | ||
|
||
return json.loads(response.text) | ||
|
||
def put(self, url, payload): | ||
url = 'https://api.eu.mist.com{}'.format(url) | ||
session = self.session | ||
headers = self.headers | ||
|
||
print('PUT {}'.format(url)) | ||
response = session.put(url, headers=headers, json=payload) | ||
|
||
if response.status_code != 200: | ||
print('Failed to PUT') | ||
print('\tURL: {}'.format(url)) | ||
print('\tPayload: {}'.format(payload)) | ||
print('\tResponse: {} ({})'.format(response.text, response.status_code)) | ||
|
||
return False | ||
|
||
return json.loads(response.text) | ||
|
||
|
||
# Main function | ||
def juniper_script( | ||
data, | ||
mist_api_token='', | ||
org_id=''): | ||
|
||
show_more_details = True # Configure True/False to enable/disable additional logging of the API response objects | ||
|
||
|
||
# Check for required variables | ||
if mist_api_token == '': | ||
print('Please provide your Mist API token as mist_api_token') | ||
sys.exit(1) | ||
elif org_id == '': | ||
print('Please provide your Mist Organization UUID as org_id') | ||
sys.exit(1) | ||
|
||
# Establish Mist session | ||
admin = Admin(mist_api_token) | ||
|
||
# Create each site from the CSV file | ||
for d in data: | ||
# Variables | ||
site_id = None | ||
site = {'name': d.get('Site Name', ''), | ||
'address': d.get('Site Address', ''), | ||
"latlng": {"lat": d.get('gps', '')[0], "lng": d.get('gps', '')[1]}, | ||
"country_code": d.get('country_code', ''), | ||
"timezone": d.get('time_zone', ''), | ||
} | ||
|
||
# MOJ specific attributes | ||
site_setting = { | ||
|
||
"vars": { | ||
"Enable GovWifi": d.get('Enable GovWifi', ''), | ||
"Enable MoJWifi": d.get('Enable MoJWifi', ''), | ||
"Wired NACS Radius Key": d.get('Wired NACS Radius Key', ''), | ||
"GovWifi Radius Key": d.get('GovWifi Radius Key', '') | ||
|
||
} | ||
|
||
} | ||
|
||
|
||
|
||
print('Calling the Mist Create Site API...') | ||
result = admin.post('/api/v1/orgs/' + org_id + '/sites', site) | ||
if result == False: | ||
print('Failed to create site {}'.format(site['name'])) | ||
print('Skipping remaining operations for this site...') | ||
print('\n\n==========\n\n') | ||
|
||
continue | ||
else: | ||
site_id = result['id'] | ||
print('Created site {} ({})'.format(site['name'], site_id)) | ||
|
||
if show_more_details: | ||
print('\nRetrieving the JSON response object...') | ||
print(json.dumps(result, sort_keys=True, indent=4)) | ||
print('\nUsing id in the Mist Update Setting API request') | ||
|
||
print() | ||
|
||
# Update Site Setting | ||
print('Calling the Mist Update Setting API...') | ||
result = admin.put('/api/v1/sites/' + site_id + '/setting', | ||
site_setting) | ||
if result == False: | ||
print('Failed to update site setting {} ({})'.format(site['name'], site_id)) | ||
else: | ||
print('Updated site setting {} ({})'.format(site['name'], site_id)) | ||
|
||
if show_more_details: | ||
print('\nRetrieving the JSON response object...') | ||
print(json.dumps(result, sort_keys=True, indent=4)) | ||
|
||
print('\n\n==========\n\n') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from juniper import juniper_script | ||
import os, csv | ||
from geocode import geocode, find_timezone, find_country_code | ||
|
||
|
||
# Convert CSV file to JSON object. | ||
def csv_to_json(file_path): | ||
csv_rows = [] | ||
with open(file_path) as csvfile: | ||
reader = csv.DictReader(csvfile, skipinitialspace=True, quotechar='"') | ||
title = reader.fieldnames | ||
|
||
for row in reader: | ||
csv_rows.extend([ {title[i]: row[title[i]] for i in range(len(title))} ]) | ||
|
||
return csv_rows | ||
|
||
if __name__ == '__main__': | ||
|
||
csv_file_path=os.getcwd() + '/../test_data/sites_with_clients.csv' | ||
|
||
# Convert CSV to valid JSON | ||
data = csv_to_json(csv_file_path) | ||
if data == None or data == []: | ||
raise ValueError('Failed to convert CSV file to JSON. Exiting script.') | ||
|
||
|
||
# Create each site from the CSV file | ||
for d in data: | ||
# Variables | ||
site_id = None | ||
site = {'name': d.get('Site Name', ''), | ||
'address': d.get('Site Name', '') | ||
} | ||
|
||
gps = geocode(d.get('Site Address', '')) | ||
country_code = find_country_code(gps) | ||
time_zone = find_timezone(gps) | ||
|
||
# Adding new key-value pairs to the dictionary | ||
d['gps'] = gps | ||
d['country_code'] = country_code | ||
d['time_zone'] = time_zone | ||
|
||
juniper_script( | ||
mist_api_token=os.environ['MIST_API_TOKEN'], | ||
org_id=os.environ['ORG_ID'], | ||
data=data | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
requests==2.21.0 | ||
geopy==2.4.1 | ||
timezonefinder==6.2.0 |
Empty file.