From 3d86ad6367d1608c2a913e533b489fc418d8aa0a Mon Sep 17 00:00:00 2001 From: Georgia Date: Wed, 26 Jun 2024 15:38:50 -0500 Subject: [PATCH] initiate changelog for ntp --- backend/app.py | 25 ++++++ backend/ntp.py | 16 ++-- frontend/src/NTPSources.jsx | 161 ++++++++++++++++++++---------------- 3 files changed, 126 insertions(+), 76 deletions(-) diff --git a/backend/app.py b/backend/app.py index 27c9678..71b3816 100644 --- a/backend/app.py +++ b/backend/app.py @@ -9,6 +9,8 @@ import shlex import socket from bson.json_util import dumps +from hashlib import sha256 +import os import config from dhcp import scan_dhcp_pool, get_lease_info @@ -220,6 +222,29 @@ def customize_ntp_test(): ntp_results = test_ntp_servers(servers) return jsonify(ntp_results) +def log_ntp_results(ntp_results): + """Log NTP test results to MongoDB.""" + db.ntp_changes.insert_one({ + 'timestamp': datetime.datetime.now(), + 'results': ntp_results, + 'description': 'Regular NTP test' + }) + +@app.route('/ntp_changes', methods=['GET']) +def get_ntp_changes(): + """Retrieve NTP configuration changes from the last 24 hours.""" + now = datetime.datetime.now() + start_time = now - datetime.timedelta(hours=24) + changes = list(db.ntp_changes.find({'timestamp': {'$gte': start_time}}, {'_id': 0})) + for change in changes: + if 'timestamp' in change: + change['timestamp'] = change['timestamp'].isoformat() + return jsonify({'ntp_changes': changes}) + +def cleanup_old_entries(): + """Remove entries older than 24 hours.""" + threshold_time = datetime.datetime.now() - datetime.timedelta(hours=24) + db.ntp_changes.delete_many({'timestamp': {'$lt': threshold_time}}) @app.route('/ping_status', methods=['GET']) def ping_status(): diff --git a/backend/ntp.py b/backend/ntp.py index 6415da2..bdb4952 100644 --- a/backend/ntp.py +++ b/backend/ntp.py @@ -48,13 +48,15 @@ def __get_local_ntp_config__(): servers (array): An array of NTP servers found in ntp.conf """ servers = [] - with open(config.NTP_FILE_PATH, 'r') as f: - lines = f.readlines() - for line in lines: - line = line.strip() - if line.startswith("pool") or line.startswith("server"): - server = line.split()[1] - servers.append(server) + try: + with open(config.NTP_FILE_PATH, 'r') as f: + lines = f.readlines() + for line in lines: + if line.startswith("pool") or line.startswith("server"): + server = line.split()[1] + servers.append(server) + except FileNotFoundError: + print("NTP configuration file not found.") return servers diff --git a/frontend/src/NTPSources.jsx b/frontend/src/NTPSources.jsx index d0dd81c..e9e7454 100644 --- a/frontend/src/NTPSources.jsx +++ b/frontend/src/NTPSources.jsx @@ -7,19 +7,21 @@ const NTPSources = () => { const [cNtpServers, setCNtpServers] = useState([]); const [customTestResults, setCustomTestResults] = useState({}); const [customTestError, setCustomTestError] = useState(''); + const [ntpChanges, setNtpChanges] = useState([]); + const [ntpChangesError, setNtpChangesError] = useState(''); useEffect(() => { const fetchNTPSources = async () => { + const backendUrl = localStorage.getItem('backendUrl'); + const port = localStorage.getItem('port'); + try { - // get backendUrl and port from sessionStorage - const backendUrl = localStorage.getItem('backendUrl'); - const port = localStorage.getItem('port'); if (!backendUrl || !port || backendUrl === '' || port === '') { setError('Please set backend URL and port in the settings.'); return; } - // make a request to the backend + // Make a request to the backend const response = await axios.get(`http://${backendUrl}:${port}/ntp_sources`); setSources(response.data); if (Object.keys(response.data).length === 0) { @@ -28,8 +30,13 @@ const NTPSources = () => { } catch (error) { setError('Error fetching NTP srouces: ' + error.message); } - }; - + try { + const changesResponse = await axios.get(`http://${backendUrl}:${port}/ntp_changes`); + setNtpChanges(changesResponse.data.ntp_changes); + } catch (error) { + setNtpChangesError('Error fetching NTP changes: ' + error.message); + } + }; fetchNTPSources(); }, []); @@ -59,71 +66,87 @@ const NTPSources = () => { return (
-
-

Local NTP Status

- {error &&

{error}

} - - {Object.keys(sources).length > 0 ? ( -
- {Object.keys(sources).map((key) => ( -
-

{key}

- {sources[key] === null ?

No Response

:( -
-

Status: {sources[key].status}

-

Offset: {(parseFloat(sources[key].offset)*1000).toFixed(2)} ms

-

Stratum: {sources[key].stratum}

-

Request Sent On: {new Date(parseInt(sources[key].local_sent_on)*1000).toLocaleTimeString()}

-

Response Received On: {new Date(parseInt(sources[key].local_received_on)*1000).toLocaleTimeString()}

-

Delay: {parseFloat(sources[key].delay).toFixed(2)}s

-
- ) - } -
- - ))} -
- ) :

Loading Local NTP Sources

} -
-
-

Other NTP Servers

-
- - -
-
- {customTestError &&

{customTestError}

} - {Object.keys(customTestResults).length > 0 ? ( -
- {Object.keys(customTestResults).map((key) => ( -
-

{key}

- {customTestResults[key] === null ?

No Response

:( -
-

Status: {customTestResults[key].status}

-

Offset: {(parseFloat(customTestResults[key].offset)*1000).toFixed(2)} ms

-

Stratum: {customTestResults[key].stratum}

-

Request Sent On: {new Date(parseInt(customTestResults[key].local_sent_on)*1000).toLocaleTimeString()}

-

Response Received On: {new Date(parseInt(customTestResults[key].local_received_on)*1000).toLocaleTimeString()}

-

Delay: {parseFloat(customTestResults[key].delay).toFixed(2)}s

-
- ) - } -
- - ))} -
- ) :

} -
- +
+

Local NTP Status

+ {error &&

{error}

} + {Object.keys(sources).length > 0 && ( +
+ {Object.keys(sources).map((key) => ( +
+

{key}

+ {sources[key] === null ?

No Response

: ( +
+

Status: {sources[key].status}

+

Offset: {(parseFloat(sources[key].offset) * 1000).toFixed(2)} ms

+

Stratum: {sources[key].stratum}

+

Request Sent On: {new Date(sources[key].local_sent_on * 1000).toLocaleTimeString()}

+

Response Received On: {new Date(sources[key].local_received_on * 1000).toLocaleTimeString()}

+

Delay: {parseFloat(sources[key].delay).toFixed(2)}s

+
+ )} +
+ ))} +
+ )} +
+
+

Other NTP Servers

+
+ + +
+
+ {customTestError &&

{customTestError}

} + {Object.keys(customTestResults).length > 0 && ( +
+ {Object.keys(customTestResults).map((key) => ( +
+

{key}

+ {customTestResults[key] === null ?

No Response

: ( +
+

Status: {customTestResults[key].status}

+

Offset: {(parseFloat(customTestResults[key].offset) * 1000).toFixed(2)} ms

+

Stratum: {customTestResults[key].stratum}

+

Request Sent On: {new Date(customTestResults[key].local_sent_on * 1000).toLocaleTimeString()}

+

Response Received On: {new Date(customTestResults[key].local_received_on * 1000).toLocaleTimeString()}

+

Delay: {parseFloat(customTestResults[key].delay).toFixed(2)}s

+
+ )} +
+ ))} +
+ )} +
+
+

NTP Configuration Changes

+ {ntpChangesError &&

{ntpChangesError}

} + {ntpChanges.length > 0 ? ( +
    + {ntpChanges.filter((change, index) => + index === 0 || ntpChanges[index - 1].hash !== change.hash + ).map((change, index) => ( +
  • + Changed on: {new Date(change.timestamp).toLocaleString()} +
  • + ))} +
+ ) :

No recent changes.

} +
); }; export default NTPSources; +