OctopusDeploy / Issues

| Public | Bug reports and known issues for Octopus Deploy and all related tools
https://octopus.com
162 stars 20 forks source link

Project names with certain special characters may fail to load with an Octopus.Core.Model.Exceptions.EntityNotFoundException error #7545

Closed donnybell closed 2 years ago

donnybell commented 2 years ago

Team

Severity

Blocking

Version

Reproduced in 2022.1.2584

Latest Version

No response

What happened?

Project names with certain special characters may fail to load with an Octopus.Core.Model.Exceptions.EntityNotFoundException error.

Examples include:

It appears that there's something going on with the URL encode/decode. For example, a project with the name åååååå in 2022.1.2584 results in the following: http://octopus_url/app#/Spaces-1/projects/åååååå turns into: http://octopus_url/api/Spaces-1/projects/%25C3%25A5%25C3%25A5%25C3%25A5%25C3%25A5%25C3%25A5%25C3%25A5 when viewing the console in my browser

The correct URL should be: http://octopus_url/api/Spaces-1/projects/%C3%A5%C3%A5%C3%A5%C3%A5%C3%A5%C3%A5

Reproduction

Create a project with the name of åååååå in 2022.1.2584, then try to access it.

Error and Stacktrace

image

2022-05-12 12:30:49.1316   1824     43  INFO  "Exception of type 'Octopus.Core.Model.Exceptions.EntityNotFoundException' was thrown."
Octopus.Core.Model.Exceptions.EntityNotFoundException: Exception of type 'Octopus.Core.Model.Exceptions.EntityNotFoundException' was thrown.
   at Octopus.Core.Features.Projects.ProjectDocumentStoreExtensionMethods.ByIdOrSlug(IDocumentStore`2 documentStore, String idOrSlug, CancellationToken cancellationToken) in ./source/Octopus.Core/Features/Projects/ProjectDocumentStoreExtensionMethods.cs:line 32
   at Octopus.Server.Web.Controllers.Projects.GetProjectByIdOrSlugController.GetByIdOrSlug(String id, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Controllers/Projects/GetProjectByIdOrSlugController.cs:line 45
   at lambda_method5614(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.Infrastructure.Authentication.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) in ./source/Octopus.Server/Web/Infrastructure/Authentication/AuthorizationMiddlewareResultHandler.cs:line 52
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.HttpOverrides.HttpMethodOverrideMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 47
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 47
   at Octopus.Server.Web.Middleware.OctopusClientOldVersionWarningMiddleware.InvokeAsync(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/OctopusClientOldVersionWarningMiddleware.cs:line 53
   at Octopus.Server.Web.Middleware.DynamicContentHeadersMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/DynamicContentHeadersMiddleware.cs:line 49
   at Octopus.Server.Web.Middleware.MaintenanceModeMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/MaintenanceModeMiddleware.cs:line 61
   at Octopus.Server.Web.Middleware.OctopusAuthenticationMiddleware.InvokeAsync(HttpContext context, CorrelationId correlationId) in ./source/Octopus.Server/Web/Middleware/OctopusAuthenticationMiddleware.cs:line 67
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.Middleware.LegacyRequestLoggerMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/LegacyRequestLoggerMiddleware.cs:line 42
   at Octopus.Server.Web.Middleware.TelemetryMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/TelemetryMiddleware.cs:line 76
   at Octopus.Server.Web.Middleware.ErrorHandlingMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/ErrorHandlingMiddleware.cs:line 96

More Information

Internal Conversation - https://octopusdeploy.slack.com/archives/CNHBHV2BX/p1652374468520679

Workaround

You can manually change the project name via the API.

$ErrorActionPreference = "Stop";

# Define working variables
$octopusURL = "https://OctopusURL"
$octopusAPIKey = "API-5HTQBFFXXXXXXXXXFOG0FKTQAMMPK"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }
$spaceName = "Default"
$oldProjectName = "Old Project Name"
$newProjectName = "New Project Name"

# Get space
$spaces = Invoke-RestMethod -Uri "$octopusURL/api/spaces?partialName=$([uri]::EscapeDataString($spaceName))&skip=0&take=100" -Headers $header
$space = $spaces.Items | Where-Object { $_.Name -eq $spaceName }

# Get project
$projects = Invoke-RestMethod -Uri "$octopusURL/api/$($space.Id)/projects?partialName=$([uri]::EscapeDataString($oldProjectName))&skip=0&take=100" -Headers $header
$project = $projects.Items | Where-Object { $_.Name -eq $oldProjectName }

# Change Project Name
$project.Name = $newProjectName

# Save project changes
Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/projects/$($project.Id)" -Headers $header -Body ($project | ConvertTo-Json -Depth 10)
veochen-octopus commented 2 years ago

From the original slack conversation it looks like it affects 2022.1.2584 and 2022.2.5111 and potentially all versions from there.

StephenHeise commented 2 years ago

I have reverted https://github.com/OctopusDeploy/OctopusDeploy/pull/11894, which is related to escaping / and % in the URL. The problem persists, so is not related to this change. Turns out this is caused by the 11894 change - I wasn't testing it properly.

boeggild commented 2 years ago

Any timeframe on a fix for this issue?

Clare-Octopus commented 2 years ago

Another customer experiencing this issue (Internal Ticket) - https://octopus.zendesk.com/agent/tickets/91016

StephenHeise commented 2 years ago

Sorry - missed the messages. I'm working on a fix for this issue this week. It is really getting into the depths of React's routing and proving to be 'difficult'.

StephenHeise commented 2 years ago

Sorry this has taken a while to get sorted. We have decided to revert the original change that caused the Unicode project names to break. The original change was done to allow % symbols in Git branch names, but that will be very rare compared to Unicode project names. The fix is in this PR.

octoreleasebot commented 2 years ago

Release Note: Fixed issue with Unicode in project names

gh-ttgo commented 2 years ago

When will this fix become available in the on-premise version?

StephenHeise commented 2 years ago

@gh-ttgo The 2022.3 release is currently scheduled for General Availability release on 5 September.

cjberg commented 2 years ago

Heads up! If any other project properties contain non-ASCII characters, the workaround script needs to be adjusted:

# Save project changes
$body = [Text.Encoding]::UTF8.GetBytes(($project | ConvertTo-Json -Depth 10))
Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/projects/$($project.Id)" -Headers $header -Body $body

Otherwise those properties will be garbled. The server (v2022.2.7457) doesn't seem to validate the received project configuration entirely, because it accepted the update. It broke both the project view and the API GET .../projects/: Octopus.Core.Model.Exceptions.DomainException: The package step provided could not be found in the project's deployment process (see Automatic Release Creation settings, via Project > Triggers). (I fixed it by updating the project with a new handcrafted JSON configuration.)

boeggild commented 2 years ago

The error is stil present in 2022.3.7782 (onprem)

Octobob commented 2 years ago

:tada: The fix for this issue has been released in:

Release stream Release
2022.1 2022.1.3180
2022.2 2022.2.7965
2022.3 2022.3.9953
2022.4+ all releases