Skip to content

Commit

Permalink
Merge pull request #10 from ministryofjustice/more-changes
Browse files Browse the repository at this point in the history
Enhancements
  • Loading branch information
Stephen James authored Dec 13, 2023
2 parents 43e09f8 + 0c86cc6 commit 5304745
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.env
.env*
.terraform/
coverage/
venv/
Expand Down
41 changes: 30 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ This repo has been developed by the DevOps Lan&Wi-Fi to automate site creation o

## Run script as end user (Assuming you don't have the repo cloned)

Run the following:
### Required package prerequisites

#### Docker

[Docker docs mac install](https://docs.docker.com/desktop/install/mac-install/)

### Run script:

1. Copy this in your terminal and paste to create the working directory.

Expand All @@ -15,28 +21,41 @@ mkdir -p ~/mist_working_directory/data_src && cd ~/mist_working_directory
2. Copy this in your terminal and paste

```
wget -O .env https://raw.githubusercontent.com/ministryofjustice/juniper-mist-integration/main/example.env
curl -o .env https://raw.githubusercontent.com/ministryofjustice/juniper-mist-integration/main/example.env
```

3. Configure .env file:
You must either provide MIST_USERNAME and MIST_PASSWORD or MIST_API_TOKEN.
If you opt for username and password MFA will be requested during runtime.
All other inputs are mandatory:
ORG_ID,
SITE_GROUP_IDS,
RF_TEMPLATE_ID
Review the .env file by running:

```
nano ~/example.env
```

To fully take advantage of the .env files, you can duplicate them and have different .envs per environment.
If you choose to do this make sure you edit the docker run command in step 6 to pass in the correctly named file.

```
.env-dev
.env-prod
```

4. Create a csv file named: `sites_with_clients.csv` within '~/mist_working_directory/data_src'
or copy the [example CSV](./example.sites_with_clients.csv) (which is formatted correctly) with the following command to the data directory:

```
wget -O data_src/sites_with_clients.csv https://raw.githubusercontent.com/ministryofjustice/juniper-mist-integration/main/example.sites_with_clients.csv
curl -o data_src/sites_with_clients.csv https://raw.githubusercontent.com/ministryofjustice/juniper-mist-integration/main/example.sites_with_clients.csv
```

5. Copy this in your terminal and paste to download and run the Dockerized tooling:
5. Make sure docker can mount the `~/mist_working_directory`

Within Docker Desktop Cog --> Resources --> File Sharing --> add `/Users/$YOURUSERNAME/mist_working_directory`

![title](assets/docker-file-sharing.png)

6. Copy this in your terminal and paste to download and run the Dockerized tooling:

```
docker run -it -v $(pwd)/data_src:/data_src --env-file .env ghcr.io/ministryofjustice/nvvs/juniper-mist-integration/app:latest
docker pull ghcr.io/ministryofjustice/nvvs/juniper-mist-integration/app:latest; docker run -it -v $(pwd)/data_src:/data_src --env-file .env ghcr.io/ministryofjustice/nvvs/juniper-mist-integration/app:latest
```

## Development setup
Expand Down
Binary file added assets/docker-file-sharing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 8 additions & 7 deletions example.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
;Mandatory Config Options
ORG_ID=
SITE_GROUP_IDS={"moj_wifi": "foo","gov_wifi": "bar"}
RF_TEMPLATE_ID=
NETWORK_TEMPLATE_ID=

; Optional config options
;MIST_USERNAME=
;MIST_PASSWORD=
;MIST_API_TOKEN=
;ORG_ID=
;MIST_API_TOKEN=
;SITE_GROUP_IDS={"moj_wifi": "foo","gov_wifi": "bar"}
;RF_TEMPLATE_ID=
;NETWORK_TEMPLATE_ID=
;MIST_LOGIN_METHOD=credentials or token
55 changes: 41 additions & 14 deletions src/juniper.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import requests
import json
import getpass
import sys

# Mist CRUD operations


class Admin:

def login_via_username_and_password(self, username, password):
def login_via_username_and_password(self, username):
# If no username defined ask user
if username is None:
username = input("Enter Mist Username:")
else:
print('Username provided: {usr}'.format(usr=username))
password = getpass.getpass(prompt='Enter Mist password:')
login_url = self.base_url + "/login"
login_payload = {'email': username, 'password': password}
self.session.post(login_url, data=login_payload)
Expand All @@ -26,7 +34,8 @@ def login_via_username_and_password(self, username, password):
raise ValueError("Login was not successful: {response}".format(
response=login_response))

def login_via_token(self, token):
def login_via_token(self):
token = getpass.getpass(prompt='Input the MIST API TOKEN:')
self.headers['Authorization'] = 'Token ' + token
request_url = self.base_url + "/self/apitokens"
responce = self.session.get(request_url, headers=self.headers)
Expand All @@ -36,17 +45,18 @@ def login_via_token(self, token):
raise ValueError(
"Login was not successful via token: {response}".format(response=responce))

def __init__(self, token=None, username=None, password=None):
def __init__(self, username=None, mist_login_method=None):
self.session = requests.Session()
self.headers = {'Content-Type': 'application/json'}
self.base_url = 'https://api.eu.mist.com/api/v1'

if token:
self.login_via_token(token)
elif username and password:
self.login_via_username_and_password(username, password)
if mist_login_method == 'token':
self.login_via_token()
elif mist_login_method == 'credentials':
self.login_via_username_and_password(username)
else:
raise ValueError("Invalid parameters provided for authentication.")
raise ValueError('Invalid mist_login_method: {method}'.format(
method=mist_login_method))

def post(self, url, payload, timeout=60):
url = 'https://api.eu.mist.com{}'.format(url)
Expand Down Expand Up @@ -93,37 +103,54 @@ def check_if_we_need_to_append_gov_wifi_or_moj_wifi_site_groups(gov_wifi, moj_wi
result.append(site_group_ids['gov_wifi'])
return result


def warn_if_using_org_id_production(org_id):
production_org_id = '3e824dd6-6b37-4cc7-90bb-97d744e91175'
if org_id == production_org_id:
production_warning_answer = input(
"Warning you are using production ORG_ID, would you like to proceed? Y/N: ").upper()
if production_warning_answer == "Y":
print("Continuing with run")
return 'Continuing_with_run'
elif production_warning_answer == "N":
sys.exit()
else:
raise ValueError('Invalid input')

# Main function


def juniper_script(
data,
mist_api_token=None,
org_id=None,
mist_username=None,
mist_password=None,
mist_login_method=None,
site_group_ids=None,
rf_template_id=None,
network_template_id=None
):

# Configure True/False to enable/disable additional logging of the API response objects
show_more_details = True

# Check for required variables
if org_id is None or org_id == '':
raise ValueError('Please provide Mist org_id')
if (mist_api_token is None) and (mist_username is None or mist_password is None):
raise ValueError(
'No authentication provided, provide mist username and password or API key')
if site_group_ids is None:
raise ValueError('Must provide site_group_ids for GovWifi & MoJWifi')
if rf_template_id is None:
raise ValueError('Must define rf_template_id')
if network_template_id is None:
raise ValueError('Must define network_template_id')
if mist_login_method is None:
print("mist_login_method not defined. Defaulting to credentials")
mist_login_method = 'credentials'

# Prompt user if we are using production org_id
warn_if_using_org_id_production(org_id)

# Establish Mist session
admin = Admin(mist_api_token, mist_username, mist_password)
admin = Admin(mist_username, mist_login_method)

# Create each site from the CSV file
for d in data:
Expand Down
5 changes: 3 additions & 2 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sys

from juniper import juniper_script
import os
import csv
Expand Down Expand Up @@ -50,9 +52,8 @@ def add_geocoding_to_json(data):
json_data_without_geocoding)

juniper_script(
mist_api_token=os.environ.get('MIST_API_TOKEN'),
mist_username=os.environ.get('MIST_USERNAME'),
mist_password=os.environ.get('MIST_PASSWORD'),
mist_login_method=os.environ.get('MIST_LOGIN_METHOD'),
site_group_ids=os.environ.get('SITE_GROUP_IDS'),
org_id=os.environ.get('ORG_ID'),
rf_template_id=os.environ.get('RF_TEMPLATE_ID'),
Expand Down
Loading

0 comments on commit 5304745

Please sign in to comment.