]> granicus.if.org Git - icinga2/commitdiff
API: Add optional reload parameter to config stage upload 5547/head
authorryanohnemus <ryan.ohnemus@tradingtechnologies.com>
Sun, 3 Sep 2017 14:15:40 +0000 (09:15 -0500)
committerMichael Friedrich <michael.friedrich@icinga.com>
Wed, 20 Sep 2017 12:16:55 +0000 (14:16 +0200)
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

doc/12-icinga2-api.md
lib/remote/configpackageutility.cpp
lib/remote/configpackageutility.hpp
lib/remote/configstageshandler.cpp

index 89ec60e7e99ab8bd8d1246a767230afc06e4575d..7133ba4f637e7f73a3722a9ed5cf2a85d997f6b3 100644 (file)
@@ -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
 configuration package to the URL path (e.g. `example-cmdb`).
 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:
 
@@ -1412,7 +1413,7 @@ intentional.
                 "code": 200.0,
                 "package": "example-cmdb",
                 "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
 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.
-If the validation for the new config stage failed, the old stage and its configuration objects
-will remain active.
+Icinga 2 automatically restarts the daemon in order to activate the new config stage. This
+can be disabled by setting `reload` to `false` in the request.
+If the validation for the new config stage failed, the old stage
+and its configuration objects will remain active.
 
 > **Note**
 >
index 9c0d1bbf300e256c189e976682f3bb21d62f8787..024b01a2c76aba183a472647468d469619b4a5cb 100644 (file)
@@ -176,7 +176,7 @@ void ConfigPackageUtility::ActivateStage(const String& packageName, const String
        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";
        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 */
        if (pr.ExitStatus == 0) {
                ActivateStage(packageName, stageName);
-               Application::RequestRestart();
+
+               if (reload)
+                       Application::RequestRestart();
        } else {
                Log(LogCritical, "ConfigPackageUtility")
                    << "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);
 
@@ -213,7 +215,7 @@ void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, cons
 
        Process::Ptr process = new Process(Process::PrepareCommand(args));
        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)
index f6f8c4cb200aa49c22f4830bc367e63b748d3de0..80813879de832f9c2f3221b065c00c15000b1b47 100644 (file)
@@ -51,7 +51,7 @@ public:
        static std::vector<String> GetStages(const String& packageName);
        static String GetActiveStage(const String& packageName);
        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);
 
@@ -65,7 +65,7 @@ private:
        static void WritePackageConfig(const String& packageName);
        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);
 };
 
 }
index ee2fc23741a58e6db6c0417ced0d79bdc3c4eb15..fa1e3309fc575991c66af3701bf3a5d65eabdc46 100644 (file)
@@ -98,6 +98,10 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
        if (!ConfigPackageUtility::ValidateName(packageName))
                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");
 
        String stageName;
@@ -109,7 +113,7 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
                stageName = ConfigPackageUtility::CreateStage(packageName, files);
 
                /* validate the config. on success, activate stage and reload */
-               ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName);
+               ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName, reload);
        } catch (const std::exception& ex) {
                return HttpUtility::SendJsonError(response, 500,
                                "Stage creation failed.",
@@ -118,10 +122,13 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
 
        Dictionary::Ptr result1 = new Dictionary();
 
+       String responseStatus = "Created stage. ";
+       responseStatus += (reload ? " Icinga2 will reload." : " Icinga2 reload skipped.");
+
        result1->Set("package", packageName);
        result1->Set("stage", stageName);
        result1->Set("code", 200);
-       result1->Set("status", "Created stage.");
+       result1->Set("status", responseStatus);
 
        Array::Ptr results = new Array();
        results->Add(result1);