diff --git a/EonaCat.Logger/EonaCat.Logger.csproj b/EonaCat.Logger/EonaCat.Logger.csproj index 4a24b5b..08ea40d 100644 --- a/EonaCat.Logger/EonaCat.Logger.csproj +++ b/EonaCat.Logger/EonaCat.Logger.csproj @@ -56,6 +56,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/EonaCat.Logger/Zabbix/API/ZabbixApi.cs b/EonaCat.Logger/Zabbix/API/ZabbixApi.cs new file mode 100644 index 0000000..1ff6966 --- /dev/null +++ b/EonaCat.Logger/Zabbix/API/ZabbixApi.cs @@ -0,0 +1,141 @@ +using EonaCat.Json; +using System; +using System.Dynamic; +using System.IO; +using System.Net; +using System.Text; + +namespace EonaCat.Logger.Zabbix.API; +// This file is part of the EonaCat project(s) which is released under the Apache License. +// See the LICENSE file or go to https://EonaCat.com/License for full license details. + +public class ZabbixApi +{ + public ZabbixApi(string user, string password, string zabbixURL, bool basicAuth) + { + _user = user; + _password = password; + _zabbixURL = zabbixURL; + + if (basicAuth) + { + _basicAuth = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(_user + ":" + _password)); + } + + _auth = null; + } + + public ZabbixApi(string user, string password, string zabbixURL) : this(user, password, zabbixURL, false) + { + + } + + private readonly string _user; + private readonly string _password; + private readonly string _zabbixURL; + private string _auth; + private readonly string _basicAuth = null; + + /// + /// Determines if the user is logged in + /// + public bool IsLoggedIn { get; set; } + + /// + /// Logs in the user + /// + public void Login() + { + dynamic authentication = new ExpandoObject(); + authentication.user = _user; + authentication.password = _password; + + ZabbixApiResponse zabbixApiResponse = ResponseAsObject("user.login", authentication); + + _auth = zabbixApiResponse.Result; + IsLoggedIn = !string.IsNullOrEmpty(_auth); + } + + /// + /// Logs out the user + /// + /// + public bool Logout() + { + ZabbixApiResponse zbxResponse = ResponseAsObject("user.logout", new string[] { }); + var result = zbxResponse.Result; + return result; + } + + /// + /// Generic method to send a request to the Zabbix API + /// + /// + /// + /// + public string ResponseAsJson(string method, object parameters) + { + ZabbixApiRequest zbxRequest = new ZabbixApiRequest("2.0", method, 1, _auth, parameters); + string jsonParameters = JsonHelper.ToJson(zbxRequest); + return SendRequest(jsonParameters); + } + + /// + /// Generic method to send a request to the Zabbix API + /// + /// + /// + /// + public ZabbixApiResponse ResponseAsObject(string method, object parameters) + { + ZabbixApiRequest zbxRequest = new ZabbixApiRequest("2.0", method, 1, _auth, parameters); + string jsonParameters = JsonHelper.ToJson(zbxRequest); + return CreateResponse(SendRequest(jsonParameters)); + } + + /// + /// Creates a ZabbixApiResponse object from a JSON string + /// + /// + /// + private ZabbixApiResponse CreateResponse(string json) + { + ZabbixApiResponse zbxResponse = JsonHelper.ToObject(json); + return zbxResponse; + } + + /// + /// Sends a request to the Zabbix API + /// + /// + /// + private string SendRequest(string jsonParams) + { + WebRequest request = WebRequest.Create(_zabbixURL); + + if (_basicAuth != null) + { + request.Headers.Add("Authorization", "Basic " + _basicAuth); + } + + request.ContentType = "application/json-rpc"; + request.Method = "POST"; + string jsonResult; + + using (var streamWriter = new StreamWriter(request.GetRequestStream())) + { + streamWriter.Write(jsonParams); + streamWriter.Flush(); + streamWriter.Close(); + } + + WebResponse response = request.GetResponse(); + using (var streamReader = new StreamReader(response.GetResponseStream())) + { + jsonResult = streamReader.ReadToEnd(); + } + + return jsonResult; + } + +} diff --git a/EonaCat.Logger/Zabbix/API/ZabbixApiRequest.cs b/EonaCat.Logger/Zabbix/API/ZabbixApiRequest.cs new file mode 100644 index 0000000..650d832 --- /dev/null +++ b/EonaCat.Logger/Zabbix/API/ZabbixApiRequest.cs @@ -0,0 +1,42 @@ +namespace EonaCat.Logger.Zabbix.API +{ + // This file is part of the EonaCat project(s) which is released under the Apache License. + // See the LICENSE file or go to https://EonaCat.com/License for full license details. + + public class ZabbixApiRequest + { + /// + /// Jsonrpc version + /// + public string Jsonrpc { get; set; } + + /// + /// Method to call + /// + public string Method { get; set; } + + /// + /// Id of the request + /// + public int Id { get; set; } + + /// + /// Authentification token + /// + public string Auth { get; set; } + + /// + /// Parameters of the request + /// + public dynamic Parameters { get; set; } + + public ZabbixApiRequest(string jsonrpc, string method, int id, string auth, dynamic parameters) + { + Jsonrpc = jsonrpc; + Method = method; + Id = id; + Auth = auth; + Parameters = parameters; + } + } +} diff --git a/EonaCat.Logger/Zabbix/API/ZabbixApiResponse.cs b/EonaCat.Logger/Zabbix/API/ZabbixApiResponse.cs new file mode 100644 index 0000000..6a838a7 --- /dev/null +++ b/EonaCat.Logger/Zabbix/API/ZabbixApiResponse.cs @@ -0,0 +1,25 @@ +using System.Dynamic; + +namespace EonaCat.Logger.Zabbix.API +{ + // This file is part of the EonaCat project(s) which is released under the Apache License. + // See the LICENSE file or go to https://EonaCat.com/License for full license details. + + public class ZabbixApiResponse + { + /// + /// Jsonrpc version + /// + public string Jsonrpc { get; set; } + + /// + /// Result of the request + /// + public dynamic Result = new ExpandoObject(); + + /// + /// Id of the request + /// + public int Id { get; set; } + } +} diff --git a/EonaCat.Logger/Zabbix/ZabbixData.cs b/EonaCat.Logger/Zabbix/ZabbixData.cs new file mode 100644 index 0000000..0bfcead --- /dev/null +++ b/EonaCat.Logger/Zabbix/ZabbixData.cs @@ -0,0 +1,17 @@ + +/// +/// Zabbix server. +/// +public class ZabbixData +{ + public string Host { get; set; } + public string Key { get; set; } + public string Value { get; set; } + + public ZabbixData(string host, string key, string value) + { + Host = host; + Key = key; + Value = value; + } +} diff --git a/EonaCat.Logger/Zabbix/ZabbixRequest.cs b/EonaCat.Logger/Zabbix/ZabbixRequest.cs new file mode 100644 index 0000000..5c376eb --- /dev/null +++ b/EonaCat.Logger/Zabbix/ZabbixRequest.cs @@ -0,0 +1,74 @@ +using EonaCat.Json; +using System; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +public class ZabbixRequest +{ + private const int BUFFER_SIZE = 1024; + + /// + /// The request to send to the Zabbix server + /// + public string Request { get; set; } + + /// + /// The data to send to the Zabbix server + /// + public ZabbixData[] Data { get; set; } + + public ZabbixRequest(string host, string key, string value) + { + Request = "sender data"; + Data = [new ZabbixData(host, key, value)]; + } + + /// + /// Sends the request to the Zabbix server + /// + /// + /// + /// + /// + /// + public async Task SendAsync(string server, int port = 10051, int timeout = 500) + { + string json = JsonHelper.ToJson(new ZabbixRequest(Data[0].Host, Data[0].Key, Data[0].Value)); + using (TcpClient tcpClient = new TcpClient(server, port)) + using (NetworkStream stream = tcpClient.GetStream()) + { + byte[] header = Encoding.ASCII.GetBytes("ZBXD\x01"); + byte[] dataLength = BitConverter.GetBytes((long)json.Length); + byte[] content = Encoding.ASCII.GetBytes(json); + byte[] message = new byte[header.Length + dataLength.Length + content.Length]; + + Buffer.BlockCopy(header, 0, message, 0, header.Length); + Buffer.BlockCopy(dataLength, 0, message, header.Length, dataLength.Length); + Buffer.BlockCopy(content, 0, message, header.Length + dataLength.Length, content.Length); + + stream.Write(message, 0, message.Length); + stream.Flush(); + + int counter = 0; + while (!stream.DataAvailable) + { + if (counter < timeout / 50) + { + counter++; + await Task.Delay(50).ConfigureAwait(false); + } + else + { + throw new TimeoutException(); + } + } + + byte[] responseBytes = new byte[BUFFER_SIZE]; + stream.Read(responseBytes, 0, responseBytes.Length); + string responseAsString = Encoding.UTF8.GetString(responseBytes); + string jsonResult = responseAsString.Substring(responseAsString.IndexOf('{')); + return JsonHelper.ToObject(jsonResult); + } + } +} \ No newline at end of file diff --git a/EonaCat.Logger/Zabbix/ZabbixResponse.cs b/EonaCat.Logger/Zabbix/ZabbixResponse.cs new file mode 100644 index 0000000..2f46c16 --- /dev/null +++ b/EonaCat.Logger/Zabbix/ZabbixResponse.cs @@ -0,0 +1,6 @@ +public class ZabbixResponse +{ + public string Response { get; set; } + public string Info { get; set; } + +}