1 #pragma once 2 3 #include "fs.hpp" 4 #include "handler_config.hpp" 5 #include "status.hpp" 6 7 #include <nlohmann/json.hpp> 8 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 namespace ipmi_flash 14 { 15 /** 16 * build a systemd file triggerable action from json data 17 */ 18 std::unique_ptr<TriggerableActionInterface> 19 buildFileSystemd(const nlohmann::json& data); 20 21 /** 22 * build a systemd triggerable action from json data 23 */ 24 std::unique_ptr<TriggerableActionInterface> 25 buildSystemd(const nlohmann::json& data); 26 27 extern const std::vector<const char*> defaultConfigPaths; 28 29 /* HandlersBuilderIfc is a helper class that builds Handlers from the json files 30 * found within a specified directory. 31 * The child class that inherits from HandlersBuilderIfc should implement 32 * buildHandlersConfigs to perform json validation and parsing. 33 * 34 */ 35 template <typename T> 36 struct HandlersBuilderIfc 37 { 38 virtual ~HandlersBuilderIfc() = default; 39 40 /** 41 * Builds configurations from the default set of paths used by the blob 42 * handler. 43 */ 44 std::vector<HandlerConfig<T>> buildHandlerConfigsFromDefaultPaths() 45 { 46 std::vector<HandlerConfig<T>> ret; 47 for (auto path : defaultConfigPaths) 48 { 49 auto tmp = buildHandlerConfigs(path); 50 std::move(tmp.begin(), tmp.end(), std::back_inserter(ret)); 51 } 52 return ret; 53 } 54 55 /** 56 * Given a folder of json configs, build the configurations. 57 * 58 * @param[in] directory - the directory to search (recurisvely). 59 * @return list of HandlerConfig objects. 60 */ 61 std::vector<HandlerConfig<T>> buildHandlerConfigs(const char* directory) 62 { 63 64 std::vector<HandlerConfig<T>> output; 65 66 std::vector<std::string> jsonPaths = GetJsonList(directory); 67 for (const auto& path : jsonPaths) 68 { 69 std::ifstream jsonFile(path); 70 if (!jsonFile.is_open()) 71 { 72 std::fprintf(stderr, "Unable to open json file: %s\n", 73 path.c_str()); 74 continue; 75 } 76 77 auto data = nlohmann::json::parse(jsonFile, nullptr, false); 78 if (data.is_discarded()) 79 { 80 std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str()); 81 continue; 82 } 83 84 std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data); 85 std::move(configs.begin(), configs.end(), 86 std::back_inserter(output)); 87 } 88 return output; 89 }; 90 91 /** 92 * Given a list of handlers as json data, construct the appropriate 93 * HandlerConfig objects. This method is meant to be called per json 94 * configuration file found. 95 * 96 * The list will only contain validly build HandlerConfig objects. Any 97 * invalid configuration is skipped. The hope is that the BMC firmware 98 * update configuration will never be invalid, but if another aspect is 99 * invalid, it can be fixed with a BMC firmware update once the bug is 100 * identified. 101 * 102 * This code does not validate that the blob specified is unique, that 103 * should be handled at a higher layer. 104 * 105 * @param[in] data - json data from a json file. 106 * @return list of HandlerConfig objects. 107 */ 108 virtual std::vector<HandlerConfig<T>> 109 buildHandlerFromJson(const nlohmann::json& data) = 0; 110 }; 111 } // namespace ipmi_flash 112