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
|
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
#include "cli/objectlistcommand.hpp"
#include "cli/objectlistutility.hpp"
#include "base/logger.hpp"
#include "base/application.hpp"
#include "base/convert.hpp"
#include "base/configobject.hpp"
#include "base/configtype.hpp"
#include "base/json.hpp"
#include "base/netstring.hpp"
#include "base/stdiostream.hpp"
#include "base/debug.hpp"
#include "base/objectlock.hpp"
#include "base/console.hpp"
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <sys/stat.h>
using namespace icinga;
namespace po = boost::program_options;
REGISTER_CLICOMMAND("object/list", ObjectListCommand);
String ObjectListCommand::GetDescription() const
{
return "Lists all Icinga 2 objects.";
}
String ObjectListCommand::GetShortDescription() const
{
return "lists all objects";
}
void ObjectListCommand::InitParameters(boost::program_options::options_description& visibleDesc,
boost::program_options::options_description& hiddenDesc) const
{
visibleDesc.add_options()
("count,c", "display object counts by types")
("name,n", po::value<std::string>(), "filter by name matches")
("type,t", po::value<std::string>(), "filter by type matches");
}
static time_t GetCtime(const String& path)
{
#ifdef _WIN32
struct _stat statbuf;
int rc = _stat(path.CStr(), &statbuf);
#else /* _WIN32 */
struct stat statbuf;
int rc = stat(path.CStr(), &statbuf);
#endif /* _WIN32 */
return rc ? 0 : statbuf.st_ctime;
}
/**
* The entry point for the "object list" CLI command.
*
* @returns An exit status.
*/
int ObjectListCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{
String objectfile = Configuration::ObjectsPath;
if (!Utility::PathExists(objectfile)) {
Log(LogCritical, "cli")
<< "Cannot open objects file '" << Configuration::ObjectsPath << "'.";
Log(LogCritical, "cli", "Run 'icinga2 daemon -C --dump-objects' to validate config and generate the cache file.");
return 1;
}
std::fstream fp;
fp.open(objectfile.CStr(), std::ios_base::in);
StdioStream::Ptr sfp = new StdioStream(&fp, false);
unsigned long objects_count = 0;
std::map<String, int> type_count;
String name_filter, type_filter;
if (vm.count("name"))
name_filter = vm["name"].as<std::string>();
if (vm.count("type"))
type_filter = vm["type"].as<std::string>();
bool first = true;
String message;
StreamReadContext src;
for (;;) {
StreamReadStatus srs = NetString::ReadStringFromStream(sfp, &message, src);
if (srs == StatusEof)
break;
if (srs != StatusNewItem)
continue;
ObjectListUtility::PrintObject(std::cout, first, message, type_count, name_filter, type_filter);
objects_count++;
}
sfp->Close();
fp.close();
if (vm.count("count")) {
if (!first)
std::cout << "\n";
PrintTypeCounts(std::cout, type_count);
std::cout << "\n";
}
Log(LogNotice, "cli")
<< "Parsed " << objects_count << " objects.";
auto objectsPathCtime (GetCtime(Configuration::ObjectsPath));
auto varsPathCtime (GetCtime(Configuration::VarsPath));
if (objectsPathCtime < varsPathCtime) {
Log(LogWarning, "cli")
<< "This data is " << Utility::FormatDuration(varsPathCtime - objectsPathCtime)
<< " older than the last Icinga config (re)load. It may be outdated. Consider running 'icinga2 daemon -C --dump-objects' first.";
}
return 0;
}
void ObjectListCommand::PrintTypeCounts(std::ostream& fp, const std::map<String, int>& type_count)
{
typedef std::map<String, int>::value_type TypeCount;
for (const TypeCount& kv : type_count) {
fp << "Found " << kv.second << " " << kv.first << " object";
if (kv.second != 1)
fp << "s";
fp << ".\n";
}
}
|