mirror of https://github.com/Icinga/icinga2.git
API: Add optional reload parameter to config stage upload
You can now specify a boolean `reload` attribute that will allow you to skip the icinga2 reload after config validation. By default this is set to true. The response text has been updated to show if icinga2 will reload or if it was requested to be skipped. fixes #4769
This commit is contained in:
parent
65390298be
commit
1cb39994a5
|
@ -1381,7 +1381,8 @@ Stages provide a way to maintain multiple configuration versions for a package.
|
||||||
Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
|
Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
|
||||||
configuration package to the URL path (e.g. `example-cmdb`).
|
configuration package to the URL path (e.g. `example-cmdb`).
|
||||||
The request body must contain the `files` attribute with the value being
|
The request body must contain the `files` attribute with the value being
|
||||||
a dictionary of file targets and their content.
|
a dictionary of file targets and their content. You can also specify an optional `reload` attribute
|
||||||
|
that will tell icinga2 to reload after stage config validation. By default this is set to `true`.
|
||||||
|
|
||||||
The file path requires one of these two directories inside its path:
|
The file path requires one of these two directories inside its path:
|
||||||
|
|
||||||
|
@ -1412,7 +1413,7 @@ intentional.
|
||||||
"code": 200.0,
|
"code": 200.0,
|
||||||
"package": "example-cmdb",
|
"package": "example-cmdb",
|
||||||
"stage": "example.localdomain-1441625839-0",
|
"stage": "example.localdomain-1441625839-0",
|
||||||
"status": "Created stage."
|
"status": "Created stage. Icinga2 will reload."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1420,9 +1421,10 @@ intentional.
|
||||||
The Icinga 2 API returns the `package` name this stage was created for, and also
|
The Icinga 2 API returns the `package` name this stage was created for, and also
|
||||||
generates a unique name for the `stage` attribute you'll need for later requests.
|
generates a unique name for the `stage` attribute you'll need for later requests.
|
||||||
|
|
||||||
Icinga 2 automatically restarts the daemon in order to activate the new config stage.
|
Icinga 2 automatically restarts the daemon in order to activate the new config stage. This
|
||||||
If the validation for the new config stage failed, the old stage and its configuration objects
|
can be disabled by setting `reload` to `false` in the request.
|
||||||
will remain active.
|
If the validation for the new config stage failed, the old stage
|
||||||
|
and its configuration objects will remain active.
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
>
|
>
|
||||||
|
|
|
@ -176,7 +176,7 @@ void ConfigPackageUtility::ActivateStage(const String& packageName, const String
|
||||||
WritePackageConfig(packageName);
|
WritePackageConfig(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName)
|
void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName, bool reload)
|
||||||
{
|
{
|
||||||
String logFile = GetPackageDir() + "/" + packageName + "/" + stageName + "/startup.log";
|
String logFile = GetPackageDir() + "/" + packageName + "/" + stageName + "/startup.log";
|
||||||
std::ofstream fpLog(logFile.CStr(), std::ofstream::out | std::ostream::binary | std::ostream::trunc);
|
std::ofstream fpLog(logFile.CStr(), std::ofstream::out | std::ostream::binary | std::ostream::trunc);
|
||||||
|
@ -191,7 +191,9 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con
|
||||||
/* validation went fine, activate stage and reload */
|
/* validation went fine, activate stage and reload */
|
||||||
if (pr.ExitStatus == 0) {
|
if (pr.ExitStatus == 0) {
|
||||||
ActivateStage(packageName, stageName);
|
ActivateStage(packageName, stageName);
|
||||||
Application::RequestRestart();
|
|
||||||
|
if (reload)
|
||||||
|
Application::RequestRestart();
|
||||||
} else {
|
} else {
|
||||||
Log(LogCritical, "ConfigPackageUtility")
|
Log(LogCritical, "ConfigPackageUtility")
|
||||||
<< "Config validation failed for package '"
|
<< "Config validation failed for package '"
|
||||||
|
@ -199,7 +201,7 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, const String& stageName)
|
void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, const String& stageName, bool reload)
|
||||||
{
|
{
|
||||||
VERIFY(Application::GetArgC() >= 1);
|
VERIFY(Application::GetArgC() >= 1);
|
||||||
|
|
||||||
|
@ -213,7 +215,7 @@ void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, cons
|
||||||
|
|
||||||
Process::Ptr process = new Process(Process::PrepareCommand(args));
|
Process::Ptr process = new Process(Process::PrepareCommand(args));
|
||||||
process->SetTimeout(300);
|
process->SetTimeout(300);
|
||||||
process->Run(boost::bind(&TryActivateStageCallback, _1, packageName, stageName));
|
process->Run(boost::bind(&TryActivateStageCallback, _1, packageName, stageName, reload));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigPackageUtility::DeleteStage(const String& packageName, const String& stageName)
|
void ConfigPackageUtility::DeleteStage(const String& packageName, const String& stageName)
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
static std::vector<String> GetStages(const String& packageName);
|
static std::vector<String> GetStages(const String& packageName);
|
||||||
static String GetActiveStage(const String& packageName);
|
static String GetActiveStage(const String& packageName);
|
||||||
static void ActivateStage(const String& packageName, const String& stageName);
|
static void ActivateStage(const String& packageName, const String& stageName);
|
||||||
static void AsyncTryActivateStage(const String& packageName, const String& stageName);
|
static void AsyncTryActivateStage(const String& packageName, const String& stageName, bool reload);
|
||||||
|
|
||||||
static std::vector<std::pair<String, bool> > GetFiles(const String& packageName, const String& stageName);
|
static std::vector<std::pair<String, bool> > GetFiles(const String& packageName, const String& stageName);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ private:
|
||||||
static void WritePackageConfig(const String& packageName);
|
static void WritePackageConfig(const String& packageName);
|
||||||
static void WriteStageConfig(const String& packageName, const String& stageName);
|
static void WriteStageConfig(const String& packageName, const String& stageName);
|
||||||
|
|
||||||
static void TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName);
|
static void TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName, bool reload);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,10 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
|
||||||
if (!ConfigPackageUtility::ValidateName(packageName))
|
if (!ConfigPackageUtility::ValidateName(packageName))
|
||||||
return HttpUtility::SendJsonError(response, 400, "Invalid package name.");
|
return HttpUtility::SendJsonError(response, 400, "Invalid package name.");
|
||||||
|
|
||||||
|
bool reload = true;
|
||||||
|
if (params->Contains("reload"))
|
||||||
|
reload = HttpUtility::GetLastParameter(params, "reload");
|
||||||
|
|
||||||
Dictionary::Ptr files = params->Get("files");
|
Dictionary::Ptr files = params->Get("files");
|
||||||
|
|
||||||
String stageName;
|
String stageName;
|
||||||
|
@ -109,7 +113,7 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
|
||||||
stageName = ConfigPackageUtility::CreateStage(packageName, files);
|
stageName = ConfigPackageUtility::CreateStage(packageName, files);
|
||||||
|
|
||||||
/* validate the config. on success, activate stage and reload */
|
/* validate the config. on success, activate stage and reload */
|
||||||
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName);
|
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName, reload);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
return HttpUtility::SendJsonError(response, 500,
|
return HttpUtility::SendJsonError(response, 500,
|
||||||
"Stage creation failed.",
|
"Stage creation failed.",
|
||||||
|
@ -118,10 +122,13 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
|
||||||
|
|
||||||
Dictionary::Ptr result1 = new Dictionary();
|
Dictionary::Ptr result1 = new Dictionary();
|
||||||
|
|
||||||
|
String responseStatus = "Created stage. ";
|
||||||
|
responseStatus += (reload ? " Icinga2 will reload." : " Icinga2 reload skipped.");
|
||||||
|
|
||||||
result1->Set("package", packageName);
|
result1->Set("package", packageName);
|
||||||
result1->Set("stage", stageName);
|
result1->Set("stage", stageName);
|
||||||
result1->Set("code", 200);
|
result1->Set("code", 200);
|
||||||
result1->Set("status", "Created stage.");
|
result1->Set("status", responseStatus);
|
||||||
|
|
||||||
Array::Ptr results = new Array();
|
Array::Ptr results = new Array();
|
||||||
results->Add(result1);
|
results->Add(result1);
|
||||||
|
|
Loading…
Reference in New Issue