commit d3036c431e3819e107ca0b70f5f1e88a33b9a2e4 Author: Ronald Date: Sat Jul 6 21:39:29 2024 +0100 Adding the little code here to a repository. Added the API to a repository, so makes sense to start tracking this code in source control aswell. diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ba0bfbc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "libs/ini"] + path = libs/ini + url = git@github.com:laytan/odin-ini-parser.git +[submodule "libs/sysinfo"] + path = libs/sysinfo + url = git@gitea.ronald1985.uk:ronald1985/odin-sysinfo.git +[submodule "libs/http"] + path = libs/http + url = git@github.com:laytan/odin-http.git diff --git a/client.odin b/client.odin new file mode 100644 index 0000000..01dc55e --- /dev/null +++ b/client.odin @@ -0,0 +1,124 @@ +package main + +import "core:fmt" +import "core:log" +import "core:os" +import "core:strings" +import "core:strconv" + +import "libs/ini" +import "libs/http" +import "libs/http/client" +import "libs/sysinfo" + +CONFIG_FILE_PATH :: "./config.ini" + +PC: Program_Config = {} + +get_config :: proc(config_file_path: string) -> Maybe(ini.INI) { + bytes, ok := os.read_entire_file_from_filename(config_file_path) + if !ok { + return nil + } + defer delete(bytes) + + config, res := ini.parse(bytes) + if res.err == ini.ParseErr.EOF { + return config + } + + return nil +} + +// Returns the host ID, of if the host doesn't exist in +// LSM then it will return -1 +get_host_id :: proc(hostname: string) -> (int, bool) { + request: client.Request + client.request_init(&request, .Get) + defer client.request_destroy(&request) + + response, err := client.request(&request, fmt.tprintf("%s/get_host_id_for_hostname/%s", PC.api_address, hostname)) + if err != nil { + return 0, false + } + defer client.response_destroy(&response) + + body, allocation, body_err := client.response_body(&response) + if body_err != nil { + return 0, false + } + defer client.body_destroy(body, allocation) + + host_id := strconv.atoi(body.(client.Body_Plain)) + + return host_id, true +} + +main :: proc() { + context.logger = log.create_console_logger(.Info) + + ini_config, ok := get_config(CONFIG_FILE_PATH).? + if !ok { + log.fatal("Failed to read config file, please ensure it's in the correct format") + } + + if _, ok := ini_config["log"]; ok { + if level, ok := ini_config["log"]["level"]; ok && level in Log_Level_Map { + log_level := strings.to_upper(level, context.temp_allocator) + log_level_ok: bool + PC.log_level, log_level_ok = Log_Level_Map[log_level] + } else { + log.info("Log level has either been not specified in configuration file or an invalid level has been specified") + log.info("Defaulting to Info") + PC.log_level = log.Level.Info + } + } + + context.logger.lowest_level = PC.log_level + + if _, ok := ini_config["api"]; ok { + if api_address, ok := ini_config["api"]["address"]; ok do PC.api_address = strings.clone(api_address) + else do log.fatal("API address not specified in config file") + } + + log.debug("Program config:", PC) + + hostname, hostname_ok := sysinfo.get_hostname().? + if !hostname_ok { + return + } + log.info("Successfully got hostname") + + PC.host_id, ok = get_host_id(hostname) + if !ok { + log.fatal("Failed to contact API and determine if host already exists in LSM") + } + + if PC.host_id < 0 { + log.info("Host doesn't exist in LSM") + log.info("Adding host now") + + request: client.Request + client.request_init(&request, .Post) + defer client.request_destroy(&request) + + post_body := Base_Host{hostname} + if err := client.with_json(&request, post_body); err != nil { + log.fatal("JSON error: %s", err) + } + + response, err := client.request(&request, fmt.tprintf("%s/add_host/", PC.api_address)) + if err != nil do log.fatal("Failed to add host to API with the error: %s", err) + defer client.response_destroy(&response) + + if response.status == .Created { + log.info("Successfully added host to LSM") + PC.host_id, ok = get_host_id(hostname) + if !ok do log.fatal("Failed to get host ID, exiting") + } + } else { + log.info("Host found in LSM") + } + log.debug("Host ID", PC.host_id) + +} diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..1c69a76 --- /dev/null +++ b/config.ini @@ -0,0 +1,5 @@ +[LOG] +LEVEL = "DEBUG" + +[API] +ADDRESS = "http://localhost:8000" diff --git a/libs/http b/libs/http new file mode 160000 index 0000000..1b70cac --- /dev/null +++ b/libs/http @@ -0,0 +1 @@ +Subproject commit 1b70cac68cd16945ba394703195c822a5aa0aeac diff --git a/libs/ini b/libs/ini new file mode 160000 index 0000000..dc9454d --- /dev/null +++ b/libs/ini @@ -0,0 +1 @@ +Subproject commit dc9454d49b26d5df3305d5698971b81414e534c4 diff --git a/libs/sysinfo b/libs/sysinfo new file mode 160000 index 0000000..1196f36 --- /dev/null +++ b/libs/sysinfo @@ -0,0 +1 @@ +Subproject commit 1196f36879a127f0898cc71904754972e256f45d diff --git a/types.odin b/types.odin new file mode 100644 index 0000000..f3bfa5a --- /dev/null +++ b/types.odin @@ -0,0 +1,45 @@ +package main + +import "core:log" + +Log_Level_Map := map[string]log.Level { + "DEBUG" = log.Level.Debug, + "INFO" = log.Level.Info, + "WARNING" = log.Level.Warning, + "ERROR" = log.Level.Error, + "FATAL" = log.Level.Fatal, +} + +Program_Config :: struct { + log_level: log.Level, + + api_address: string, + + host_id: int, +} + +CPU :: struct { + name: string, + socket: int, + usage: f16, +} + +Memory :: struct { + type: string, // physical/virtual + total: int, + used: int, + usage: f16, +} + +Host :: struct { + hostname: string, + host_id: int, + + cpus: [dynamic]CPU, + memory: [dynamic]Memory, +} + +Base_Host :: struct { + hostname: string +} +