Skip to content

Commit 5eb2426

Browse files
authored
Release: 2.5.1
Adds a longer timeout to checking for commit status
2 parents 30fa871 + d4b2f5f commit 5eb2426

28 files changed

Lines changed: 634 additions & 86 deletions
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
run-name: Build and Test Solution - ${{ github.sha }}
2+
name: Build and Test Solution
3+
4+
on:
5+
pull_request:
6+
types: [opened, synchronize, reopened]
7+
8+
jobs:
9+
build-and-test-solution:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
dotnet-version: [ '6.0.x', '8.0.x' ]
14+
steps:
15+
- name: Checkout Code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup .NET 6
19+
uses: actions/setup-dotnet@v4
20+
with:
21+
dotnet-version: '6.0.x'
22+
23+
- name: Setup .NET 8
24+
uses: actions/setup-dotnet@v4
25+
with:
26+
dotnet-version: '8.0.x'
27+
28+
- name: Add Keyfactor NuGet Source
29+
run: dotnet nuget add source https://nuget.pkg.github.com/Keyfactor/index.json -n github -u ${{ github.actor }} -p ${{ secrets.V2BUILDTOKEN }} --store-password-in-clear-text
30+
31+
- name: Restore Dependencies
32+
run: dotnet restore
33+
34+
- name: Build solution
35+
run: dotnet build --no-restore --configuration Release
36+
37+
- name: Run Unit Tests
38+
run: dotnet test --configuration Release --no-build --filter "Category!=Integration"

.github/workflows/keyfactor-starter-workflow.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,17 @@ on:
1111

1212
jobs:
1313
call-starter-workflow:
14-
uses: keyfactor/actions/.github/workflows/starter.yml@v3
14+
uses: keyfactor/actions/.github/workflows/starter.yml@v4
15+
with:
16+
command_token_url: ${{ vars.COMMAND_TOKEN_URL }}
17+
command_hostname: ${{ vars.COMMAND_HOSTNAME }}
18+
command_base_api_path: ${{ vars.COMMAND_API_PATH }}
1519
secrets:
1620
token: ${{ secrets.V2BUILDTOKEN}}
17-
APPROVE_README_PUSH: ${{ secrets.APPROVE_README_PUSH}}
1821
gpg_key: ${{ secrets.KF_GPG_PRIVATE_KEY }}
1922
gpg_pass: ${{ secrets.KF_GPG_PASSPHRASE }}
2023
scan_token: ${{ secrets.SAST_TOKEN }}
24+
entra_username: ${{ secrets.DOCTOOL_ENTRA_USERNAME }}
25+
entra_password: ${{ secrets.DOCTOOL_ENTRA_PASSWD }}
26+
command_client_id: ${{ secrets.COMMAND_CLIENT_ID }}
27+
command_client_secret: ${{ secrets.COMMAND_CLIENT_SECRET }}

CHANGELOG.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,53 @@
1-
2.5.0
1+
# 2.5.1
2+
Features:
3+
- Add validation logic for certificate alias length. If targeting Firewall directly, alias length must be less than 64 characters. If targeting Panorama, alias length must be less than 32 characters. This is to prevent errors when pushing certificates to Palo Alto.
4+
- Increased timeout for checking on job status from 10 minutes to 60 minutes.
5+
- Improved error handling and logging for commit operations, including more detailed error messages when commits fail.
6+
7+
# 2.5.0
28
Features:
39
- Add support for multiple Device Groups. You can now specify a comma-delimited list of Device Groups for your Certificate Store. i.e. `Group 1;Group 2;Group 3`.
410
- Improved support for validating commit changes are successfully pushed from Panorama to Firewall.
511

6-
2.4.0
12+
# 2.4.0
713
* .Net 6 and .Net 8 Build Support
814
* Documentation Updates
915

10-
2.3.1
16+
# 2.3.1
1117
* Fixed issue where trace logs had extra info in them
1218
* Fixed issue with chain support when pushing certs to palo
1319

14-
2.3.0
20+
# 2.3.0
1521
* Added support for Template Only Commits
1622
* Added support for Template Stack Commits
1723
* Added support for ingoring Trusted Default Certs on inventory to speed up the inventory job
1824

19-
2.2.1
25+
# 2.2.1
2026
* Fixed URL Encoding on Palo Username and Pwd that caused invalid credentials error
2127

22-
2.2.0
28+
# 2.2.0
2329
* Removed support for binding cert to new binding location, can only update certs that are previously bound
2430
* Support for replacing certs on all binding locations both Panorama and Firewalls as long as it was there before
2531
* Support for Virtual Systems on Firewalls, tested with only Azure Virtual Version of Firewall
2632
* Support for Virtual Systems on Panorama Templates
2733

28-
2.1.1
34+
# 2.1.1
2935
* Bug - Add Renew Failure Object Reference Error when Adding/Renewing a cert.
3036

31-
2.1.0
37+
# 2.1.0
3238
* Support for Pan Level Certficates
3339
* Support for Pushing Entire Certificate Chain to Panorama
3440
* Auto Detection of Trusted Root Certificates
3541
* Fix Inventory Check For Private Key from Dummy to Anything
3642

37-
2.0.1
43+
# 2.0.1
3844
* Fix Epoch Time in Model from int to long to prevent inventory errors
3945

40-
2.0.0
46+
# 2.0.0
4147
* Support for Panorama or Firewall connectivity
4248
* Commits changes to the Individual Firewall
4349
* Support for Panorama push to firewalls
4450

45-
1.0.3
51+
# 1.0.3
4652
* Added PAM Support for Orchestrator
4753

PaloAlto.IntegrationTests/BaseIntegrationTest.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2025 Keyfactor
1+
// Copyright 2026 Keyfactor
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -16,16 +16,31 @@
1616
using Keyfactor.Orchestrators.Common.Enums;
1717
using Keyfactor.Orchestrators.Extensions;
1818
using Keyfactor.Orchestrators.Extensions.Interfaces;
19+
using Microsoft.Extensions.Logging;
20+
using MartinCostello.Logging.XUnit;
1921
using Moq;
2022
using Newtonsoft.Json;
2123
using PaloAlto.IntegrationTests.Models;
2224
using Xunit;
25+
using Xunit.Abstractions;
2326

2427
namespace PaloAlto.IntegrationTests;
2528

29+
[Trait("Category", "Integration")]
2630
public abstract class BaseIntegrationTest
2731
{
2832
protected readonly string MockCertificatePassword = "sldfklsdfsldjfk";
33+
private readonly ILogger _logger;
34+
35+
protected BaseIntegrationTest(ITestOutputHelper output)
36+
{
37+
var loggerFactory = LoggerFactory.Create(builder =>
38+
{
39+
builder.AddProvider(new XUnitLoggerProvider(output, new XUnitLoggerOptions()));
40+
builder.SetMinimumLevel(LogLevel.Debug);
41+
});
42+
_logger = loggerFactory.CreateLogger<BaseIntegrationTest>();
43+
}
2944

3045
protected void AssertJobSuccess(JobResult result, string context)
3146
{
@@ -62,7 +77,7 @@ protected JobResult ProcessInventoryJob(TestInventoryJobConfigurationProperties
6277
mgmtSecretResolver
6378
.Setup(m => m.Resolve(It.Is<string>(s => s == config.ServerPassword)))
6479
.Returns(() => config.ServerPassword);
65-
var inventory = new Inventory(mgmtSecretResolver.Object);
80+
var inventory = new Inventory(mgmtSecretResolver.Object, _logger);
6681
return inventory.ProcessJob(config, _ => true);
6782
}
6883

@@ -75,7 +90,7 @@ private JobResult ProcessManagementJob(ManagementJobConfiguration config)
7590
mgmtSecretResolver
7691
.Setup(m => m.Resolve(It.Is<string>(s => s == config.ServerPassword)))
7792
.Returns(() => config.ServerPassword);
78-
var mgmt = new Management(mgmtSecretResolver.Object);
93+
var mgmt = new Management(mgmtSecretResolver.Object, _logger);
7994
return mgmt.ProcessJob(config);
8095
}
8196

PaloAlto.IntegrationTests/InventoryIntegrationTests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2025 Keyfactor
1+
// Copyright 2026 Keyfactor
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -14,11 +14,17 @@
1414

1515
using PaloAlto.IntegrationTests.Models;
1616
using Xunit;
17+
using Xunit.Abstractions;
1718

1819
namespace PaloAlto.IntegrationTests;
1920

2021
public class InventoryIntegrationTests : BaseIntegrationTest
2122
{
23+
public InventoryIntegrationTests(ITestOutputHelper output) : base(output)
24+
{
25+
26+
}
27+
2228
#region Firewall Tests
2329

2430
// Test Case 6 repeats across Management + Inventory. Keeping number in place for parity.

PaloAlto.IntegrationTests/ManagementIntegrationTests.cs

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2025 Keyfactor
1+
// Copyright 2026 Keyfactor
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -15,11 +15,16 @@
1515
using PaloAlto.IntegrationTests.Generators;
1616
using PaloAlto.IntegrationTests.Models;
1717
using Xunit;
18+
using Xunit.Abstractions;
1819

1920
namespace PaloAlto.IntegrationTests;
2021

2122
public class ManagementIntegrationTests : BaseIntegrationTest
2223
{
24+
public ManagementIntegrationTests(ITestOutputHelper output) : base(output)
25+
{
26+
}
27+
2328
#region Firewall Tests
2429

2530
[Fact(DisplayName = "TC01: Firewall Enroll No Bindings")]
@@ -898,4 +903,107 @@ public void TestCase25_PanoramaAdd_Vsys_BoundCert_WithOverride_ShouldSucceed()
898903
}
899904

900905
#endregion
906+
907+
#region Alias Length Validation
908+
909+
[Fact(DisplayName = "TC26a: Panorama Enroll when alias name is too long, returns error")]
910+
public void TestCase26a_PanoramaEnroll_WhenAliasNameIsTooLong_ReturnsFailure()
911+
{
912+
var alias = new string('a', 32);
913+
var certificateContent = PfxGenerator.GetBlobWithChain(alias, MockCertificatePassword);
914+
915+
var props = new TestManagementJobConfigurationProperties()
916+
{
917+
StorePath =
918+
"/config/devices/entry[@name='localhost.localdomain']/template/entry[@name='CertificatesTemplate']/config/shared",
919+
DeviceGroup = "Group1",
920+
Alias = alias,
921+
Overwrite = false,
922+
923+
CertificateContents = certificateContent,
924+
CertificatePassword = MockCertificatePassword,
925+
TemplateStack = ""
926+
};
927+
props.AddPanoramaCredentials();
928+
929+
var result = ProcessManagementAddJob(props);
930+
931+
AssertJobFailure(result, $"Certificate alias '{alias}' is too long, it must not be more than 31 characters. Current length: 32");
932+
}
933+
934+
[Fact(DisplayName = "TC26b: Firewall Enroll when alias name is too long, returns error")]
935+
public void TestCase26b_FirewallEnroll_WhenAliasNameIsTooLong_ReturnsFailure()
936+
{
937+
var alias = new string('a', 64);
938+
var certificateContent = PfxGenerator.GetBlobWithChain(alias, MockCertificatePassword);
939+
940+
var props = new TestManagementJobConfigurationProperties()
941+
{
942+
StorePath =
943+
"/config/shared",
944+
DeviceGroup = "",
945+
Alias = alias,
946+
Overwrite = false,
947+
948+
CertificateContents = certificateContent,
949+
CertificatePassword = MockCertificatePassword,
950+
TemplateStack = ""
951+
};
952+
props.AddPanoramaCredentials();
953+
954+
var result = ProcessManagementAddJob(props);
955+
956+
AssertJobFailure(result, $"Certificate alias '{alias}' is too long, it must not be more than 63 characters. Current length: 64");
957+
}
958+
959+
[Fact(DisplayName = "TC26c: Panorama Enroll Enroll Alias Length Valid")]
960+
public void TestCase26c_PanoramaEnroll_WhenAliasNameValid_NoFailure()
961+
{
962+
var alias = new string('a', 31);
963+
var certificateContent = PfxGenerator.GetBlobWithChain(alias, MockCertificatePassword);
964+
965+
var props = new TestManagementJobConfigurationProperties()
966+
{
967+
StorePath =
968+
"/config/devices/entry[@name='localhost.localdomain']/template/entry[@name='CertificatesTemplate']/config/shared",
969+
DeviceGroup = "",
970+
Alias = alias,
971+
Overwrite = true,
972+
973+
CertificateContents = certificateContent,
974+
CertificatePassword = MockCertificatePassword,
975+
TemplateStack = ""
976+
};
977+
props.AddPanoramaCredentials();
978+
979+
var result = ProcessManagementAddJob(props);
980+
981+
AssertJobSuccess(result, "Add");
982+
}
983+
984+
[Fact(DisplayName = "TC26d: Firewall Enroll Alias Length Valid")]
985+
public void TestCase26d_FirewallEnroll_WhenAliasNameValid_NoFailure()
986+
{
987+
var alias = new string('a', 63);
988+
var certificateContent = PfxGenerator.GetBlobWithChain(alias, MockCertificatePassword);
989+
990+
var props = new TestManagementJobConfigurationProperties()
991+
{
992+
StorePath = "/config/shared",
993+
DeviceGroup = "",
994+
Alias = alias,
995+
Overwrite = true,
996+
997+
CertificateContents = certificateContent,
998+
CertificatePassword = MockCertificatePassword,
999+
TemplateStack = ""
1000+
};
1001+
props.AddFirewallCredentials();
1002+
1003+
var result = ProcessManagementAddJob(props);
1004+
1005+
AssertJobSuccess(result, "Add");
1006+
}
1007+
1008+
#endregion
9011009
}

PaloAlto.IntegrationTests/PaloAlto.IntegrationTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12+
<PackageReference Include="MartinCostello.Logging.XUnit" Version="0.6.0" />
1213
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0"/>
1314
<PackageReference Include="Moq.AutoMock" Version="3.4.0" />
1415
<PackageReference Include="xunit" Version="2.4.1"/>

0 commit comments

Comments
 (0)