Skip to content

Commit

Permalink
reloadOnChange for targets. Separate targets config.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mihal committed Dec 21, 2020
1 parent ff9d8a3 commit 73d7ebd
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 69 deletions.
3 changes: 3 additions & 0 deletions AlertProxy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<Content Update="cfg\settings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="cfg\targets.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="cfg\users.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
Expand Down
39 changes: 23 additions & 16 deletions Classes/Proxy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Stubble;
using Stubble.Core.Builders;
Expand All @@ -22,17 +23,19 @@ public interface IProxy
public class Proxy:IProxy
{
private readonly ILogger<Proxy> _logger;
private readonly IConfiguration _config;

private readonly IHttpClientFactory _clientFactory;

private readonly IOptionsSnapshot<Dictionary<string, Target>> _options;

private readonly HttpClient _client;


public Proxy(ILogger<Proxy> logger, IConfiguration config, IHttpClientFactory clientFactory)
public Proxy(ILogger<Proxy> logger, IHttpClientFactory clientFactory, IOptionsSnapshot<Dictionary<string,Target>> optionsSnapshot)
{
_config = config;

_logger = logger;
_clientFactory = clientFactory;
_options = optionsSnapshot;


_client = _clientFactory.CreateClient();
Expand Down Expand Up @@ -67,19 +70,20 @@ public async Task<List<string>> Process(string target, object alert)

private async Task<HttpResponseMessage> ProcessAlert(string target,object alert)
{
var settings = _config.GetSection("targets").GetSection(target);
//var settings = _config.GetSection("targets").GetSection(target);
var settings = _options.Value[target];

var st = new StubbleBuilder().Configure(settings => settings.AddJsonNet()).Build();




var Url = st.Render(settings["UrlTemplate"], alert);
var Url = st.Render(settings.UrlTemplate, alert);
var request = new HttpRequestMessage(HttpMethod.Post, Url);
//Add headers
foreach (var h in _config.GetSection("targets").GetSection(target).GetSection("headers").GetChildren().ToDictionary(p => p.Value))
foreach (var h in settings.headers)
{
request.Headers.Add(h.Value.Key, h.Value.Value.ToString());
request.Headers.Add(h.Key, h.Value);

}

Expand All @@ -89,12 +93,12 @@ private async Task<HttpResponseMessage> ProcessAlert(string target,object alert)
var state = jalert["status"];

jalert.Add("emoji", "");
if (state.ToString().ToUpper() == "FIRING") jalert["emoji"] = settings["firingEmoji"] != null ? settings["firingEmoji"].ToString() : "";
if (state.ToString().ToUpper() == "RESOLVED") jalert["emoji"] = settings["resolvingEmoji"] != null ? settings["resolvingEmoji"].ToString() : "";
if (state.ToString().ToUpper() == "FIRING") jalert["emoji"] = settings.firingEmoji != null ? settings.firingEmoji : "";
if (state.ToString().ToUpper() == "RESOLVED") jalert["emoji"] = settings.resolvingEmoji != null ? settings.resolvingEmoji : "";



var Body = st.Render(settings["BodyTemplate"], jalert);
var Body = st.Render(settings.Bodytemplate, jalert);


request.Content = new StringContent(
Expand All @@ -111,19 +115,22 @@ private async Task<HttpResponseMessage> ProcessAlert(string target,object alert)

public async Task<HttpResponseMessage> ProcessFree(string target, object obj)
{
var settings = _config.GetSection("targets").GetSection(target);
var settings = _options.Value[target];

var st = new StubbleBuilder().Configure(settings => settings.AddJsonNet()).Build();
var Url = st.Render(settings["UrlTemplate"], obj);
_client.BaseAddress = new Uri(Url);
var Url = st.Render(settings.UrlTemplate, obj);



var Body = st.Render(settings["BodyTemplate"], obj);
var Body = st.Render(settings.Bodytemplate, obj);

var body = new StringContent(
Body, Encoding.UTF8, "application/json");

return await _client.PostAsync("", body);
var request = new HttpRequestMessage(HttpMethod.Post, Url);
request.Content = body;

return await _client.SendAsync(request);
}


Expand Down
18 changes: 18 additions & 0 deletions Classes/Target.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AlertProxy.Classes
{
public class Target
{
public string UrlTemplate { get; set; }
public string Bodytemplate { get; set; }
public Dictionary<string,string> headers { get; set; }
public string firingEmoji { get; set; }
public string resolvingEmoji { get; set; }


}
}
14 changes: 12 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,22 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
.AddCommandLine(args)
.Build();


webBuilder
.UseConfiguration(config)
.ConfigureAppConfiguration((builderContext, config) =>
{
IHostEnvironment env = builderContext.HostingEnvironment;
config
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(Path.Combine(AppContext.BaseDirectory, "cfg", "settings.json"), optional: false, reloadOnChange: true)
.AddJsonFile(Path.Combine(AppContext.BaseDirectory, "cfg", "targets.json"), optional: false, reloadOnChange: true)
.AddCommandLine(args);
}
)
//.UseConfiguration(config)

.ConfigureKestrel((context, options) =>
{

options.Listen(IPAddress.Any, int.Parse(config.GetSection("SSL")["port"]), listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
Expand Down
65 changes: 36 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@



[![Build Status](https://travis-ci.com/mihalby/alertproxy.svg?branch=master)](https://travis-ci.com/mihalby/alertproxy)
[![Docker Build](https://img.shields.io/docker/automated/mihalby/alertproxy.svg)](https://hub.docker.com/r/mihalby/alertproxy)
[![Docker Pulls](https://img.shields.io/docker/pulls/mihalby/alertproxy.svg)](https://hub.docker.com/r/mihalby/alertproxy)
Expand All @@ -25,47 +26,53 @@ Download .zip from [Releases](https://github.com/mihalby/AlertProxy/releases) un
### Windows x64
Download archive from [Releases](https://github.com/mihalby/AlertProxy/releases), change configs and run exe file.

### 1. Create configs (settings.json, user.json, serilog.json)
### 1.1. settings.json
### 1. Create configs (settings.json, targets.json user.json, serilog.json)
### 1.1. settings.json
Base application config
**SSL** - configure ssl. Now service work only with ssl. Place you pfx to ./cfg directory. You will find fake pfx file in repo ./cfg, password 123123.

**Targets** - templates to forwards. Url and Body is mustache templates. [More info about mustache](https://mustache.github.io/mustache.5.html).

example:
**target https:/youAlertproxy:8100/alert/kafka-ms** forward request to http://awx.uni.bn/api/v2/job_templates/108/launch/ ...
**target https:/youAlertproxy:8100/alert/tlg-itretail** forward message to telegram between telegram http api.

{
"SSL": {
"password": "123123",
"port": 8100,
"sertificateName": "aspncer.pfx"
},
"targets": {
"kafka-ms": {
"UrlTemplate": "http://awx.uni.bn/api/v2/job_templates/108/launch/",
"Bodytemplate": "{\"ask_inventory_on_launch\": false,\"can_start_without_user_input\": true,\"defaults\": {\"extra_vars\": \"\",\"inventory\": {\"id\": 3,\"name\": \"FirstInventory\"}},\"survey_enabled\": false,\"variables_needed_to_start\": [],\"node_templates_missing\": [],\"node_prompts_rejected\": [],\"job_template_data\": {\"id\": 108,\"description\": \"KAFKA-SERVICES-CHECK-RUN\",\"name\": \"KAFKA-SERVICES-CHECK-RUN\"}}",
"headers": {
"Accept-Encoding": "gzip,deflate",
"authorization": "Basic Yneneulewxo"
}
},
"tlg-itretail": {
"UrlTemplate": "https://api.telegram.org/botBOT-TOKEN/sendMessage",
"Bodytemplate": "{\"chat_id\": \"-CHAT-ID\", \"text\": \"{{emoji}}<b>ALERT {{status}}</b>\n<code>Instance : {{labels.instance}}\nalert name : {{labels.alertname}}\njob : {{labels.job}}</code>\", \"disable_notification\": false,\"parse_mode\":\"HTML\"}",
"headers": {
"Accept-Encoding": "gzip,deflate"
},
"firingEmoji": "\\uD83E\\uDD14",
"resolvingEmoji": "\uD83D\uDE42"
}
},


"AllowedHosts": "*"
}

### 1.2 targets.json
**Targets** - templates to forwards. Url and Body is mustache templates. [More info about mustache](https://mustache.github.io/mustache.5.html).
**target https:/youAlertproxy:8100/alert/kafka-ms** forward request to http://awx.uni.bn/api/v2/job_templates/108/launch/ ...
**target https:/youAlertproxy:8100/alert/tlg-itretail** forward message to telegram between telegram http api.

All targets load dynamicaly, you not need restart application if targets.json is changed.
example tagrets.json

{
"targets": {
"kafka-ms": {
"UrlTemplate": "http://awx.uni.bn/api/v2/job_templates/108/launch/",
"Bodytemplate": "{\"ask_inventory_on_launch\": false,\"can_start_without_user_input\": true,\"defaults\": {\"extra_vars\": \"\",\"inventory\": {\"id\": 3,\"name\": \"FirstInventory\"}},\"survey_enabled\": false,\"variables_needed_to_start\": [],\"node_templates_missing\": [],\"node_prompts_rejected\": [],\"job_template_data\": {\"id\": 108,\"description\": \"KAFKA-SERVICES-CHECK-RUN\",\"name\": \"KAFKA-SERVICES-CHECK-RUN\"}}",
"headers": {
"Accept-Encoding": "gzip,deflate",
"authorization": "Basic Yneneulewxo"
}
},
"tlg-itretail": {
"UrlTemplate": "https://api.telegram.org/botBOT-TOKEN/sendMessage",
"Bodytemplate": "{\"chat_id\": \"-CHAT-ID\", \"text\": \"{{emoji}}<b>ALERT {{status}}</b>\n<code>Instance : {{labels.instance}}\nalert name : {{labels.alertname}}\njob : {{labels.job}}</code>\", \"disable_notification\": false,\"parse_mode\":\"HTML\"}",
"headers": {
"Accept-Encoding": "gzip,deflate"
},
"firingEmoji": "\\uD83E\\uDD14",
"resolvingEmoji": "\uD83D\uDE42"
}
}
}

### 1.2. user.json
### 1.3. user.json
AlertProxy work only with basic authorization. Example user.json

[
Expand All @@ -77,7 +84,7 @@ AlertProxy work only with basic authorization. Example user.json
"Password":"test"
}
]
### 1.3. Logging config - serilog.json
### 1.4. Logging config - serilog.json
example:

{
Expand Down
4 changes: 2 additions & 2 deletions Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public void ConfigureServices(IServiceCollection services)
services.AddScoped<IUserList, UserList>();
services.AddScoped<IUserService, UserService>();

services.Configure<Dictionary<string,Target>>(Configuration.GetSection("targets"));


services.AddSingleton<IConfiguration>(Configuration);

services.AddHttpClient();

services.AddScoped<IProxy, Proxy>();
Expand Down
20 changes: 0 additions & 20 deletions cfg/settings.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,6 @@
"port": 8100,
"sertificateName": "aspncer.pfx"
},
"targets": {
"kafka-ms": {
"UrlTemplate": "http://awx.uni.bn/api/v2/job_templates/108/launch/",
"Bodytemplate": "{\"ask_inventory_on_launch\": false,\"can_start_without_user_input\": true,\"defaults\": {\"extra_vars\": \"\",\"inventory\": {\"id\": 3,\"name\": \"FirstInventory\"}},\"survey_enabled\": false,\"variables_needed_to_start\": [],\"node_templates_missing\": [],\"node_prompts_rejected\": [],\"job_template_data\": {\"id\": 108,\"description\": \"KAFKA-SERVICES-CHECK-RUN\",\"name\": \"KAFKA-SERVICES-CHECK-RUN\"}}",
"headers": {
"Accept-Encoding": "gzip,deflate",
"authorization": "Basic Yneneulewxo"
}
},
"tlg-itretail": {
"UrlTemplate": "https://api.telegram.org/botBOT-TOKEN/sendMessage",
"Bodytemplate": "{\"chat_id\": \"-CHAT-ID\", \"text\": \"{{emoji}}<b>ALERT {{status}}</b>\n<code>Instance : {{labels.instance}}\nalert name : {{labels.alertname}}\njob : {{labels.job}}</code>\", \"disable_notification\": false,\"parse_mode\":\"HTML\"}",
"headers": {
"Accept-Encoding": "gzip,deflate"
},
"firingEmoji": "\\uD83E\\uDD14",
"resolvingEmoji": "\uD83D\uDE42"
}
},

"AllowedHosts": "*"
}

32 changes: 32 additions & 0 deletions cfg/targets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{

"targets": {
"kafka-ms": {
"UrlTemplate": "http://awx.bk/api/v2/job_templates/108/launch/",
"Bodytemplate": "{\"ask_inventory_on_launch\": false,\"can_start_without_user_input\": true,\"defaults\": {\"extra_vars\": \"\",\"inventory\": {\"id\": 3,\"name\": \"FirstInventory\"}},\"survey_enabled\": false,\"variables_needed_to_start\": [],\"node_templates_missing\": [],\"node_prompts_rejected\": [],\"job_template_data\": {\"id\": 108,\"description\": \"KAFKA-SERVICES-CHECK-RUN\",\"name\": \"KAFKA-SERVICES-CHECK-RUN\"}}",
"headers": {
"Accept-Encoding": "gzip,deflate",
"authorization": "Basic Zbdj7ejjlldjqd"
}
},
"tlg-itretail": {
"UrlTemplate": "https://api.telegram.org/botBOT-ID/sendMessage",
"Bodytemplate": "{\"chat_id\": \"CHAT-ID\", \"text\": \"{{emoji}}<b>ALERT {{status}}</b>\n<code>Instance : {{labels.instance}}\nalert name : {{labels.alertname}}\njob : {{labels.job}}</code>\", \"disable_notification\": false,\"parse_mode\":\"HTML\"}",
"headers": {
"Accept-Encoding": "gzip,deflate"
},
"firingEmoji": "\\uD83E\\uDD14",
"resolvingEmoji": "\uD83D\uDE42"
},
"tlg-test": {
"UrlTemplate": "https://api.telegram.org/botBOT-ID/sendMessage",
"Bodytemplate": "{\"chat_id\": \"CHAT-ID\", \"text\": \"{{emoji}}<b>ALERT {{status}}</b>\n<code>Instance : {{labels.instance}}\nalert name : {{labels.alertname}}\njob : {{labels.job}}</code>\", \"disable_notification\": false,\"parse_mode\":\"HTML\"}",
"headers": {
"Accept-Encoding": "gzip,deflate"
},
"firingEmoji": "\\uD83E\\uDD14",
"resolvingEmoji": "\uD83D\uDE42"
}

}
}

0 comments on commit 73d7ebd

Please sign in to comment.