[pkg-nagios-changes] [Git][nagios-team/pkg-icinga2][upstream] New upstream version 2.12.4

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Thu May 27 14:10:27 BST 2021



Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / pkg-icinga2


Commits:
7f1d1d73 by Bas Couwenberg at 2021-05-27T14:15:24+02:00
New upstream version 2.12.4
- - - - -


26 changed files:

- .github/workflows/packages.yml
- CHANGELOG.md
- CMakeLists.txt
- VERSION
- doc/19-technical-concepts.md
- lib/base/string.cpp
- lib/base/string.hpp
- lib/base/utility.cpp
- lib/cli/daemoncommand.cpp
- lib/db_ido/dbconnection.cpp
- lib/db_ido_mysql/idomysqlconnection.cpp
- lib/icinga/apiactions.cpp
- lib/icinga/clusterevents.cpp
- lib/icinga/downtime.cpp
- lib/icinga/downtime.hpp
- lib/icinga/externalcommandprocessor.cpp
- lib/icinga/notification.cpp
- lib/icinga/scheduleddowntime.cpp
- lib/notification/notificationcomponent.cpp
- lib/perfdata/elasticsearchwriter.cpp
- lib/perfdata/influxdbwriter.cpp
- lib/remote/configfileshandler.cpp
- lib/remote/configobjectutility.cpp
- lib/remote/httpserverconnection.cpp
- lib/remote/httputility.cpp
- lib/remote/infohandler.cpp


Changes:

=====================================
.github/workflows/packages.yml
=====================================
@@ -21,6 +21,9 @@ jobs:
           - name: debian
             codename: stretch
             has32bit: true
+          - name: ubuntu
+            codename: hirsute
+            has32bit: false
           - name: ubuntu
             codename: groovy
             has32bit: false
@@ -30,9 +33,6 @@ jobs:
           - name: ubuntu
             codename: bionic
             has32bit: true
-          - name: ubuntu
-            codename: xenial
-            has32bit: true
 
     runs-on: ubuntu-latest
 
@@ -116,16 +116,11 @@ jobs:
             -e ICINGA_BUILD_TYPE=snapshot \
             registry.icinga.com/build-docker/${{ matrix.distro.name }}/${{ matrix.distro.codename }}:x86 \
             icinga-build-test
-
-      - name: Artifacts
-        uses: actions/upload-artifact at v1
-        with:
-          name: '${{ matrix.distro.name }}-${{ matrix.distro.codename }}-packages'
-          path: deb-icinga2/build
   rpm:
     name: .rpm
 
     strategy:
+      fail-fast: false
       matrix:
         distro:
           - name: centos
@@ -133,15 +128,15 @@ jobs:
           - name: centos
             release: 7
           - name: fedora
-            release: 32
+            release: 34
           - name: fedora
-            release: 31
+            release: 33
           - name: sles
-            release: '15.1'
+            release: '15.2'
           - name: sles
             release: '12.5'
           - name: opensuse
-            release: '15.1'
+            release: '15.2'
 
     runs-on: ubuntu-latest
 
@@ -220,17 +215,11 @@ jobs:
             -e ICINGA_BUILD_TYPE=snapshot \
             registry.icinga.com/build-docker/${{ matrix.distro.name }}/${{ matrix.distro.release }} \
             icinga-build-test
-
-      - name: Artifacts
-        if: "steps.vars.outputs.CAN_BUILD == 'true'"
-        uses: actions/upload-artifact at v1
-        with:
-          name: '${{ matrix.distro.name }}-${{ matrix.distro.release }}-packages'
-          path: rpm-icinga2/build
   raspbian:
     name: Raspbian
 
     strategy:
+      fail-fast: false
       matrix:
         codename:
           - buster
@@ -298,9 +287,3 @@ jobs:
 #            -e ICINGA_BUILD_DEB_DEFAULT_ARCH=armhf \
 #            registry.icinga.com/build-docker/raspbian/${{ matrix.codename }} \
 #            icinga-build-test
-
-      - name: Artifacts
-        uses: actions/upload-artifact at v1
-        with:
-          name: 'raspbian-${{ matrix.codename }}-packages'
-          path: raspbian-icinga2/build


=====================================
CHANGELOG.md
=====================================
@@ -7,6 +7,27 @@ documentation before upgrading to a new release.
 
 Released closed milestones can be found on [GitHub](https://github.com/Icinga/icinga2/milestones?state=closed).
 
+## 2.12.4 (2021-05-27)
+
+Version 2.12.4 is a maintenance release that fixes some crashes, improves error handling
+and adds compatibility for systems coming with newer Boost versions.
+
+### Bugfixes
+
+* Fix a crash when notification objects are deleted using the API #8782
+* Fix crashes that might occur during downtime scheduling if host or downtime objects are deleted using the API #8785
+* Fix an issue where notifications may incorrectly be skipped after a downtime ends #8775
+* Don't send reminder notification if the notification is still suppressed by a time period #8808
+* Fix an issue where attempting to create a duplicate object using the API
+  might result in the original object being deleted #8787
+* IDO: prioritize program status updates #8809
+* Improve exceptions handling, including a fix for an uncaught exception on Windows #8777
+* Retry file rename operations on Windows to avoid intermittent locking issues #8771
+
+### Enhancements
+
+* Support Boost 1.74 (Ubuntu 21.04, Fedora 34) #8792
+
 ## 2.12.3 (2020-12-15)
 
 Version 2.12.3 resolves a security vulnerability with revoked certificates being
@@ -302,6 +323,108 @@ Thanks to all contributors:
   * Code quality fixes
   * Small documentation fixes
 
+## 2.11.8 (2020-12-15)
+
+Version 2.11.8 resolves a security vulnerability with revoked certificates being
+renewed automatically ignoring the CRL.
+
+This version also resolves issues with high load on Windows regarding the config sync
+and not being able to disable/enable Icinga 2 features over the API.
+
+### Security
+
+* Fix that revoked certificates due for renewal will automatically be renewed ignoring the CRL (CVE-2020-29663)
+
+When a CRL is specified in the ApiListener configuration, Icinga 2 only used it
+when connections were established so far, but not when a certificate is requested.
+This allows a node to automatically renew a revoked certificate if it meets the
+other conditions for auto renewal (issued before 2017 or expires in less than 30 days).
+
+Because Icinga 2 currently (v2.12.3 and earlier) uses a validity duration of 15 years,
+this only affects setups with external certificate signing and revoked certificates
+that expire in less then 30 days.
+
+### Bugfixes
+
+* Improve config sync locking - resolves high load issues on Windows #8510
+* Fix runtime config updates being ignored for objects without zone #8550
+* Use proper buffer size for OpenSSL error messages #8543
+
+### Enhancements
+
+* On checkable recovery: re-check children that have a problem #8560 
+
+## 2.11.7 (2020-12-01)
+
+Version 2.11.7 fixes several issues to improve the reliability of the cluster functionality.
+
+### Bugfixes
+
+* Fix a connection leak with misconfigured agents #8482
+* Properly sync changes of config objects in global zones done via the API #8473 #8457
+* Prevent other clients from being disconnected when replaying the cluster log takes very long #8475
+* Avoid duplicate connections between endpoints #8399
+* Ignore incoming config object updates for unknown zones #8459
+* Check timestamps before removing files in config sync #8486
+
+### Enhancements
+
+* Include HTTP status codes in log #8454
+
+## 2.11.6 (2020-10-15)
+
+Version 2.11.6 fixes several crashes, prevents unnecessary notifications
+and addresses several bugs in IDO and API.
+
+### Bugfixes
+
+* Crashes
+  * Fix crashes during config update #8337 #8308
+  * Fix crash while removing a downtime #8226
+  * Ensure the daemon doesn't get killed by logrotate #8227
+* IDO
+  * Prevent unnecessary IDO updates #8316 #8305
+  * Commit IDO MySQL transactions earlier #8298
+  * Make sure to insert IDO program status #8291
+  * Improve IDO queue stats logging #8270 #8325 #8378
+* API
+  * Ensure API connections are closed properly #8292
+  * Fix open connections when agent waits for CA approval #8230
+  * Close connections without successful TLS handshakes within 10s #8224
+* Misc
+  * Prevent unnecessary notifications #8300
+  * Fix Windows .exe version #8235
+  * Reset Icinga check warning after successful config update #8225
+
+## 2.11.5 (2020-08-05)
+
+Version 2.11.5 fixes file system race conditions
+in the config update process occurring in large HA environments
+and improves the cluster connection liveness mechanisms.
+
+### Bugfixes
+
+* Make the config update process mutually exclusive (Prevents file system race conditions) #8093
+* Consider a JsonRpcConnection alive on a single byte of TLS payload, not only on a whole message #8094
+* Send JsonRpcConnection heartbeat every 20s instead of 10s #8103
+* Use JsonRpcConnection heartbeat only to update connection liveness (m\_Seen) #8097
+
+## 2.11.4 (2020-06-18)
+
+Version 2.11.4 fixes a crash during a heartbeat timeout with clients not yet signed. It also resolves
+an issue with endpoints not reconnecting after a reload/deploy, which caused a lot of UNKNOWN states.
+
+### Bugfixes
+
+* Cluster
+  * Fix segfault during heartbeat timeout with clients not yet signed #7997
+  * Fix endpoints not reconnecting after reload (UNKNOWN hosts/services after reload) #8043
+* Setup
+  * Fix exception on trusted cert not readable during node setup #8044
+  * prepare-dirs: Only set permissions during directory creation #8046
+* DSL
+  * Fix segfault on missing compare function in Array functions (sort, map, reduce, filter, any, all) #8054
+
 ## 2.11.3 (2020-03-02)
 
 The 2.11.3 release fixes a critical crash in our JSON-RPC connections. This mainly affects large HA
@@ -465,6 +588,25 @@ Thanks to all contributors: [BarbUk](https://github.com/Icinga/icinga2/pulls?q=i
 
 
 
+## 2.10.7 (2019-10-17)
+
+[Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.10.7)
+
+### Bugfixes
+
+* Cluster config master must not load/sync its marker to other instances #7544
+  * This affects scenarios where the satellite/agent is newer than the master, e.g. master=2.10.x satellite=2.11.0
+
+
+## 2.10.6 (2019-07-30)
+
+[Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.10.6)
+
+### Bugfixes
+
+* Fix el7 not loading ECDHE cipher suites #7247
+
+
 ## 2.10.5 (2019-05-23)
 
 [Issues and PRs](https://github.com/Icinga/icinga2/milestone/81?closed=1)
@@ -825,6 +967,16 @@ Documentation updates:
 * [#6410](https://github.com/icinga/icinga2/issues/6410) (code-quality, PR): Remove unused code
 * [#4959](https://github.com/icinga/icinga2/issues/4959) (Installation, Windows): Windows Agent Wizard Window resizes with screen, hiding buttons
 
+## 2.9.3 (2019-07-30)
+
+[Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.9.3)
+
+### Bugfixes
+
+* Fix el7 not loading ECDHE cipher suites #7247
+* Fix checkresults from the future breaking checks #6797 ref/NC/595861
+* DB IDO: Don't enqueue queries when the feature is paused (HA) #5876
+
 ## 2.9.2 (2018-09-26)
 
 ### Enhancement


=====================================
CMakeLists.txt
=====================================
@@ -172,6 +172,9 @@ add_definitions(-DBOOST_COROUTINES_NO_DEPRECATION_WARNING)
 
 add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)
 
+# Required for Boost v1.74+
+add_definitions(-DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+
 link_directories(${Boost_LIBRARY_DIRS})
 include_directories(${Boost_INCLUDE_DIRS})
 


=====================================
VERSION
=====================================
@@ -1,2 +1,2 @@
-Version: 2.12.3
+Version: 2.12.4
 Revision: 1


=====================================
doc/19-technical-concepts.md
=====================================
@@ -1431,7 +1431,7 @@ Message updates will be dropped when:
 * Checkable does not exist.
 * Origin endpoint's zone is not allowed to access this checkable.
 
-#### event::SuppressedNotifications <a id="technical-concepts-json-rpc-messages-event-setsupressednotifications"></a>
+#### event::SetSuppressedNotifications <a id="technical-concepts-json-rpc-messages-event-setsupressednotifications"></a>
 
 > Location: `clusterevents.cpp`
 
@@ -1440,7 +1440,7 @@ Message updates will be dropped when:
 Key       | Value
 ----------|---------
 jsonrpc   | 2.0
-method    | event::SuppressedNotifications
+method    | event::SetSuppressedNotifications
 params    | Dictionary
 
 ##### Params
@@ -1456,6 +1456,8 @@ supressed\_notifications | Number 	 | Bitmask for suppressed notifications.
 Event Sender: `Checkable::OnSuppressedNotificationsChanged`
 Event Receiver: `SuppressedNotificationsChangedAPIHandler`
 
+Used to sync the notification state of a host or service object within the same HA zone.
+
 ##### Permissions
 
 The receiver will not process messages from not configured endpoints.
@@ -1463,7 +1465,7 @@ The receiver will not process messages from not configured endpoints.
 Message updates will be dropped when:
 
 * Checkable does not exist.
-* Origin endpoint's zone is not allowed to access this checkable.
+* Origin endpoint is not within the local zone.
 
 #### event::SetSuppressedNotificationTypes <a id="technical-concepts-json-rpc-messages-event-setsuppressednotificationtypes"></a>
 
@@ -1484,6 +1486,8 @@ Key         		 | Type   | Description
 notification             | String | Notification name
 supressed\_notifications | Number | Bitmask for suppressed notifications.
 
+Used to sync the state of a notification object within the same HA zone.
+
 ##### Functions
 
 Event Sender: `Notification::OnSuppressedNotificationsChanged`
@@ -1496,7 +1500,7 @@ The receiver will not process messages from not configured endpoints.
 Message updates will be dropped when:
 
 * Notification does not exist.
-* Origin endpoint's zone is not allowed to access this notification.
+* Origin endpoint is not within the local zone.
 
 
 #### event::SetNextNotification <a id="technical-concepts-json-rpc-messages-event-setnextnotification"></a>
@@ -1702,6 +1706,9 @@ text      | String        | Notification text
 Event Sender: `Checkable::OnNotificationsRequested`
 Event Receiver: `SendNotificationsAPIHandler`
 
+Signals that notifications have to be sent within the same HA zone. This is relevant if the checkable and its
+notifications are active on different endpoints.
+
 ##### Permissions
 
 The receiver will not process messages from not configured endpoints.
@@ -1709,7 +1716,7 @@ The receiver will not process messages from not configured endpoints.
 Message updates will be dropped when:
 
 * Checkable does not exist.
-* Origin endpoint's zone the same as the receiver. This binds notification messages to the HA zone.
+* Origin endpoint is not within the local zone.
 
 #### event::NotificationSentUser <a id="technical-concepts-json-rpc-messages-event-notificationsentuser"></a>
 


=====================================
lib/base/string.cpp
=====================================
@@ -127,6 +127,18 @@ String::operator const std::string&() const
 	return m_Data;
 }
 
+/**
+ * Conversion function to boost::string_view.
+ *
+ * This allows using String as the value for HTTP headers in boost::beast::http::basic_fields::set.
+ *
+ * @return A boost::string_view representing this string.
+ */
+String::operator boost::string_view() const
+{
+	return boost::string_view(m_Data);
+}
+
 const char *String::CStr() const
 {
 	return m_Data.c_str();


=====================================
lib/base/string.hpp
=====================================
@@ -6,6 +6,7 @@
 #include "base/i2-base.hpp"
 #include "base/object.hpp"
 #include <boost/range/iterator.hpp>
+#include <boost/utility/string_view.hpp>
 #include <string>
 #include <iosfwd>
 
@@ -71,6 +72,7 @@ public:
 	bool operator<(const String& rhs) const;
 
 	operator const std::string&() const;
+	operator boost::string_view() const;
 
 	const char *CStr() const;
 


=====================================
lib/base/utility.cpp
=====================================
@@ -725,7 +725,11 @@ void Utility::CopyFile(const String& source, const String& target)
 {
 	namespace fs = boost::filesystem;
 
+#if BOOST_VERSION >= 107400
+	fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_options::overwrite_existing);
+#else /* BOOST_VERSION */
 	fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_option::overwrite_if_exists);
+#endif /* BOOST_VERSION */
 }
 
 /*
@@ -736,7 +740,59 @@ void Utility::RenameFile(const String& source, const String& target)
 {
 	namespace fs = boost::filesystem;
 
-	fs::rename(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()));
+	fs::path sourcePath(source.Begin(), source.End()), targetPath(target.Begin(), target.End());
+
+#ifndef _WIN32
+	fs::rename(sourcePath, targetPath);
+#else /* _WIN32 */
+	/*
+	 * Renaming files can be tricky on Windows, especially if your application is built around POSIX filesystem
+	 * semantics. For example, the quite common pattern of replacing a file by writing a new version to a temporary
+	 * location and then moving it to the final location can fail if the destination file already exists and any
+	 * process has an open file handle to it.
+	 *
+	 * We try to handle this situation as best as we can by retrying the rename operation a few times hoping the other
+	 * process closes its file handle in the meantime. This is similar to what for example Go does internally in some
+	 * situations (https://golang.org/pkg/cmd/go/internal/robustio/#Rename):
+	 *
+	 *    robustio.Rename is like os.Rename, but on Windows retries errors that may occur if the file is concurrently
+	 *    read or overwritten. (See https://golang.org/issue/31247 and https://golang.org/issue/32188)
+	 */
+
+	double sleep = 0.1;
+	int last_error = ERROR_SUCCESS;
+
+	for (int retries = 0, remaining = 15;; retries++, remaining--) {
+		try {
+			fs::rename(sourcePath, targetPath);
+
+			if (retries > 0) {
+				Log(LogWarning, "Utility") << "Renaming '" << source << "' to '" << target
+					<< "' succeeded after " << retries << " retries";
+			}
+
+			break;
+		} catch (const fs::filesystem_error& ex) {
+			int error = ex.code().value();
+			bool ephemeral = error == ERROR_ACCESS_DENIED ||
+				error == ERROR_FILE_NOT_FOUND ||
+				error == ERROR_SHARING_VIOLATION;
+
+			if (remaining <= 0 || !ephemeral) {
+				throw; // giving up
+			}
+
+			if (error != last_error) {
+				Log(LogWarning, "Utility") << "Renaming '" << source << "' to '" << target << "' failed: "
+					<< ex.code().message() << " (trying up to " << remaining << " more times)";
+				last_error = error;
+			}
+
+			Utility::Sleep(sleep);
+			sleep *= 1.3;
+		}
+	}
+#endif /* _WIN32 */
 }
 
 /*


=====================================
lib/cli/daemoncommand.cpp
=====================================
@@ -518,6 +518,9 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs, bool close
 				}
 
 				_exit(RunWorker(configs, closeConsoleLog, stderrFile));
+			} catch (const std::exception& ex) {
+				Log(LogCritical, "cli") << "Exception in main process: " << DiagnosticInformation(ex);
+				_exit(EXIT_FAILURE);
 			} catch (...) {
 				_exit(EXIT_FAILURE);
 			}
@@ -680,7 +683,14 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
 	}
 
 #ifdef _WIN32
-	return RunWorker(configs);
+	try {
+		return RunWorker(configs);
+	} catch (const std::exception& ex) {
+		Log(LogCritical, "cli")	<< "Exception in main process: " << DiagnosticInformation(ex);
+		return EXIT_FAILURE;
+	} catch (...) {
+		return EXIT_FAILURE;
+	}
 #else /* _WIN32 */
 	l_UmbrellaPid = getpid();
 	Application::SetUmbrellaProcess(l_UmbrellaPid);


=====================================
lib/db_ido/dbconnection.cpp
=====================================
@@ -150,12 +150,17 @@ void DbConnection::UpdateProgramStatus()
 	std::vector<DbQuery> queries;
 
 	DbQuery query1;
-	query1.Table = "programstatus";
-	query1.IdColumn = "programstatus_id";
-	query1.Type = DbQueryInsert | DbQueryDelete;
-	query1.Category = DbCatProgramStatus;
+	query1.Type = DbQueryNewTransaction;
+	query1.Priority = PriorityImmediate;
+	queries.emplace_back(std::move(query1));
 
-	query1.Fields = new Dictionary({
+	DbQuery query2;
+	query2.Table = "programstatus";
+	query2.IdColumn = "programstatus_id";
+	query2.Type = DbQueryInsert | DbQueryDelete;
+	query2.Category = DbCatProgramStatus;
+
+	query2.Fields = new Dictionary({
 		{ "instance_id", 0 }, /* DbConnection class fills in real ID */
 		{ "program_version", Application::GetAppVersion() },
 		{ "status_update_time", DbValue::FromTimestamp(Utility::GetTime()) },
@@ -175,27 +180,26 @@ void DbConnection::UpdateProgramStatus()
 		{ "process_performance_data", (icingaApplication->GetEnablePerfdata() ? 1 : 0) }
 	});
 
-	query1.WhereCriteria = new Dictionary({
+	query2.WhereCriteria = new Dictionary({
 		{ "instance_id", 0 }  /* DbConnection class fills in real ID */
 	});
 
-	query1.Priority = PriorityImmediate;
-	queries.emplace_back(std::move(query1));
-
-	DbQuery query2;
-	query2.Type = DbQueryNewTransaction;
 	queries.emplace_back(std::move(query2));
 
+	DbQuery query3;
+	query3.Type = DbQueryNewTransaction;
+	queries.emplace_back(std::move(query3));
+
 	DbObject::OnMultipleQueries(queries);
 
-	DbQuery query3;
-	query3.Table = "runtimevariables";
-	query3.Type = DbQueryDelete;
-	query3.Category = DbCatProgramStatus;
-	query3.WhereCriteria = new Dictionary({
+	DbQuery query4;
+	query4.Table = "runtimevariables";
+	query4.Type = DbQueryDelete;
+	query4.Category = DbCatProgramStatus;
+	query4.WhereCriteria = new Dictionary({
 		{ "instance_id", 0 } /* DbConnection class fills in real ID */
 	});
-	DbObject::OnQuery(query3);
+	DbObject::OnQuery(query4);
 
 	InsertRuntimeVariable("total_services", ConfigType::Get<Service>()->GetObjectCount());
 	InsertRuntimeVariable("total_scheduled_services", ConfigType::Get<Service>()->GetObjectCount());


=====================================
lib/db_ido_mysql/idomysqlconnection.cpp
=====================================
@@ -165,8 +165,7 @@ void IdoMysqlConnection::NewTransaction()
 		<< "Scheduling new transaction and finishing async queries.";
 #endif /* I2_DEBUG */
 
-	m_QueryQueue.Enqueue(std::bind(&IdoMysqlConnection::InternalNewTransaction, this), PriorityNormal);
-	m_QueryQueue.Enqueue(std::bind(&IdoMysqlConnection::FinishAsyncQueries, this), PriorityNormal);
+	m_QueryQueue.Enqueue(std::bind(&IdoMysqlConnection::InternalNewTransaction, this), PriorityHigh);
 }
 
 void IdoMysqlConnection::InternalNewTransaction()
@@ -180,6 +179,8 @@ void IdoMysqlConnection::InternalNewTransaction()
 
 	AsyncQuery("COMMIT");
 	AsyncQuery("BEGIN");
+
+	FinishAsyncQueries();
 }
 
 void IdoMysqlConnection::ReconnectTimerHandler()


=====================================
lib/icinga/apiactions.cpp
=====================================
@@ -370,10 +370,9 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
 		}
 	}
 
-	String downtimeName = Downtime::AddDowntime(checkable, author, comment, startTime, endTime,
+	Downtime::Ptr downtime = Downtime::AddDowntime(checkable, author, comment, startTime, endTime,
 		fixed, triggerName, duration);
-
-	Downtime::Ptr downtime = Downtime::GetByName(downtimeName);
+	String downtimeName = downtime->GetName();
 
 	Dictionary::Ptr additional = new Dictionary({
 		{ "name", downtimeName },
@@ -393,10 +392,9 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
 			Log(LogNotice, "ApiActions")
 				<< "Creating downtime for service " << hostService->GetName() << " on host " << host->GetName();
 
-			String serviceDowntimeName = Downtime::AddDowntime(hostService, author, comment, startTime, endTime,
+			Downtime::Ptr serviceDowntime = Downtime::AddDowntime(hostService, author, comment, startTime, endTime,
 				fixed, triggerName, duration);
-
-			Downtime::Ptr serviceDowntime = Downtime::GetByName(serviceDowntimeName);
+			String serviceDowntimeName = serviceDowntime->GetName();
 
 			serviceDowntimes.push_back(new Dictionary({
 				{ "name", serviceDowntimeName },
@@ -424,14 +422,13 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
 			Log(LogNotice, "ApiActions")
 				<< "Scheduling downtime for child object " << child->GetName();
 
-			String childDowntimeName = Downtime::AddDowntime(child, author, comment, startTime, endTime,
+			Downtime::Ptr childDowntime = Downtime::AddDowntime(child, author, comment, startTime, endTime,
 				fixed, triggerName, duration);
+			String childDowntimeName = childDowntime->GetName();
 
 			Log(LogNotice, "ApiActions")
 				<< "Add child downtime '" << childDowntimeName << "'.";
 
-			Downtime::Ptr childDowntime = Downtime::GetByName(childDowntimeName);
-
 			Dictionary::Ptr childAdditional = new Dictionary({
 				{ "name", childDowntimeName },
 				{ "legacy_id", childDowntime->GetLegacyId() }
@@ -449,10 +446,9 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
 					Log(LogNotice, "ApiActions")
 						<< "Creating downtime for service " << hostService->GetName() << " on child host " << host->GetName();
 
-					String serviceDowntimeName = Downtime::AddDowntime(hostService, author, comment, startTime, endTime,
+					Downtime::Ptr serviceDowntime = Downtime::AddDowntime(hostService, author, comment, startTime, endTime,
 						fixed, triggerName, duration);
-
-					Downtime::Ptr serviceDowntime = Downtime::GetByName(serviceDowntimeName);
+					String serviceDowntimeName = serviceDowntime->GetName();
 
 					childServiceDowntimes.push_back(new Dictionary({
 						{ "name", serviceDowntimeName },


=====================================
lib/icinga/clusterevents.cpp
=====================================
@@ -322,7 +322,7 @@ void ClusterEvents::SuppressedNotificationsChangedHandler(const Checkable::Ptr&
 	message->Set("method", "event::SetSuppressedNotifications");
 	message->Set("params", params);
 
-	listener->RelayMessage(origin, checkable, message, true);
+	listener->RelayMessage(origin, nullptr, message, true);
 }
 
 Value ClusterEvents::SuppressedNotificationsChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
@@ -350,7 +350,7 @@ Value ClusterEvents::SuppressedNotificationsChangedAPIHandler(const MessageOrigi
 	if (!checkable)
 		return Empty;
 
-	if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) {
+	if (origin->FromZone && origin->FromZone != Zone::GetLocalZone()) {
 		Log(LogNotice, "ClusterEvents")
 			<< "Discarding 'suppressed notifications changed' message for checkable '" << checkable->GetName()
 			<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
@@ -378,7 +378,7 @@ void ClusterEvents::SuppressedNotificationTypesChangedHandler(const Notification
 	message->Set("method", "event::SetSuppressedNotificationTypes");
 	message->Set("params", params);
 
-	listener->RelayMessage(origin, notification, message, true);
+	listener->RelayMessage(origin, nullptr, message, true);
 }
 
 Value ClusterEvents::SuppressedNotificationTypesChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
@@ -396,7 +396,7 @@ Value ClusterEvents::SuppressedNotificationTypesChangedAPIHandler(const MessageO
 	if (!notification)
 		return Empty;
 
-	if (origin->FromZone && !origin->FromZone->CanAccessObject(notification)) {
+	if (origin->FromZone && origin->FromZone != Zone::GetLocalZone()) {
 		Log(LogNotice, "ClusterEvents")
 			<< "Discarding 'suppressed notification types changed' message for notification '" << notification->GetName()
 			<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";


=====================================
lib/icinga/downtime.cpp
=====================================
@@ -75,12 +75,10 @@ void Downtime::OnAllConfigLoaded()
 {
 	ObjectImpl<Downtime>::OnAllConfigLoaded();
 
-	Host::Ptr host = Host::GetByName(GetHostName());
-
 	if (GetServiceName().IsEmpty())
-		m_Checkable = host;
+		m_Checkable = Host::GetByName(GetHostName());
 	else
-		m_Checkable = host->GetServiceByShortName(GetServiceName());
+		m_Checkable = Service::GetByNamePair(GetHostName(), GetServiceName());
 
 	if (!m_Checkable)
 		BOOST_THROW_EXCEPTION(ScriptError("Downtime '" + GetName() + "' references a host/service which doesn't exist.", GetDebugInfo()));
@@ -208,7 +206,7 @@ int Downtime::GetNextDowntimeID()
 	return l_NextDowntimeID;
 }
 
-String Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& author,
+Downtime::Ptr Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& author,
 	const String& comment, double startTime, double endTime, bool fixed,
 	const String& triggeredBy, double duration,
 	const String& scheduledDowntime, const String& scheduledBy,
@@ -304,7 +302,7 @@ String Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& auth
 		<< "' and '" << Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", endTime) << "', author: '"
 		<< author << "', " << (fixed ? "fixed" : "flexible with " + Convert::ToString(duration) + "s duration");
 
-	return fullName;
+	return downtime;
 }
 
 void Downtime::RemoveDowntime(const String& id, bool cancelled, bool expired, const MessageOrigin::Ptr& origin)


=====================================
lib/icinga/downtime.hpp
=====================================
@@ -45,7 +45,7 @@ public:
 
 	static int GetNextDowntimeID();
 
-	static String AddDowntime(const intrusive_ptr<Checkable>& checkable, const String& author,
+	static Ptr AddDowntime(const intrusive_ptr<Checkable>& checkable, const String& author,
 		const String& comment, double startTime, double endTime, bool fixed,
 		const String& triggeredBy, double duration, const String& scheduledDowntime = String(),
 		const String& scheduledBy = String(), const String& id = String(),


=====================================
lib/icinga/externalcommandprocessor.cpp
=====================================
@@ -1049,7 +1049,7 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double,
 	Log(LogNotice, "ExternalCommandProcessor")
 		<< "Creating downtime for host " << host->GetName();
 
-	String parentDowntime = Downtime::AddDowntime(host, arguments[6], arguments[7],
+	Downtime::Ptr parentDowntime = Downtime::AddDowntime(host, arguments[6], arguments[7],
 		Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
 		Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
 
@@ -1065,7 +1065,7 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double,
 
 		(void) Downtime::AddDowntime(child, arguments[6], arguments[7],
 			Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
-			Convert::ToBool(is_fixed), parentDowntime, Convert::ToDouble(arguments[5]));
+			Convert::ToBool(is_fixed), parentDowntime->GetName(), Convert::ToDouble(arguments[5]));
 	}
 }
 


=====================================
lib/icinga/notification.cpp
=====================================
@@ -431,7 +431,11 @@ void Notification::BeginExecuteNotification(NotificationType type, const CheckRe
 			<< "Sending " << (reminder ? "reminder " : "") << "'" << NotificationTypeToString(type) << "' notification '"
 			<< notificationName << "' for user '" << userName << "'";
 
-		Utility::QueueAsyncCallback(std::bind(&Notification::ExecuteNotificationHelper, this, type, user, cr, force, author, text));
+		// Explicitly use Notification::Ptr to keep the reference counted while the callback is active
+		Notification::Ptr notification (this);
+		Utility::QueueAsyncCallback([notification, type, user, cr, force, author, text]() {
+			notification->ExecuteNotificationHelper(type, user, cr, force, author, text);
+		});
 
 		/* collect all notified users */
 		allNotifiedUsers.insert(user);


=====================================
lib/icinga/scheduleddowntime.cpp
=====================================
@@ -253,11 +253,10 @@ void ScheduledDowntime::CreateNextDowntime()
 			return;
 	}
 
-	String downtimeName = Downtime::AddDowntime(GetCheckable(), GetAuthor(), GetComment(),
+	Downtime::Ptr downtime = Downtime::AddDowntime(GetCheckable(), GetAuthor(), GetComment(),
 		segment.first, segment.second,
 		GetFixed(), String(), GetDuration(), GetName(), GetName());
-
-	Downtime::Ptr downtime = Downtime::GetByName(downtimeName);
+	String downtimeName = downtime->GetName();
 
 	int childOptions = Downtime::ChildOptionsFromValue(GetChildOptions());
 	if (childOptions > 0) {
@@ -275,11 +274,11 @@ void ScheduledDowntime::CreateNextDowntime()
 			Log(LogNotice, "ScheduledDowntime")
 				<< "Scheduling downtime for child object " << child->GetName();
 
-			String childDowntimeName = Downtime::AddDowntime(child, GetAuthor(), GetComment(),
+			Downtime::Ptr childDowntime = Downtime::AddDowntime(child, GetAuthor(), GetComment(),
 				segment.first, segment.second, GetFixed(), triggerName, GetDuration(), GetName(), GetName());
 
 			Log(LogNotice, "ScheduledDowntime")
-				<< "Add child downtime '" << childDowntimeName << "'.";
+				<< "Add child downtime '" << childDowntime->GetName() << "'.";
 		}
 	}
 }


=====================================
lib/notification/notificationcomponent.cpp
=====================================
@@ -233,7 +233,7 @@ void NotificationComponent::NotificationTimerHandler()
 				continue;
 
 			/* Don't send reminder notifications before initial ones. */
-			if (checkable->GetSuppressedNotifications() & NotificationProblem)
+			if (checkable->GetSuppressedNotifications() & NotificationProblem || notification->GetSuppressedNotifications() & NotificationProblem)
 				continue;
 
 			/* Skip in runtime filters. */


=====================================
lib/perfdata/elasticsearchwriter.cpp
=====================================
@@ -494,7 +494,7 @@ void ElasticsearchWriter::SendRequest(const String& body)
 		request.set(http::field::authorization, "Basic " + Base64::Encode(username + ":" + password));
 
 	request.body() = body;
-	request.set(http::field::content_length, request.body().size());
+	request.content_length(request.body().size());
 
 	/* Don't log the request body to debug log, this is already done above. */
 	Log(LogDebug, "ElasticsearchWriter")


=====================================
lib/perfdata/influxdbwriter.cpp
=====================================
@@ -505,7 +505,7 @@ void InfluxdbWriter::Flush()
 	request.set(http::field::host, url->GetHost() + ":" + url->GetPort());
 
 	request.body() = body;
-	request.set(http::field::content_length, request.body().size());
+	request.content_length(request.body().size());
 
 	try {
 		if (stream.first) {


=====================================
lib/remote/configfileshandler.cpp
=====================================
@@ -84,7 +84,7 @@ bool ConfigFilesHandler::HandleRequest(
 		response.result(http::status::ok);
 		response.set(http::field::content_type, "application/octet-stream");
 		response.body() = content;
-		response.set(http::field::content_length, response.body().size());
+		response.content_length(response.body().size());
 	} catch (const std::exception& ex) {
 		HttpUtility::SendJsonError(response, params, 500, "Could not read file.",
 			DiagnosticInformation(ex));


=====================================
lib/remote/configobjectutility.cpp
=====================================
@@ -152,11 +152,13 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
 {
 	CreateStorage();
 
-	ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, fullName);
+	{
+		auto configType (dynamic_cast<ConfigType*>(type.get()));
 
-	if (item) {
-		errors->Add("Object '" + fullName + "' already exists.");
-		return false;
+		if (configType && configType->GetObject(fullName)) {
+			errors->Add("Object '" + fullName + "' already exists.");
+			return false;
+		}
 	}
 
 	String path;


=====================================
lib/remote/httpserverconnection.cpp
=====================================
@@ -186,7 +186,7 @@ bool EnsureValidHeaders(
 		} else {
 			response.set(http::field::content_type, "text/html");
 			response.body() = String("<h1>Bad Request</h1><p><pre>") + errorMsg + "</pre></p>";
-			response.set(http::field::content_length, response.body().size());
+			response.content_length(response.body().size());
 		}
 
 		response.set(http::field::connection, "close");
@@ -259,7 +259,7 @@ bool HandleAccessControl(
 					response.set(http::field::access_control_allow_methods, "GET, POST, PUT, DELETE");
 					response.set(http::field::access_control_allow_headers, "Authorization, X-HTTP-Method-Override");
 					response.body() = "Preflight OK";
-					response.set(http::field::content_length, response.body().size());
+					response.content_length(response.body().size());
 					response.set(http::field::connection, "close");
 
 					boost::system::error_code ec;
@@ -290,7 +290,7 @@ bool EnsureAcceptHeader(
 		response.result(http::status::bad_request);
 		response.set(http::field::content_type, "text/html");
 		response.body() = "<h1>Accept header is missing or not set to 'application/json'.</h1>";
-		response.set(http::field::content_length, response.body().size());
+		response.content_length(response.body().size());
 		response.set(http::field::connection, "close");
 
 		boost::system::error_code ec;
@@ -331,7 +331,7 @@ bool EnsureAuthenticatedUser(
 		} else {
 			response.set(http::field::content_type, "text/html");
 			response.body() = "<h1>Unauthorized. Please check your user credentials.</h1>";
-			response.set(http::field::content_length, response.body().size());
+			response.content_length(response.body().size());
 		}
 
 		boost::system::error_code ec;
@@ -423,7 +423,7 @@ bool EnsureValidBody(
 		} else {
 			response.set(http::field::content_type, "text/html");
 			response.body() = String("<h1>Bad Request</h1><p><pre>") + ec.message() + "</pre></p>";
-			response.set(http::field::content_length, response.body().size());
+			response.content_length(response.body().size());
 		}
 
 		response.set(http::field::connection, "close");


=====================================
lib/remote/httputility.cpp
=====================================
@@ -58,7 +58,7 @@ void HttpUtility::SendJsonBody(boost::beast::http::response<boost::beast::http::
 
 	response.set(http::field::content_type, "application/json");
 	response.body() = JsonEncode(val, params && GetLastParameter(params, "pretty"));
-	response.set(http::field::content_length, response.body().size());
+	response.content_length(response.body().size());
 }
 
 void HttpUtility::SendJsonError(boost::beast::http::response<boost::beast::http::string_body>& response,


=====================================
lib/remote/infohandler.cpp
=====================================
@@ -92,7 +92,7 @@ bool InfoHandler::HandleRequest(
 
 		body += R"(<p>More information about API requests is available in the <a href="https://icinga.com/docs/icinga2/latest/" target="_blank">documentation</a>.</p></html>)";
 		response.body() = body;
-		response.set(http::field::content_length, response.body().size());
+		response.content_length(response.body().size());
 	}
 
 	return true;



View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icinga2/-/commit/7f1d1d732ec2f1d91786402f7c0b8b7c853922bb

-- 
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icinga2/-/commit/7f1d1d732ec2f1d91786402f7c0b8b7c853922bb
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/20210527/bbb09bfc/attachment-0001.htm>


More information about the pkg-nagios-changes mailing list