Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticroentgen committed Sep 9, 2024
0 parents commit 4e14827
Show file tree
Hide file tree
Showing 88 changed files with 75,330 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
9 changes: 9 additions & 0 deletions Sherlog.Server/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Sherlog.Server;

public class Config
{
public string SmtpServer { get; set; }
public string SmtpUser { get; set; }
public string SmtpPassword { get; set; }
public string MailFrom { get; set; }
}
7 changes: 7 additions & 0 deletions Sherlog.Server/Contact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Sherlog.Server;

public class Contact
{
public string Name { get; set; }
public string Email { get; set; }
}
23 changes: 23 additions & 0 deletions Sherlog.Server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["Sherlog.Server/Sherlog.Server.csproj", "Sherlog.Server/"]
RUN dotnet restore "Sherlog.Server/Sherlog.Server.csproj"
COPY . .
WORKDIR "/src/Sherlog.Server"
RUN dotnet build "Sherlog.Server.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "Sherlog.Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Sherlog.Server.dll"]
11 changes: 11 additions & 0 deletions Sherlog.Server/LogEntryDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Sherlog.Server;

public class LogEntryDto
{
public int Id { get; set; }
public string Tenant { get; set; }
public List<string> RecipientGroups { get; set; }
public string LogType { get; set; }
public string Project { get; set; }
public string Message { get; set; }
}
85 changes: 85 additions & 0 deletions Sherlog.Server/LogbookController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Net;
using System.Net.Mail;
using Microsoft.AspNetCore.Mvc;

namespace Sherlog.Server;

[ApiController]
[Route("api/logbook")]
public class LogbookController : ControllerBase
{
private readonly NetboxAPi _netboxApi;

public LogbookController()
{

_netboxApi = new NetboxAPi("https://netbox.ethquokkaops.io", "60f53d1002164803b460228193b9e3b8");
}
[HttpPost("add-log-entry")]
public async Task<ActionResult> AddLogEntry(LogEntryDto logEntry)
{
// Save the entry to database

// Get all contacts
List<Contact> contacts = new();
foreach (var group in logEntry.RecipientGroups)
{
contacts.AddRange(await _netboxApi.GetContactAssignmentsForTenents(logEntry.Tenant, group));
}

// Compose message
string header = "This is a notification";
if(logEntry.LogType == "Incident started")
header = "Devops opened an incident";
else if(logEntry.LogType == "Incident resolved")
header = "Devops resolved an incident";
else if(logEntry.LogType == "Incident updated")
header = "Devops updated an incident";

string subject = $"{header} for {logEntry.Tenant} - {logEntry.Project}";
string message =
@$"{subject}:
{logEntry.Message}
--- You are receiving this message because you are listed as Stakeholder in the Service Manifest for {logEntry.Tenant} - {logEntry.Project} ---";


// Send message to
MailMessage mail = new MailMessage();
mail.From = new MailAddress(Program.Configuration.MailFrom);
foreach (var contact in contacts)
{
mail.To.Add(contact.Email);
}
mail.CC.Add(Program.Configuration.MailFrom);
mail.Subject = subject;
mail.Body = message;

SmtpClient smtpServer = new SmtpClient(Program.Configuration.SmtpServer);
smtpServer.Port = 587; // This is the default port for SMTP. Change it according to your server
smtpServer.Credentials = new NetworkCredential(Program.Configuration.SmtpUser, Program.Configuration.SmtpPassword);
smtpServer.EnableSsl = true;

smtpServer.Send(mail);


return CreatedAtAction(nameof(AddLogEntry), new { id = logEntry.Id }, logEntry);
}

[HttpGet("get-tenants")]
public async Task<ActionResult> GetTenants()
{
var result = await _netboxApi.GetNetboxTenants();

return new JsonResult(result.Select(x => x.Slug));
}

[HttpGet("get-tenant-roles/{tenantSlug}")]
public async Task<ActionResult> GetContactRolesForTenant(string tenantSlug)
{
var result = await _netboxApi.GetContactRolesForTenant(slug: tenantSlug);

return new JsonResult(result);
}
}
85 changes: 85 additions & 0 deletions Sherlog.Server/NetboxAPi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Net.Http.Headers;
using System.Text.Json.Nodes;

namespace Sherlog.Server;

public class NetboxAPi
{
private readonly HttpClient _client;

public NetboxAPi(string netboxUrl, string netboxApiKey)
{
_client = new HttpClient();
_client.BaseAddress = new Uri(netboxUrl);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", netboxApiKey);
}

public async Task<List<NetboxTenant>> GetNetboxTenants()
{
string jsonResponse = await _client.GetStringAsync("/api/tenancy/tenants/");
JsonNode? tenents = JsonNode.Parse(jsonResponse);
List<NetboxTenant> tenants = new();
foreach (var tenant in tenents["results"] as JsonArray)
{
tenants.Add(new NetboxTenant
{
Slug = tenant["slug"].GetValue<string>(),
Id = tenant["id"].GetValue<int>()
});
}
return tenants;
}

public async Task<List<string>> GetContactRolesForTenant(string slug)
{
var tenants = await GetNetboxTenants();
var tenantId = tenants.FirstOrDefault(x => x.Slug == slug)?.Id;

string jsonResponse = await _client.GetStringAsync($"/api/tenancy/contact-assignments/?content_type=tenancy.tenant&object_id={tenantId}");
JsonNode? assignment = JsonNode.Parse(jsonResponse);

// get roles
List<string> roles = new();
foreach (var a in assignment["results"] as JsonArray)
{
roles.Add(a["role"]["slug"].GetValue<string>());
}

return roles.Distinct().ToList();

}

public async Task<IEnumerable<Contact>> GetContactAssignmentsForTenents(string logEntryTenant, string group)
{
// Get tenant id
var tenants = await GetNetboxTenants();
var tenantId = tenants.FirstOrDefault(x => x.Slug == logEntryTenant)?.Id;

// Get assignments
string jsonResponse = await _client.GetStringAsync($"/api/tenancy/contact-assignments/?content_type=tenancy.tenant&object_id={tenantId}");
JsonNode? assignment = JsonNode.Parse(jsonResponse);

// get roles
List<Contact> contacts = new();
foreach (var a in assignment["results"] as JsonArray)
{
if(a["role"]["slug"].GetValue<string>() != group) { continue; }

int contactId = a["contact"]["id"].GetValue<int>();
string jrContact = await _client.GetStringAsync($"/api/tenancy/contacts/{contactId}/");
JsonNode? contact = JsonNode.Parse(jrContact);

contacts.Add(new Contact()
{
Name = a["contact"]["name"].GetValue<string>(),
Email = contact["email"].GetValue<string>()
});

}

return contacts;

}
}
7 changes: 7 additions & 0 deletions Sherlog.Server/NetboxTenant.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Sherlog.Server;

public class NetboxTenant
{
public string Slug { get; set; }
public int Id { get; set; }
}
26 changes: 26 additions & 0 deletions Sherlog.Server/Pages/Error.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
26 changes: 26 additions & 0 deletions Sherlog.Server/Pages/Error.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Sherlog.Server.Pages;

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

private readonly ILogger<ErrorModel> _logger;

public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}

public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
10 changes: 10 additions & 0 deletions Sherlog.Server/Pages/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
18 changes: 18 additions & 0 deletions Sherlog.Server/Pages/Index.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Sherlog.Server.Pages;

public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;

public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}

public void OnGet()
{
}
}
8 changes: 8 additions & 0 deletions Sherlog.Server/Pages/Privacy.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>
18 changes: 18 additions & 0 deletions Sherlog.Server/Pages/Privacy.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Sherlog.Server.Pages;

public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;

public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}

public void OnGet()
{
}
}
Loading

0 comments on commit 4e14827

Please sign in to comment.