Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Docker Image CI

on:
push:
branches: [ "main" ] # Triggers the workflow on push events to the main branch
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: meysam57 # Your Docker Hub username
password: ${{ secrets.DOCKERHUB_TOKEN }} # Your Docker Hub token stored as a secret

- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
push: true
tags: meysam57/networkinfrastructureweb:latest # Replace with your Docker Hub username and desired image name/tag
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use the official ASP.NET Core runtime as a parent image
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

# Use the official .NET SDK as a build image
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["src/NetworkInfrastructure.Web/NetworkInfrastructure.Web.csproj", "NetworkInfrastructure.Web/"]
# Copy other .csproj files if there are any in the solution that NetworkInfrastructure.Web depends on
# For example: COPY ["src/NetworkInfrastructure.AnotherProject/NetworkInfrastructure.AnotherProject.csproj", "NetworkInfrastructure.AnotherProject/"]
RUN dotnet restore "NetworkInfrastructure.Web/NetworkInfrastructure.Web.csproj"
COPY . .
WORKDIR "/src/NetworkInfrastructure.Web"
RUN dotnet build "NetworkInfrastructure.Web.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "NetworkInfrastructure.Web.csproj" -c Release -o /app/publish /p:UseAppHost=false

# Build runtime image
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "NetworkInfrastructure.Web.dll"]
97 changes: 71 additions & 26 deletions src/NetworkInfrastructure.Web/Controllers/NetworkController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using NetworkInfrastructure.Web.Data.Entities;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;

namespace NetworkInfrastructure.Web.Controllers
{
Expand All @@ -24,20 +25,23 @@ public class NetworkController : Controller
private readonly IValidator<NetworkAssetDto> _netValidator;
private readonly IConfiguration _configuration;
private readonly IMapper _mapper;
private readonly ILogger<NetworkController> _logger;

public NetworkController(INetworkService networkService,
IUserService userService,
IValidator<UserDto> validator,
IConfiguration configuration,
IMapper mapper,
IValidator<NetworkAssetDto> netValidator)
IValidator<NetworkAssetDto> netValidator,
ILogger<NetworkController> logger)
{
_networkService = networkService;
_userService = userService;
_userValidator = validator;
_configuration = configuration;
_mapper = mapper;
_netValidator = netValidator;
_logger = logger;
}

[AllowAnonymous]
Expand All @@ -60,6 +64,7 @@ public async Task<IActionResult> Login(UserDto user)

if (!validate.IsValid)
{
_logger.LogWarning("Login validation failed for user {UserName}.", user.UserName);
validate.AddToModelState(this.ModelState);
return View(user);
}
Expand Down Expand Up @@ -104,9 +109,11 @@ await HttpContext.SignInAsync(
new ClaimsPrincipal(claimsIdentity),
authProperties);

_logger.LogInformation("User {UserName} logged in successfully.", user.UserName);
return RedirectToAction(nameof(Index));
}

_logger.LogWarning("Invalid login attempt for user {UserName}.", user.UserName);
ViewData["ErrMesage"] = "Invalid login attempt.";

return View(user);
Expand Down Expand Up @@ -148,23 +155,40 @@ public IActionResult Create()
[HttpPost]
public async Task<IActionResult> Create(NetworkAssetDto model)
{
var validate = _netValidator.Validate(model);

if (!validate.IsValid)
_logger.LogInformation("Attempting to create network asset with ServerName: {ServerName}", model.ServerName);
try
{
validate.AddToModelState(this.ModelState);
return View(model);
}
var validate = _netValidator.Validate(model);

model.UserName = string.IsNullOrEmpty(ClaimTypes.Name)
? throw new ArgumentNullException(nameof(User))
: User.FindFirstValue(claimType: ClaimTypes.Name);
if (!validate.IsValid)
{
_logger.LogWarning("Validation failed for creating network asset with ServerName: {ServerName}", model.ServerName);
validate.AddToModelState(this.ModelState);
return View(model);
}

var mapper = _mapper.Map<NetworkAsset>(model);
model.UserName = string.IsNullOrEmpty(ClaimTypes.Name)
? throw new ArgumentNullException(nameof(User))
: User.FindFirstValue(claimType: ClaimTypes.Name);

await _networkService.AddAsync(mapper);
var mapper = _mapper.Map<NetworkAsset>(model);

return RedirectToAction(nameof(Index));
await _networkService.AddAsync(mapper);
_logger.LogInformation("Successfully created network asset with ServerName: {ServerName}, ID: {Id}", model.ServerName, mapper.Id);
return RedirectToAction(nameof(Index));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException while creating network asset {ServerName}: User claim for UserName was null or empty.", model.ServerName);
// Potentially return a specific error view or message
throw; // Re-throwing as it's a critical issue for this action
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occurred while creating network asset {ServerName}.", model.ServerName);
// Handle appropriately, maybe return an error view
return View("Error", new ErrorViewModel { RequestId = HttpContext.TraceIdentifier }); // Assuming you have an ErrorViewModel
}
}

public async Task<IActionResult> Details(Guid id)
Expand All @@ -190,12 +214,22 @@ public async Task<IActionResult> Delete(Guid id)
{
if (id == null || id == Guid.Empty)
{
_logger.LogWarning("DeleteAsync called with null or empty ID.");
throw new ArgumentNullException(nameof(id));
}

await _networkService.DeleteAsync(id);

return RedirectToAction(nameof(Index));
_logger.LogInformation("Attempting to delete network asset with ID: {Id}", id);
try
{
await _networkService.DeleteAsync(id);
_logger.LogInformation("Successfully deleted network asset with ID: {Id}", id);
return RedirectToAction(nameof(Index));
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occurred while deleting network asset with ID: {Id}", id);
// Handle appropriately, maybe return an error view
return View("Error", new ErrorViewModel { RequestId = HttpContext.TraceIdentifier }); // Assuming you have an ErrorViewModel
}
}


Expand All @@ -221,19 +255,30 @@ public async Task<IActionResult> Edit(Guid id)
[HttpPost]
public async Task<IActionResult> Edit(NetworkAssetDto model)
{
var validate = _netValidator.Validate(model);

if (!validate.IsValid)
_logger.LogInformation("Attempting to edit network asset with ID: {Id}", model.Id);
try
{
validate.AddToModelState(this.ModelState);
return View(model);
}
var validate = _netValidator.Validate(model);

var mapper = _mapper.Map<NetworkAsset>(model);
if (!validate.IsValid)
{
_logger.LogWarning("Validation failed for editing network asset with ID: {Id}", model.Id);
validate.AddToModelState(this.ModelState);
return View(model);
}

await _networkService.EditAsync(mapper);
var mapper = _mapper.Map<NetworkAsset>(model);

return RedirectToAction(nameof(Index));
await _networkService.EditAsync(mapper);
_logger.LogInformation("Successfully edited network asset with ID: {Id}", model.Id);
return RedirectToAction(nameof(Index));
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occurred while editing network asset with ID: {Id}", model.Id);
// Handle appropriately, maybe return an error view
return View("Error", new ErrorViewModel { RequestId = HttpContext.TraceIdentifier }); // Assuming you have an ErrorViewModel
}
}
}
}