Compare commits
10 Commits
fcc3a1d917
...
main
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 os import environ
|
||||
from subprocess import call, DEVNULL, STDOUT
|
||||
from logging.config import dictConfig
|
||||
|
||||
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']
|
||||
}
|
||||
})
|
||||
|
||||
import logging
|
||||
|
||||
app = Flask(__name__)
|
||||
app.logger.setLevel(logging.INFO)
|
||||
|
||||
# Get router username and password from environment variables
|
||||
username = environ.get('ROUTER_USERNAME')
|
||||
password = environ.get('ROUTER_PASSWORD')
|
||||
|
||||
# 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'
|
||||
|
||||
@app.route('/', methods=['POST'])
|
||||
@@ -40,15 +24,6 @@ def result():
|
||||
def safe():
|
||||
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
|
||||
websites = ['www.google.com', 'www.facebook.com', 'www.twitter.com', 'www.reddit.com', 'www.amazon.com']
|
||||
success = 0
|
||||
@@ -57,14 +32,15 @@ def safe():
|
||||
app.logger.info(f'Successfully resolved {website}')
|
||||
success += 1
|
||||
else:
|
||||
app.logger.error(f'Unable to resolve {website}')
|
||||
app.logger.info(f'Unable to resolve {website}')
|
||||
|
||||
if success > 3:
|
||||
app.logger.error('DNS is working, debug manually')
|
||||
return 'Error: DNS seems to be working, debug manually!'
|
||||
|
||||
# Reboot 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:
|
||||
app.logger.error('Reboot failed')
|
||||
@@ -76,7 +52,7 @@ def safe():
|
||||
@app.route('/force', methods=['POST'])
|
||||
def force():
|
||||
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:
|
||||
app.logger.error('Reboot failed')
|
||||
@@ -89,3 +65,4 @@ def force():
|
||||
def grafana():
|
||||
if request.json['state'] == 'alerting':
|
||||
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):
|
||||
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'):
|
||||
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__':
|
||||
username = environ.get('ROUTER_USERNAME')
|
||||
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'
|
||||
|
||||
reboot(username, password, url, path)
|
||||
|
Reference in New Issue
Block a user