[pkg-nagios-changes] [Git][nagios-team/pkg-icinga2][upstream] New upstream version 2.9.2
Bas Couwenberg
gitlab at salsa.debian.org
Fri Sep 28 07:03:05 BST 2018
Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / pkg-icinga2
Commits:
e36992a0 by Bas Couwenberg at 2018-09-28T05:30:36Z
New upstream version 2.9.2
- - - - -
14 changed files:
- AUTHORS
- CHANGELOG.md
- RELEASE.md
- VERSION
- doc/16-upgrading-icinga-2.md
- lib/base/scriptutils.cpp
- lib/config/configitem.cpp
- lib/methods/clusterzonechecktask.cpp
- lib/perfdata/elasticsearchwriter.cpp
- lib/perfdata/influxdbwriter.cpp
- lib/remote/apilistener.cpp
- lib/remote/filterutility.cpp
- lib/remote/pkiutility.cpp
- lib/remote/pkiutility.hpp
Changes:
=====================================
AUTHORS
=====================================
@@ -31,6 +31,7 @@ Christian Jonak <christian at jonak.org>
Christian Lehmann <christian_lehmann at gmx.de>
Christian Loos <cloos at netsandbox.de>
Christian Schmidt <github at chsc.dk>
+Christopher Schirner <schinken at bamberg.ccc.de>
Claudio Bilotta <bilottalove at gmail.com>
Claudio Kuenzler <ck at claudiokuenzler.com>
Conrad Clement <cclement at printeron.com>
=====================================
CHANGELOG.md
=====================================
@@ -1,5 +1,34 @@
# Icinga 2.x CHANGELOG
+## 2.9.2 (2018-09-26)
+
+### Enhancement
+
+* [#6602](https://github.com/icinga/icinga2/issues/6602) (API, Cluster, PR): Improve TLS handshake exception logging
+* [#6568](https://github.com/icinga/icinga2/issues/6568) (Configuration, PR): Ensure that config object types are committed in dependent load order
+* [#6497](https://github.com/icinga/icinga2/issues/6497) (Configuration, PR): Improve error logging for match/regex/cidr\_match functions and unsupported dictionary usage
+
+### Bug
+
+* [#6596](https://github.com/icinga/icinga2/issues/6596) (Crash, PR): Fix crash on API queries with Fedora 28 hardening and GCC 8
+* [#6581](https://github.com/icinga/icinga2/issues/6581) (Configuration, PR): Shuffle items before config validation
+* [#6569](https://github.com/icinga/icinga2/issues/6569) (DB IDO): Custom Vars not updated after upgrade
+* [#6533](https://github.com/icinga/icinga2/issues/6533) (Crash): Icinga2 crashes after using some api-commands on Fedora 28
+* [#6505](https://github.com/icinga/icinga2/issues/6505) (Cluster, PR): Fix clusterzonecheck if not connected
+* [#6498](https://github.com/icinga/icinga2/issues/6498) (Configuration, PR): Fix regression with MatchAny false conditions on match/regex/cidr\_match
+* [#6496](https://github.com/icinga/icinga2/issues/6496) (Configuration): error with match and type matchany
+
+### Documentation
+
+* [#6590](https://github.com/icinga/icinga2/issues/6590) (DB IDO, Documentation, PR): Update workaround for custom vars
+* [#6572](https://github.com/icinga/icinga2/issues/6572) (Documentation, PR): Add note about workaround for broken custom vars
+
+### Support
+
+* [#6540](https://github.com/icinga/icinga2/issues/6540) (Configuration): Evaluate a fixed config compiler commit order
+* [#6486](https://github.com/icinga/icinga2/issues/6486) (Configuration): Configuration validation w/ ScheduledDowntimes performance decreased in 2.9
+* [#6442](https://github.com/icinga/icinga2/issues/6442) (Configuration): Error while evaluating "assign where match" expression: std::bad\_cast
+
## 2.9.1 (2018-07-24)
### Bug
=====================================
RELEASE.md
=====================================
@@ -26,7 +26,7 @@
Specify the release version.
```
-VERSION=2.9.0
+VERSION=2.9.2
```
Add your signing key to your Git configuration file, if not already there.
@@ -60,10 +60,11 @@ git log --use-mailmap | grep '^Author:' | cut -f2- -d' ' | sort | uniq > AUTHORS
## Version <a id="version"></a>
-Update the version in the version file:
+Update the version:
```
sed -i "s/Version: .*/Version: $VERSION/g" VERSION
+sed -i "s/VERSION=.*/VERSION=$VERSION/g" RELEASE.md
```
## Changelog <a id="changelog"></a>
=====================================
VERSION
=====================================
@@ -1,2 +1,2 @@
-Version: 2.9.1
+Version: 2.9.2
Revision: 1
=====================================
doc/16-upgrading-icinga-2.md
=====================================
@@ -97,6 +97,24 @@ With the removal of RHEL 5 as supported platform, we can finally use real unique
This is reflected in generating names for e.g. API stage names. Previously it was a handcrafted
mix of local FQDN, timestamps and random numbers.
+### Custom Vars not updating <a id="upgrading-to-2-9-custom-vars-not-updating"></a>
+
+A rare issue preventing the custom vars of objects created prior to 2.9.0 being updated when changed may occur. To
+remedy this, truncate the customvar tables and restart Icinga 2. The following is an example of how to do this with mysql:
+
+```
+$ mysql -uroot -picinga icinga
+MariaDB [icinga]> truncate icinga_customvariables;
+Query OK, 0 rows affected (0.05 sec)
+MariaDB [icinga]> truncate icinga_customvariablestatus;
+Query OK, 0 rows affected (0.03 sec)
+MariaDB [icinga]> exit
+Bye
+$ sudo systemctl restart icinga2
+```
+
+Custom vars should now stay up to date.
+
## Upgrading to v2.8.2 <a id="upgrading-to-2-8-2"></a>
=====================================
lib/base/scriptutils.cpp
=====================================
@@ -108,10 +108,14 @@ bool ScriptUtils::CastBool(const Value& value)
bool ScriptUtils::Regex(const std::vector<Value>& args)
{
if (args.size() < 2)
- BOOST_THROW_EXCEPTION(std::invalid_argument("Regular expression and text must be specified."));
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Regular expression and text must be specified for regex()."));
String pattern = args[0];
const Value& argTexts = args[1];
+
+ if (argTexts.IsObjectType<Dictionary>())
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionaries are not supported by regex()."));
+
MatchType mode;
if (args.size() > 2)
@@ -147,7 +151,8 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
return false;
}
- return true;
+ /* MatchAny: Nothing matched. MatchAll: Everything matched. */
+ return mode == MatchAll;
} else {
String text = argTexts;
boost::smatch what;
@@ -158,10 +163,14 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
bool ScriptUtils::Match(const std::vector<Value>& args)
{
if (args.size() < 2)
- BOOST_THROW_EXCEPTION(std::invalid_argument("Pattern and text must be specified."));
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Pattern and text must be specified for match()."));
String pattern = args[0];
const Value& argTexts = args[1];
+
+ if (argTexts.IsObjectType<Dictionary>())
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionaries are not supported by match()."));
+
MatchType mode;
if (args.size() > 2)
@@ -189,7 +198,8 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
return false;
}
- return true;
+ /* MatchAny: Nothing matched. MatchAll: Everything matched. */
+ return mode == MatchAll;
} else {
String text = argTexts;
return Utility::Match(pattern, argTexts);
@@ -199,10 +209,14 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
{
if (args.size() < 2)
- BOOST_THROW_EXCEPTION(std::invalid_argument("CIDR and IP address must be specified."));
+ BOOST_THROW_EXCEPTION(std::invalid_argument("CIDR and IP address must be specified for cidr_match()."));
String pattern = args[0];
const Value& argIps = args[1];
+
+ if (argIps.IsObjectType<Dictionary>())
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionaries are not supported by cidr_match()."));
+
MatchType mode;
if (args.size() > 2)
@@ -230,7 +244,8 @@ bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
return false;
}
- return true;
+ /* MatchAny: Nothing matched. MatchAll: Everything matched. */
+ return mode == MatchAll;
} else {
String ip = argIps;
return Utility::CidrMatch(pattern, ip);
=====================================
lib/config/configitem.cpp
=====================================
@@ -38,6 +38,8 @@
#include "base/function.hpp"
#include <sstream>
#include <fstream>
+#include <algorithm>
+#include <random>
using namespace icinga;
@@ -428,26 +430,77 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
if (items.empty())
return true;
- for (const auto& ip : items)
- newItems.push_back(ip.first);
-
- upq.ParallelFor(items, [](const ItemPair& ip) {
- ip.first->Commit(ip.second);
- });
+ // Shuffle all items to evenly distribute them over the threads of the workqueue. This increases perfomance
+ // noticably in environments with lots of objects and available threads.
+ std::shuffle(std::begin(items), std::end(items), std::default_random_engine {});
- upq.Join();
+#ifdef I2_DEBUG
+ Log(LogDebug, "configitem")
+ << "Committing " << items.size() << " new items.";
+#endif /* I2_DEBUG */
- if (upq.HasExceptions())
- return false;
+ for (const auto& ip : items)
+ newItems.push_back(ip.first);
std::set<Type::Ptr> types;
+ std::set<Type::Ptr> completed_types;
for (const Type::Ptr& type : Type::GetAllTypes()) {
if (ConfigObject::TypeInstance->IsAssignableFrom(type))
types.insert(type);
}
- std::set<Type::Ptr> completed_types;
+ while (types.size() != completed_types.size()) {
+ for (const Type::Ptr& type : types) {
+ if (completed_types.find(type) != completed_types.end())
+ continue;
+
+ bool unresolved_dep = false;
+
+ /* skip this type (for now) if there are unresolved load dependencies */
+ for (const String& loadDep : type->GetLoadDependencies()) {
+ Type::Ptr pLoadDep = Type::GetByName(loadDep);
+ if (types.find(pLoadDep) != types.end() && completed_types.find(pLoadDep) == completed_types.end()) {
+ unresolved_dep = true;
+ break;
+ }
+ }
+
+ if (unresolved_dep)
+ continue;
+
+ int committed_items = 0;
+ upq.ParallelFor(items, [&type, &committed_items](const ItemPair& ip) {
+ const ConfigItem::Ptr& item = ip.first;
+
+ if (item->m_Type != type)
+ return;
+
+ ip.first->Commit(ip.second);
+ committed_items++;
+ });
+
+ upq.Join();
+
+ completed_types.insert(type);
+
+#ifdef I2_DEBUG
+ if (committed_items > 0)
+ Log(LogDebug, "configitem")
+ << "Committed " << committed_items << " items of type '" << type->GetName() << "'.";
+#endif /* I2_DEBUG */
+
+ if (upq.HasExceptions())
+ return false;
+ }
+ }
+
+#ifdef I2_DEBUG
+ Log(LogDebug, "configitem")
+ << "Committed " << items.size() << " items.";
+#endif /* I2_DEBUG */
+
+ completed_types.clear();
while (types.size() != completed_types.size()) {
for (const Type::Ptr& type : types) {
@@ -468,7 +521,8 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
if (unresolved_dep)
continue;
- upq.ParallelFor(items, [&type](const ItemPair& ip) {
+ int notified_items = 0;
+ upq.ParallelFor(items, [&type, ¬ified_items](const ItemPair& ip) {
const ConfigItem::Ptr& item = ip.first;
if (!item->m_Object || item->m_Type != type)
@@ -476,6 +530,7 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
try {
item->m_Object->OnAllConfigLoaded();
+ notified_items++;
} catch (const std::exception& ex) {
if (!item->m_IgnoreOnError)
throw;
@@ -496,11 +551,18 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
upq.Join();
+#ifdef I2_DEBUG
+ if (notified_items > 0)
+ Log(LogDebug, "configitem")
+ << "Sent OnAllConfigLoaded to " << notified_items << " items of type '" << type->GetName() << "'.";
+#endif /* I2_DEBUG */
+
if (upq.HasExceptions())
return false;
+ notified_items = 0;
for (const String& loadDep : type->GetLoadDependencies()) {
- upq.ParallelFor(items, [loadDep, &type](const ItemPair& ip) {
+ upq.ParallelFor(items, [loadDep, &type, ¬ified_items](const ItemPair& ip) {
const ConfigItem::Ptr& item = ip.first;
if (!item->m_Object || item->m_Type->GetName() != loadDep)
@@ -508,14 +570,22 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
ActivationScope ascope(item->m_ActivationContext);
item->m_Object->CreateChildObjects(type);
+ notified_items++;
});
}
upq.Join();
+#ifdef I2_DEBUG
+ if (notified_items > 0)
+ Log(LogDebug, "configitem")
+ << "Sent CreateChildObjects to " << notified_items << " items of type '" << type->GetName() << "'.";
+#endif /* I2_DEBUG */
+
if (upq.HasExceptions())
return false;
+ // Make sure to activate any additionally generated items
if (!CommitNewItems(context, upq, newItems))
return false;
}
=====================================
lib/methods/clusterzonechecktask.cpp
=====================================
@@ -122,23 +122,23 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
bytesReceivedPerSecond += endpoint->GetBytesReceivedPerSecond();
}
- if (!connected) {
- cr->SetState(ServiceCritical);
- cr->SetOutput("Zone '" + zoneName + "' is not connected. Log lag: " + Utility::FormatDuration(zoneLag));
- } else {
+ if (connected) {
cr->SetState(ServiceOK);
cr->SetOutput("Zone '" + zoneName + "' is connected. Log lag: " + Utility::FormatDuration(zoneLag));
- }
- /* Check whether the thresholds have been resolved and compare them */
- if (missingLagCritical.IsEmpty() && zoneLag > lagCritical) {
+ /* Check whether the thresholds have been resolved and compare them */
+ if (missingLagCritical.IsEmpty() && zoneLag > lagCritical) {
+ cr->SetState(ServiceCritical);
+ cr->SetOutput("Zone '" + zoneName + "' is connected. Log lag: " + Utility::FormatDuration(zoneLag)
+ + " greater than critical threshold: " + Utility::FormatDuration(lagCritical));
+ } else if (missingLagWarning.IsEmpty() && zoneLag > lagWarning) {
+ cr->SetState(ServiceWarning);
+ cr->SetOutput("Zone '" + zoneName + "' is connected. Log lag: " + Utility::FormatDuration(zoneLag)
+ + " greater than warning threshold: " + Utility::FormatDuration(lagWarning));
+ }
+ } else {
cr->SetState(ServiceCritical);
- cr->SetOutput("Zone '" + zoneName + "' is connected. Log lag: " + Utility::FormatDuration(zoneLag)
- + " greater than critical threshold: " + Utility::FormatDuration(lagCritical));
- } else if (missingLagWarning.IsEmpty() && zoneLag > lagWarning) {
- cr->SetState(ServiceWarning);
- cr->SetOutput("Zone '" + zoneName + "' is connected. Log lag: " + Utility::FormatDuration(zoneLag)
- + " greater than warning threshold: " + Utility::FormatDuration(lagWarning));
+ cr->SetOutput("Zone '" + zoneName + "' is not connected. Log lag: " + Utility::FormatDuration(zoneLag));
}
cr->SetPerformanceData(new Array({
=====================================
lib/perfdata/elasticsearchwriter.cpp
=====================================
@@ -434,7 +434,7 @@ void ElasticsearchWriter::SendRequest(const String& body)
stream = Connect();
} catch (const std::exception& ex) {
Log(LogWarning, "ElasticsearchWriter")
- << "Flush failed, cannot connect to Elasticsearch.";
+ << "Flush failed, cannot connect to Elasticsearch: " << DiagnosticInformation(ex, false);
return;
}
=====================================
lib/perfdata/influxdbwriter.cpp
=====================================
@@ -425,7 +425,7 @@ void InfluxdbWriter::Flush()
stream = Connect();
} catch (const std::exception& ex) {
Log(LogWarning, "InfluxDbWriter")
- << "Flush failed, cannot connect to InfluxDB.";
+ << "Flush failed, cannot connect to InfluxDB: " << DiagnosticInformation(ex, false);
return;
}
=====================================
lib/remote/apilistener.cpp
=====================================
@@ -454,9 +454,9 @@ void ApiListener::NewClientHandlerInternal(const Socket::Ptr& client, const Stri
try {
tlsStream->Handshake();
- } catch (const std::exception&) {
+ } catch (const std::exception& ex) {
Log(LogCritical, "ApiListener")
- << "Client TLS handshake failed (" << conninfo << ")";
+ << "Client TLS handshake failed (" << conninfo << "): " << DiagnosticInformation(ex, false);
tlsStream->Close();
return;
}
=====================================
lib/remote/filterutility.cpp
=====================================
@@ -127,7 +127,7 @@ static void FilteredAddTarget(ScriptFrame& permissionFrame, Expression *permissi
ScriptFrame& frame, Expression *ufilter, std::vector<Value>& result, const String& variableName, const Object::Ptr& target)
{
if (FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName) && FilterUtility::EvaluateFilter(frame, ufilter, target, variableName))
- result.emplace_back(target);
+ result.emplace_back(std::move(target));
}
void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter)
@@ -206,7 +206,7 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
if (attr == "type")
attr = "name";
- if (query->Contains(attr)) {
+ if (query && query->Contains(attr)) {
String name = HttpUtility::GetLastParameter(query, attr);
Object::Ptr target = provider->GetTargetByName(type, name);
@@ -219,7 +219,7 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
attr = provider->GetPluralName(type);
boost::algorithm::to_lower(attr);
- if (query->Contains(attr)) {
+ if (query && query->Contains(attr)) {
Array::Ptr names = query->Get(attr);
if (names) {
ObjectLock olock(names);
@@ -235,7 +235,7 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
}
}
- if (query->Contains("filter") || result.empty()) {
+ if ((query && query->Contains("filter")) || result.empty()) {
if (!query->Contains("type"))
BOOST_THROW_EXCEPTION(std::invalid_argument("Type must be specified when using a filter."));
@@ -251,26 +251,31 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
frame.Sandboxed = true;
Dictionary::Ptr uvars = new Dictionary();
- std::unique_ptr<Expression> ufilter;
-
if (query->Contains("filter")) {
String filter = HttpUtility::GetLastParameter(query, "filter");
- ufilter = ConfigCompiler::CompileText("<API query>", filter);
- }
+ std::unique_ptr<Expression> ufilter = ConfigCompiler::CompileText("<API query>", filter);
- Dictionary::Ptr filter_vars = query->Get("filter_vars");
- if (filter_vars) {
- ObjectLock olock(filter_vars);
- for (const Dictionary::Pair& kv : filter_vars) {
- uvars->Set(kv.first, kv.second);
+ Dictionary::Ptr filter_vars = query->Get("filter_vars");
+ if (filter_vars) {
+ ObjectLock olock(filter_vars);
+ for (const Dictionary::Pair& kv : filter_vars) {
+ uvars->Set(kv.first, kv.second);
+ }
}
- }
-
- frame.Self = uvars;
- provider->FindTargets(type, std::bind(&FilteredAddTarget,
- std::ref(permissionFrame), permissionFilter,
- std::ref(frame), &*ufilter, std::ref(result), variableName, _1));
+ frame.Self = uvars;
+
+ provider->FindTargets(type, std::bind(&FilteredAddTarget,
+ std::ref(permissionFrame), permissionFilter,
+ std::ref(frame), &*ufilter, std::ref(result), variableName, _1));
+ } else {
+ /* Ensure to pass a nullptr as filter expression.
+ * GCC 8.1.1 on F28 causes problems, see GH #6533.
+ */
+ provider->FindTargets(type, std::bind(&FilteredAddTarget,
+ std::ref(permissionFrame), permissionFilter,
+ std::ref(frame), nullptr, std::ref(result), variableName, _1));
+ }
}
return result;
=====================================
lib/remote/pkiutility.cpp
=====================================
@@ -187,8 +187,9 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const
try {
stream->Handshake();
- } catch (const std::exception&) {
- Log(LogCritical, "cli", "Client TLS handshake failed.");
+ } catch (const std::exception& ex) {
+ Log(LogCritical, "cli")
+ << "Client TLS handshake failed: " << DiagnosticInformation(ex, false);
return 1;
}
=====================================
lib/remote/pkiutility.hpp
=====================================
@@ -21,6 +21,7 @@
#define PKIUTILITY_H
#include "remote/i2-remote.hpp"
+#include "base/exception.hpp"
#include "base/dictionary.hpp"
#include "base/string.hpp"
#include <openssl/x509v3.h>
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icinga2/commit/e36992a043a20bb6fb29fe36629fdc2d325f55b7
--
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icinga2/commit/e36992a043a20bb6fb29fe36629fdc2d325f55b7
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20180928/4c2dea69/attachment-0001.html>
More information about the pkg-nagios-changes
mailing list