Puts agents config into the database

main
Yasen Pramatarov 2024-10-15 20:48:28 +03:00
parent 9ea7929510
commit 3f87481c06
2 changed files with 93 additions and 32 deletions

View File

@ -21,4 +21,4 @@ servers:
check_period: 10 check_period: 10
# database to store in # database to store in
database_path: "./meet.db" database_path: "./jilo-server.db"

121
main.go
View File

@ -17,21 +17,22 @@ import (
// Structures // Structures
type Agent struct { type Agent struct {
Endpoint string `yaml:"endpoint"` ID int
Secret string `yaml:"secret"` URL string
CheckPeriod int `yaml:"check_period"` Secret string
} CheckPeriod int
type Server struct {
Agents map[string]Agent `yaml:"agents"`
} }
type Config struct { type Config struct {
Servers map[string]Server `yaml:"servers"`
DatabasePath string `yaml:"database_path"` DatabasePath string `yaml:"database_path"`
} }
var defaultConfig = Config {
DatabasePath: "./jilo-server.db",
}
// Loading the config file // Loading the config file
func readConfig(filePath string) Config { func readConfig(filePath string) Config {
var config Config config := defaultConfig
file, err := ioutil.ReadFile(filePath) file, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
@ -73,13 +74,15 @@ func setupDatabase(dbPath string, initDB bool) (*sql.DB, error) {
// If the table is not there, initialize it // If the table is not there, initialize it
createTable := ` createTable := `
CREATE TABLE IF NOT EXISTS endpoint_data ( CREATE TABLE IF NOT EXISTS jilo_agent_checks (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_id INTEGER,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
status_code INTEGER, status_code INTEGER,
response_time_ms INTEGER, response_time_ms INTEGER,
response_content TEXT response_content TEXT,
);` FOREIGN KEY(agent_id) REFERENCES jilo_agents(id)
);`
_, err = db.Exec(createTable) _, err = db.Exec(createTable)
if err != nil { if err != nil {
return nil, err return nil, err
@ -90,17 +93,59 @@ func setupDatabase(dbPath string, initDB bool) (*sql.DB, error) {
// Check for the table // Check for the table
func checkTableExists(db *sql.DB) bool { func checkTableExists(db *sql.DB) bool {
sql := ` sql := `SELECT
SELECT name name
FROM sqlite_master FROM
WHERE type='table' sqlite_master
AND name='endpoint_data';` WHERE
type='table'
AND
name='jilo_agent_checks';`
row := db.QueryRow(sql) row := db.QueryRow(sql)
var name string var name string
err := row.Scan(&name) err := row.Scan(&name)
return err == nil && name == "endpoint_data" return err == nil && name == "jilo_agent_checks"
}
// Get Jilo agents details
func getAgents(db *sql.DB) ([]Agent, error) {
sql := `SELECT
ja.id,
ja.url,
ja.secret_key,
ja.check_period,
jat.endpoint
FROM
jilo_agents ja
JOIN
jilo_agent_types jat ON ja.agent_type_id = jat.id`
rows, err := db.Query(sql)
if err != nil {
return nil, err
}
defer rows.Close()
var agents []Agent
for rows.Next() {
var agent Agent
var endpoint string
var checkPeriod int
// Get the agent details
if err := rows.Scan(&agent.ID, &agent.URL, &agent.Secret, &checkPeriod, &endpoint); err != nil {
return nil, err
}
// Form the whole enpoint
agent.URL += endpoint
agent.CheckPeriod = checkPeriod
agents = append(agents, agent)
}
// We return the endpoints, not all the details
return agents, nil
} }
// JWT token generation // JWT token generation
@ -119,10 +164,10 @@ func generateJWT(secret string) (string, error) {
// Check agent endpoint // Check agent endpoint
func checkEndpoint(agent Agent) (int, int64, string, bool) { func checkEndpoint(agent Agent) (int, int64, string, bool) {
log.Println("Sending HTTP get request to Jilo agent:", agent.Endpoint) log.Println("Sending HTTP get request to Jilo agent:", agent.URL)
// Create the http request // Create the http request
req, err := http.NewRequest("GET", agent.Endpoint, nil) req, err := http.NewRequest("GET", agent.URL, nil)
if err != nil { if err != nil {
log.Println("Failed to create the HTTP request:", err) log.Println("Failed to create the HTTP request:", err)
return 0, 0, "", false return 0, 0, "", false
@ -162,8 +207,13 @@ func checkEndpoint(agent Agent) (int, int64, string, bool) {
} }
// Insert the checks into the database // Insert the checks into the database
func saveData(db *sql.DB, statusCode int, responseTime int64, responseContent string) { func saveData(db *sql.DB, agentID int, statusCode int, responseTime int64, responseContent string) {
_, err := db.Exec("INSERT INTO endpoint_data (status_code, response_time_ms, response_content) VALUES (?, ?, ?)", statusCode, responseTime, responseContent) sql := `INSERT INTO
jilo_agent_checks
(agent_id, status_code, response_time_ms, response_content)
VALUES
(?, ?, ?, ?)`
_, err := db.Exec(sql, agentID, statusCode, responseTime, responseContent)
if err != nil { if err != nil {
log.Println("Failed to insert data into the database:", err) log.Println("Failed to insert data into the database:", err)
} }
@ -176,11 +226,14 @@ func main() {
// Command-line option "--init-db" creates the table // Command-line option "--init-db" creates the table
initDB := flag.Bool("init-db", false, "Create database table if not present without prompting") initDB := flag.Bool("init-db", false, "Create database table if not present without prompting")
configPath := flag.String("config", "jilo-server.conf", "Path to the configuration file")
flag.Parse() flag.Parse()
// Config file // Config file
log.Println("Reading the config file...") log.Println("Reading the config file...")
config := readConfig("jilo-server.conf") config := readConfig(*configPath)
// Connect to or setup the database // Connect to or setup the database
log.Println("Initializing the database...") log.Println("Initializing the database...")
@ -190,30 +243,38 @@ func main() {
} }
defer db.Close() defer db.Close()
// Prepare the Agents
agents, err := getAgents(db)
if err != nil {
log.Fatal("Failed to fetch the agents:", err)
}
log.Println("Starting endpoint checker...") log.Println("Starting endpoint checker...")
// Iterate over the servers and agents // Iterate over the servers and agents
for serverName, server := range config.Servers { for _, agent := range agents {
for agentName, agent := range server.Agents { if agent.CheckPeriod > 0 {
go func(serverName, agentName string, agent Agent) { go func(agent Agent) {
// Ticker for the periodic checks // Ticker for the periodic checks
ticker := time.NewTicker(time.Duration(agent.CheckPeriod) * time.Minute) ticker := time.NewTicker(time.Duration(agent.CheckPeriod) * time.Minute)
defer ticker.Stop() defer ticker.Stop()
for { for {
log.Printf("Checking agent [%s - %s]: %s", serverName, agentName, agent.Endpoint) log.Printf("Checking agent [%d]: %s", agent.ID, agent.URL)
statusCode, responseTime, responseContent, success := checkEndpoint(agent) statusCode, responseTime, responseContent, success := checkEndpoint(agent)
if success { if success {
log.Printf("Agent [%s - %s]: Status code: %d, Response time: %d ms", serverName, agentName, statusCode, responseTime) log.Printf("Agent [%d]: Status code: %d, Response time: %d ms", agent.ID, statusCode, responseTime)
saveData(db, statusCode, responseTime, responseContent) saveData(db, agent.ID, statusCode, responseTime, responseContent)
} else { } else {
log.Printf("Check for agent [%s - %s] failed, kipping database insert", serverName, agentName) log.Printf("Check for agent [%d] failed, skipping database insert", agent.ID)
} }
// Sleep until the next tick // Sleep until the next tick
<-ticker.C <-ticker.C
} }
}(serverName, agentName, agent) }(agent)
} else {
log.Printf("Agent [%d] has an invalid CheckPeriod (%d), skipping it.", agent.ID, agent.CheckPeriod)
} }
} }