Files
cosmoserver/files/api/app.py
2026-03-09 16:32:43 -07:00

237 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, jsonify, request
from flask_apscheduler import APScheduler
from typing import Dict, Union
import json, time, redis, yaml
from Components import *
# declare flask apps
app = Flask(__name__)
scheduler = APScheduler()
#######################################################################
### Settings Handler Functions
#######################################################################
# default application setting variables
app_settings = {
"noisy_test" : False,
"debug_output" : False,
"log_output" : False,
"secure_api" : True,
"push_redis" : False,
"run_background" : True
}
with open('cosmostat_settings.yaml', 'r') as f:
print("Loading cosmostat_settings file")
cosmostat_settings = yaml.safe_load(f)
print("...Done")
# initialize system variables from settings file
print("Checking for system var overrides")
for setting in app_settings:
if setting in cosmostat_settings:
cosmos_setting = cosmostat_settings[setting]
if app_settings["debug_output"]:
print(f"{setting}: {cosmos_setting}")
app_settings[setting] = cosmos_setting
print("...Done")
# this returns the docker gateway from the settings
def docker_gateway_settings() -> str:
return cosmostat_settings["docker_gateway"]
# this returns the jenkins user that ran the pipeline
def jenkins_user_settings() -> str:
return cosmostat_settings["jenkins_user"]
# this returns the ansible_hostname from setup
def jenkins_hostname_settings() -> str:
return cosmostat_settings["ansible_hostname"]
# this returns the inventory_generation_timestamp
def jenkins_inventory_generation_timestamp_settings() -> str:
return cosmostat_settings["inventory_generation_timestamp"]
def service_gateway_ip():
if cosmostat_settings["secure_api"]:
return docker_gateway_settings()
else:
return "0.0.0.0"
#######################################################################
### Redis Functions
#######################################################################
# Redis client will publish updates
r = redis.Redis(host=service_gateway_ip(), port=6379)
def update_redis_channel(redis_channel, data):
# Publish to the specified Redis channel
r.publish(redis_channel, json.dumps(data))
if app_settings["noisy_test"]:
print(f"{redis_channel} Redis Update")
print(data)
def update_redis_server():
# Update Stats Redis Channel
update_redis_channel("host_stats", get_full_summary())
# Update history_stats Redis Channel
update_redis_channel("history_stats", get_component_list())
#######################################################################
### Other Functions
#######################################################################
def get_component_summary():
result = []
for component in cosmostat_system.components:
result.append(component.get_summary_key())
return result
def get_full_summary():
result = []
for component in cosmostat_system.components:
result.append(component.get_summary_key())
for sysvar in cosmostat_system.get_sysvars_summary_keys():
result.append(sysvar)
return result
# This will instantiate a System object
def new_cosmos_system():
new_system = System(f"{jenkins_hostname_settings()}")
if app_settings["log_output"]:
print(f"New system object name: {new_system.name}")
for component in new_system.components:
print(component)
return new_system
def get_component_list(history_count = None):
result = []
for component in cosmostat_system.components:
if history_count is not None:
history = component.get_history(history_count)
else:
history = component.get_history()
result.append(
{
"info": component.get_info_key(),
"history": history
}
)
return result
def get_info():
device_summary = []
for component in cosmostat_system.components:
device_summary.append(
{
"info": component.get_info_key(),
}
)
result = {
"system_info":
{
"user": jenkins_user_settings(),
"hostname": jenkins_hostname_settings(),
"timestamp": jenkins_inventory_generation_timestamp_settings(),
"component_count:": len(cosmostat_system.components),
"object_name": cosmostat_system.name,
"docker_gateway": docker_gateway_settings()
},
"device_summary": device_summary
}
return result
#def get_history_summary():
#######################################################################
### Flask Routes
#######################################################################
# full component list
@app.route('/component_list', methods=['GET'])
def component_list():
count = request.args.get('count', type=int)
return jsonify(get_component_list(count))
# component summary
@app.route('/component_summary', methods=['GET'])
def component_summary():
return jsonify(get_component_summary())
# full summary
@app.route('/full_summary', methods=['GET'])
def full_summary():
return jsonify(get_full_summary())
# system info
@app.route('/info', methods=['GET'])
def info():
return jsonify(get_info())
# test route
@app.route('/test', methods=['GET'])
def test():
return jsonify(
{
"component_count:": len(cosmostat_system.components),
"user": jenkins_user_settings(),
"hostname": jenkins_hostname_settings()
}
)
#######################################################################
### Main Subroutine
#######################################################################
if __name__ == '__main__':
# Background Loop Function
def background_loop():
# Update all data on the System object
cosmostat_system.update_values()
if app_settings["push_redis"]:
update_redis_server()
if app_settings["noisy_test"]:
print("Sorry about the mess...")
print(f"Blame {jenkins_user_settings()}")
# instantiate system
cosmostat_system = new_cosmos_system()
# send initial stats update to redis
if app_settings["push_redis"]:
update_redis_server()
# Flask scheduler for scanner
if app_settings["run_background"]:
if app_settings["log_output"]:
print("Loading flask background subroutine...")
scheduler.add_job(id='background_loop',
func=background_loop,
trigger='interval',
seconds=1)
scheduler.init_app(app)
scheduler.start()
if app_settings["log_output"]:
print("...Done")
else:
if app_settings["log_output"]:
print("Skipping flask background task")
# Flask API
app.run(debug=True, host=service_gateway_ip(), port=5000)