diff --git a/.dockerignore b/.dockerignore index 36c983b..1eaba0e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,4 +4,6 @@ db.sqlite3 data.csv public/styles/style.css README.md -Dockerfile \ No newline at end of file +Dockerfile +data/db.sqlite3 +data/data.csv \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2390b24..f4db8aa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,10 @@ node_modules/ rubbish/ db.sqlite3 data.csv +data/db.sqlite3 +data/data.csv public/styles/style.css swarm/.env.deploy +swarm/.env.netmon.brent +swarm/.env.netmon.josh +swarm/.env.netmon.shannon diff --git a/README.md b/README.md index d29ad5a..3b8127e 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,14 @@ super basic way to run ``` -touch db.sqlite3 +*untested now +mkdir data docker run --rm -d \ --name netmon \ -p 4000:3000 \ -e dstHost=1.1.1.1 \ -e dstPort=53 \ - --mount type=bind,source=$(pwd)/db.sqlite3,target=/app/db.sqlite3 \ + -v $(pwd)/data:/app/data \ daveplsno/netmon:latest ``` @@ -36,3 +37,39 @@ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest postcss-cli npm install tailwindcss postcss autoprefixer postcss-cli ``` + +dev outside the container + +``` +python3 -m http.server 8000 +python3 netmon.py monitor +npm run dev +``` + +## docker img update steps + +update tag +`docker-compose build` +`docker push daveplsno/netmon:` + +misc container things + +``` +docker run --rm \ + --name netmonThrowaway \ + -p 4000:3000 \ + -e dstHost=1.1.1.1 \ + -e dstPort=53 \ + daveplsno/netmon:2 + +# used this to migrate data between old/new mounts +docker run --rm -it --name pls -w /app \ + -v netmon_netmon-data:/dataOld \ + -v netmon_data-david:/dataNew \ + nikolaik/python-nodejs:python3.9-nodejs16-alpine sh + +docker run --rm -it --name pls -w /app \ + -v netmon_netmon-data-shannon:/dataOld \ + -v netmon_data-shannon:/dataNew \ + nikolaik/python-nodejs:python3.9-nodejs16-alpine sh +``` diff --git a/data/.keep b/data/.keep new file mode 100644 index 0000000..e69de29 diff --git a/database.js b/database.js index a0118bd..87422ce 100644 --- a/database.js +++ b/database.js @@ -1,6 +1,6 @@ var sqlite3 = require('sqlite3').verbose(); -const db = new sqlite3.Database('db.sqlite3', (err) => { +const db = new sqlite3.Database('data/db.sqlite3', (err) => { if (err) { console.error(err.message); throw err; diff --git a/docker-compose.yml b/docker-compose.yml index 4b6918f..92207ae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,4 +5,4 @@ services: netmon-build: build: context: . - image: daveplsno/netmon:latest + image: daveplsno/netmon:4 diff --git a/netmon.py b/netmon.py index 4a085ff..dfd5ebb 100644 --- a/netmon.py +++ b/netmon.py @@ -15,7 +15,7 @@ path = Path(__file__).resolve().parent def update_db(payload): conn = None try: - db = (str(path) + "/db.sqlite3") + db = (str(path) + "/data/db.sqlite3") conn = sqlite3.connect(db) c = conn.cursor() @@ -76,12 +76,12 @@ def secs_to_HMS(secs): def record_file_exist(): """ Check if records file exist """ - return os.path.isfile('data.csv') + return os.path.isfile('data/data.csv') def create_record_file(): """ Create a new record file """ - with open('data.csv', 'a') as csvfile: + with open('data/data.csv', 'a') as csvfile: columns = ['timestamp', 'status'] writer = csv.DictWriter(csvfile, fieldnames=columns) writer.writeheader() @@ -90,7 +90,7 @@ def create_record_file(): def last_record_status(): """ Get last record """ result = None - with open('data.csv', 'r') as csvfile: + with open('data/data.csv', 'r') as csvfile: reader = csv.DictReader(csvfile) for row in reader: result = row @@ -99,7 +99,7 @@ def last_record_status(): def write_record(status): """ Create a new record """ - with open('data.csv', 'a') as csvfile: + with open('data/data.csv', 'a') as csvfile: columns = ['timestamp', 'status'] writer = csv.DictWriter(csvfile, fieldnames=columns) writer.writerow({'timestamp': str(current_timestamp()), 'status': status}) @@ -110,7 +110,7 @@ def get_total_downtime(): seconds = 0 down = None up = None - with open('data.csv', 'r') as csvfile: + with open('data/data.csv', 'r') as csvfile: reader = csv.DictReader(csvfile) for record in reader: try: diff --git a/swarm/docker-compose.netmon.yml b/swarm/docker-compose.netmon.yml index b6e94ce..78d47eb 100644 --- a/swarm/docker-compose.netmon.yml +++ b/swarm/docker-compose.netmon.yml @@ -6,15 +6,18 @@ networks: external: true volumes: - netmon-data: + data-david: + data-brent: + data-shannon: + data-josh: services: app: - image: daveplsno/netmon:latest + image: daveplsno/netmon:4 hostname: netmon env_file: .env.netmon volumes: - - netmon-data:/app + - data-david:/app/data networks: - swarmnet-public deploy: @@ -32,3 +35,75 @@ services: - traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls=true - traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls.certresolver=le - traefik.http.services.${netmonTraefikGrp? Variable not set}.loadbalancer.server.port=3000 + + brent: + image: daveplsno/netmon:4 + hostname: netmonBrent + env_file: .env.netmon.brent + volumes: + - data-brent:/app/data + networks: + - swarmnet-public + deploy: + restart_policy: + condition: on-failure + placement: + constraints: + - node.labels.${netmonNode? Variable not set} == true + labels: + - traefik.enable=true + - traefik.docker.network=swarmnet-public + - traefik.constraint-label=swarmnet-public + - traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.rule=Host(`${netmonBrentTraefikUrl? Variable not set}`) + - traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.entrypoints=websecure + - traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.tls=true + - traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.tls.certresolver=le + - traefik.http.services.${netmonBrentTraefikGrp? Variable not set}.loadbalancer.server.port=3000 + + shannon: + image: daveplsno/netmon:4 + hostname: netmonShannon + env_file: .env.netmon.shannon + volumes: + - data-shannon:/app/data + networks: + - swarmnet-public + deploy: + restart_policy: + condition: on-failure + placement: + constraints: + - node.labels.${netmonNode? Variable not set} == true + labels: + - traefik.enable=true + - traefik.docker.network=swarmnet-public + - traefik.constraint-label=swarmnet-public + - traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.rule=Host(`${netmonShannonTraefikUrl? Variable not set}`) + - traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.entrypoints=websecure + - traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.tls=true + - traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.tls.certresolver=le + - traefik.http.services.${netmonShannonTraefikGrp? Variable not set}.loadbalancer.server.port=3000 + + josh: + image: daveplsno/netmon:4 + hostname: netmonJosh + env_file: .env.netmon.josh + volumes: + - data-josh:/app/data + networks: + - swarmnet-public + deploy: + restart_policy: + condition: on-failure + placement: + constraints: + - node.labels.${netmonNode? Variable not set} == true + labels: + - traefik.enable=true + - traefik.docker.network=swarmnet-public + - traefik.constraint-label=swarmnet-public + - traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.rule=Host(`${netmonJoshTraefikUrl? Variable not set}`) + - traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.entrypoints=websecure + - traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.tls=true + - traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.tls.certresolver=le + - traefik.http.services.${netmonJoshTraefikGrp? Variable not set}.loadbalancer.server.port=3000 diff --git a/swarm/netmonDeploy.bash b/swarm/netmonDeploy.bash index 8593f1d..3af8e58 100755 --- a/swarm/netmonDeploy.bash +++ b/swarm/netmonDeploy.bash @@ -2,7 +2,7 @@ export $(cat .env.deploy) # deploy to swarm -docker stack deploy -c docker-compose.netmon.yml netmon +docker stack deploy -c docker-compose.netmon.yml --prune netmon # unset the env vars unset $(cat .env.deploy | cut -f 1 -d '=' $1) \ No newline at end of file diff --git a/swarm/netmonStatus.bash b/swarm/netmonStatus.bash index c1dd37b..2fa2d9b 100755 --- a/swarm/netmonStatus.bash +++ b/swarm/netmonStatus.bash @@ -1,2 +1,2 @@ #!/bin/bash -docker service ps netmon_app \ No newline at end of file +docker stack services netmon \ No newline at end of file diff --git a/views/Card.jsx b/views/Card.jsx index d778453..b622c4e 100644 --- a/views/Card.jsx +++ b/views/Card.jsx @@ -1,12 +1,25 @@ const React = require('react'); -import { TimeBetweenRows } from './DiffCard'; +import { TimeDiff } from './TimeDiff'; export const Card = ({ dbdata }) => { return dbdata.reverse().map((row, index) => { const nextRow = dbdata[index + 1]; + const lastRow = dbdata.slice()[0]; + const textStyles = 'flex justify-center items-center py-2 text-sm'; return (
+ {row.id === lastRow.id ? ( +
+ {row.status === 1 ? 'yeh all good for ' : 'absolutely cooked for '} + +
+ ) : null} +
{
{row.timestamp}
{row.status === 1 ? '🟢' : '🔴'}
- {!!nextRow ? ( -
- +
+
) : null}
diff --git a/views/DiffCard.jsx b/views/TimeDiff.jsx similarity index 92% rename from views/DiffCard.jsx rename to views/TimeDiff.jsx index e390c3c..0224703 100644 --- a/views/DiffCard.jsx +++ b/views/TimeDiff.jsx @@ -1,18 +1,18 @@ const React = require('react'); const dayjs = require('dayjs'); -export const TimeBetweenRows = ({ row, nextRow }) => { +export const TimeDiff = ({ row, nextRow }) => { if (nextRow) { + const now = dayjs(); const firstDate = dayjs(row.timestamp); const secondDate = dayjs(nextRow.timestamp); - const theDiff = firstDate.diff(secondDate); + const theDiff = + row.id === nextRow.id ? now.diff(firstDate) : firstDate.diff(secondDate); const theSeconds = theDiff / 1000; const theMinutes = theSeconds / 60; const theHours = theMinutes / 60; const theDays = theHours / 24; - // console.log(theDiff, theSeconds, theMinutes, theHours, theDays); - const renderSecs = <>{theSeconds === 1 ? 'sec' : 'secs'}; const renderMins = <>{theMinutes === 1 ? 'min ' : 'mins '}; const renderHrs = <>{theHours === 1 ? 'hr ' : 'hrs '};