Compare commits
10 Commits
fcc3a1d917
...
30fb5fe862
Author | SHA1 | Date | |
---|---|---|---|
30fb5fe862 | |||
d73798656d | |||
0c546d71aa | |||
673ca6ee39 | |||
e75f150949 | |||
df49de30e0 | |||
7b93fb6595 | |||
8c84039e9d | |||
ae1ac488d8 | |||
37269ee7ba |
30
.gitlab-ci.yml
Normal file
30
.gitlab-ci.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Build a Docker image with CI/CD and push to the GitLab registry.
|
||||||
|
# Docker-in-Docker documentation: https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
|
||||||
|
#
|
||||||
|
# This template uses one generic job with conditional builds
|
||||||
|
# for the default branch and all other (MR) branches.
|
||||||
|
|
||||||
|
docker-build:
|
||||||
|
# Use the official docker image.
|
||||||
|
image: docker:latest
|
||||||
|
stage: build
|
||||||
|
before_script:
|
||||||
|
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
|
||||||
|
# Default branch leaves tag empty (= latest tag)
|
||||||
|
# All other branches are tagged with the escaped branch name (commit ref slug)
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
|
||||||
|
tag=""
|
||||||
|
echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'"
|
||||||
|
else
|
||||||
|
tag=":$CI_COMMIT_REF_SLUG"
|
||||||
|
echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag"
|
||||||
|
fi
|
||||||
|
- docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" .
|
||||||
|
- docker push "$CI_REGISTRY_IMAGE${tag}"
|
||||||
|
# Run this job in a branch where a Dockerfile exists
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH
|
||||||
|
exists:
|
||||||
|
- Dockerfile
|
39
src/app.py
39
src/app.py
@@ -2,33 +2,17 @@ from flask import Flask, request
|
|||||||
from reconnect import reboot
|
from reconnect import reboot
|
||||||
from os import environ
|
from os import environ
|
||||||
from subprocess import call, DEVNULL, STDOUT
|
from subprocess import call, DEVNULL, STDOUT
|
||||||
from logging.config import dictConfig
|
import logging
|
||||||
|
|
||||||
dictConfig({
|
|
||||||
'version': 1,
|
|
||||||
'formatters': {'default': {
|
|
||||||
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
|
|
||||||
}},
|
|
||||||
'handlers': {'wsgi': {
|
|
||||||
'class': 'logging.StreamHandler',
|
|
||||||
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
|
||||||
'formatter': 'default'
|
|
||||||
}},
|
|
||||||
'root': {
|
|
||||||
'level': 'INFO',
|
|
||||||
'handlers': ['wsgi']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
app.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
# Get router username and password from environment variables
|
# Get router username and password from environment variables
|
||||||
username = environ.get('ROUTER_USERNAME')
|
username = environ.get('ROUTER_USERNAME')
|
||||||
password = environ.get('ROUTER_PASSWORD')
|
password = environ.get('ROUTER_PASSWORD')
|
||||||
|
|
||||||
# Get router IP and path from environment variables if they exist
|
# Get router IP and path from environment variables if they exist
|
||||||
url = environ.get('ROUTER_IP') or '192.168.1.1'
|
url = environ.get('ROUTER_IP') or 'http://192.168.1.1'
|
||||||
path = environ.get('ROUTER_PATH') or '/ws'
|
path = environ.get('ROUTER_PATH') or '/ws'
|
||||||
|
|
||||||
@app.route('/', methods=['POST'])
|
@app.route('/', methods=['POST'])
|
||||||
@@ -40,15 +24,6 @@ def result():
|
|||||||
def safe():
|
def safe():
|
||||||
app.logger.info('Initializing safe reboot process')
|
app.logger.info('Initializing safe reboot process')
|
||||||
|
|
||||||
# Try to ping the router 100 times
|
|
||||||
for i in range(50):
|
|
||||||
if call(['ping', '-c', '1', url], stdout=DEVNULL, stderr=STDOUT) == 0:
|
|
||||||
app.logger.info('Router is online')
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
app.logger.error('Router is offline')
|
|
||||||
return 'Error: Unable to ping and reboot router automatically!'
|
|
||||||
|
|
||||||
# Try to nslookup 5 different websites to see if DNS is working
|
# Try to nslookup 5 different websites to see if DNS is working
|
||||||
websites = ['www.google.com', 'www.facebook.com', 'www.twitter.com', 'www.reddit.com', 'www.amazon.com']
|
websites = ['www.google.com', 'www.facebook.com', 'www.twitter.com', 'www.reddit.com', 'www.amazon.com']
|
||||||
success = 0
|
success = 0
|
||||||
@@ -57,14 +32,15 @@ def safe():
|
|||||||
app.logger.info(f'Successfully resolved {website}')
|
app.logger.info(f'Successfully resolved {website}')
|
||||||
success += 1
|
success += 1
|
||||||
else:
|
else:
|
||||||
app.logger.error(f'Unable to resolve {website}')
|
app.logger.info(f'Unable to resolve {website}')
|
||||||
|
|
||||||
if success > 3:
|
if success > 3:
|
||||||
|
app.logger.error('DNS is working, debug manually')
|
||||||
return 'Error: DNS seems to be working, debug manually!'
|
return 'Error: DNS seems to be working, debug manually!'
|
||||||
|
|
||||||
# Reboot router
|
# Reboot router
|
||||||
app.logger.info('Rebooting router')
|
app.logger.info('Rebooting router')
|
||||||
status = reboot(url, path, username, password).text
|
status = reboot(username, password, username, password).text
|
||||||
|
|
||||||
if '{"status":true}' not in status:
|
if '{"status":true}' not in status:
|
||||||
app.logger.error('Reboot failed')
|
app.logger.error('Reboot failed')
|
||||||
@@ -76,7 +52,7 @@ def safe():
|
|||||||
@app.route('/force', methods=['POST'])
|
@app.route('/force', methods=['POST'])
|
||||||
def force():
|
def force():
|
||||||
app.logger.info('Initializing force reboot process')
|
app.logger.info('Initializing force reboot process')
|
||||||
status = reboot(url, path, username, password).text
|
status = reboot(username, password, url, path).text
|
||||||
|
|
||||||
if '{"status":true}' not in status:
|
if '{"status":true}' not in status:
|
||||||
app.logger.error('Reboot failed')
|
app.logger.error('Reboot failed')
|
||||||
@@ -89,3 +65,4 @@ def force():
|
|||||||
def grafana():
|
def grafana():
|
||||||
if request.json['state'] == 'alerting':
|
if request.json['state'] == 'alerting':
|
||||||
return safe()
|
return safe()
|
||||||
|
return "State is OK!"
|
||||||
|
@@ -31,27 +31,6 @@ def login(username, password, url='http://192.168.1.1', path='/ws'):
|
|||||||
def cookie(session_key, session_value, context_id):
|
def cookie(session_key, session_value, context_id):
|
||||||
return f'UILang=en; lastKnownIpv6TabState=visible; {session_key}/accept-language=en-US,en; {session_key}/sessid={session_value}; sah/contextId={context_id}'
|
return f'UILang=en; lastKnownIpv6TabState=visible; {session_key}/accept-language=en-US,en; {session_key}/sessid={session_value}; sah/contextId={context_id}'
|
||||||
|
|
||||||
def traceroute(username, password, url='http://192.168.1.1', path='/ws'):
|
|
||||||
session_key, session_value, context_id = login(username, password, url, path)
|
|
||||||
|
|
||||||
headers = {
|
|
||||||
'Accept': '*/*',
|
|
||||||
'Content-Type': 'application/x-sah-ws-4-call+json',
|
|
||||||
'Authorization': 'X-Sah ' + context_id,
|
|
||||||
'Cookie': cookie(session_key, session_value, context_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
'service': 'Traceroute',
|
|
||||||
'method': 'start_diagnostic',
|
|
||||||
'parameters': {
|
|
||||||
'host': 'www.google.com',
|
|
||||||
'ipversion': 'IPv4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return post(url + path, headers=headers, data=dumps(data))
|
|
||||||
|
|
||||||
def reboot(username, password, url='http://192.168.1.1', path='/ws'):
|
def reboot(username, password, url='http://192.168.1.1', path='/ws'):
|
||||||
session_key, session_value, context_id = login(username, password, url, path)
|
session_key, session_value, context_id = login(username, password, url, path)
|
||||||
|
|
||||||
@@ -75,8 +54,7 @@ def reboot(username, password, url='http://192.168.1.1', path='/ws'):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
username = environ.get('ROUTER_USERNAME')
|
username = environ.get('ROUTER_USERNAME')
|
||||||
password = environ.get('ROUTER_PASSWORD')
|
password = environ.get('ROUTER_PASSWORD')
|
||||||
url = environ.get('ROUTER_IP') or '192.168.1.1'
|
url = environ.get('ROUTER_IP') or 'http://192.168.1.1'
|
||||||
path = environ.get('ROUTER_PATH') or '/ws'
|
path = environ.get('ROUTER_PATH') or '/ws'
|
||||||
|
|
||||||
reboot(username, password, url, path)
|
reboot(username, password, url, path)
|
||||||
|
|
Reference in New Issue
Block a user