mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-08 17:05:25 +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.
|
||||
|
||||
### 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>
|
||||
|
||||
### 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.
|
||||
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.
|
||||
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`.
|
||||
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`.
|
||||
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:
|
||||
|
||||
|
@ -114,9 +114,21 @@ int Socket::GetError() const
|
||||
/**
|
||||
* 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 service[NI_MAXSERV];
|
||||
@ -140,17 +152,15 @@ String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
std::ostringstream s;
|
||||
s << "[" << host << "]:" << service;
|
||||
return s.str();
|
||||
return std::make_pair(host, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
@ -175,22 +185,32 @@ String Socket::GetClientAddress()
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
String address;
|
||||
std::pair<String, String> details;
|
||||
try {
|
||||
address = GetAddressFromSockaddr((sockaddr *)&sin, len);
|
||||
details = GetDetailsFromSockaddr((sockaddr *)&sin, len);
|
||||
} catch (const std::exception&) {
|
||||
/* 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);
|
||||
|
||||
@ -215,14 +235,24 @@ String Socket::GetPeerAddress()
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
String address;
|
||||
std::pair<String, String> details;
|
||||
try {
|
||||
address = GetAddressFromSockaddr((sockaddr *)&sin, len);
|
||||
details = GetDetailsFromSockaddr((sockaddr *)&sin, len);
|
||||
} catch (const std::exception&) {
|
||||
/* 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_errno(errno));
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,9 @@ public:
|
||||
|
||||
void Close();
|
||||
|
||||
std::pair<String, String> GetClientAddressDetails();
|
||||
String GetClientAddress();
|
||||
std::pair<String, String> GetPeerAddressDetails();
|
||||
String GetPeerAddress();
|
||||
|
||||
size_t Read(void *buffer, size_t size);
|
||||
@ -70,7 +72,8 @@ protected:
|
||||
private:
|
||||
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 { };
|
||||
|
@ -264,8 +264,12 @@ void ApiListener::Stop(bool runtimeDeleted)
|
||||
Log(LogInformation, "ApiListener")
|
||||
<< "'" << GetName() << "' stopped.";
|
||||
|
||||
boost::mutex::scoped_lock lock(m_LogLock);
|
||||
CloseLogFile();
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_LogLock);
|
||||
CloseLogFile();
|
||||
}
|
||||
|
||||
RemoveStatusFile();
|
||||
}
|
||||
|
||||
ApiListener::Ptr ApiListener::GetInstance()
|
||||
@ -318,9 +322,6 @@ bool ApiListener::AddListener(const String& node, const String& service)
|
||||
return false;
|
||||
}
|
||||
|
||||
Log(LogInformation, "ApiListener")
|
||||
<< "Adding new listener on port '" << service << "'";
|
||||
|
||||
TcpSocket::Ptr server = new TcpSocket();
|
||||
|
||||
try {
|
||||
@ -331,11 +332,16 @@ bool ApiListener::AddListener(const String& node, const String& service)
|
||||
return false;
|
||||
}
|
||||
|
||||
Log(LogInformation, "ApiListener")
|
||||
<< "Started new listener on '" << server->GetClientAddress() << "'";
|
||||
|
||||
std::thread thread(std::bind(&ApiListener::ListenerThreadProc, this, server));
|
||||
thread.detach();
|
||||
|
||||
m_Servers.insert(server);
|
||||
|
||||
UpdateStatusFile(server);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1469,3 +1475,28 @@ String ApiListener::GetFromZoneName(const Zone::Ptr& fromZone)
|
||||
|
||||
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);
|
||||
|
||||
void UpdateStatusFile(TcpSocket::Ptr socket);
|
||||
void RemoveStatusFile();
|
||||
|
||||
/* filesync */
|
||||
static ConfigDirInformation LoadConfigDir(const String& dir);
|
||||
static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config);
|
||||
|
@ -41,9 +41,11 @@ class ApiListener : ConfigObject
|
||||
default {{{ return "TLSv1"; }}}
|
||||
};
|
||||
|
||||
[config] String bind_host;
|
||||
[config] String bind_host {
|
||||
default {{{ return Application::GetConst("ApiBindHost"); }}}
|
||||
};
|
||||
[config] String bind_port {
|
||||
default {{{ return "5665"; }}}
|
||||
default {{{ return Application::GetConst("ApiBindPort", "5665"); }}}
|
||||
};
|
||||
|
||||
[config] bool accept_config;
|
||||
|
Loading…
x
Reference in New Issue
Block a user