]> granicus.if.org Git - icinga2/blob - lib/base/scriptglobal.cpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / scriptglobal.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "base/scriptglobal.hpp"
4 #include "base/singleton.hpp"
5 #include "base/logger.hpp"
6 #include "base/stdiostream.hpp"
7 #include "base/netstring.hpp"
8 #include "base/json.hpp"
9 #include "base/convert.hpp"
10 #include "base/objectlock.hpp"
11 #include "base/exception.hpp"
12 #include "base/namespace.hpp"
13 #include "base/utility.hpp"
14 #include <fstream>
15
16 using namespace icinga;
17
18 Namespace::Ptr ScriptGlobal::m_Globals = new Namespace();
19
20 Value ScriptGlobal::Get(const String& name, const Value *defaultValue)
21 {
22         Value result;
23
24         if (!m_Globals->Get(name, &result)) {
25                 if (defaultValue)
26                         return *defaultValue;
27
28                 BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to access undefined script variable '" + name + "'"));
29         }
30
31         return result;
32 }
33
34 void ScriptGlobal::Set(const String& name, const Value& value, bool overrideFrozen)
35 {
36         std::vector<String> tokens = name.Split(".");
37
38         if (tokens.empty())
39                 BOOST_THROW_EXCEPTION(std::invalid_argument("Name must not be empty"));
40
41         {
42                 ObjectLock olock(m_Globals);
43
44                 Namespace::Ptr parent = m_Globals;
45
46                 for (std::vector<String>::size_type i = 0; i < tokens.size(); i++) {
47                         const String& token = tokens[i];
48
49                         if (i + 1 != tokens.size()) {
50                                 Value vparent;
51
52                                 if (!parent->Get(token, &vparent)) {
53                                         Namespace::Ptr dict = new Namespace();
54                                         parent->Set(token, dict);
55                                         parent = dict;
56                                 } else {
57                                         parent = vparent;
58                                 }
59                         }
60                 }
61
62                 parent->SetFieldByName(tokens[tokens.size() - 1], value, overrideFrozen, DebugInfo());
63         }
64 }
65
66 void ScriptGlobal::SetConst(const String& name, const Value& value)
67 {
68         GetGlobals()->SetAttribute(name, std::make_shared<ConstEmbeddedNamespaceValue>(value));
69 }
70
71 bool ScriptGlobal::Exists(const String& name)
72 {
73         return m_Globals->Contains(name);
74 }
75
76 Namespace::Ptr ScriptGlobal::GetGlobals()
77 {
78         return m_Globals;
79 }
80
81 void ScriptGlobal::WriteToFile(const String& filename)
82 {
83         Log(LogInformation, "ScriptGlobal")
84                 << "Dumping variables to file '" << filename << "'";
85
86         std::fstream fp;
87         String tempFilename = Utility::CreateTempFile(filename + ".XXXXXX", 0600, fp);
88
89         if (!fp)
90                 BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));
91
92         StdioStream::Ptr sfp = new StdioStream(&fp, false);
93
94         ObjectLock olock(m_Globals);
95         for (const Namespace::Pair& kv : m_Globals) {
96                 Value value = kv.second->Get();
97
98                 if (value.IsObject())
99                         value = Convert::ToString(value);
100
101                 Dictionary::Ptr persistentVariable = new Dictionary({
102                         { "name", kv.first },
103                         { "value", value }
104                 });
105
106                 String json = JsonEncode(persistentVariable);
107
108                 NetString::WriteStringToStream(sfp, json);
109         }
110
111         sfp->Close();
112
113         fp.close();
114
115         Utility::RenameFile(tempFilename, filename);
116 }
117