mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-10-31 19:24:25 +01:00 
			
		
		
		
	Merge pull request #8310 from Icinga/feature/scheduleddowntime-change-remove-downtimes-8309
On ScheduledDowntime change: remove downtimes created before change
This commit is contained in:
		
						commit
						7d2a1bbffe
					
				| @ -246,6 +246,12 @@ Downtime::Ptr Downtime::AddDowntime(const Checkable::Ptr& checkable, const Strin | |||||||
| 		if (localZone) { | 		if (localZone) { | ||||||
| 			attrs->Set("authoritative_zone", localZone->GetName()); | 			attrs->Set("authoritative_zone", localZone->GetName()); | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		auto sd (ScheduledDowntime::GetByName(scheduledDowntime)); | ||||||
|  | 
 | ||||||
|  | 		if (sd) { | ||||||
|  | 			attrs->Set("config_owner_hash", sd->HashDowntimeOptions()); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Host::Ptr host; | 	Host::Ptr host; | ||||||
|  | |||||||
| @ -69,6 +69,7 @@ class Downtime : ConfigObject < DowntimeNameComposer | |||||||
| 	[state] int legacy_id; | 	[state] int legacy_id; | ||||||
| 	[state] bool was_cancelled; | 	[state] bool was_cancelled; | ||||||
| 	[config] String config_owner; | 	[config] String config_owner; | ||||||
|  | 	[config] String config_owner_hash; | ||||||
| 	[config] String authoritative_zone; | 	[config] String authoritative_zone; | ||||||
| 
 | 
 | ||||||
| 	[no_user_view, no_user_modify] String removed_by; | 	[no_user_view, no_user_modify] String removed_by; | ||||||
|  | |||||||
| @ -6,13 +6,17 @@ | |||||||
| #include "icinga/downtime.hpp" | #include "icinga/downtime.hpp" | ||||||
| #include "icinga/service.hpp" | #include "icinga/service.hpp" | ||||||
| #include "base/timer.hpp" | #include "base/timer.hpp" | ||||||
|  | #include "base/tlsutility.hpp" | ||||||
| #include "base/configtype.hpp" | #include "base/configtype.hpp" | ||||||
| #include "base/utility.hpp" | #include "base/utility.hpp" | ||||||
| #include "base/objectlock.hpp" | #include "base/objectlock.hpp" | ||||||
|  | #include "base/object-packer.hpp" | ||||||
|  | #include "base/serializer.hpp" | ||||||
| #include "base/convert.hpp" | #include "base/convert.hpp" | ||||||
| #include "base/logger.hpp" | #include "base/logger.hpp" | ||||||
| #include "base/exception.hpp" | #include "base/exception.hpp" | ||||||
| #include <boost/thread/once.hpp> | #include <boost/thread/once.hpp> | ||||||
|  | #include <set> | ||||||
| 
 | 
 | ||||||
| using namespace icinga; | using namespace icinga; | ||||||
| 
 | 
 | ||||||
| @ -94,6 +98,15 @@ void ScheduledDowntime::TimerProc() | |||||||
| 				Log(LogCritical, "ScheduledDowntime") | 				Log(LogCritical, "ScheduledDowntime") | ||||||
| 					<< "Exception occurred during creation of next downtime for scheduled downtime '" | 					<< "Exception occurred during creation of next downtime for scheduled downtime '" | ||||||
| 					<< sd->GetName() << "': " << DiagnosticInformation(ex, false); | 					<< sd->GetName() << "': " << DiagnosticInformation(ex, false); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			try { | ||||||
|  | 				sd->RemoveObsoleteDowntimes(); | ||||||
|  | 			} catch (const std::exception& ex) { | ||||||
|  | 				Log(LogCritical, "ScheduledDowntime") | ||||||
|  | 					<< "Exception occurred during removal of obsolete downtime for scheduled downtime '" | ||||||
|  | 					<< sd->GetName() << "': " << DiagnosticInformation(ex, false); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -236,11 +249,16 @@ void ScheduledDowntime::CreateNextDowntime() | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	double minEnd = 0; | 	double minEnd = 0; | ||||||
|  | 	auto downtimeOptionsHash (HashDowntimeOptions()); | ||||||
| 
 | 
 | ||||||
| 	for (const Downtime::Ptr& downtime : GetCheckable()->GetDowntimes()) { | 	for (const Downtime::Ptr& downtime : GetCheckable()->GetDowntimes()) { | ||||||
| 		if (downtime->GetScheduledBy() != GetName()) | 		if (downtime->GetScheduledBy() != GetName()) | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
|  | 		auto configOwnerHash (downtime->GetConfigOwnerHash()); | ||||||
|  | 		if (!configOwnerHash.IsEmpty() && configOwnerHash != downtimeOptionsHash) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
| 		double end = downtime->GetEndTime(); | 		double end = downtime->GetEndTime(); | ||||||
| 		if (end > minEnd) | 		if (end > minEnd) | ||||||
| 			minEnd = end; | 			minEnd = end; | ||||||
| @ -292,6 +310,24 @@ void ScheduledDowntime::CreateNextDowntime() | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ScheduledDowntime::RemoveObsoleteDowntimes() | ||||||
|  | { | ||||||
|  | 	auto name (GetName()); | ||||||
|  | 	auto downtimeOptionsHash (HashDowntimeOptions()); | ||||||
|  | 
 | ||||||
|  | 	// Just to be sure start and removal don't happen at the same time
 | ||||||
|  | 	auto threshold (Utility::GetTime() + 5 * 60); | ||||||
|  | 
 | ||||||
|  | 	for (const Downtime::Ptr& downtime : GetCheckable()->GetDowntimes()) { | ||||||
|  | 		if (downtime->GetScheduledBy() == name && downtime->GetStartTime() > threshold) { | ||||||
|  | 			auto configOwnerHash (downtime->GetConfigOwnerHash()); | ||||||
|  | 
 | ||||||
|  | 			if (!configOwnerHash.IsEmpty() && configOwnerHash != downtimeOptionsHash) | ||||||
|  | 				Downtime::RemoveDowntime(downtime->GetName(), false, true); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ScheduledDowntime::ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) | void ScheduledDowntime::ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) | ||||||
| { | { | ||||||
| 	ObjectImpl<ScheduledDowntime>::ValidateRanges(lvalue, utils); | 	ObjectImpl<ScheduledDowntime>::ValidateRanges(lvalue, utils); | ||||||
| @ -333,6 +369,22 @@ void ScheduledDowntime::ValidateChildOptions(const Lazy<Value>& lvalue, const Va | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static const std::set<String> l_SDDowntimeOptions ({ | ||||||
|  | 	"author", "child_options", "comment", "duration", "fixed", "ranges", "vars" | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | String ScheduledDowntime::HashDowntimeOptions() | ||||||
|  | { | ||||||
|  | 	Dictionary::Ptr allOpts = Serialize(this, FAConfig); | ||||||
|  | 	Dictionary::Ptr opts = new Dictionary(); | ||||||
|  | 
 | ||||||
|  | 	for (auto& opt : l_SDDowntimeOptions) { | ||||||
|  | 		opts->Set(opt, allOpts->Get(opt)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return SHA256(PackObject(opts)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool ScheduledDowntime::AllConfigIsLoaded() | bool ScheduledDowntime::AllConfigIsLoaded() | ||||||
| { | { | ||||||
| 	return m_AllConfigLoaded.load(); | 	return m_AllConfigLoaded.load(); | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ public: | |||||||
| 
 | 
 | ||||||
| 	void ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override; | 	void ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override; | ||||||
| 	void ValidateChildOptions(const Lazy<Value>& lvalue, const ValidationUtils& utils) override; | 	void ValidateChildOptions(const Lazy<Value>& lvalue, const ValidationUtils& utils) override; | ||||||
|  | 	String HashDowntimeOptions(); | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	void OnAllConfigLoaded() override; | 	void OnAllConfigLoaded() override; | ||||||
| @ -46,6 +47,7 @@ private: | |||||||
| 	std::pair<double, double> FindRunningSegment(double minEnd = 0); | 	std::pair<double, double> FindRunningSegment(double minEnd = 0); | ||||||
| 	std::pair<double, double> FindNextSegment(); | 	std::pair<double, double> FindNextSegment(); | ||||||
| 	void CreateNextDowntime(); | 	void CreateNextDowntime(); | ||||||
|  | 	void RemoveObsoleteDowntimes(); | ||||||
| 
 | 
 | ||||||
| 	static std::atomic<bool> m_AllConfigLoaded; | 	static std::atomic<bool> m_AllConfigLoaded; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user