Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SBS login monitoring and timestamp #1

Merged
merged 2 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions getmonitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
import sys

# getmonitor.py is used to retrieve the monitor values
# using Zabbix system.run[]


def get(env, command):
try:
with open(f'status/{env}.log', 'r') as f:
time = f.readline()
test = f.readline()
login = f.readline()
if command == 'time':
return time.strip()
elif command == 'test':
return test.strip()
elif command == 'login':
return login.strip()
elif command == 'pam':
return login.strip()
except Exception:
return "error\n"


if __name__ == '__main__':
if len(sys.argv) < 3:
sys.exit(sys.argv[0] + " <env> <command>")
env = sys.argv[1]
command = sys.argv[2]
print(get(env, command))
148 changes: 148 additions & 0 deletions pam-monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#!/usr/bin/env python
import sys
import time
import yaml
import requests
import json
import re
import traceback

from selenium.webdriver import Remote, ChromeOptions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import (staleness_of, presence_of_element_located,
title_contains)
from selenium.webdriver.common.by import By

if len(sys.argv) < 2:
sys.exit(sys.argv[0] + " <argument>")

print(f"= READING {sys.argv[1]} ====", file=sys.stderr)
with open(sys.argv[1], 'r') as f:
try:
config = yaml.load(f, Loader=yaml.FullLoader)
except yaml.YAMLError as exc:
print(exc)

KEY = 'pam_monitor'
config = config[KEY]

start_payload = {
# "user_id": "ascz",
"attribute": "username",
"cache_duration": 60,
"GIT_COMMIT": "monitor",
"JSONPARSER_GIT_COMMIT": "monitor",
}
regex = r"(https?://.*)\s"
xpath_login_button = "//span[@class='textual' and text()='Log in']"
xpath_code_element = "//span[@class='value']"


print("= Starting Chrome ===", file=sys.stderr)
options = ChromeOptions()
options.add_argument('--headless')
browser = Remote("http://127.0.0.1:4444", options=options)
send_command = ('POST', '/session/$sessionId/chromium/send_command')
browser.command_executor._commands['SEND_COMMAND'] = send_command
browser.implicitly_wait(1)
wait = WebDriverWait(browser, timeout=2)


try:
for url, values in config.items():
token = values['token']
account = values['account']
(username, password) = account.split('.')
# print(f"{url}, {token}", file=sys.stderr)
# print(f"{username}:{password}", file=sys.stderr)
health = f'{url}health'
headers = {
"Authorization": f"Bearer {token}",
}

r = requests.post(f"{url}pam-weblogin/start", json=start_payload, headers=headers)
j = json.loads(r.text)

session_id = j['session_id']
challenge = j['challenge']
link = re.findall(regex, challenge)[0]
print(link, file=sys.stderr)
# break

# Wait for SBS health up
status = ""
while status != "UP":
browser.get(health)
state = json.loads(browser.find_element(By.XPATH, "//pre").text)
status = state.get("status")
time.sleep(1)

# Clear cookies
browser.execute('SEND_COMMAND', dict(cmd='Network.clearBrowserCookies', params={}))

# Get SBS link page
browser.get(link)

# Wait for loginpage to load
wait.until(presence_of_element_located((By.XPATH, xpath_login_button)),
'Timeout waiting for Profile')

# Click login
browser.find_element(By.XPATH, xpath_login_button).click()

# Wait for discovery to load
wait.until(title_contains('SURF Research Access Management'),
'Timeout waiting for discovery')

# Choose Monitoring IdP
try:
xpath = "//div[@class='primary' and text()='SRAM Monitoring IdP']"
monitor = browser.find_element(By.XPATH, xpath)
except Exception:
search = browser.find_element(By.ID, 'searchinput')
search.send_keys('monitoring')
xpath = "//div[@class='text-truncate label primary' and text()='SRAM Monitoring IdP']"
monitor = browser.find_element(By.XPATH, xpath)

monitor.click()

wait.until(staleness_of(monitor))

# Login as user
browser.find_element(By.ID, 'username').send_keys(username)
browser.find_element(By.ID, 'password').send_keys(password)
browser.find_element(By.NAME, 'f').submit()

# Wait for Verification code to load
wait.until(presence_of_element_located((By.XPATH, xpath_code_element)),
'Timeout waiting for Profile')

# Test admin attributes
code = browser.find_elements(By.XPATH, xpath_code_element)[0].text

print(f"code: {code}", file=sys.stderr)

pin_payload = {
"session_id": session_id,
"pin": code,
}

r = requests.post(f"{url}pam-weblogin/check-pin", json=pin_payload, headers=headers)
j = json.loads(r.text)

result = j['result']

if not result == "SUCCESS":
raise Exception("FAIL")

print(f"result: {result}", file=sys.stderr)
print("= OK =======", file=sys.stderr)

print("OK")
browser.quit()

except Exception as e:
tr = traceback.extract_tb(e.__traceback__)[0]
print(f"error {type(e).__name__} on line {tr.lineno} of '{tr.filename}'")
browser.quit()
exit(1)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
PyYAML
selenium
requests
23 changes: 17 additions & 6 deletions run_sram_monitoring.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,29 @@ if [ ! -f ${ENV}.yml ]; then
exit 1
fi

docker run --rm -d --name chrome -p 4444:4444 selenium/standalone-chrome >/dev/null 2>&1
while ! curl --output /dev/null --silent --head http://localhost:4444/wd/hub; do
docker run --shm-size=2g --rm -d --name chrome -p 4444:4444 selenium/standalone-chrome >/dev/null 2>&1
while ! curl --output /dev/null --silent --head http://localhost:4444/wd/hub/status; do
# echo -n "."
sleep 1
done
# echo " Up!"

LOGFILE="status/${ENV}.log"

#date
date --utc +"%s" > $LOGFILE

# monitoring test
OUTPUT=$(python3 sram_monitoring_test.py ${ENV}.yml)
RESULT=$?
echo $OUTPUT >> $LOGFILE

# SBS login test
OUTPUT=$(python3 sbs-login.py ${ENV}.yml)
echo $OUTPUT >> $LOGFILE

# SBS login test
OUTPUT=$(python3 pam-monitor.py ${ENV}.yml)
echo $OUTPUT >> $LOGFILE

docker stop chrome >/dev/null 2>&1
# echo "Down"

echo $OUTPUT > status/${ENV}.log
exit $RESULT
115 changes: 115 additions & 0 deletions sbs-login.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python

from selenium.webdriver import Remote, ChromeOptions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import (staleness_of, presence_of_element_located,
title_contains)
from selenium.webdriver.common.by import By

import sys
import yaml
import json
import time
import traceback

if len(sys.argv) < 2:
sys.exit(sys.argv[0] + " <argument>")

print(f"= READING {sys.argv[1]} ====", file=sys.stderr)
with open(sys.argv[1], 'r') as f:
try:
config = yaml.load(f, Loader=yaml.FullLoader)
except yaml.YAMLError as exc:
print(exc)

KEY = 'sbs_login'
config = config[KEY]

xpath_login_button = '//button[span[text()="Log in"]]'
xpath_logo = '//a[@class="logo"]//span[text()="Research Access Management"]'

print("= Starting Chrome ===", file=sys.stderr)
options = ChromeOptions()
options.add_argument('--headless')
browser = Remote("http://127.0.0.1:4444", options=options)
send_command = ('POST', '/session/$sessionId/chromium/send_command')
browser.command_executor._commands['SEND_COMMAND'] = send_command
browser.implicitly_wait(1)
wait = WebDriverWait(browser, timeout=2)


try:
for (url, login) in config.items():
print(url, file=sys.stderr)
for (account, name) in login.items():
(username, password) = account.split('.')
print("============", file=sys.stderr)
print(username, name, file=sys.stderr)
# print(password, file=sys.stderr)
# print(name, file=sys.stderr)

health = f'{url}health'
start = f'{url}profile'

# Wait for SBS health up
status = ""
while status != "UP":
browser.get(health)
state = json.loads(browser.find_element(By.XPATH, "//pre").text)
status = state.get("status")
time.sleep(1)

# Clear cookies
browser.execute('SEND_COMMAND', dict(cmd='Network.clearBrowserCookies', params={}))

# Get SBS profile page
browser.get(start)

# Wait for discovery to load
wait.until(title_contains('SURF Research Access Management'),
'Timeout waiting for discovery')

# Choose Monitoring IdP
try:
xpath = "//div[@class='primary' and text()='SRAM Monitoring IdP']"
monitor = browser.find_element(By.XPATH, xpath)
except Exception:
search = browser.find_element(By.ID, 'searchinput')
search.send_keys('monitoring')
xpath = "//div[@class='text-truncate label primary' and text()='SRAM Monitoring IdP']"
monitor = browser.find_element(By.XPATH, xpath)

monitor.click()

wait.until(staleness_of(monitor))

# Login as user
browser.find_element(By.ID, 'username').send_keys(username)
browser.find_element(By.ID, 'password').send_keys(password)
browser.find_element(By.NAME, 'f').submit()

# Wait for Profile to load
wait.until(presence_of_element_located((By.XPATH, "//h2[text()='Your profile']")),
'Timeout waiting for Profile')

# Test admin attributes
attributes = browser.find_elements(By.XPATH, "//table[@class='my-attributes']/*/*/*")
# for a in attributes:
# print(f"a.text: {a.text}")
assert (name in [a.text for a in attributes]), "No valid admin profile found"
print("= OK =======", file=sys.stderr)
print("OK")
browser.quit()
print("============", file=sys.stderr)
exit(0)

except Exception as e:
# url = browser.current_url
# print(f"url: {url}")

tr = traceback.extract_tb(e.__traceback__)[0]
print(f"error {type(e).__name__} on line {tr.lineno} of '{tr.filename}'")
browser.quit()

print("", end="", flush=True)
exit(1)
6 changes: 3 additions & 3 deletions sram_monitoring_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
KEY = 'sram_monitoring'
config = config[KEY]

print(f"= Starting Chrome ===", file=sys.stderr)
print("= Starting Chrome ===", file=sys.stderr)
options = ChromeOptions()
options.add_argument('--headless')
browser = Remote("http://127.0.0.1:4444/wd/hub", options=options)
Expand Down Expand Up @@ -92,7 +92,7 @@ def test_user(start, user, userinfo):
print(f"FAILED on user={user['name']} page={start}")
# page = browser.page_source
# print("page: {}".format(page))
# browser.close()
browser.quit()

# exit without error, so that the next tests will still run
exit(0)
Expand All @@ -110,5 +110,5 @@ def test_user(start, user, userinfo):
test_user(startpage, user, userinfo)

# Close browser
# browser.close()
browser.quit()
print('OK')
Loading