Skip to content

Commit

Permalink
Checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
bhillkeyfactor committed Nov 1, 2024
1 parent ce8205d commit 7f3231b
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 67 deletions.
4 changes: 2 additions & 2 deletions PaloAlto.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30717.126
# Visual Studio Version 17
VisualStudioVersion = 17.11.35222.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PaloAlto", "PaloAlto\PaloAlto.csproj", "{33FBC5A1-3466-4F10-B9A6-7186F804A65A}"
EndProject
Expand Down
16 changes: 16 additions & 0 deletions PaloAlto/Client/PaloAltoClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ public async Task<NamedListResponse> GetDeviceGroupList()
_logger.LogError($"Error Occured in PaloAltoClient.GetDeviceGroupList: {e.Message}");
throw;
}
}

public async Task<NamedListResponse> GetTemplateStackList()
{
try
{
var uri =
$"/api/?type=config&action=get&xpath=/config/devices/entry[@name='localhost.localdomain']/template-stack/entry/@name&key={ApiKey}";
var response = await GetXmlResponseAsync<NamedListResponse>(await HttpClient.GetAsync(uri));
return response;
}
catch (Exception e)
{
_logger.LogError($"Error Occured in PaloAltoClient.GetDeviceGroupList: {e.Message}");
throw;
}
}

public async Task<CommitResponse> GetCommitResponse()
Expand Down
2 changes: 1 addition & 1 deletion PaloAlto/Jobs/Management.cs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ private string CommitChanges(ManagementJobConfiguration config, PaloAltoClient c
_logger.LogTrace($"Template Stack {templateStack}");

//If there is a template and device group then push to all firewall devices because it is Panorama
if (IsPanoramaDevice(config))
if (Validators.IsValidPanoramaVsysFormat(config.CertificateStoreDetails.StorePath) || Validators.IsValidPanoramaFormat(config.CertificateStoreDetails.StorePath))
{
_logger.LogTrace("It is a panorama device, build some delay in there so it works, pan issue.");
Thread.Sleep(120000); //Some delay built in so pushes to devices work
Expand Down
28 changes: 24 additions & 4 deletions PaloAlto/Validators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ private static string GetTemplateName(string storePath)
return templateName;
}

static bool IsValidPanoramaFormat(string input)
public static bool IsValidPanoramaFormat(string input)
{
string pattern = @"^/config/devices/entry\[@name='[^\]]+'\]/template/entry\[@name='[^']+'\]/config/shared$";
Regex regex = new Regex(pattern);
return regex.IsMatch(input);
}

static bool IsValidFirewallVsysFormat(string input)
public static bool IsValidFirewallVsysFormat(string input)
{
string pattern = @"^/config/devices/entry\[@name='localhost\.localdomain'\]/vsys/entry\[@name='[^']+'\]$";
return Regex.IsMatch(input, pattern);
Expand All @@ -77,12 +77,20 @@ public static (bool valid, JobResult result) ValidateStoreProperties(JobProperti
}

// If it is a firewall (store path of /) then you don't need the Group Name
if (!storePath.Contains("template",System.StringComparison.CurrentCultureIgnoreCase))
if (!storePath.Contains("template", System.StringComparison.CurrentCultureIgnoreCase))
{
if (!string.IsNullOrEmpty(storeProperties?.DeviceGroup))
{
errors +=
"You do not need a device group with a Palo Alto Firewall. It is only required for Panorama.";
}
}
if (!string.IsNullOrEmpty(storeProperties?.TemplateStack))
{
errors +=
"You do not need a Template Stack with a Palo Alto Firewall. It is only required for Panorama.";
}
}


// Considered Panorama device if store path is not "/" and there is a valid value for store path
if (storePath.Contains("template", System.StringComparison.CurrentCultureIgnoreCase))
Expand All @@ -101,8 +109,20 @@ public static (bool valid, JobResult result) ValidateStoreProperties(JobProperti
errors +=
$"Could not find your Device Group In Panorama. Valid Device Groups are {string.Join(",", deviceList.Result.Result.Entry.Select(d => d.Name))}";
}
}

if (!string.IsNullOrEmpty(storeProperties?.TemplateStack))
{
var templateStackList = client.GetTemplateStackList();
var templateStacks = templateStackList.Result.Result.Entry.Where(d => d.Name == storeProperties?.TemplateStack);
if (!templateStacks.Any())
{
errors +=
$"Could not find your Template Stacks In Panorama. Valid Device Groups are {string.Join(",", templateStackList.Result.Result.Entry.Select(d => d.Name))}";
}
}


//Validate Template Exists in Panorama, required for Panorama
var templateList = client.GetTemplateList();
var templates = templateList.Result.Result.Entry.Where(d => d.Name == GetTemplateName(storePath));
Expand Down
2 changes: 1 addition & 1 deletion PaloAltoTestConsole/FirewallInventory.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"ClientMachine": "ClientMachineGoesHere",
"StorePath": "/",
"StorePassword": "",
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"\"}",
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"\",\"InventoryTrustedCerts\": false,\"TemplateStack\":\"TemplateStackGoesHere\"}",
"Type": 105
},
"JobCancelled": false,
Expand Down
2 changes: 1 addition & 1 deletion PaloAltoTestConsole/KeyfactorClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public async Task<KeyfactorEnrollmentResult> EnrollCertificate(string commonName
var request = new RestRequest("/KeyfactorAPI/Enrollment/PFX", Method.Post);
request.AddHeader("X-Keyfactor-Requested-With", "APIClient");
request.AddHeader("x-certificateformat", "PFX");
request.AddHeader("Authorization", "Basic Q29tbWFuZFxLRkFkbWluOldoNUcyVGM2VkJZalNNcEM=");
request.AddHeader("Authorization", "Basic Y29tbWFuZFxLRkFkbWluOldoNUcyVGM2VkJZalNNcEM=");
request.AddHeader("Content-Type", "application/json");
var enrollRequest = new KeyfactorEnrollmentRequest
{
Expand Down
2 changes: 1 addition & 1 deletion PaloAltoTestConsole/ManagementRemove.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"ClientMachine": "ClientMachineGoesHere",
"StorePath": "TemplateNameGoesHere",
"StorePassword": null,
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"DeviceGroupGoesHere\"}",
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"DeviceGroupGoesHere\",\"InventoryTrustedCerts\": false,\"TemplateStack\":\"TemplateStackGoesHere\"}",
"Type": 105
},
"OperationType": 3,
Expand Down
2 changes: 1 addition & 1 deletion PaloAltoTestConsole/PanoramaInventory.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"ClientMachine": "ClientMachineGoesHere",
"StorePath": "TemplateNameGoesHere",
"StorePassword": "",
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"DeviceGroupGoesHere\"}",
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"DeviceGroupGoesHere\",\"InventoryTrustedCerts\": false,\"TemplateStack\":\"TemplateStackGoesHere\"}",
"Type": 105
},
"JobCancelled": false,
Expand Down
2 changes: 1 addition & 1 deletion PaloAltoTestConsole/PanoramaMgmt.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"ClientMachine": "ClientMachineGoesHere",
"StorePath": "TemplateNameGoesHere",
"StorePassword": null,
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"DeviceGroupGoesHere\"}",
"Properties": "{\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\",\"DeviceGroup\":\"DeviceGroupGoesHere\",\"InventoryTrustedCerts\": false,\"TemplateStack\":\"TemplateStackGoesHere\"}",
"Type": 105
},
"OperationType": 2,
Expand Down
64 changes: 58 additions & 6 deletions PaloAltoTestConsole/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using Keyfactor.Orchestrators.Extensions.Interfaces;
using Moq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace PaloAltoTestConsole
{
Expand All @@ -33,6 +34,8 @@ internal class Program
public static string CertAlias { get; set; }
public static string ClientMachine { get; set; }
public static string DeviceGroup { get; set; }
public static string InventoryTrusted { get; set; }
public static string TemplateStackName { get; set; }
public static string StorePath { get; set; }
public static string Overwrite { get; set; }
public static string ManagementType { get; set; }
Expand All @@ -59,6 +62,8 @@ private static async Task Main(string[] args)
Password = arguments["-password"];
StorePath = arguments["-storepath"];
DeviceGroup = arguments["-devicegroup"];
InventoryTrusted = arguments["-inventorytrusted"];
TemplateStackName = arguments["-templatestackname"];
ClientMachine = arguments["-clientmachine"];
}
else
Expand All @@ -73,6 +78,10 @@ private static async Task Main(string[] args)
StorePath = Console.ReadLine();
Console.WriteLine("Enter DeviceGroup");
DeviceGroup = Console.ReadLine();
Console.WriteLine("Inventory Trusted");
InventoryTrusted = Console.ReadLine();
Console.WriteLine("Template Stack Name");
TemplateStackName = Console.ReadLine();
Console.WriteLine("Enter ClientMachine");
ClientMachine = Console.ReadLine();
}
Expand Down Expand Up @@ -184,20 +193,49 @@ public static bool GetItems(IEnumerable<CurrentInventoryItem> items)

public static InventoryJobConfiguration GetInventoryJobConfiguration()
{
var intentoryTrustedReplaceString = "\"InventoryTrustedCerts\": false";
if (InventoryTrusted.ToUpper() == "TRUE")
{
intentoryTrustedReplaceString = "\"InventoryTrustedCerts\": true";
}

var fileContent = File.ReadAllText("FirewallInventory.json").Replace("UserNameGoesHere", UserName)
.Replace("PasswordGoesHere", Password).Replace("ClientMachineGoesHere", ClientMachine);
.Replace("PasswordGoesHere", Password).Replace("ClientMachineGoesHere", ClientMachine)
.Replace("\"InventoryTrustedCerts\": false", intentoryTrustedReplaceString);
var jsonObject = JObject.Parse(fileContent);

// Navigate to the InventoryTrustedCerts property and set it to true
jsonObject["CertificateStoreDetails"]["Properties"] = jsonObject["CertificateStoreDetails"]["Properties"].ToString().Replace("\"InventoryTrustedCerts\": false", intentoryTrustedReplaceString);


var result =
JsonConvert.DeserializeObject<InventoryJobConfiguration>(fileContent);
JsonConvert.DeserializeObject<InventoryJobConfiguration>(jsonObject.ToString());

return result;
}

public static InventoryJobConfiguration GetPanoramaInventoryJobConfiguration()
{
var intentoryTrustedReplaceString = "\"InventoryTrustedCerts\": false";
if (InventoryTrusted.ToUpper() == "TRUE")
{
intentoryTrustedReplaceString = "\"InventoryTrustedCerts\": true";
}

var fileContent = File.ReadAllText("PanoramaInventory.json").Replace("UserNameGoesHere", UserName)
.Replace("PasswordGoesHere", Password).Replace("TemplateNameGoesHere", StorePath)
.Replace("ClientMachineGoesHere", ClientMachine).Replace("DeviceGroupGoesHere", DeviceGroup);
.Replace("ClientMachineGoesHere", ClientMachine)
.Replace("DeviceGroupGoesHere", DeviceGroup);


var jsonObject = JObject.Parse(fileContent);

// Navigate to the InventoryTrustedCerts property and set it to true
jsonObject["CertificateStoreDetails"]["Properties"] = jsonObject["CertificateStoreDetails"]["Properties"].ToString().Replace("\"InventoryTrustedCerts\": false", intentoryTrustedReplaceString);


var result =
JsonConvert.DeserializeObject<InventoryJobConfiguration>(fileContent);
JsonConvert.DeserializeObject<InventoryJobConfiguration>(jsonObject.ToString());
return result;
}

Expand All @@ -209,15 +247,29 @@ public static ManagementJobConfiguration GetManagementJobConfiguration()
{
overWriteReplaceString = "\"Overwrite\": true";
}


var intentoryTrustedReplaceString = "\"InventoryTrustedCerts\": false";
if (InventoryTrusted.ToUpper() == "TRUE")
{
intentoryTrustedReplaceString = "\"InventoryTrustedCerts\": true";
}

var fileContent = File.ReadAllText("PanoramaMgmt.json").Replace("UserNameGoesHere", UserName)
.Replace("PasswordGoesHere", Password).Replace("TemplateNameGoesHere", StorePath)
.Replace("DeviceGroupGoesHere", DeviceGroup).Replace("AliasGoesHere", CertAlias)
.Replace("TemplateStackGoesHere", TemplateStackName)
.Replace("ClientMachineGoesHere", ClientMachine)
.Replace("\"Overwrite\": false",overWriteReplaceString)
.Replace("CertificateContentGoesHere", CertificateContent);

var jsonObject = JObject.Parse(fileContent);

// Navigate to the InventoryTrustedCerts property and set it to true
jsonObject["CertificateStoreDetails"]["Properties"] = jsonObject["CertificateStoreDetails"]["Properties"].ToString().Replace("\"InventoryTrustedCerts\": false", intentoryTrustedReplaceString);

var result =
JsonConvert.DeserializeObject<ManagementJobConfiguration>(fileContent);
JsonConvert.DeserializeObject<ManagementJobConfiguration>(jsonObject.ToString());

return result;
}

Expand Down
Loading

0 comments on commit 7f3231b

Please sign in to comment.