/usr/include/facter/facts/collection.hpp is in facter-dev 3.10.0-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | /**
* @file
* Declares the fact collection.
*/
#pragma once
#include "resolver.hpp"
#include "value.hpp"
#include "external/resolver.hpp"
#include "../export.h"
#include <list>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>
#include <string>
#include <memory>
#include <functional>
#include <stdexcept>
#include <iostream>
namespace facter { namespace facts {
/**
* The supported output format for the fact collection.
*/
enum class format
{
/**
* Use ruby "hash" as the format (default).
*/
hash,
/**
* Use JSON as the format.
*/
json,
/**
* Use YAML as the format.
*/
yaml
};
namespace {
/**
* Stream adapter for using with rapidjson
*/
struct stream_adapter
{
typedef char Ch;
/**
* Constructs an adapter for use with rapidjson around the given stream.
* @param stream an output stream to which JSON will be written
*/
explicit stream_adapter(std::ostream& stream) : _stream(stream)
{
}
/**
* Adds a character to the stream.
* @param c the char to add
*/
void Put(char c)
{
_stream << c;
}
/**
* Flushes the stream.
*/
void Flush()
{
_stream.flush();
}
private:
std::ostream& _stream;
};
}
/**
* Represents the fact collection.
* The fact collection is responsible for resolving and storing facts.
*/
struct LIBFACTER_EXPORT collection
{
/**
* Inherent "has_weight" value for external facts.
*/
constexpr static size_t external_fact_weight = 10000;
/**
* Constructs a fact collection.
* @param blocklist the names of resolvers that should not be resolved
* @param ttls a map of resolver names to cache intervals (times-to-live)
* for the facts they resolve
* @param ignore_cache true if the cache should not be consulted when resolving facts
*/
collection(std::set<std::string> const& blocklist = std::set<std::string>(),
std::unordered_map<std::string, int64_t> const& ttls = std::unordered_map<std::string, int64_t>{},
bool ignore_cache = false);
/**
* Destructor for fact collection.
*/
~collection();
/**
* Prevents the fact collection from being copied.
*/
collection(collection const&) = delete;
/**
* Prevents the fact collection from being copied.
* @returns Returns this fact collection.
*/
collection& operator=(collection const&) = delete;
/**
* Moves the given fact collection into this fact collection.
* @param other The fact collection to move into this fact collection.
*/
// Visual Studio 12 still doesn't allow default for move constructor.
collection(collection&& other);
/**
* Moves the given fact collection into this fact collection.
* @param other The fact collection to move into this fact collection.
* @return Returns this fact collection.
*/
// Visual Studio 12 still doesn't allow default for move assignment.
collection& operator=(collection&& other);
/**
* Adds the default facts to the collection.
* @param include_ruby_facts Whether or not to include facts which require Ruby in the collection.
*/
void add_default_facts(bool include_ruby_facts);
/**
* Adds a resolver to the fact collection.
* The last resolver that was added for a particular name or pattern will "win" resolution.
* @param res The resolver to add to the fact collection.
*/
void add(std::shared_ptr<resolver> const& res);
/**
* Adds a fact to the fact collection.
* @param name The name of the fact.
* @param value The value of the fact.
*/
void add(std::string name, std::unique_ptr<value> value);
/**
* Adds a custom fact to the fact collection.
* @param name The name of the fact.
* @param value The value of the fact.
* @param weight The weight of the fact.
*/
void add_custom(std::string name, std::unique_ptr<value> value, size_t weight);
/**
* Adds an external fact to the fact collection.
* @param name The name of the fact.
* @param value The value of the fact.
*/
void add_external(std::string name, std::unique_ptr<value> value);
/**
* Adds external facts to the fact collection.
* @param directories The directories to search for external facts. If empty, the default search paths will be used.
*/
void add_external_facts(std::vector<std::string> const& directories = {});
/**
* Adds facts defined via "FACTER_xyz" environment variables.
* @param callback The callback that is called with the name of each fact added from the environment.
*/
void add_environment_facts(std::function<void(std::string const&)> callback = nullptr);
/**
* Removes a resolver from the fact collection.
* @param res The resolver to remove from the fact collection.
*/
void remove(std::shared_ptr<resolver> const& res);
/**
* Removes a fact by name.
* @param name The name of the fact to remove.
*/
void remove(std::string const& name);
/**
* Clears the entire fact collection.
* This will remove all built-in facts and resolvers from the fact collection.
*/
void clear();
/**
* Checks to see if the fact collection is empty.
* All facts will be resolved to determine if the collection is empty.
* @return Returns true if the fact collection is empty or false if it is not.
*/
bool empty();
/**
* Gets the count of facts in the fact collection.
* All facts will be resolved to determine the size of the collection.
* @return Returns the number of facts in the fact collection.
*/
size_t size();
/**
* Gets a fact value by name.
* @tparam T The expected type of the value.
* @param name The name of the fact to get the value of.
* @return Returns a pointer to the fact value or nullptr if the fact is not in the fact collection or the value is not the expected type.
*/
template <typename T = value>
T const* get(std::string const& name)
{
return dynamic_cast<T const*>(get_value(name));
}
/**
* Gets a fact value by name without resolving the fact.
* @tparam T The expected type of the value.
* @param name The name of the fact to get the value of.
* @return Returns a pointer to the fact value or nullptr if the fact is not resolved or the value is not the expected type.
*/
template <typename T = value>
T const* get_resolved(std::string const& name) const
{
// Lookup the fact without resolving
auto it = _facts.find(name);
return dynamic_cast<T const*>(it == _facts.end() ? nullptr : it->second.get());
}
/**
* Gets a fact value by name
* @param name The name of the fact to get the value of.
* @return Returns a pointer to the fact value or nullptr if the fact is not in the fact collection.
*/
value const* operator[](std::string const& name);
/**
* Query the collection.
* @tparam T The expected type of the value.
* @param query The query to run.
* @return Returns the result of the query or nullptr if the query returned no value.
*/
template <typename T = value>
T const* query(std::string const& query)
{
return dynamic_cast<T const*>(query_value(query, false));
}
/**
* Enumerates all facts in the collection.
* All facts will be resolved prior to enumeration.
* @param func The callback function called for each fact in the collection.
*/
void each(std::function<bool(std::string const&, value const*)> func);
/**
* Writes the contents of the fact collection to the given stream, hiding legacy facts.
* All facts will be resolved prior to writing.
* @param stream The stream to write the facts to.
* @param fmt The output format to use.
* @param queries The set of queries to filter the output to. If empty, all facts will be output.
* @return Returns the stream being written to.
*/
std::ostream& write(std::ostream& stream, format fmt = format::hash, std::set<std::string> const& queries = std::set<std::string>());
/**
* Writes the contents of the fact collection to the given stream.
* All facts will be resolved prior to writing.
* @param stream The stream to write the facts to.
* @param fmt The output format to use.
* @param queries The set of queries to filter the output to. If empty, all facts will be output.
* @param show_legacy Show legacy facts when querying all facts.
* @param strict_errors Report additional error cases
* @return Returns the stream being written to.
*/
std::ostream& write(std::ostream& stream, format fmt, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
/**
* Resolves all facts in the collection.
*/
void resolve_facts();
/**
* Returns the names of all the resolvers currently in the collection,
* along with their associated facts. The group names are used to allow
* caching of those facts.
* @return a map of group names to their associated fact names
*/
std::map<std::string, std::vector<std::string>> get_fact_groups();
/**
* Returns the names of all blockable resolvers currently in the collection,
* along with their associated facts. The group names are used to allow
* blocking of those facts.
* @return a map of blockable group names to their associated fact names
*/
std::map<std::string, std::vector<std::string>> get_blockable_fact_groups();
protected:
/**
* Gets external fact directories for the current platform.
* @return A list of file paths that will be searched for external facts.
*/
virtual std::vector<std::string> get_external_fact_directories() const;
private:
LIBFACTER_NO_EXPORT void resolve_fact(std::string const& name);
LIBFACTER_NO_EXPORT value const* get_value(std::string const& name);
LIBFACTER_NO_EXPORT value const* query_value(std::string const& query, bool strict_errors);
LIBFACTER_NO_EXPORT value const* lookup(value const* value, std::string const& name, bool strict_errors);
LIBFACTER_NO_EXPORT void write_hash(std::ostream& stream, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
LIBFACTER_NO_EXPORT void write_json(std::ostream& stream, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
LIBFACTER_NO_EXPORT void write_yaml(std::ostream& stream, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
LIBFACTER_NO_EXPORT void add_common_facts(bool include_ruby_facts);
LIBFACTER_NO_EXPORT bool add_external_facts_dir(std::vector<std::unique_ptr<external::resolver>> const& resolvers, std::string const& directory, bool warn);
LIBFACTER_NO_EXPORT bool try_block(std::shared_ptr<resolver> const& res);
LIBFACTER_NO_EXPORT void resolve(std::shared_ptr<resolver> const& res);
// Platform specific members
LIBFACTER_NO_EXPORT void add_platform_facts();
LIBFACTER_NO_EXPORT std::vector<std::unique_ptr<external::resolver>> get_external_resolvers();
std::map<std::string, std::unique_ptr<value>> _facts;
std::list<std::shared_ptr<resolver>> _resolvers;
std::multimap<std::string, std::shared_ptr<resolver>> _resolver_map;
std::list<std::shared_ptr<resolver>> _pattern_resolvers;
std::set<std::string> _blocklist;
std::unordered_map<std::string, int64_t> _ttls;
bool _ignore_cache;
};
}} // namespace facter::facts
|