mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-24 22:24:44 +02:00
Merge pull request #6511 from Icinga/feature/apilistener-dynamic-port
ApiListener: Add support for dynamic port handling
This commit is contained in:
commit
3cc8bd2fcc
@ -37,6 +37,12 @@ has been removed and this setting has no effect.
|
|||||||
>
|
>
|
||||||
> This is important if you rely on the sysconfig configuration in your own scripts.
|
> This is important if you rely on the sysconfig configuration in your own scripts.
|
||||||
|
|
||||||
|
### New Constants <a id="upgrading-to-2-10-path-new-constants"></a>
|
||||||
|
|
||||||
|
New [Icinga constants](17-language-reference.md#icinga-constants) have been added in this release.
|
||||||
|
|
||||||
|
* `ApiBindHost` and `ApiBindPort` to allow overriding the default ApiListener values. This will be used for an Icinga addon only.
|
||||||
|
|
||||||
## Upgrading to v2.9 <a id="upgrading-to-2-9"></a>
|
## Upgrading to v2.9 <a id="upgrading-to-2-9"></a>
|
||||||
|
|
||||||
### Deprecation and Removal Notes <a id="upgrading-to-2-9-deprecation-removal-notes"></a>
|
### Deprecation and Removal Notes <a id="upgrading-to-2-9-deprecation-removal-notes"></a>
|
||||||
|
@ -409,8 +409,10 @@ Vars |**Read-write.** Contains a dictionary with global custom at
|
|||||||
NodeName |**Read-write.** Contains the cluster node name. Set to the local hostname by default.
|
NodeName |**Read-write.** Contains the cluster node name. Set to the local hostname by default.
|
||||||
RunAsUser |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
|
RunAsUser |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
|
||||||
RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
|
RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
|
||||||
MaxConcurrentChecks |**Read-write**. The number of max checks run simultaneously. Defaults to `512`.
|
MaxConcurrentChecks |**Read-write.** The number of max checks run simultaneously. Defaults to `512`.
|
||||||
Environment |**Read-write**. The name of the Icinga environment. Included in the SNI host name when making outbound connections. Defaults to `production`.
|
Environment |**Read-write.** The name of the Icinga environment. Included in the SNI host name when making outbound connections. Defaults to `production`.
|
||||||
|
ApiBindHost |**Read-write.** Overrides the default value for the ApiListener `bind_host` attribute. Not set by default.
|
||||||
|
ApiBindPort |**Read-write.** Overrides the default value for the ApiListener `bind_port` attribute. Not set by default.
|
||||||
|
|
||||||
Application runtime details:
|
Application runtime details:
|
||||||
|
|
||||||
|
@ -114,9 +114,21 @@ int Socket::GetError() const
|
|||||||
/**
|
/**
|
||||||
* Formats a sockaddr in a human-readable way.
|
* Formats a sockaddr in a human-readable way.
|
||||||
*
|
*
|
||||||
* @returns A String describing the sockaddr.
|
* @returns A pair of host and service.
|
||||||
*/
|
*/
|
||||||
String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
|
String Socket::GetHumanReadableAddress(const std::pair<String, String>& socketDetails)
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << "[" << socketDetails.first << "]:" << socketDetails.second;
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns host and service as pair.
|
||||||
|
*
|
||||||
|
* @returns A pair with host and service.
|
||||||
|
*/
|
||||||
|
std::pair<String, String> Socket::GetDetailsFromSockaddr(sockaddr *address, socklen_t len)
|
||||||
{
|
{
|
||||||
char host[NI_MAXHOST];
|
char host[NI_MAXHOST];
|
||||||
char service[NI_MAXSERV];
|
char service[NI_MAXSERV];
|
||||||
@ -140,17 +152,15 @@ String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream s;
|
return std::make_pair(host, service);
|
||||||
s << "[" << host << "]:" << service;
|
|
||||||
return s.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a String describing the local address of the socket.
|
* Returns a pair describing the local host and service of the socket.
|
||||||
*
|
*
|
||||||
* @returns A String describing the local address.
|
* @returns A pair describing the local host and service.
|
||||||
*/
|
*/
|
||||||
String Socket::GetClientAddress()
|
std::pair<String, String> Socket::GetClientAddressDetails()
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_SocketMutex);
|
boost::mutex::scoped_lock lock(m_SocketMutex);
|
||||||
|
|
||||||
@ -175,22 +185,32 @@ String Socket::GetClientAddress()
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
String address;
|
std::pair<String, String> details;
|
||||||
try {
|
try {
|
||||||
address = GetAddressFromSockaddr((sockaddr *)&sin, len);
|
details = GetDetailsFromSockaddr((sockaddr *)&sin, len);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
/* already logged */
|
/* already logged */
|
||||||
}
|
}
|
||||||
|
|
||||||
return address;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a String describing the peer address of the socket.
|
* Returns a String describing the local address of the socket.
|
||||||
*
|
*
|
||||||
* @returns A String describing the peer address.
|
* @returns A String describing the local address.
|
||||||
*/
|
*/
|
||||||
String Socket::GetPeerAddress()
|
String Socket::GetClientAddress()
|
||||||
|
{
|
||||||
|
return GetHumanReadableAddress(GetClientAddressDetails());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pair describing the peer host and service of the socket.
|
||||||
|
*
|
||||||
|
* @returns A pair describing the peer host and service.
|
||||||
|
*/
|
||||||
|
std::pair<String, String> Socket::GetPeerAddressDetails()
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_SocketMutex);
|
boost::mutex::scoped_lock lock(m_SocketMutex);
|
||||||
|
|
||||||
@ -215,14 +235,24 @@ String Socket::GetPeerAddress()
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
String address;
|
std::pair<String, String> details;
|
||||||
try {
|
try {
|
||||||
address = GetAddressFromSockaddr((sockaddr *)&sin, len);
|
details = GetDetailsFromSockaddr((sockaddr *)&sin, len);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
/* already logged */
|
/* already logged */
|
||||||
}
|
}
|
||||||
|
|
||||||
return address;
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a String describing the peer address of the socket.
|
||||||
|
*
|
||||||
|
* @returns A String describing the peer address.
|
||||||
|
*/
|
||||||
|
String Socket::GetPeerAddress()
|
||||||
|
{
|
||||||
|
return GetHumanReadableAddress(GetPeerAddressDetails());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -415,4 +445,3 @@ void Socket::SocketPair(SOCKET s[2])
|
|||||||
<< boost::errinfo_api_function("socketpair")
|
<< boost::errinfo_api_function("socketpair")
|
||||||
<< boost::errinfo_errno(errno));
|
<< boost::errinfo_errno(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,9 @@ public:
|
|||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
std::pair<String, String> GetClientAddressDetails();
|
||||||
String GetClientAddress();
|
String GetClientAddress();
|
||||||
|
std::pair<String, String> GetPeerAddressDetails();
|
||||||
String GetPeerAddress();
|
String GetPeerAddress();
|
||||||
|
|
||||||
size_t Read(void *buffer, size_t size);
|
size_t Read(void *buffer, size_t size);
|
||||||
@ -70,7 +72,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
SOCKET m_FD{INVALID_SOCKET}; /**< The socket descriptor. */
|
SOCKET m_FD{INVALID_SOCKET}; /**< The socket descriptor. */
|
||||||
|
|
||||||
static String GetAddressFromSockaddr(sockaddr *address, socklen_t len);
|
static std::pair<String, String> GetDetailsFromSockaddr(sockaddr *address, socklen_t len);
|
||||||
|
static String GetHumanReadableAddress(const std::pair<String, String>& socketDetails);
|
||||||
};
|
};
|
||||||
|
|
||||||
class socket_error : virtual public std::exception, virtual public boost::exception { };
|
class socket_error : virtual public std::exception, virtual public boost::exception { };
|
||||||
|
@ -264,8 +264,12 @@ void ApiListener::Stop(bool runtimeDeleted)
|
|||||||
Log(LogInformation, "ApiListener")
|
Log(LogInformation, "ApiListener")
|
||||||
<< "'" << GetName() << "' stopped.";
|
<< "'" << GetName() << "' stopped.";
|
||||||
|
|
||||||
boost::mutex::scoped_lock lock(m_LogLock);
|
{
|
||||||
CloseLogFile();
|
boost::mutex::scoped_lock lock(m_LogLock);
|
||||||
|
CloseLogFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveStatusFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiListener::Ptr ApiListener::GetInstance()
|
ApiListener::Ptr ApiListener::GetInstance()
|
||||||
@ -318,9 +322,6 @@ bool ApiListener::AddListener(const String& node, const String& service)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(LogInformation, "ApiListener")
|
|
||||||
<< "Adding new listener on port '" << service << "'";
|
|
||||||
|
|
||||||
TcpSocket::Ptr server = new TcpSocket();
|
TcpSocket::Ptr server = new TcpSocket();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -331,11 +332,16 @@ bool ApiListener::AddListener(const String& node, const String& service)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log(LogInformation, "ApiListener")
|
||||||
|
<< "Started new listener on '" << server->GetClientAddress() << "'";
|
||||||
|
|
||||||
std::thread thread(std::bind(&ApiListener::ListenerThreadProc, this, server));
|
std::thread thread(std::bind(&ApiListener::ListenerThreadProc, this, server));
|
||||||
thread.detach();
|
thread.detach();
|
||||||
|
|
||||||
m_Servers.insert(server);
|
m_Servers.insert(server);
|
||||||
|
|
||||||
|
UpdateStatusFile(server);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1469,3 +1475,28 @@ String ApiListener::GetFromZoneName(const Zone::Ptr& fromZone)
|
|||||||
|
|
||||||
return fromZoneName;
|
return fromZoneName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiListener::UpdateStatusFile(TcpSocket::Ptr socket)
|
||||||
|
{
|
||||||
|
String path = Application::GetConst("CacheDir") + "/api-state.json";
|
||||||
|
std::pair<String, String> details = socket->GetClientAddressDetails();
|
||||||
|
|
||||||
|
Utility::SaveJsonFile(path, 0644, new Dictionary({
|
||||||
|
{"host", details.first},
|
||||||
|
{"port", details.second}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiListener::RemoveStatusFile()
|
||||||
|
{
|
||||||
|
String path = Application::GetConst("CacheDir") + "/api-state.json";
|
||||||
|
|
||||||
|
if (Utility::PathExists(path)) {
|
||||||
|
if (unlink(path.CStr()) < 0 && errno != ENOENT) {
|
||||||
|
BOOST_THROW_EXCEPTION(posix_error()
|
||||||
|
<< boost::errinfo_api_function("unlink")
|
||||||
|
<< boost::errinfo_errno(errno)
|
||||||
|
<< boost::errinfo_file_name(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -163,6 +163,9 @@ private:
|
|||||||
|
|
||||||
static void CopyCertificateFile(const String& oldCertPath, const String& newCertPath);
|
static void CopyCertificateFile(const String& oldCertPath, const String& newCertPath);
|
||||||
|
|
||||||
|
void UpdateStatusFile(TcpSocket::Ptr socket);
|
||||||
|
void RemoveStatusFile();
|
||||||
|
|
||||||
/* filesync */
|
/* filesync */
|
||||||
static ConfigDirInformation LoadConfigDir(const String& dir);
|
static ConfigDirInformation LoadConfigDir(const String& dir);
|
||||||
static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config);
|
static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config);
|
||||||
|
@ -41,9 +41,11 @@ class ApiListener : ConfigObject
|
|||||||
default {{{ return "TLSv1"; }}}
|
default {{{ return "TLSv1"; }}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[config] String bind_host;
|
[config] String bind_host {
|
||||||
|
default {{{ return Application::GetConst("ApiBindHost"); }}}
|
||||||
|
};
|
||||||
[config] String bind_port {
|
[config] String bind_port {
|
||||||
default {{{ return "5665"; }}}
|
default {{{ return Application::GetConst("ApiBindPort", "5665"); }}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[config] bool accept_config;
|
[config] bool accept_config;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user