diff --git a/assets/pango/errors/panos.go b/assets/pango/errors/panos.go index 9b9f30c4..d98daf02 100644 --- a/assets/pango/errors/panos.go +++ b/assets/pango/errors/panos.go @@ -58,8 +58,12 @@ func Parse(body []byte) error { _ = xml.Unmarshal(body, &e) if e.Failed() { + msg := e.Message() + if msg == "" { + msg = fmt.Sprintf("(raw response: %s)", strings.TrimSpace(string(body))) + } return Panos{ - Msg: e.Message(), + Msg: msg, Code: e.Code, } } diff --git a/assets/terraform/examples/resources/panos_administrator/resource.tf b/assets/terraform/examples/resources/panos_administrator/resource.tf new file mode 100644 index 00000000..0df3024a --- /dev/null +++ b/assets/terraform/examples/resources/panos_administrator/resource.tf @@ -0,0 +1,13 @@ +resource "panos_administrator" "example" { + location = { + panorama = {} + } + name = "admin-user" + authentication_profile = "my-auth-profile" + + permissions = { + role_based = { + superuser = true + } + } +} diff --git a/assets/terraform/examples/resources/panos_decryption_profile/resource.tf b/assets/terraform/examples/resources/panos_decryption_profile/resource.tf new file mode 100644 index 00000000..119278ee --- /dev/null +++ b/assets/terraform/examples/resources/panos_decryption_profile/resource.tf @@ -0,0 +1,26 @@ +resource "panos_decryption_profile" "example" { + location = { + shared = {} + } + name = "my-decryption-profile" + + ssl_forward_proxy = { + block_expired_certificate = true + block_untrusted_issuer = true + block_unknown_cert = true + block_unsupported_version = true + block_unsupported_cipher = true + restrict_cert_exts = true + } + + ssl_protocol_settings = { + min_version = "tls1-2" + max_version = "max" + keyxchg_algo_rsa = true + keyxchg_algo_ecdhe = true + enc_algo_aes_128_gcm = true + enc_algo_aes_256_gcm = true + auth_algo_sha256 = true + auth_algo_sha384 = true + } +} diff --git a/assets/terraform/examples/resources/panos_email_server_profile/resource.tf b/assets/terraform/examples/resources/panos_email_server_profile/resource.tf index c9d7c115..eb45766e 100644 --- a/assets/terraform/examples/resources/panos_email_server_profile/resource.tf +++ b/assets/terraform/examples/resources/panos_email_server_profile/resource.tf @@ -1,50 +1,18 @@ -resource "panos_template" "example" { - location = { panorama = {} } - name = "example-template" -} - -# Email server profile forwarding security logs to a corporate SMTP relay -# with authenticated SMTP and custom log format strings. resource "panos_email_server_profile" "example" { - location = { - template = { - name = panos_template.example.name - } - } - - name = "security-alerts-email" - - servers = [ - { - name = "corporate-smtp" - display_name = "Corporate SMTP Relay" - from = "panos-alerts@corp.example.com" - to = "security-team@corp.example.com" - and_also_to = "noc@corp.example.com" - gateway = "smtp.corp.example.com" - protocol = "SMTP" - port = 587 - - # Use Login authentication with SMTP credentials - authentication_type = "Login" - username = "panos-svc" - password = "Str0ngP@ssw0rd!" - } - ] - - # Custom format strings for log types relevant to security operations. - # These override the default PAN-OS email log format. - format = { - traffic = "$receive_time,$serial,$type,$subtype,$src,$dst,$proto,$action" - threat = "$receive_time,$serial,$type,$subtype,$src,$dst,$threat_name,$severity" - system = "$receive_time,$serial,$type,$subtype,$severity,$opaque" - url = "$receive_time,$serial,$type,$subtype,$src,$dst,$url" - wildfire = "$receive_time,$serial,$type,$subtype,$src,$dst,$threat_name,$filetype" + location = { + vsys = { + name = "vsys1" + } + } + name = "my-email-server-profile" - # Escape backslashes and double-quotes in log field values - escaping = { - escape_character = "\\" - escaped_characters = "\"" - } - } + servers = [ + { + name = "email-server-1" + from = "panos@example.com" + to = "alerts@example.com" + gateway = "smtp.example.com" + port = 25 + } + ] } diff --git a/assets/terraform/examples/resources/panos_snmptrap_profile/resource.tf b/assets/terraform/examples/resources/panos_snmptrap_profile/resource.tf new file mode 100644 index 00000000..713e7346 --- /dev/null +++ b/assets/terraform/examples/resources/panos_snmptrap_profile/resource.tf @@ -0,0 +1,20 @@ +resource "panos_snmptrap_profile" "example" { + location = { + vsys = { + name = "vsys1" + } + } + name = "my-snmp-trap-profile" + + version = { + v2c = { + servers = [ + { + name = "snmp-server-1" + manager = "192.0.2.1" + community = "public" + } + ] + } + } +} diff --git a/assets/terraform/internal/provider/administrator_custom.go b/assets/terraform/internal/provider/administrator_custom.go new file mode 100644 index 00000000..cd944746 --- /dev/null +++ b/assets/terraform/internal/provider/administrator_custom.go @@ -0,0 +1,11 @@ +package provider + +import ( + "context" + + "github.com/PaloAltoNetworks/pango/util" +) + +func administratorCreatePasswordHash(ctx context.Context, client util.PangoClient, password string) (string, error) { + return client.RequestPasswordHash(ctx, password) +} diff --git a/assets/terraform/test/resource_administrators_test.go b/assets/terraform/test/resource_administrators_test.go new file mode 100644 index 00000000..2f226ca5 --- /dev/null +++ b/assets/terraform/test/resource_administrators_test.go @@ -0,0 +1,1003 @@ +package provider_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + //"github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +func TestAccAdministrator_Password_Hashing(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_Password_Hashing_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + "password": config.StringVariable("initial"), + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("password"), + knownvalue.StringExact("initial"), + ), + }, + }, + { + Config: panosAdministrators_Password_Hashing_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + "password": config.StringVariable("updated"), + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("password"), + knownvalue.StringExact("updated"), + ), + }, + }, + }, + }) +} + +const panosAdministrators_Password_Hashing_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } +variable "password" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = { panorama = {} } + + name = var.prefix + + password = var.password +} +` + +func TestAccAdministrator_Basic(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_Basic_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("client_certificate_only"), + knownvalue.Bool(false), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("disable_dns"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("traffic").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("Example Query"), + "query": knownvalue.StringExact("addr.src in 10.0.0.0/8"), + }), + ), + }, + }, + }, + }) +} + +const panosAdministrators_Basic_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + password = "admin123" + + client_certificate_only = false + + preferences = { + disable_dns = true + saved_log_query = { + traffic = [ + { + name = "Example Query" + query = "addr.src in 10.0.0.0/8" + } + ] + } + } +} +` + +func TestAccAdministrator_RoleBased_Custom(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_Custom_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("custom").AtMapKey("profile"), + knownvalue.StringExact(prefix), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_Custom_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_admin_role" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + role = { + vsys = { + cli = "vsysreader" + } + } +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + custom = { + profile = panos_admin_role.example.name + } + } + } +} +` + +func TestAccAdministrator_RoleBased_DeviceAdmin(t *testing.T) { + t.Parallel() + t.Skip("requires valid device references") + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_DeviceAdmin_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("device_admins"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("device1"), + knownvalue.StringExact("device2"), + }), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_DeviceAdmin_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + device_admins = ["device1", "device2"] + } + } +} +` + +func TestAccAdministrator_RoleBased_DeviceReader(t *testing.T) { + t.Parallel() + t.Skip("requires valid device references") + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_DeviceReader_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("devicereader"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("device1"), + knownvalue.StringExact("device2"), + }), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_DeviceReader_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + devicereader = ["device1", "device2"] + } + } +} +` + +func TestAccAdministrator_RoleBased_PanoramaAdmin(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_PanoramaAdmin_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("panorama_admin"), + knownvalue.StringExact("yes"), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_PanoramaAdmin_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + panorama_admin = "yes" + } + } +} +` + +func TestAccAdministrator_RoleBased_SuperReader(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_SuperReader_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("superreader"), + knownvalue.StringExact("yes"), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_SuperReader_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + superreader = "yes" + } + } +} +` + +func TestAccAdministrator_RoleBased_SuperUser(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_SuperUser_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("superuser"), + knownvalue.StringExact("yes"), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_SuperUser_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" example { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + superuser = "yes" + } + } +} +` + +func TestAccAdministrator_RoleBased_VsysAdmin(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_VsysAdmin_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("vsys_admins").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("localhost.localdomain"), + "vsys": knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("vsys1"), + }), + }), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_VsysAdmin_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = { template = { name = "test-tmpl-commit" } } + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + vsys_admins = [ + { + name = "localhost.localdomain" + vsys = ["vsys1"] + } + ] + } + } +} +` + +func TestAccAdministrator_RoleBased_VsysReader(t *testing.T) { + t.Parallel() + t.Skip("requires valid device references") + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrators_RoleBased_VsysReader_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("permissions").AtMapKey("role_based").AtMapKey("vsys_readers").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("localhost.localdomain"), + "vsys": knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("vsys1"), + }), + }), + ), + }, + }, + }, + }) +} + +const panosAdministrators_RoleBased_VsysReader_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" "example" { + location = { panorama = {} } + + name = var.prefix +} + + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + permissions = { + role_based = { + vsys_readers = [ + { + name = "localhost.localdomain" + vsys = ["vsys1"] + } + ] + } + } +} +` + +func TestAccAdministrator_AuthenticationProfile(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrator_AuthenticationProfile_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("authentication_profile"), + knownvalue.StringExact("auth-profile"), + ), + }, + }, + }, + }) +} + +const panosAdministrator_AuthenticationProfile_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_authentication_profile" "auth_profile" { + depends_on = [panos_template.example] + location = var.location + name = "auth-profile" + user_domain = "example.com" +} + +resource "panos_administrator" "example" { + depends_on = [panos_authentication_profile.auth_profile] + location = var.location + name = var.prefix + password = "admin123" + + authentication_profile = panos_authentication_profile.auth_profile.name +} +` + +func TestAccAdministrator_PasswordProfile(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrator_PasswordProfile_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("password_profile"), + knownvalue.StringExact("password-profile"), + ), + }, + }, + }, + }) +} + +const panosAdministrator_PasswordProfile_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_password_profile" "pwd_profile" { + depends_on = [panos_template.example] + location = var.location + name = "password-profile" + + password_change = { + expiration_period = 90 + expiration_warning_period = 7 + post_expiration_admin_login_count = 3 + post_expiration_grace_period = 5 + } +} + +resource "panos_administrator" "example" { + depends_on = [panos_password_profile.pwd_profile] + location = var.location + name = var.prefix + password = "admin123" + + password_profile = panos_password_profile.pwd_profile.name +} +` + +func TestAccAdministrator_PublicKey(t *testing.T) { + t.Parallel() + t.Skip("requires valid SSH public key") + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKqKT5TZ3Z example@example.com" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrator_PublicKey_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + "public_key": config.StringVariable(publicKey), + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("public_key"), + knownvalue.StringExact(publicKey), + ), + }, + }, + }, + }) +} + +const panosAdministrator_PublicKey_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } +variable "public_key" { type = string } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + public_key = var.public_key +} +` + +func TestAccAdministrator_Preferences_SavedLogQuery(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: panosAdministrator_Preferences_SavedLogQuery_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("alarm").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("Alarm Query"), + "query": knownvalue.StringExact("severity eq critical"), + }), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("auth").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("Auth Query"), + "query": knownvalue.StringExact("( authproto eq 'RADIUS' )"), + }), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("config").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("Config Query"), + "query": knownvalue.StringExact("( cmd eq 'set' )"), + }), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("threat").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("Threat Query"), + "query": knownvalue.StringExact("severity eq high"), + }), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("decryption").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("Decryption Query"), + "query": knownvalue.StringExact("( policy_name eq 'SSL-Decrypt' )"), + }), + ), + statecheck.ExpectKnownValue( + "panos_administrator.example", + tfjsonpath.New("preferences").AtMapKey("saved_log_query").AtMapKey("system").AtSliceIndex(0), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "name": knownvalue.StringExact("System Query"), + "query": knownvalue.StringExact("( eventid eq 'general' )"), + }), + ), + }, + }, + }, + }) +} + +const panosAdministrator_Preferences_SavedLogQuery_Tmpl = ` +variable "location" { type = any } +variable "prefix" { type = string } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_administrator" "example" { + depends_on = [panos_template.example] + location = var.location + name = var.prefix + password = "admin123" + + preferences = { + saved_log_query = { + alarm = [ + { + name = "Alarm Query" + query = "severity eq critical" + } + ] + auth = [ + { + name = "Auth Query" + query = "( authproto eq 'RADIUS' )" + } + ] + config = [ + { + name = "Config Query" + query = "( cmd eq 'set' )" + } + ] + threat = [ + { + name = "Threat Query" + query = "severity eq high" + } + ] + decryption = [ + { + name = "Decryption Query" + query = "( policy_name eq 'SSL-Decrypt' )" + } + ] + system = [ + { + name = "System Query" + query = "( eventid eq 'general' )" + } + ] + } + } +} +` diff --git a/assets/terraform/test/resource_decryption_profile_test.go b/assets/terraform/test/resource_decryption_profile_test.go new file mode 100644 index 00000000..90a62962 --- /dev/null +++ b/assets/terraform/test/resource_decryption_profile_test.go @@ -0,0 +1,478 @@ +package provider_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +func TestAccDecryptionProfile_Basic(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "device_group": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: decryptionProfile_Basic_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("disable_override"), + knownvalue.StringExact("yes"), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("forwarded_only"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("interface"), + knownvalue.StringExact("ethernet1/1"), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_forward_proxy"), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "auto_include_altname": knownvalue.Bool(true), + "block_client_cert": knownvalue.Bool(true), + "block_expired_certificate": knownvalue.Bool(true), + "block_if_hsm_unavailable": knownvalue.Bool(true), + "block_if_no_resource": knownvalue.Bool(true), + // block_if_sni_mismatch has version constraint (11.0.2-11.0.3) + "block_if_sni_mismatch": knownvalue.Bool(true), + "block_timeout_cert": knownvalue.Bool(true), + "block_tls13_downgrade_no_resource": knownvalue.Bool(true), + "block_unknown_cert": knownvalue.Bool(true), + "block_unsupported_cipher": knownvalue.Bool(true), + "block_unsupported_version": knownvalue.Bool(true), + "block_untrusted_issuer": knownvalue.Bool(true), + "restrict_cert_exts": knownvalue.Bool(true), + "strip_alpn": knownvalue.Bool(true), + }), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("min_version"), + knownvalue.StringExact("tls1-1"), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("max_version"), + knownvalue.StringExact("tls1-3"), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("auth_algo_sha256"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("enc_algo_aes_256_gcm"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("keyxchg_algo_ecdhe"), + knownvalue.Bool(true), + ), + }, + }, + }, + }) +} + +const decryptionProfile_Basic_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_device_group" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_decryption_profile" "example" { + depends_on = [panos_device_group.example] + location = var.location + name = var.prefix + disable_override = "yes" + forwarded_only = true + interface = "ethernet1/1" + ssl_forward_proxy = { + auto_include_altname = true + block_client_cert = true + block_expired_certificate = true + block_if_hsm_unavailable = true + block_if_no_resource = true + # block_if_sni_mismatch has version constraint (11.0.2-11.0.3) + block_if_sni_mismatch = true + block_timeout_cert = true + block_tls13_downgrade_no_resource = true + block_unknown_cert = true + block_unsupported_cipher = true + block_unsupported_version = true + block_untrusted_issuer = true + restrict_cert_exts = true + strip_alpn = true + } + ssl_protocol_settings = { + min_version = "tls1-1" + max_version = "tls1-3" + auth_algo_sha256 = true + enc_algo_aes_256_gcm = true + keyxchg_algo_ecdhe = true + } +} +` + +func TestAccDecryptionProfile_SshProxy(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "device_group": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: decryptionProfile_SshProxy_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssh_proxy"), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "block_if_no_resource": knownvalue.Bool(true), + "block_ssh_errors": knownvalue.Bool(true), + "block_unsupported_alg": knownvalue.Bool(true), + "block_unsupported_version": knownvalue.Bool(true), + }), + ), + }, + }, + }, + }) +} + +const decryptionProfile_SshProxy_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_device_group" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_decryption_profile" "example" { + depends_on = [panos_device_group.example] + location = var.location + name = var.prefix + ssh_proxy = { + block_if_no_resource = true + block_ssh_errors = true + block_unsupported_alg = true + block_unsupported_version = true + } +} +` + +func TestAccDecryptionProfile_SslInboundProxy(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "device_group": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: decryptionProfile_SslInboundProxy_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_inbound_proxy"), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "block_if_hsm_unavailable": knownvalue.Bool(true), + "block_if_no_resource": knownvalue.Bool(true), + "block_tls13_downgrade_no_resource": knownvalue.Bool(true), + "block_unsupported_cipher": knownvalue.Bool(true), + "block_unsupported_version": knownvalue.Bool(true), + }), + ), + }, + }, + }, + }) +} + +const decryptionProfile_SslInboundProxy_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_device_group" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_decryption_profile" "example" { + depends_on = [panos_device_group.example] + location = var.location + name = var.prefix + ssl_inbound_proxy = { + block_if_hsm_unavailable = true + block_if_no_resource = true + block_tls13_downgrade_no_resource = true + block_unsupported_cipher = true + block_unsupported_version = true + } +} +` + +func TestAccDecryptionProfile_SslNoProxy(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "device_group": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: decryptionProfile_SslNoProxy_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_no_proxy"), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "block_expired_certificate": knownvalue.Bool(true), + "block_untrusted_issuer": knownvalue.Bool(true), + }), + ), + }, + }, + }, + }) +} + +const decryptionProfile_SslNoProxy_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_device_group" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_decryption_profile" "example" { + depends_on = [panos_device_group.example] + location = var.location + name = var.prefix + ssl_no_proxy = { + block_expired_certificate = true + block_untrusted_issuer = true + } +} +` + +// --- Enum value coverage tests for ssl_protocol_settings min/max versions --- + +func TestAccDecryptionProfile_SslProtocolSettings_Versions(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "device_group": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: decryptionProfile_SslProtocolSettings_Versions_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("min_version"), + knownvalue.StringExact("tls1-0"), + ), + // "max" is the PR default — verify device accepts it + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("max_version"), + knownvalue.StringExact("max"), + ), + }, + }, + }, + }) +} + +const decryptionProfile_SslProtocolSettings_Versions_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_device_group" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_decryption_profile" "example" { + depends_on = [panos_device_group.example] + location = var.location + name = var.prefix + ssl_protocol_settings = { + min_version = "tls1-0" + max_version = "max" + } +} +` + +func TestAccDecryptionProfile_SslProtocolSettings_LegacyVersions(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "device_group": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: decryptionProfile_SslProtocolSettings_LegacyVersions_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("min_version"), + knownvalue.StringExact("sslv3"), + ), + statecheck.ExpectKnownValue( + "panos_decryption_profile.example", + tfjsonpath.New("ssl_protocol_settings").AtMapKey("max_version"), + knownvalue.StringExact("tls1-2"), + ), + }, + }, + }, + }) +} + +const decryptionProfile_SslProtocolSettings_LegacyVersions_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_device_group" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_decryption_profile" "example" { + depends_on = [panos_device_group.example] + location = var.location + name = var.prefix + ssl_protocol_settings = { + min_version = "sslv3" + max_version = "tls1-2" + } +} +` diff --git a/assets/terraform/test/resource_email_server_profile_test.go b/assets/terraform/test/resource_email_server_profile_test.go index 8b425c96..bda7d336 100644 --- a/assets/terraform/test/resource_email_server_profile_test.go +++ b/assets/terraform/test/resource_email_server_profile_test.go @@ -40,21 +40,77 @@ func TestAccEmailServerProfile_Basic(t *testing.T) { tfjsonpath.New("name"), knownvalue.StringExact(prefix), ), + // All 17 format log-type params statecheck.ExpectKnownValue( "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("traffic"), - knownvalue.StringExact("traffic-fmt"), + tfjsonpath.New("format").AtMapKey("auth"), + knownvalue.StringExact("auth-fmt"), ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("threat"), - knownvalue.StringExact("threat-fmt"), + tfjsonpath.New("format").AtMapKey("config"), + knownvalue.StringExact("config-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("correlation"), + knownvalue.StringExact("correlation-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("data"), + knownvalue.StringExact("data-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("decryption"), + knownvalue.StringExact("decryption-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("globalprotect"), + knownvalue.StringExact("globalprotect-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("gtp"), + knownvalue.StringExact("gtp-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("hip_match"), + knownvalue.StringExact("hip-match-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("iptag"), + knownvalue.StringExact("iptag-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("sctp"), + knownvalue.StringExact("sctp-fmt"), ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", tfjsonpath.New("format").AtMapKey("system"), knownvalue.StringExact("system-fmt"), ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("threat"), + knownvalue.StringExact("threat-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("traffic"), + knownvalue.StringExact("traffic-fmt"), + ), + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("format").AtMapKey("tunnel"), + knownvalue.StringExact("tunnel-fmt"), + ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", tfjsonpath.New("format").AtMapKey("url"), @@ -62,14 +118,15 @@ func TestAccEmailServerProfile_Basic(t *testing.T) { ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("data"), - knownvalue.StringExact("data-fmt"), + tfjsonpath.New("format").AtMapKey("userid"), + knownvalue.StringExact("userid-fmt"), ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", tfjsonpath.New("format").AtMapKey("wildfire"), knownvalue.StringExact("wildfire-fmt"), ), + // Escaping sub-object statecheck.ExpectKnownValue( "panos_email_server_profile.example", tfjsonpath.New("format").AtMapKey("escaping").AtMapKey("escape_character"), @@ -80,6 +137,7 @@ func TestAccEmailServerProfile_Basic(t *testing.T) { tfjsonpath.New("format").AtMapKey("escaping").AtMapKey("escaped_characters"), knownvalue.StringExact(`'"`), ), + // Fully-parameterized SMTP server with credentials statecheck.ExpectKnownValue( "panos_email_server_profile.example", tfjsonpath.New("servers").AtSliceIndex(0).AtMapKey("name"), @@ -120,6 +178,12 @@ func TestAccEmailServerProfile_Basic(t *testing.T) { tfjsonpath.New("servers").AtSliceIndex(0).AtMapKey("port"), knownvalue.Int64Exact(587), ), + // tls_version defaults to "1.2" even for SMTP protocol + statecheck.ExpectKnownValue( + "panos_email_server_profile.example", + tfjsonpath.New("servers").AtSliceIndex(0).AtMapKey("tls_version"), + knownvalue.StringExact("1.2"), + ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", tfjsonpath.New("servers").AtSliceIndex(0).AtMapKey("authentication_type"), @@ -163,12 +227,23 @@ resource "panos_email_server_profile" "example" { name = var.prefix format = { - traffic = "traffic-fmt" - threat = "threat-fmt" - system = "system-fmt" - url = "url-fmt" - data = "data-fmt" - wildfire = "wildfire-fmt" + auth = "auth-fmt" + config = "config-fmt" + correlation = "correlation-fmt" + data = "data-fmt" + decryption = "decryption-fmt" + globalprotect = "globalprotect-fmt" + gtp = "gtp-fmt" + hip_match = "hip-match-fmt" + iptag = "iptag-fmt" + sctp = "sctp-fmt" + system = "system-fmt" + threat = "threat-fmt" + traffic = "traffic-fmt" + tunnel = "tunnel-fmt" + url = "url-fmt" + userid = "userid-fmt" + wildfire = "wildfire-fmt" escaping = { escape_character = "\\" escaped_characters = "'\"" @@ -194,7 +269,7 @@ resource "panos_email_server_profile" "example" { } ` -func TestAccEmailServerProfile_TlsProtocol(t *testing.T) { +func TestAccEmailServerProfile_Protocol_TLS(t *testing.T) { t.Parallel() nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) @@ -211,7 +286,7 @@ func TestAccEmailServerProfile_TlsProtocol(t *testing.T) { ProtoV6ProviderFactories: testAccProviders, Steps: []resource.TestStep{ { - Config: emailServerProfile_TlsProtocol_Tmpl, + Config: emailServerProfile_Protocol_TLS_Tmpl, ConfigVariables: map[string]config.Variable{ "prefix": config.StringVariable(prefix), "location": location, @@ -253,7 +328,7 @@ func TestAccEmailServerProfile_TlsProtocol(t *testing.T) { }) } -const emailServerProfile_TlsProtocol_Tmpl = ` +const emailServerProfile_Protocol_TLS_Tmpl = ` variable "prefix" { type = string } variable "location" { type = any } @@ -392,7 +467,7 @@ resource "panos_email_server_profile" "example" { } ` -func TestAccEmailServerProfile_FormatOnly(t *testing.T) { +func TestAccEmailServerProfile_TlsVersion_1_0(t *testing.T) { t.Parallel() nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) @@ -409,7 +484,7 @@ func TestAccEmailServerProfile_FormatOnly(t *testing.T) { ProtoV6ProviderFactories: testAccProviders, Steps: []resource.TestStep{ { - Config: emailServerProfile_FormatOnly_Tmpl, + Config: emailServerProfile_TlsVersion_1_0_Tmpl, ConfigVariables: map[string]config.Variable{ "prefix": config.StringVariable(prefix), "location": location, @@ -422,88 +497,13 @@ func TestAccEmailServerProfile_FormatOnly(t *testing.T) { ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("auth"), - knownvalue.StringExact("auth-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("config"), - knownvalue.StringExact("config-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("correlation"), - knownvalue.StringExact("correlation-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("data"), - knownvalue.StringExact("data-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("decryption"), - knownvalue.StringExact("decryption-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("globalprotect"), - knownvalue.StringExact("globalprotect-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("gtp"), - knownvalue.StringExact("gtp-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("hip_match"), - knownvalue.StringExact("hip-match-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("iptag"), - knownvalue.StringExact("iptag-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("sctp"), - knownvalue.StringExact("sctp-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("system"), - knownvalue.StringExact("system-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("threat"), - knownvalue.StringExact("threat-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("traffic"), - knownvalue.StringExact("traffic-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("tunnel"), - knownvalue.StringExact("tunnel-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("url"), - knownvalue.StringExact("url-fmt"), - ), - statecheck.ExpectKnownValue( - "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("userid"), - knownvalue.StringExact("userid-fmt"), + tfjsonpath.New("servers").AtSliceIndex(0).AtMapKey("protocol"), + knownvalue.StringExact("TLS"), ), statecheck.ExpectKnownValue( "panos_email_server_profile.example", - tfjsonpath.New("format").AtMapKey("wildfire"), - knownvalue.StringExact("wildfire-fmt"), + tfjsonpath.New("servers").AtSliceIndex(0).AtMapKey("tls_version"), + knownvalue.StringExact("1.0"), ), }, }, @@ -511,7 +511,9 @@ func TestAccEmailServerProfile_FormatOnly(t *testing.T) { }) } -const emailServerProfile_FormatOnly_Tmpl = ` +// tls_version "1.0" is from the PR spec — not in the XML schema. +// This test verifies whether the device actually accepts it. +const emailServerProfile_TlsVersion_1_0_Tmpl = ` variable "prefix" { type = string } variable "location" { type = any } @@ -526,24 +528,16 @@ resource "panos_email_server_profile" "example" { name = var.prefix - format = { - auth = "auth-fmt" - config = "config-fmt" - correlation = "correlation-fmt" - data = "data-fmt" - decryption = "decryption-fmt" - globalprotect = "globalprotect-fmt" - gtp = "gtp-fmt" - hip_match = "hip-match-fmt" - iptag = "iptag-fmt" - sctp = "sctp-fmt" - system = "system-fmt" - threat = "threat-fmt" - traffic = "traffic-fmt" - tunnel = "tunnel-fmt" - url = "url-fmt" - userid = "userid-fmt" - wildfire = "wildfire-fmt" - } + servers = [ + { + name = "tls10-server" + from = "alerts@example.com" + to = "admin@example.com" + gateway = "smtp.example.com" + protocol = "TLS" + tls_version = "1.0" + port = 587 + } + ] } ` diff --git a/assets/terraform/test/resource_snmptrap_profile_test.go b/assets/terraform/test/resource_snmptrap_profile_test.go new file mode 100644 index 00000000..2557ab27 --- /dev/null +++ b/assets/terraform/test/resource_snmptrap_profile_test.go @@ -0,0 +1,619 @@ +package provider_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +func TestAccSnmptrapProfile_Basic_V2c(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_Basic_V2c_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v2c").AtMapKey("servers").AtSliceIndex(0).AtMapKey("name"), + knownvalue.StringExact("trap-v2c-1"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v2c").AtMapKey("servers").AtSliceIndex(0).AtMapKey("manager"), + knownvalue.StringExact("192.168.1.100"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v2c").AtMapKey("servers").AtSliceIndex(0).AtMapKey("community"), + knownvalue.StringExact("public"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v2c").AtMapKey("servers").AtSliceIndex(1).AtMapKey("name"), + knownvalue.StringExact("trap-v2c-2"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v2c").AtMapKey("servers").AtSliceIndex(1).AtMapKey("manager"), + knownvalue.StringExact("192.168.1.101"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v2c").AtMapKey("servers").AtSliceIndex(1).AtMapKey("community"), + knownvalue.StringExact("private"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_Basic_V2c_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v2c = { + servers = [ + { + name = "trap-v2c-1" + manager = "192.168.1.100" + community = "public" + }, + { + name = "trap-v2c-2" + manager = "192.168.1.101" + community = "private" + } + ] + } + } +} +` + +func TestAccSnmptrapProfile_Basic_V3(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_Basic_V3_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("name"), + knownvalue.StringExact(prefix), + ), + // First server: all params with non-default auth/priv protocols + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("name"), + knownvalue.StringExact("trap-v3-1"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("manager"), + knownvalue.StringExact("10.0.0.1"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("user"), + knownvalue.StringExact("snmpuser"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("engine_id"), + knownvalue.StringExact("0x80001F8880A1B2C3D4E5F601"), + ), + // authentication_password has hashing type solo - only check NotNull + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("authentication_password"), + knownvalue.NotNull(), + ), + // privacy_password has hashing type solo - only check NotNull + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("privacy_password"), + knownvalue.NotNull(), + ), + // Non-default auth protocol (SHA-256 instead of SHA) + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("authentication_protocol"), + knownvalue.StringExact("SHA-256"), + ), + // Non-default priv protocol (AES-192 instead of AES) + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("privacy_protocol"), + knownvalue.StringExact("AES-192"), + ), + // Second server: uses defaults for auth/priv protocols + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("name"), + knownvalue.StringExact("trap-v3-2"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("manager"), + knownvalue.StringExact("10.0.0.2"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("user"), + knownvalue.StringExact("snmpuser2"), + ), + // authentication_password has hashing type solo - only check NotNull + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("authentication_password"), + knownvalue.NotNull(), + ), + // privacy_password has hashing type solo - only check NotNull + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("privacy_password"), + knownvalue.NotNull(), + ), + // Default auth protocol (SHA) + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("authentication_protocol"), + knownvalue.StringExact("SHA"), + ), + // Default priv protocol (AES) + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(1).AtMapKey("privacy_protocol"), + knownvalue.StringExact("AES"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_Basic_V3_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v3 = { + servers = [ + { + name = "trap-v3-1" + manager = "10.0.0.1" + user = "snmpuser" + engine_id = "0x80001F8880A1B2C3D4E5F601" + authentication_password = "AuthPassword1!" + privacy_password = "PrivPassword1!" + authentication_protocol = "SHA-256" + privacy_protocol = "AES-192" + }, + { + name = "trap-v3-2" + manager = "10.0.0.2" + user = "snmpuser2" + authentication_password = "AuthPassword2!" + privacy_password = "PrivPassword2!" + } + ] + } + } +} +` + +// --- Enum value coverage tests --- +// Each test exercises untested auth/priv protocol enum values. + +func TestAccSnmptrapProfile_V3_AuthProto_SHA224(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_V3_AuthProto_SHA224_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("authentication_protocol"), + knownvalue.StringExact("SHA-224"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("privacy_protocol"), + knownvalue.StringExact("AES-256"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_V3_AuthProto_SHA224_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v3 = { + servers = [ + { + name = "sha224-server" + manager = "10.0.0.1" + user = "snmpuser" + authentication_password = "AuthPassword1!" + privacy_password = "PrivPassword1!" + authentication_protocol = "SHA-224" + privacy_protocol = "AES-256" + } + ] + } + } +} +` + +func TestAccSnmptrapProfile_V3_AuthProto_SHA384(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_V3_AuthProto_SHA384_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("authentication_protocol"), + knownvalue.StringExact("SHA-384"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_V3_AuthProto_SHA384_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v3 = { + servers = [ + { + name = "sha384-server" + manager = "10.0.0.1" + user = "snmpuser" + authentication_password = "AuthPassword1!" + privacy_password = "PrivPassword1!" + authentication_protocol = "SHA-384" + } + ] + } + } +} +` + +func TestAccSnmptrapProfile_V3_AuthProto_SHA512(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_V3_AuthProto_SHA512_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("authentication_protocol"), + knownvalue.StringExact("SHA-512"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_V3_AuthProto_SHA512_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v3 = { + servers = [ + { + name = "sha512-server" + manager = "10.0.0.1" + user = "snmpuser" + authentication_password = "AuthPassword1!" + privacy_password = "PrivPassword1!" + authentication_protocol = "SHA-512" + } + ] + } + } +} +` + +// Legacy enum values from PR — not in our XML schema. +// These tests verify whether the device actually accepts MD5, DES, AES128. + +func TestAccSnmptrapProfile_V3_Legacy_MD5(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_V3_Legacy_MD5_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("authentication_protocol"), + knownvalue.StringExact("MD5"), + ), + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("privacy_protocol"), + knownvalue.StringExact("DES"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_V3_Legacy_MD5_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v3 = { + servers = [ + { + name = "md5-server" + manager = "10.0.0.1" + user = "snmpuser" + authentication_password = "AuthPassword1!" + privacy_password = "PrivPassword1!" + authentication_protocol = "MD5" + privacy_protocol = "DES" + } + ] + } + } +} +` + +func TestAccSnmptrapProfile_V3_Legacy_AES128(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + + location := config.ObjectVariable(map[string]config.Variable{ + "template": config.ObjectVariable(map[string]config.Variable{ + "name": config.StringVariable(prefix), + }), + }) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: snmptrapProfile_V3_Legacy_AES128_Tmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "location": location, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_snmptrap_profile.example", + tfjsonpath.New("version").AtMapKey("v3").AtMapKey("servers").AtSliceIndex(0).AtMapKey("privacy_protocol"), + knownvalue.StringExact("AES128"), + ), + }, + }, + }, + }) +} + +const snmptrapProfile_V3_Legacy_AES128_Tmpl = ` +variable "prefix" { type = string } +variable "location" { type = any } + +resource "panos_template" "example" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_snmptrap_profile" "example" { + depends_on = [panos_template.example] + location = var.location + + name = var.prefix + + version = { + v3 = { + servers = [ + { + name = "aes128-server" + manager = "10.0.0.1" + user = "snmpuser" + authentication_password = "AuthPassword1!" + privacy_password = "PrivPassword1!" + privacy_protocol = "AES128" + } + ] + } + } +} +` diff --git a/specs/device/administrator.yaml b/specs/device/administrator.yaml new file mode 100644 index 00000000..c6302f13 --- /dev/null +++ b/specs/device/administrator.yaml @@ -0,0 +1,894 @@ +name: administrator +terraform_provider_config: + description: Administrator + skip_resource: false + skip_datasource: false + resource_type: entry + resource_variants: + - singular + suffix: administrator + plural_suffix: '' + plural_name: '' + plural_description: '' + custom_validation: false +go_sdk_config: + skip: false + package: + - device + - administrator +panos_xpath: + path: + - users + vars: [] +locations: +- name: panorama + xpath: + path: + - config + - mgt-config + vars: [] + description: Located in panorama. + validators: [] + required: false + read_only: false +- name: ngfw + xpath: + path: + - config + - mgt-config + vars: [] + description: Located within device-level configuration + devices: + - ngfw + validators: [] + required: false + read_only: false +- name: template + xpath: + path: + - config + - devices + - $panorama_device + - template + - $template + - config + - mgt-config + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template + description: Specific Panorama template + required: true + validators: [] + type: entry + description: A management configuration object located within a specific template + devices: + - panorama + validators: [] + required: false + read_only: false +- name: template-stack + xpath: + path: + - config + - devices + - $panorama_device + - template-stack + - $template_stack + - config + - mgt-config + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template_stack + description: The template stack + required: true + validators: [] + type: entry + description: A management configuration object located within a specific template + devices: + - panorama + validators: [] + required: false + read_only: false +entries: +- name: name + description: '' + validators: [] +spec: + params: + - name: authentication-profile + type: string + profiles: + - xpath: + - authentication-profile + validators: [] + spec: {} + description: Authentication profile for this administrator + required: false + - name: client-certificate-only + type: bool + profiles: + - xpath: + - client-certificate-only + validators: [] + spec: {} + description: Is client certificate authentication enough? + required: false + - name: password-profile + type: string + profiles: + - xpath: + - password-profile + validators: [] + spec: {} + description: '' + required: false + - name: permissions + type: object + profiles: + - xpath: + - permissions + validators: [] + spec: + params: [] + variants: + - name: role-based + type: object + profiles: + - xpath: + - role-based + validators: [] + spec: + params: [] + variants: + - name: custom + type: object + profiles: + - xpath: + - custom + validators: [] + spec: + params: + - name: profile + type: string + profiles: + - xpath: + - profile + validators: + - type: length + spec: + max: 63 + spec: {} + description: Custom admin role profile name + required: false + - name: vsys + type: list + profiles: + - xpath: + - vsys + type: member + validators: [] + spec: + type: string + items: + type: string + description: '' + required: false + variants: [] + description: Custom role based on an admin role profile + required: false + - name: deviceadmin + type: list + profiles: + - xpath: + - deviceadmin + type: member + validators: [] + spec: + type: string + items: + type: string + description: Device administrator access (all vsys) + required: false + codegen_overrides: + terraform: + name: device_admins + - name: devicereader + type: list + profiles: + - xpath: + - devicereader + type: member + validators: [] + spec: + type: string + items: + type: string + description: Device read-only access (all vsys) + required: false + codegen_overrides: + terraform: + name: device_readers + - name: panorama-admin + type: enum + profiles: + - xpath: + - panorama-admin + validators: + - type: values + spec: + values: + - 'yes' + spec: + values: + - value: 'yes' + description: '' + required: false + - name: superreader + type: enum + profiles: + - xpath: + - superreader + validators: + - type: values + spec: + values: + - 'yes' + spec: + values: + - value: 'yes' + description: Read-only access to entire system + required: false + - name: superuser + type: enum + profiles: + - xpath: + - superuser + validators: + - type: values + spec: + values: + - 'yes' + spec: + values: + - value: 'yes' + description: Full system access + required: false + - name: vsysadmin + type: list + profiles: + - xpath: + - vsysadmin + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: vsys + type: list + profiles: + - xpath: + - vsys + type: member + validators: [] + spec: + type: string + items: + type: string + description: '' + required: false + variants: [] + description: Virtual system administrator access + required: false + codegen_overrides: + terraform: + name: vsys_admins + - name: vsysreader + type: list + profiles: + - xpath: + - vsysreader + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: vsys + type: list + profiles: + - xpath: + - vsys + type: member + validators: [] + spec: + type: string + items: + type: string + description: '' + required: false + variants: [] + description: Virtual system read-only access + required: false + codegen_overrides: + terraform: + name: vsys_readers + variant_check: Disabled + description: Role-based access control + required: false + description: Administrator permissions and role assignment + required: false + - name: phash + type: string + profiles: + - xpath: + - phash + validators: + - type: length + spec: + max: 63 + spec: {} + description: Hashed administrator password + required: false + codegen_overrides: + terraform: + name: password + hashing: + type: client + spec: + hashing_func: + name: administratorCreatePasswordHash + - name: preferences + type: object + profiles: + - xpath: + - preferences + validators: [] + spec: + params: + - name: disable-dns + type: bool + profiles: + - xpath: + - disable-dns + validators: [] + spec: {} + description: '' + required: false + - name: saved-log-query + type: object + profiles: + - xpath: + - saved-log-query + validators: [] + spec: + params: + - name: alarm + type: list + profiles: + - xpath: + - alarm + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: auth + type: list + profiles: + - xpath: + - auth + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: config + type: list + profiles: + - xpath: + - config + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: corr + type: list + profiles: + - xpath: + - corr + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: data + type: list + profiles: + - xpath: + - data + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: decryption + type: list + profiles: + - xpath: + - decryption + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: globalprotect + type: list + profiles: + - xpath: + - globalprotect + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: gtp + type: list + profiles: + - xpath: + - gtp + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: hipmatch + type: list + profiles: + - xpath: + - hipmatch + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: system + type: list + profiles: + - xpath: + - system + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: threat + type: list + profiles: + - xpath: + - threat + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: traffic + type: list + profiles: + - xpath: + - traffic + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: tunnel + type: list + profiles: + - xpath: + - tunnel + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: unified + type: list + profiles: + - xpath: + - unified + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: url + type: list + profiles: + - xpath: + - url + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: userid + type: list + profiles: + - xpath: + - userid + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + - name: wildfire + type: list + profiles: + - xpath: + - wildfire + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: query + type: string + profiles: + - xpath: + - query + validators: + - type: length + spec: + max: 2048 + spec: {} + description: '' + required: false + variants: [] + description: '' + required: false + variants: [] + description: '' + required: false + variants: [] + description: '' + required: false + - name: public-key + type: string + profiles: + - xpath: + - public-key + validators: + - type: length + spec: + min: 1 + max: 4096 + spec: {} + description: SSH public key for certificate-based authentication + required: false + variants: [] diff --git a/specs/device/profiles/data-filtering.yaml b/specs/device/profiles/data-filtering.yaml index 785042ee..99e3f9b5 100644 --- a/specs/device/profiles/data-filtering.yaml +++ b/specs/device/profiles/data-filtering.yaml @@ -82,7 +82,7 @@ spec: - data-capture validators: [] spec: {} - description: '' + description: Enable data capture required: false - name: description type: string @@ -113,7 +113,7 @@ spec: values: - value: 'yes' - value: 'no' - description: disable object override in child device groups + description: Disable object override in child device groups required: false - name: rules type: list @@ -136,7 +136,7 @@ spec: - data-object validators: [] spec: {} - description: '' + description: Name of the data pattern object required: false - name: direction type: enum @@ -151,11 +151,12 @@ spec: - download - both spec: + default: both values: - value: upload - value: download - value: both - description: '' + description: Direction of data transfer to monitor required: false - name: alert-threshold type: int64 @@ -169,7 +170,7 @@ spec: max: 65535 spec: default: 1 - description: '' + description: Alert threshold count required: false - name: block-threshold type: int64 @@ -183,7 +184,7 @@ spec: max: 65535 spec: default: 1 - description: '' + description: Block threshold count required: false - name: log-severity type: string @@ -193,7 +194,7 @@ spec: validators: [] spec: default: informational - description: '' + description: Log severity for matched traffic required: false - name: application type: list @@ -206,7 +207,7 @@ spec: type: string items: type: string - description: '' + description: Applications to match required: false - name: file-type type: list @@ -219,9 +220,9 @@ spec: type: string items: type: string - description: '' + description: File types to match required: false variants: [] - description: '' + description: Data filtering rules required: false variants: [] diff --git a/specs/device/profiles/email.yaml b/specs/device/profiles/email.yaml index 80406970..5837d3f8 100644 --- a/specs/device/profiles/email.yaml +++ b/specs/device/profiles/email.yaml @@ -243,7 +243,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for auth log required: false - name: config type: string @@ -255,7 +255,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for config log required: false - name: correlation type: string @@ -267,7 +267,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for correlation log required: false - name: data type: string @@ -279,7 +279,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for data log required: false - name: decryption type: string @@ -291,7 +291,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for decryption log required: false - name: escaping type: object @@ -339,7 +339,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for globalprotect log required: false - name: gtp type: string @@ -351,7 +351,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for gtp log required: false - name: hip-match type: string @@ -363,7 +363,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for hip-match log required: false - name: iptag type: string @@ -375,7 +375,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for iptag log required: false - name: sctp type: string @@ -387,7 +387,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for sctp log required: false - name: system type: string @@ -399,7 +399,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for system log required: false - name: threat type: string @@ -411,7 +411,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for threat log required: false - name: traffic type: string @@ -423,7 +423,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for traffic log required: false - name: tunnel type: string @@ -435,7 +435,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for tunnel log required: false - name: url type: string @@ -447,7 +447,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for url log required: false - name: userid type: string @@ -459,7 +459,7 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for userid log required: false - name: wildfire type: string @@ -471,10 +471,10 @@ spec: spec: max: 2048 spec: {} - description: '' + description: Custom format for wildfire log required: false variants: [] - description: custom formats for forwarded logs + description: Custom log format strings required: false - name: server type: list @@ -509,7 +509,7 @@ spec: spec: max: 128 spec: {} - description: email address (e.g. admin@mycompany.com) + description: From email address required: false - name: to type: string @@ -521,7 +521,7 @@ spec: spec: max: 128 spec: {} - description: email address (e.g. admin@mycompany.com) + description: To email address required: false - name: and-also-to type: string @@ -533,7 +533,7 @@ spec: spec: max: 128 spec: {} - description: email address (e.g. admin@mycompany.com) + description: Additional CC email address required: false - name: gateway type: string @@ -545,7 +545,7 @@ spec: spec: max: 63 spec: {} - description: IP address or FQDN of SMTP gateway to use + description: IP address or FQDN of SMTP gateway required: false - name: protocol type: enum @@ -577,7 +577,7 @@ spec: max: 65535 spec: default: 25 - description: Port number (Standard EMAIL ports SMTP:25, TLS:587) + description: SMTP port number required: false - name: tls-version type: enum @@ -614,7 +614,7 @@ spec: - value: Auto - value: Login - value: Plain - description: '' + description: Authentication method for SMTP required: false codegen_overrides: terraform: @@ -627,7 +627,7 @@ spec: validators: [] spec: default: None - description: Certificate Profile for validating server certificate + description: Certificate profile for TLS verification required: false - name: username type: string @@ -658,7 +658,7 @@ spec: hashing: type: solo variants: [] - description: '' + description: List of email servers required: false codegen_overrides: terraform: diff --git a/specs/device/profiles/snmptrap.yaml b/specs/device/profiles/snmptrap.yaml new file mode 100644 index 00000000..f07e4dfd --- /dev/null +++ b/specs/device/profiles/snmptrap.yaml @@ -0,0 +1,444 @@ +name: snmptrap-profile +terraform_provider_config: + description: SNMP Trap Server Profile + skip_resource: false + skip_datasource: false + resource_type: entry + resource_variants: + - singular + suffix: snmptrap_profile + plural_suffix: '' + plural_name: '' + plural_description: '' + custom_validation: false +go_sdk_config: + skip: false + package: + - device + - profiles + - snmptrap +panos_xpath: + path: + - log-settings + - snmptrap + vars: [] +locations: +- name: panorama + xpath: + path: + - config + - panorama + vars: [] + description: Located in a panorama. + validators: [] + required: false + read_only: false +- name: vsys + xpath: + path: + - config + - devices + - $ngfw_device + - vsys + - $vsys + vars: + - name: ngfw_device + description: The NGFW device name + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: vsys + description: The Virtual System name + required: false + default: vsys1 + validators: + - type: not-values + spec: + values: + - value: shared + error: The vsys name cannot be "shared". Use the "shared" location instead + type: entry + description: Located in a specific Virtual System + devices: + - ngfw + validators: [] + required: false + read_only: false +- name: template + xpath: + path: + - config + - devices + - $panorama_device + - template + - $template + - config + - shared + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template + description: Specific Panorama template + required: true + validators: [] + type: entry + description: A shared resource located within a specific template + devices: + - panorama + validators: [] + required: false + read_only: false +- name: template-vsys + xpath: + path: + - config + - devices + - $panorama_device + - template + - $template + - config + - devices + - $ngfw_device + - vsys + - $vsys + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template + description: Specific Panorama template + required: true + validators: [] + type: entry + - name: ngfw_device + description: The NGFW device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: vsys + description: The vsys. + required: false + default: vsys1 + validators: + - type: not-values + spec: + values: + - value: shared + error: The vsys cannot be "shared". + type: entry + description: Located in a specific template, device and vsys. + devices: + - panorama + - ngfw + validators: [] + required: false + read_only: false +- name: template-stack + xpath: + path: + - config + - devices + - $panorama_device + - template-stack + - $template_stack + - config + - shared + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template_stack + description: The template stack + required: true + validators: [] + type: entry + description: Located in a specific template + devices: + - panorama + validators: [] + required: false + read_only: false +- name: template-stack-vsys + xpath: + path: + - config + - devices + - $panorama_device + - template-stack + - $template_stack + - config + - devices + - $ngfw_device + - vsys + - $vsys + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template_stack + description: The template stack + required: true + validators: [] + type: entry + - name: ngfw_device + description: The NGFW device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: vsys + description: The vsys. + required: false + default: vsys1 + validators: + - type: not-values + spec: + values: + - value: shared + error: The vsys cannot be "shared". + type: entry + description: Located in a specific template, device and vsys. + devices: + - panorama + - ngfw + validators: [] + required: false + read_only: false +entries: +- name: name + description: '' + validators: [] +spec: + params: + - name: version + type: object + profiles: + - xpath: + - version + validators: [] + spec: + params: [] + variants: + - name: v2c + type: object + profiles: + - xpath: + - v2c + validators: [] + spec: + params: + - name: server + type: list + profiles: + - xpath: + - server + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: manager + type: string + profiles: + - xpath: + - manager + validators: [] + spec: {} + description: IP address or FQDN of SNMP manager + required: false + - name: community + type: string + profiles: + - xpath: + - community + validators: + - type: length + spec: + max: 127 + spec: {} + description: SNMP community string + required: false + variants: [] + description: List of SNMPv2c trap receivers + required: false + codegen_overrides: + terraform: + name: servers + variants: [] + description: SNMPv2c configuration + required: false + - name: v3 + type: object + profiles: + - xpath: + - v3 + validators: [] + spec: + params: + - name: server + type: list + profiles: + - xpath: + - server + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: manager + type: string + profiles: + - xpath: + - manager + validators: [] + spec: {} + description: IP address or FQDN of SNMP manager + required: false + - name: user + type: string + profiles: + - xpath: + - user + validators: + - type: length + spec: + max: 31 + spec: {} + description: SNMPv3 username + required: false + - name: engineid + type: string + profiles: + - xpath: + - engineid + validators: + - type: length + spec: + max: 255 + spec: {} + description: SNMP engine ID (hex string, e.g. 0x80...) + required: false + codegen_overrides: + terraform: + name: engine-id + - name: authpwd + type: string + profiles: + - xpath: + - authpwd + validators: + - type: length + spec: + min: 8 + max: 256 + spec: {} + description: SNMPv3 authentication password + required: false + codegen_overrides: + terraform: + name: authentication-password + hashing: + type: solo + - name: privpwd + type: string + profiles: + - xpath: + - privpwd + validators: + - type: length + spec: + min: 8 + max: 256 + spec: {} + description: SNMPv3 privacy password + required: false + codegen_overrides: + terraform: + name: privacy-password + hashing: + type: solo + - name: authproto + type: enum + profiles: + - xpath: + - authproto + validators: + - type: values + spec: + values: + - SHA + - SHA-224 + - SHA-256 + - SHA-384 + - SHA-512 + spec: + default: SHA + values: + - value: SHA + - value: SHA-224 + - value: SHA-256 + - value: SHA-384 + - value: SHA-512 + description: Authentication protocol + required: false + codegen_overrides: + terraform: + name: authentication-protocol + - name: privproto + type: enum + profiles: + - xpath: + - privproto + validators: + - type: values + spec: + values: + - AES + - AES-192 + - AES-256 + spec: + default: AES + values: + - value: AES + - value: AES-192 + - value: AES-256 + description: Privacy protocol + required: false + codegen_overrides: + terraform: + name: privacy-protocol + variants: [] + description: List of SNMPv3 trap receivers + required: false + codegen_overrides: + terraform: + name: servers + variants: [] + description: SNMPv3 configuration + required: false + description: SNMP version and server configuration + required: false + variants: [] diff --git a/specs/objects/profiles/decryption-profile.yaml b/specs/objects/profiles/decryption-profile.yaml new file mode 100644 index 00000000..c2f1dfe0 --- /dev/null +++ b/specs/objects/profiles/decryption-profile.yaml @@ -0,0 +1,603 @@ +name: decryption-profile +terraform_provider_config: + description: Decryption Profile + skip_resource: false + skip_datasource: false + resource_type: entry + resource_variants: + - singular + suffix: decryption_profile + plural_suffix: '' + plural_name: '' + plural_description: '' + custom_validation: false +go_sdk_config: + skip: false + package: + - objects + - profiles + - decryption +panos_xpath: + path: + - profiles + - decryption + vars: [] +locations: +- name: shared + xpath: + path: + - config + - shared + vars: [] + description: Panorama shared object + devices: + - panorama + - ngfw + validators: [] + required: false + read_only: false +- name: vsys + xpath: + path: + - config + - devices + - $ngfw_device + - vsys + - $vsys + vars: + - name: ngfw_device + description: The NGFW device name + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: vsys + description: The Virtual System name + required: false + default: vsys1 + validators: + - type: not-values + spec: + values: + - value: shared + error: The vsys name cannot be "shared". Use the "shared" location instead + type: entry + description: Located in a specific Virtual System + devices: + - ngfw + validators: [] + required: false + read_only: false +- name: device-group + xpath: + path: + - config + - devices + - $panorama_device + - device-group + - $device_group + vars: + - name: panorama_device + description: Panorama device name + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: device_group + description: Device Group name + required: true + validators: + - type: not-values + spec: + values: + - value: shared + error: The device group name cannot be "shared". Use the "shared" location + instead + type: entry + location_filter: true + description: Located in a specific Device Group + devices: + - panorama + validators: [] + required: false + read_only: false +entries: +- name: name + description: '' + validators: [] +spec: + params: + - name: disable-override + type: enum + profiles: + - xpath: + - disable-override + validators: + - type: values + spec: + values: + - 'yes' + - 'no' + spec: + default: 'no' + values: + - value: 'yes' + - value: 'no' + description: disable object override in child device groups + required: false + - name: forwarded-only + type: bool + profiles: + - xpath: + - forwarded-only + validators: [] + spec: {} + description: mirror after security policy allow + required: false + - name: interface + type: string + profiles: + - xpath: + - interface + validators: [] + spec: {} + description: decrypt mirror port + required: false + - name: ssh-proxy + type: object + profiles: + - xpath: + - ssh-proxy + validators: [] + spec: + params: + - name: block-if-no-resource + type: bool + profiles: + - xpath: + - block-if-no-resource + validators: [] + spec: {} + description: whether to block sessions if device has no enough resources + required: false + - name: block-ssh-errors + type: bool + profiles: + - xpath: + - block-ssh-errors + validators: [] + spec: {} + description: whether to block sessions if ssh errors are encountered + required: false + - name: block-unsupported-alg + type: bool + profiles: + - xpath: + - block-unsupported-alg + validators: [] + spec: {} + description: whether to block sessions if ssh algorithm is not supported + required: false + - name: block-unsupported-version + type: bool + profiles: + - xpath: + - block-unsupported-version + validators: [] + spec: {} + description: whether to block sessions if ssh version is not supported + required: false + variants: [] + description: '' + required: false + - name: ssl-forward-proxy + type: object + profiles: + - xpath: + - ssl-forward-proxy + validators: [] + spec: + params: + - name: auto-include-altname + type: bool + profiles: + - xpath: + - auto-include-altname + validators: [] + spec: {} + description: whether to automatically append SAN to impersonating certificate + if server certificate is missing SAN + required: false + - name: block-client-cert + type: bool + profiles: + - xpath: + - block-client-cert + validators: [] + spec: {} + description: Block sessions with client certificate + required: false + - name: block-expired-certificate + type: bool + profiles: + - xpath: + - block-expired-certificate + validators: [] + spec: {} + description: Block sessions with expired certificates + required: false + - name: block-if-hsm-unavailable + type: bool + profiles: + - xpath: + - block-if-hsm-unavailable + validators: [] + spec: {} + description: whether to block sessions if HSM is unavailable + required: false + - name: block-if-no-resource + type: bool + profiles: + - xpath: + - block-if-no-resource + validators: [] + spec: {} + description: whether to block sessions if device has no enough resources + required: false + - name: block-if-sni-mismatch + type: bool + profiles: + - xpath: + - block-if-sni-mismatch + min_version: 11.0.2 + max_version: 11.0.3 + validators: [] + spec: {} + description: whether to block a session when certificate's subject name or + SAN doesn't match SNI + required: false + - name: block-timeout-cert + type: bool + profiles: + - xpath: + - block-timeout-cert + validators: [] + spec: {} + description: Block sessions if certificate status cannot be retrieved within + timeout + required: false + - name: block-tls13-downgrade-no-resource + type: bool + profiles: + - xpath: + - block-tls13-downgrade-no-resource + validators: [] + spec: {} + description: whether to downgrade from tls1.3 if device has not enough resources + required: false + - name: block-unknown-cert + type: bool + profiles: + - xpath: + - block-unknown-cert + validators: [] + spec: {} + description: Block sessions if certificate status is unknown + required: false + - name: block-unsupported-cipher + type: bool + profiles: + - xpath: + - block-unsupported-cipher + validators: [] + spec: {} + description: Block sessions with unsupported cipher suites + required: false + - name: block-unsupported-version + type: bool + profiles: + - xpath: + - block-unsupported-version + validators: [] + spec: {} + description: Block sessions with unsupported protocol versions + required: false + - name: block-untrusted-issuer + type: bool + profiles: + - xpath: + - block-untrusted-issuer + validators: [] + spec: {} + description: Block sessions with untrusted certificate issuers + required: false + - name: restrict-cert-exts + type: bool + profiles: + - xpath: + - restrict-cert-exts + validators: [] + spec: {} + description: Restrict certificate extensions + required: false + - name: strip-alpn + type: bool + profiles: + - xpath: + - strip-alpn + validators: [] + spec: {} + description: Strip ALPN extension from ClientHello + required: false + variants: [] + description: SSL forward proxy decryption settings + required: false + - name: ssl-inbound-proxy + type: object + profiles: + - xpath: + - ssl-inbound-proxy + validators: [] + spec: + params: + - name: block-if-hsm-unavailable + type: bool + profiles: + - xpath: + - block-if-hsm-unavailable + validators: [] + spec: {} + description: Block sessions when HSM is unavailable + required: false + - name: block-if-no-resource + type: bool + profiles: + - xpath: + - block-if-no-resource + validators: [] + spec: {} + description: Block sessions when decryption resources are not available + required: false + - name: block-tls13-downgrade-no-resource + type: bool + profiles: + - xpath: + - block-tls13-downgrade-no-resource + validators: [] + spec: {} + description: Block TLS 1.3 downgrade when no resources are available + required: false + - name: block-unsupported-cipher + type: bool + profiles: + - xpath: + - block-unsupported-cipher + validators: [] + spec: {} + description: Block sessions with unsupported cipher suites + required: false + - name: block-unsupported-version + type: bool + profiles: + - xpath: + - block-unsupported-version + validators: [] + spec: {} + description: Block sessions with unsupported protocol versions + required: false + variants: [] + description: SSL inbound proxy decryption settings + required: false + - name: ssl-no-proxy + type: object + profiles: + - xpath: + - ssl-no-proxy + validators: [] + spec: + params: + - name: block-expired-certificate + type: bool + profiles: + - xpath: + - block-expired-certificate + validators: [] + spec: {} + description: Block sessions with expired certificates + required: false + - name: block-untrusted-issuer + type: bool + profiles: + - xpath: + - block-untrusted-issuer + validators: [] + spec: {} + description: Block sessions with untrusted certificate issuers + required: false + variants: [] + description: SSL no-proxy decryption settings + required: false + - name: ssl-protocol-settings + type: object + profiles: + - xpath: + - ssl-protocol-settings + validators: [] + spec: + params: + - name: auth-algo-md5 + type: bool + profiles: + - xpath: + - auth-algo-md5 + validators: [] + spec: {} + description: Allow MD5 authentication algorithm + required: false + - name: auth-algo-sha1 + type: bool + profiles: + - xpath: + - auth-algo-sha1 + validators: [] + spec: {} + description: Allow SHA1 authentication algorithm + required: false + - name: auth-algo-sha256 + type: bool + profiles: + - xpath: + - auth-algo-sha256 + validators: [] + spec: {} + description: Allow SHA256 authentication algorithm + required: false + - name: auth-algo-sha384 + type: bool + profiles: + - xpath: + - auth-algo-sha384 + validators: [] + spec: {} + description: Allow SHA384 authentication algorithm + required: false + - name: enc-algo-3des + type: bool + profiles: + - xpath: + - enc-algo-3des + validators: [] + spec: {} + description: Allow 3DES encryption algorithm + required: false + - name: enc-algo-aes-128-cbc + type: bool + profiles: + - xpath: + - enc-algo-aes-128-cbc + validators: [] + spec: {} + description: Allow AES-128-CBC encryption algorithm + required: false + - name: enc-algo-aes-128-gcm + type: bool + profiles: + - xpath: + - enc-algo-aes-128-gcm + validators: [] + spec: {} + description: Allow AES-128-GCM encryption algorithm + required: false + - name: enc-algo-aes-256-cbc + type: bool + profiles: + - xpath: + - enc-algo-aes-256-cbc + validators: [] + spec: {} + description: Allow AES-256-CBC encryption algorithm + required: false + - name: enc-algo-aes-256-gcm + type: bool + profiles: + - xpath: + - enc-algo-aes-256-gcm + validators: [] + spec: {} + description: Allow AES-256-GCM encryption algorithm + required: false + - name: enc-algo-chacha20-poly1305 + type: bool + profiles: + - xpath: + - enc-algo-chacha20-poly1305 + validators: [] + spec: {} + description: Allow algorithm chacha20-poly1305 + required: false + - name: enc-algo-rc4 + type: bool + profiles: + - xpath: + - enc-algo-rc4 + validators: [] + spec: {} + description: Allow RC4 encryption algorithm + required: false + - name: keyxchg-algo-dhe + type: bool + profiles: + - xpath: + - keyxchg-algo-dhe + validators: [] + spec: {} + description: Allow DHE key exchange algorithm + required: false + - name: keyxchg-algo-ecdhe + type: bool + profiles: + - xpath: + - keyxchg-algo-ecdhe + validators: [] + spec: {} + description: Allow ECDHE key exchange algorithm + required: false + - name: keyxchg-algo-rsa + type: bool + profiles: + - xpath: + - keyxchg-algo-rsa + validators: [] + spec: {} + description: Allow RSA key exchange algorithm + required: false + - name: max-version + type: enum + profiles: + - xpath: + - max-version + validators: + - type: values + spec: + values: + - tls1-0 + - tls1-1 + - tls1-2 + - tls1-3 + - max + spec: + default: tls1-2 + values: + - value: tls1-0 + - value: tls1-1 + - value: tls1-2 + - value: tls1-3 + - value: max + description: Maximum SSL/TLS protocol version + required: false + - name: min-version + type: enum + profiles: + - xpath: + - min-version + validators: + - type: values + spec: + values: + - tls1-0 + - tls1-1 + - tls1-2 + - tls1-3 + spec: + default: tls1-0 + values: + - value: tls1-0 + - value: tls1-1 + - value: tls1-2 + - value: tls1-3 + description: Minimum SSL/TLS protocol version + required: false + variants: [] + description: SSL/TLS protocol settings + required: false + variants: []