Skip to content

Commit 34ce649

Browse files
Track deleted runtime objects to avaóid erroneous recreation
1 parent cf699b2 commit 34ce649

4 files changed

Lines changed: 38 additions & 2 deletions

File tree

lib/icinga/icingaapplication.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
#include "base/scriptglobal.hpp"
2020
#include "base/initialize.hpp"
2121
#include "base/statsfunction.hpp"
22-
#include "base/loader.hpp"
23-
#include <fstream>
22+
#include "remote/apilistener.hpp"
2423

2524
using namespace icinga;
2625

@@ -162,6 +161,7 @@ static void PersistModAttrHelper(AtomicFile& fp, ConfigObject::Ptr& previousObje
162161

163162
void IcingaApplication::DumpProgramState()
164163
{
164+
ApiListener::GetInstance()->PruneDeletedRuntimeObjects();
165165
ConfigObject::DumpObjects(Configuration::StatePath);
166166
DumpModifiedAttributes();
167167
}

lib/remote/apilistener-configsync.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
9898
/* update the object */
9999
double objVersion = params->Get("version");
100100

101+
auto deletedRuntimeObjects = listener->GetDeletedRuntimeObjects();
102+
Dictionary::Ptr deletedInfo = deletedRuntimeObjects->Get(objName);
103+
104+
if (deletedInfo && deletedInfo->Get("version") >= objVersion) {
105+
Log(LogWarning, "ApiListener")
106+
<< "Ignoring config update for deleted object '" << objName << "' of type '" << objType << "' from '"
107+
<< identity << "' (endpoint: '" << endpoint->GetName() << "', zone: '" << endpointZone->GetName() << "')";
108+
return Empty;
109+
}
110+
101111
Type::Ptr ptype = Type::GetByName(objType);
102112
auto *ctype = dynamic_cast<ConfigType *>(ptype.get());
103113

@@ -437,6 +447,12 @@ void ApiListener::DeleteConfigObject(const ConfigObject::Ptr& object, const Mess
437447
if (object->GetPackage() != "_api")
438448
return;
439449

450+
Dictionary::Ptr deletionInfo = new Dictionary{
451+
{"version", object->GetVersion()},
452+
{"deleted", Utility::GetTime()},
453+
};
454+
GetDeletedRuntimeObjects()->Set(object->GetName(), deletionInfo);
455+
440456
/* only send objects to zones which have access to the object */
441457
if (client) {
442458
Zone::Ptr target_zone = client->GetEndpoint()->GetZone();
@@ -508,3 +524,17 @@ void ApiListener::SendRuntimeConfigObjects(const JsonRpcConnection::Ptr& aclient
508524
Log(LogInformation, "ApiListener")
509525
<< "Finished syncing runtime objects to endpoint '" << endpoint->GetName() << "'.";
510526
}
527+
528+
void ApiListener::PruneDeletedRuntimeObjects()
529+
{
530+
auto deletedRuntimeObjects = GetDeletedRuntimeObjects();
531+
double cutoff = Utility::GetTime() - GetLocalEndpoint()->GetLogDuration();
532+
ObjectLock lock(deletedRuntimeObjects);
533+
534+
for (auto it = deletedRuntimeObjects->Begin(); it != deletedRuntimeObjects->End(); ++it) {
535+
Dictionary::Ptr deletedInfo = it->second;
536+
if (deletedInfo->Get("deleted") < cutoff) {
537+
deletedRuntimeObjects->Remove(it);
538+
};
539+
}
540+
}

lib/remote/apilistener.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ class ApiListener final : public ObjectImpl<ApiListener>
142142

143143
static void UpdateObjectAuthority();
144144

145+
void PruneDeletedRuntimeObjects();
146+
145147
static bool IsHACluster();
146148
static String GetFromZoneName(const Zone::Ptr& fromZone);
147149

lib/remote/apilistener.ti

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class ApiListener : ConfigObject
6363
[no_user_modify] String identity;
6464

6565
[state, no_user_modify] Dictionary::Ptr last_failed_zones_stage_validation;
66+
67+
[state, no_user_modify] Dictionary::Ptr deleted_runtime_objects {
68+
default {{{ return new Dictionary(); }}}
69+
};
6670
};
6771

6872
}

0 commit comments

Comments
 (0)