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