summaryrefslogtreecommitdiffstats
path: root/configutil/src/lib/modelinspect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'configutil/src/lib/modelinspect.cpp')
-rw-r--r--configutil/src/lib/modelinspect.cpp366
1 files changed, 366 insertions, 0 deletions
diff --git a/configutil/src/lib/modelinspect.cpp b/configutil/src/lib/modelinspect.cpp
new file mode 100644
index 00000000000..69fd2b804df
--- /dev/null
+++ b/configutil/src/lib/modelinspect.cpp
@@ -0,0 +1,366 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/fastos/fastos.h>
+#include <ctype.h>
+#include <vespa/log/log.h>
+LOG_SETUP("vespa-model-inspect");
+#include <iostream>
+#include "modelinspect.h"
+#include <set>
+#include <lib/tags.h>
+
+using configdefinitions::tagsContain;
+using configdefinitions::upcase;
+
+ModelInspect::ModelInspect(Flags flags, const config::ConfigUri uri, std::ostream &out)
+ : _cfg(), _flags(flags), _out(out)
+{
+ if (_flags.verbose) {
+ std::cerr << "subscribing to model config with configid " << uri.getConfigId() << "\n";
+ }
+
+ try {
+ _cfg = config::ConfigGetter<cloud::config::ModelConfig>::getConfig(uri.getConfigId(),
+ uri.getContext());
+ } catch(config::ConfigRuntimeException &e) {
+ std::cerr << e.getMessage() << "\n";
+ }
+ if (_cfg.get() != NULL) {
+ if (_flags.verbose) std::cerr << "success!\n";
+ } else {
+ std::cerr << "FATAL ERROR: failed to get model configuration.\n";
+ exit(1);
+ }
+}
+
+ModelInspect::~ModelInspect()
+{
+}
+
+void
+ModelInspect::printPort(const vespalib::string &host, int port,
+ const vespalib::string &tags)
+{
+ if (_flags.tagfilt) {
+ for (size_t i = 0; i < _flags.tagFilter.size(); ++i) {
+ if (! tagsContain(tags, _flags.tagFilter[i])) {
+ return;
+ }
+ }
+ }
+ if (_flags.makeuri && tagsContain(tags, "HTTP")) {
+ _out << " http://" << host << ":" << port << "/";
+ } else {
+ _out << " tcp/" << host << ":" << port;
+ }
+ if (_flags.tagfilt) {
+ _out << "\n";
+ } else {
+ vespalib::string upper = upcase(tags);
+ _out << " (" << upper << ")\n";
+ }
+}
+
+void
+ModelInspect::printService(const cloud::config::ModelConfig::Hosts::Services &svc,
+ const vespalib::string &host)
+{
+ if (!_flags.tagfilt) {
+ _out << svc.name << " @ " << host << " : " << svc.clustertype << std::endl;
+ _out << svc.configid << std::endl;
+ }
+ for (size_t i = 0; i < svc.ports.size(); ++i) {
+ printPort(host, svc.ports[i].number, svc.ports[i].tags);
+ }
+}
+
+int
+ModelInspect::action(int cnt, char **argv)
+{
+ const vespalib::string cmd = *argv++;
+ if (cnt == 1) {
+ if (cmd == "yamldump") {
+ yamlDump();
+ return 0;
+ }
+ if (cmd == "hosts") {
+ listHosts();
+ return 0;
+ }
+ if (cmd == "services") {
+ listServices();
+ return 0;
+ }
+ if (cmd == "clusters") {
+ listClusters();
+ return 0;
+ }
+ if (cmd == "configids") {
+ listConfigIds();
+ return 0;
+ }
+ if (cmd == "filter:hosts") {
+ if (!_flags.tagfilt) {
+ std::cerr << "filter needs some filter options" << std::endl;
+ return 1;
+ }
+ std::cerr << "not implemented" << std::endl;
+ return 1;
+ }
+ if (cmd == "filter:ports") {
+ if (!_flags.tagfilt) {
+ std::cerr << "filter needs some filter options" << std::endl;
+ return 1;
+ }
+ return listAllPorts();
+ }
+ }
+ if (cnt == 2) {
+ vespalib::string arg = *argv++;
+ if (cmd == "host") {
+ return listHost(arg);
+ }
+ if (cmd == "cluster") {
+ return listCluster(arg);
+ }
+ if (cmd == "service") {
+ size_t colon = arg.find(':');
+ if (colon != vespalib::string::npos) {
+ return listService(arg.substr(0, colon),
+ arg.substr(colon + 1));
+ } else {
+ return listService(arg);
+ }
+ }
+ if (cmd == "configid") {
+ return listConfigId(arg);
+ }
+ }
+ if (cnt == 3) {
+ vespalib::string arg1 = *argv++;
+ vespalib::string arg2 = *argv++;
+ if (cmd == "get-index-of") {
+ return getIndexOf(arg1, arg2);
+ }
+ };
+ std::cerr << "bad args '" << cmd << "' (got " << cnt << " arguments)" << std::endl;
+ return 1;
+}
+
+void
+ModelInspect::dumpService(const cloud::config::ModelConfig::Hosts::Services &svc,
+ const vespalib::string &host)
+{
+ _out << "- servicename: " << svc.name << "\n";
+ _out << " servicetype: " << svc.type << "\n";
+ _out << " clustertype: " << svc.clustertype << "\n";
+ _out << " clustername: " << svc.clustername << "\n";
+ _out << " index: " << svc.index << "\n";
+ _out << " hostname: " << host << "\n";
+ _out << " config-id: " << svc.configid << "\n";
+
+ if (svc.ports.size() > 0) {
+ _out << " ports: \n";
+ for (size_t i = 0; i < svc.ports.size(); ++i) {
+ _out << " - " << svc.ports[i].number << "\n";
+ }
+ }
+}
+
+void
+ModelInspect::yamlDump()
+{
+ _out << "--- \n";
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ dumpService(hconf.services[j], hconf.name);
+ }
+ }
+}
+
+void
+ModelInspect::listHosts()
+{
+ std::vector<vespalib::string> hosts;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ hosts.push_back(hconf.name);
+ }
+ std::sort(hosts.begin(), hosts.end());
+ for (size_t i = 0; i < hosts.size(); ++i) {
+ _out << hosts[i] << std::endl;
+ }
+}
+
+void
+ModelInspect::listServices()
+{
+ typedef std::set<vespalib::string> Set;
+ Set services;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ services.insert(hconf.services[j].type);
+ }
+ }
+ for (Set::const_iterator it = services.begin(); it != services.end(); ++it) {
+ _out << (*it) << std::endl;
+ }
+}
+
+void
+ModelInspect::listClusters()
+{
+ typedef std::set<vespalib::string> Set;
+ Set clusters;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ clusters.insert(hconf.services[j].clustername);
+ }
+ }
+ for (Set::const_iterator it = clusters.begin(); it != clusters.end(); ++it) {
+ _out << (*it) << std::endl;
+ }
+}
+
+void
+ModelInspect::listConfigIds()
+{
+ std::vector<vespalib::string> configids;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ configids.push_back(hconf.services[j].configid);
+ }
+ }
+ std::sort(configids.begin(), configids.end());
+ for (size_t i = 0; i < configids.size(); ++i) {
+ _out << configids[i] << std::endl;
+ }
+}
+
+int
+ModelInspect::listHost(const vespalib::string host)
+{
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ if (host == hconf.name) {
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ printService(hconf.services[j], host);
+ }
+ return 0;
+ }
+ }
+ std::cerr << "no config found for host '" << host << "'\n";
+ return 1;
+}
+
+int
+ModelInspect::listCluster(const vespalib::string cluster)
+{
+ bool found = false;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ if (cluster == hconf.services[j].clustername) {
+ found = true;
+ printService(hconf.services[j], hconf.name);
+ }
+ }
+ }
+ if (found) return 0;
+ std::cerr << "no config found for cluster '" << cluster << "'\n";
+ return 1;
+}
+
+int
+ModelInspect::listAllPorts()
+{
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ printService(hconf.services[j], hconf.name);
+ }
+ }
+ return 0;
+}
+
+int
+ModelInspect::listService(const vespalib::string svctype)
+{
+ bool found = false;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ if (svctype == hconf.services[j].type) {
+ found = true;
+ printService(hconf.services[j], hconf.name);
+ }
+ }
+ }
+ if (found) return 0;
+ std::cerr << "no services found with type '" << svctype << "'\n";
+ return 1;
+}
+
+
+int
+ModelInspect::listService(const vespalib::string cluster,
+ const vespalib::string svctype)
+{
+ bool found = false;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ if (cluster == hconf.services[j].clustername &&
+ svctype == hconf.services[j].type)
+ {
+ found = true;
+ printService(hconf.services[j], hconf.name);
+ }
+ }
+ }
+ if (found) return 0;
+ std::cerr << "no services found with type '" << svctype << "' in cluster '" << cluster << "'\n";
+ return 1;
+}
+
+int
+ModelInspect::listConfigId(const vespalib::string configid)
+{
+ bool found = false;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ if (configid == hconf.services[j].configid) {
+ found = true;
+ printService(hconf.services[j], hconf.name);
+ }
+ }
+ }
+ if (found) return 0;
+ std::cerr << "no services found with configid '" << configid << "'\n";
+ return 1;
+}
+
+int
+ModelInspect::getIndexOf(const vespalib::string service, const vespalib::string host)
+{
+ bool found = false;
+ for (size_t i = 0; i < _cfg->hosts.size(); ++i) {
+ const cloud::config::ModelConfig::Hosts &hconf = _cfg->hosts[i];
+ if (host == hconf.name) {
+ for (size_t j = 0; j < hconf.services.size(); ++j) {
+ if (service == hconf.services[j].type) {
+ found = true;
+ _out << hconf.services[j].index << std::endl;
+ }
+ }
+ }
+ }
+ if (found) return 0;
+ std::cerr << "no service of type '" << service << "' found for host '" << host << "'\n";
+ return 1;
+}