1 #include "systemd_target_parser.hpp"
2 
3 #include <cassert>
4 #include <fstream>
5 #include <iostream>
6 
7 void validateErrorsToMonitor(std::vector<std::string>& errorsToMonitor)
8 {
9     assert(errorsToMonitor.size());
10 
11     const std::vector<std::string> validErrorsToMonitor = {
12         "default", "timeout", "failed", "dependency"};
13     for (const auto& errorToMonitor : errorsToMonitor)
14     {
15         if (std::find(validErrorsToMonitor.begin(), validErrorsToMonitor.end(),
16                       errorToMonitor) == validErrorsToMonitor.end())
17         {
18             throw std::out_of_range("Found invalid error to monitor");
19         }
20     }
21     // See if default was in the errors to monitor, if so replace with defaults
22     auto errorItr = std::find(errorsToMonitor.begin(), errorsToMonitor.end(),
23                               "default");
24     if (errorItr != errorsToMonitor.end())
25     {
26         // Verify default is the only entry
27         if (errorsToMonitor.size() != 1)
28         {
29             throw std::invalid_argument(
30                 "default must be only error to monitor");
31         }
32         // delete "default" and insert defaults
33         errorsToMonitor.erase(errorItr);
34         errorsToMonitor.push_back("timeout");
35         errorsToMonitor.push_back("failed");
36         errorsToMonitor.push_back("dependency");
37     }
38 }
39 
40 TargetErrorData parseFiles(const std::vector<std::string>& filePaths)
41 {
42     TargetErrorData systemdTargetMap;
43     for (const auto& jsonFile : filePaths)
44     {
45         if (gVerbose)
46         {
47             std::cout << "Parsing input file " << jsonFile << std::endl;
48         }
49         std::ifstream fileStream(jsonFile);
50         auto j = json::parse(fileStream);
51 
52         for (auto it = j["targets"].begin(); it != j["targets"].end(); ++it)
53         {
54             targetEntry entry;
55             if (gVerbose)
56             {
57                 std::cout << "target: " << it.key() << " | " << it.value()
58                           << std::endl;
59             }
60 
61             // Be unforgiving on invalid json files. Just throw or allow
62             // nlohmann to throw an exception if something is off
63             auto errorsToMonitor = it.value().find("errorsToMonitor");
64             entry.errorsToMonitor =
65                 errorsToMonitor->get<std::vector<std::string>>();
66 
67             validateErrorsToMonitor(entry.errorsToMonitor);
68 
69             auto errorToLog = it.value().find("errorToLog");
70             entry.errorToLog = errorToLog->get<std::string>();
71 
72             systemdTargetMap[it.key()] = entry;
73         }
74     }
75     return systemdTargetMap;
76 }
77