diff --git a/package.json b/package.json index 5f8536a54..e20715b3d 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "re-gen": "yarn clean-all && yarn gen-all", "getBlogs": "node scripts/feed2json.js https://medium.com/feed/palo-alto-networks-developer-blog > src/components/Medium/blogs.json", "getHashicorpBlogs": "node scripts/feed2json.js https://www.hashicorp.com/blog/products/terraform/feed.xml > src/components/ProductLandingPage/Feeds/feeds.json", - "getAllFeeds": "yarn --silent getBlogs", + "getTerraformVersions": "node scripts/fetchTerraformVersions.js", + "getAllFeeds": "yarn --silent getBlogs && yarn --silent getTerraformVersions", "start:netsec": "cross-env PRODUCTS_INCLUDE=cdss,threat-vault,dns-security,iot,expedition,cloudngfw,cdl,panos,terraform,ansible,splunk,aiops-ngfw-bpa,email-dlp,dlp,prisma-airs,prisma-airs-redteam,prisma-airs-model-security yarn start", "start:splunk": "cross-env PRODUCTS_INCLUDE=panos,terraform,ansible,splunk yarn start", "start:iot": "cross-env PRODUCTS_INCLUDE=iot yarn start", diff --git a/products/contributing/advanced/auto-generated-docs.md b/products/contributing/advanced/auto-generated-docs.md index 1eb65c0da..7c52e2be3 100644 --- a/products/contributing/advanced/auto-generated-docs.md +++ b/products/contributing/advanced/auto-generated-docs.md @@ -14,8 +14,8 @@ Some content in pan.dev is generated elsewhere, not in the pan.dev repository di The pages linked from the [Orchestration Hub](https://pan.dev/swfw) which describe References Architectures, Examples and Modules for Terraform are automatically copied from their source repository, using a sync system. These pages are viewable on pan.dev at `https://pan.dev/terraform/docs/swfw/{{cloud-id}}}}/vmseries/{{type}}/`, where `cloud-id` is currently `aws`, `azure` or `gcp`, and `type` is currently `reference-architectures`, `examples` or `modules`. Changes required to these pages should be made in the source repositories. These are currently: -- AWS: https://github.com/PaloAltoNetworks/terraform-aws-vmseries-modules -- Azure: https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules -- GCP: https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules +- AWS: https://github.com/PaloAltoNetworks/terraform-aws-swfw-modules +- Azure: https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules +- GCP: https://github.com/PaloAltoNetworks/terraform-google-swfw-modules Any changes made to the README.md files in the `examples` or `modules` directories of the repositories above will be copied to the pan.dev repository in a cloud-specific PR and branch, when a release is performed in the source repository. The changes can then be reviewed and merged using the usual process for pan.dev content. diff --git a/scripts/fetchTerraformVersions.js b/scripts/fetchTerraformVersions.js new file mode 100644 index 000000000..c6a3044d4 --- /dev/null +++ b/scripts/fetchTerraformVersions.js @@ -0,0 +1,142 @@ +// fetchTerraformVersions.js +// Fetches latest versions of Terraform providers and modules from the +// Terraform Registry API and writes them to src/data/terraform-versions.json. +// Run as part of the build: node scripts/fetchTerraformVersions.js + +const https = require("https"); +const fs = require("fs"); +const path = require("path"); + +const REGISTRY_BASE = "https://registry.terraform.io/v1"; + +// Providers: key = provider type, value = namespace/type for the API +const PROVIDERS = { + panos: "PaloAltoNetworks/panos", + cloudngfwaws: "PaloAltoNetworks/cloudngfwaws", + prismacloud: "PaloAltoNetworks/prismacloud", + prismacloudcompute: "PaloAltoNetworks/prismacloudcompute", + bridgecrew: "PaloAltoNetworks/bridgecrew", +}; + +// Modules: key = name/provider, value = namespace/name/provider for the API +const MODULES = { + "swfw-modules/aws": "PaloAltoNetworks/swfw-modules/aws", + "swfw-modules/google": "PaloAltoNetworks/swfw-modules/google", + "swfw-modules/azurerm": "PaloAltoNetworks/swfw-modules/azurerm", + "ag-dag-nia/panos": "PaloAltoNetworks/ag-dag-nia/panos", + "dag-nia/panos": "PaloAltoNetworks/dag-nia/panos", +}; + +const OUT_PATH = path.join( + __dirname, + "..", + "src", + "data", + "terraform-versions.json" +); + +function fetchJSON(url) { + return new Promise((resolve, reject) => { + https + .get(url, { headers: { "User-Agent": "pan-dev-build" } }, (res) => { + if (res.statusCode !== 200) { + res.resume(); + return reject(new Error(`HTTP ${res.statusCode} for ${url}`)); + } + let data = ""; + res.on("data", (chunk) => (data += chunk)); + res.on("end", () => { + try { + resolve(JSON.parse(data)); + } catch (e) { + reject(new Error(`Invalid JSON from ${url}`)); + } + }); + res.on("error", reject); + }) + .on("error", reject); + }); +} + +// Pre-release versions contain a hyphen after the numeric part (e.g. 3.0.0-rc.1) +function isStableVersion(version) { + return !/^\d+\.\d+\.\d+-.+/.test(version); +} + +async function getProviderVersion(apiPath) { + const data = await fetchJSON(`${REGISTRY_BASE}/providers/${apiPath}`); + const stable = data.versions.filter(isStableVersion); + return stable[stable.length - 1]; +} + +async function getModuleVersion(apiPath) { + const data = await fetchJSON(`${REGISTRY_BASE}/modules/${apiPath}`); + if (isStableVersion(data.version)) { + return data.version; + } + // Latest is pre-release; find the latest stable from the versions list + const stable = data.versions.filter(isStableVersion); + return stable[stable.length - 1]; +} + +async function main() { + // Load existing versions as fallback + let existing = { providers: {}, modules: {} }; + if (fs.existsSync(OUT_PATH)) { + try { + existing = JSON.parse(fs.readFileSync(OUT_PATH, "utf-8")); + } catch {} + } + + const versions = { providers: {}, modules: {} }; + + console.log("Fetching Terraform provider versions..."); + const providerResults = await Promise.allSettled( + Object.entries(PROVIDERS).map(async ([key, apiPath]) => { + const version = await getProviderVersion(apiPath); + versions.providers[key] = `v${version}`; + console.log(` ${key}: v${version}`); + }) + ); + + console.log("Fetching Terraform module versions..."); + const moduleResults = await Promise.allSettled( + Object.entries(MODULES).map(async ([key, apiPath]) => { + const version = await getModuleVersion(apiPath); + versions.modules[key] = `v${version}`; + console.log(` ${key}: v${version}`); + }) + ); + + // For any failures, fall back to existing values + const allResults = [...providerResults, ...moduleResults]; + const failures = allResults.filter((r) => r.status === "rejected"); + if (failures.length > 0) { + console.warn("\nWarning: Some version fetches failed:"); + failures.forEach((f) => console.warn(` ${f.reason.message}`)); + } + + for (const key of Object.keys(PROVIDERS)) { + if (!versions.providers[key]) { + versions.providers[key] = existing.providers?.[key] || "unknown"; + console.warn(` Using fallback for provider ${key}: ${versions.providers[key]}`); + } + } + for (const key of Object.keys(MODULES)) { + if (!versions.modules[key]) { + versions.modules[key] = existing.modules?.[key] || "unknown"; + console.warn(` Using fallback for module ${key}: ${versions.modules[key]}`); + } + } + + fs.mkdirSync(path.dirname(OUT_PATH), { recursive: true }); + fs.writeFileSync(OUT_PATH, JSON.stringify(versions, null, 2) + "\n"); + console.log(`\nWrote ${OUT_PATH}`); +} + +main().catch((err) => { + console.error("Error fetching Terraform versions:", err); + // Non-fatal: don't break the build if the registry is unreachable. + // The existing JSON file (checked into git) will be used instead. + process.exit(0); +}); diff --git a/src/constants/terraform/index.js b/src/constants/terraform/index.js index 2d955a8b2..da702aa7f 100644 --- a/src/constants/terraform/index.js +++ b/src/constants/terraform/index.js @@ -1,5 +1,6 @@ import React from "react"; import Link from "@docusaurus/Link"; +import terraformVersions from "../../data/terraform-versions.json"; // Terraform Landing Page Constants Template // Usage: Define your constants with their respective data for each component and import them into your desired landing page within src/pages. Follow terraform.js for reference to how each constant can be used as props within their respective components. @@ -88,7 +89,7 @@ export const TERRAFORM_PROVIDER_CONTENT = { providerCards: [ { title: "PAN-OS", - latestTag: "v1.11.1", + latestTag: terraformVersions.providers.panos, description: "Define and manage your network security configuration as code, including Panorama, PA-Series, VM-Series and CN-Series.", cta: { @@ -108,7 +109,7 @@ export const TERRAFORM_PROVIDER_CONTENT = { }, { title: "Cloud NGFW", - latestTag: "v2.0.1", + latestTag: terraformVersions.providers.cloudngfwaws, description: "Deploy and manage NGFW functionality, delivered as a cloud-native service within your public cloud tenants, using Terraform.", cta: { @@ -128,7 +129,7 @@ export const TERRAFORM_PROVIDER_CONTENT = { }, { title: "Prisma Cloud", - latestTag: "v1.3.2", + latestTag: terraformVersions.providers.prismacloud, description: "Configure your cloud-native security with Prisma Cloud using Terraform, facilitating automated cloud security operations.", cta: { @@ -148,7 +149,7 @@ export const TERRAFORM_PROVIDER_CONTENT = { }, { title: "Prisma Cloud Compute", - latestTag: "v0.7.0", + latestTag: terraformVersions.providers.prismacloudcompute, description: "Define your cloud workload protection suing Terraform, to protect your host, container and serverless deployments in any cloud.", cta: { @@ -168,7 +169,7 @@ export const TERRAFORM_PROVIDER_CONTENT = { }, { title: "Bridgecrew", - latestTag: "v0.3.7", + latestTag: terraformVersions.providers.bridgecrew, description: "Automate your security engineering by identifying and remediating misconfigurations and vulnerabilities, across code, secrets and images, all defined with Terraform.", cta: { @@ -274,8 +275,8 @@ export const TERRAFORM_MODULES_CONTENT = { { tabLabel: "AWS", title: "Terraform Reusable Modules for VM-Series on AWS", - link: "https://registry.terraform.io/modules/PaloAltoNetworks/vmseries-modules/aws/latest", - latestTag: "v0.4.1", + link: "https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/aws/latest", + latestTag: terraformVersions.modules["swfw-modules/aws"], description: (
A set of modules for using Palo Alto Networks VM-Series firewalls to @@ -304,8 +305,8 @@ export const TERRAFORM_MODULES_CONTENT = { { tabLabel: "GCP", title: "Terraform Reusable Modules for VM-Series on GCP", - link: "https://registry.terraform.io/modules/PaloAltoNetworks/vmseries-modules/google/latest", - latestTag: "v0.5.0", + link: "https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/google/latest", + latestTag: terraformVersions.modules["swfw-modules/google"], description: (
A set of modules for using Palo Alto Networks VM-Series firewalls to @@ -334,8 +335,8 @@ export const TERRAFORM_MODULES_CONTENT = { { tabLabel: "Azure", title: "Terraform Reusable Modules for VM-Series on Azure", - link: "https://registry.terraform.io/modules/PaloAltoNetworks/vmseries-modules/azurerm/latest", - latestTag: "v0.5.1", + link: "https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/azurerm/latest", + latestTag: terraformVersions.modules["swfw-modules/azurerm"], description: (
A set of modules for using Palo Alto Networks VM-Series firewalls to @@ -367,7 +368,7 @@ export const TERRAFORM_MODULES_CONTENT = { tabLabel: "Static Address Groups", title: "Consul-Terraform-Sync Modules for PAN-OS", link: "https://registry.terraform.io/modules/PaloAltoNetworks/ag-dag-nia/panos/latest", - latestTag: "v0.1.0", + latestTag: terraformVersions.modules["ag-dag-nia/panos"], description: (
This Terraform module allows users to support Dynamic Firewalling by @@ -401,7 +402,7 @@ export const TERRAFORM_MODULES_CONTENT = { tabLabel: "Dynamic Address Groups", title: "Consul-Terraform-Sync Modules for PAN-OS", link: "https://registry.terraform.io/modules/PaloAltoNetworks/dag-nia/panos/latest", - latestTag: "v0.2.0", + latestTag: terraformVersions.modules["dag-nia/panos"], description: (
This Terraform module allows users to support Dynamic Firewalling by diff --git a/src/data/terraform-versions.json b/src/data/terraform-versions.json new file mode 100644 index 000000000..3fa43b746 --- /dev/null +++ b/src/data/terraform-versions.json @@ -0,0 +1,16 @@ +{ + "providers": { + "bridgecrew": "v0.3.7", + "prismacloudcompute": "v0.8.0", + "cloudngfwaws": "v3.0.4", + "prismacloud": "v1.7.1", + "panos": "v2.0.10" + }, + "modules": { + "swfw-modules/aws": "v2.2.7", + "swfw-modules/google": "v2.0.12", + "dag-nia/panos": "v0.2.0", + "swfw-modules/azurerm": "v3.4.5", + "ag-dag-nia/panos": "v0.1.0" + } +}