diff --git a/assets/terraform/test/resource_dns_proxy_test.go b/assets/terraform/test/resource_dns_proxy_test.go new file mode 100644 index 00000000..15b605f6 --- /dev/null +++ b/assets/terraform/test/resource_dns_proxy_test.go @@ -0,0 +1,238 @@ +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 TestAccDnsProxy(t *testing.T) { + t.Parallel() + + nameSuffix := acctest.RandStringFromCharSet(6, acctest.CharSetAlphaNum) + prefix := fmt.Sprintf("test-acc-%s", nameSuffix) + name := "dns-proxy-test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: dnsProxyResourceTmpl, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "name": config.StringVariable(name), + "enabled": config.BoolVariable(true), + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("name"), + knownvalue.StringExact(name), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("enabled"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("default").AtMapKey("primary"), + knownvalue.StringExact("8.8.8.8"), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("default").AtMapKey("secondary"), + knownvalue.StringExact("8.8.4.4"), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("interface"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("ethernet1/1"), + knownvalue.StringExact("ethernet1/2"), + }), + ), + }, + }, + { + Config: dnsProxyResourceTmplFull, + ConfigVariables: map[string]config.Variable{ + "prefix": config.StringVariable(prefix), + "name": config.StringVariable(name), + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("name"), + knownvalue.StringExact(name), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("enabled"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("cache").AtMapKey("enabled"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("cache").AtMapKey("cache_edns"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("cache").AtMapKey("max_ttl").AtMapKey("enabled"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("cache").AtMapKey("max_ttl").AtMapKey("time_to_live"), + knownvalue.Int64Exact(3600), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("domain_servers").AtSliceIndex(0).AtMapKey("name"), + knownvalue.StringExact("internal-servers"), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("domain_servers").AtSliceIndex(0).AtMapKey("domain_name"), + knownvalue.ListExact([]knownvalue.Check{knownvalue.StringExact("internal.example.com")}), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("static_entries").AtSliceIndex(0).AtMapKey("name"), + knownvalue.StringExact("static-entry-1"), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("static_entries").AtSliceIndex(0).AtMapKey("domain"), + knownvalue.StringExact("static.example.com"), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("tcp_queries").AtMapKey("enabled"), + knownvalue.Bool(true), + ), + statecheck.ExpectKnownValue( + "panos_dns_proxy.proxy", + tfjsonpath.New("udp_queries").AtMapKey("retries").AtMapKey("attempts"), + knownvalue.Int64Exact(10), + ), + }, + }, + }, + }) +} + +const dnsProxyResourceTmpl = ` +variable "prefix" { type = string } +variable "name" { type = string } +variable "enabled" { type = bool } + +resource "panos_template" "tmpl" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_ethernet_interface" "iface1" { + location = { template = { name = panos_template.tmpl.name } } + name = "ethernet1/1" + layer3 = {} +} + +resource "panos_ethernet_interface" "iface2" { + location = { template = { name = panos_template.tmpl.name } } + name = "ethernet1/2" + layer3 = {} +} + +resource "panos_dns_proxy" "proxy" { + location = { template = { name = panos_template.tmpl.name } } + name = var.name + enabled = var.enabled + default = { + primary = "8.8.8.8" + secondary = "8.8.4.4" + } + interface = [panos_ethernet_interface.iface1.name, panos_ethernet_interface.iface2.name] +} +` + +const dnsProxyResourceTmplFull = ` +variable "prefix" { type = string } +variable "name" { type = string } + +resource "panos_template" "tmpl" { + location = { panorama = {} } + name = var.prefix +} + +resource "panos_ethernet_interface" "iface1" { + location = { template = { name = panos_template.tmpl.name } } + name = "ethernet1/1" + layer3 = {} +} + +resource "panos_ethernet_interface" "iface2" { + location = { template = { name = panos_template.tmpl.name } } + name = "ethernet1/2" + layer3 = {} +} + +resource "panos_dns_proxy" "proxy" { + location = { template = { name = panos_template.tmpl.name } } + name = var.name + enabled = true + interface = [panos_ethernet_interface.iface1.name, panos_ethernet_interface.iface2.name] + + cache = { + enabled = true + cache_edns = true + max_ttl = { + enabled = true + time_to_live = 3600 + } + } + + default = { + primary = "8.8.8.8" + secondary = "8.8.4.4" + } + + domain_servers = [{ + name = "internal-servers" + domain_name = ["internal.example.com"] + primary = "10.0.0.1" + secondary = "10.0.0.2" + cacheable = true + }] + + static_entries = [{ + name = "static-entry-1" + domain = "static.example.com" + address = ["192.168.1.100"] + }] + + tcp_queries = { + enabled = true + max_pending_requests = 128 + } + + udp_queries = { + retries = { + attempts = 10 + interval = 5 + } + } +} +` diff --git a/specs/network/dns-proxy.yaml b/specs/network/dns-proxy.yaml new file mode 100644 index 00000000..4b306632 --- /dev/null +++ b/specs/network/dns-proxy.yaml @@ -0,0 +1,418 @@ +name: dhcp +terraform_provider_config: + description: DNS Proxy + skip_resource: false + skip_datasource: false + resource_type: entry + resource_variants: + - singular + suffix: dns_proxy + plural_suffix: '' + plural_name: '' + plural_description: '' +go_sdk_config: + skip: false + package: + - network + - dnsproxy +panos_xpath: + path: + - network + - dns-proxy + vars: [] +locations: +- name: template + xpath: + path: + - config + - devices + - $panorama_device + - template + - $template + - config + - devices + - $ngfw_device + 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 + description: Located in 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 + - devices + - $ngfw_device + vars: + - name: panorama_device + description: Specific Panorama device + required: false + default: localhost.localdomain + validators: [] + type: entry + - name: template_stack + description: Specific Panorama template stack + required: true + validators: [] + type: entry + - name: ngfw_device + description: The NGFW device + required: false + default: localhost.localdomain + validators: [] + type: entry + description: Located in a specific template stack + devices: + - panorama + validators: [] + required: false + read_only: false +entries: +- name: name + description: '' + validators: [] +imports: [] +spec: + params: + - name: cache + type: object + profiles: + - xpath: + - cache + validators: [] + spec: + params: + - name: cache-edns + type: bool + profiles: + - xpath: + - cache-edns + validators: [] + spec: {} + description: Cache EDNS UDP response + required: false + - name: enabled + type: bool + profiles: + - xpath: + - enabled + validators: [] + spec: {} + description: Turn on caching for this DNS object + required: false + - name: max-ttl + type: object + profiles: + - xpath: + - max-ttl + validators: [] + spec: + params: + - name: enabled + type: bool + profiles: + - xpath: + - enabled + validators: [] + spec: {} + description: Enable max ttl for this DNS object + required: false + - name: time-to-live + type: int64 + profiles: + - xpath: + - time-to-live + validators: + - type: length + spec: + min: 60 + max: 86400 + spec: {} + description: Time in seconds after which entry is cleared + required: false + variants: [] + description: Specify DNS cache related settings + required: false + variants: [] + description: Specify DNS cache related settings + required: false + - name: default + type: object + profiles: + - xpath: + - default + validators: [] + spec: + params: + - name: inheritance + type: object + profiles: + - xpath: + - inheritance + validators: [] + spec: + params: + - name: source + type: string + profiles: + - xpath: + - source + validators: [] + spec: {} + description: Dynamic interface + required: false + variants: [] + description: Inherit settings from interface + required: false + - name: primary + type: string + profiles: + - xpath: + - primary + validators: [] + spec: {} + description: Primary DNS Name server IP address + required: false + - name: secondary + type: string + profiles: + - xpath: + - secondary + validators: [] + spec: {} + description: Secondary DNS Name server IP address + required: false + variants: [] + description: Specify DNS default settings + required: false + - name: domain-servers + type: list + profiles: + - xpath: + - domain-servers + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: cacheable + type: bool + profiles: + - xpath: + - cacheable + validators: [] + spec: {} + description: Turn on caching of domains resolved by this mapping + required: false + - name: primary + type: string + profiles: + - xpath: + - primary + validators: [] + spec: {} + description: Primary DNS Name server IP address + required: false + - name: secondary + type: string + profiles: + - xpath: + - secondary + validators: [] + spec: {} + description: Secondary DNS Name server IP address + required: false + - name: domain-name + type: list + profiles: + - xpath: + - domain-name + type: member + validators: [] + spec: + type: string + items: + type: string + description: '' + required: false + variants: [] + description: '' + required: false + - name: enabled + type: bool + profiles: + - xpath: + - enabled + validators: [] + spec: {} + description: Enable or disable processing of DNS requests on interface(s) on this + object + required: false + - name: interface + type: list + profiles: + - xpath: + - interface + type: member + validators: [] + spec: + type: string + items: + type: string + description: '' + required: false + - name: static-entries + type: list + profiles: + - xpath: + - static-entries + - entry + type: entry + validators: [] + spec: + type: object + items: + type: object + spec: + params: + - name: domain + type: string + profiles: + - xpath: + - domain + validators: + - type: length + spec: + max: 255 + spec: {} + description: Fully qualified domain name for specified IP address + required: false + - name: address + type: list + profiles: + - xpath: + - address + type: member + validators: [] + spec: + type: string + items: + type: string + description: '' + required: false + variants: [] + description: '' + required: false + - name: tcp-queries + type: object + profiles: + - xpath: + - tcp-queries + validators: [] + spec: + params: + - name: enabled + type: bool + profiles: + - xpath: + - enabled + validators: [] + spec: {} + description: Turn on forwarding of TCP DNS queries + required: false + - name: max-pending-requests + type: int64 + profiles: + - xpath: + - max-pending-requests + validators: + - type: length + spec: + min: 64 + max: 256 + spec: + default: 64 + description: Upper limit on number of concurrent TCP DNS requests + required: false + variants: [] + description: Specify TCP queries related settings + required: false + - name: udp-queries + type: object + profiles: + - xpath: + - udp-queries + validators: [] + spec: + params: + - name: retries + type: object + profiles: + - xpath: + - retries + validators: [] + spec: + params: + - name: attempts + type: int64 + profiles: + - xpath: + - attempts + validators: + - type: length + spec: + min: 1 + max: 30 + spec: + default: 5 + description: Maximum number of retries before trying next name server + required: false + - name: interval + type: int64 + profiles: + - xpath: + - interval + validators: + - type: length + spec: + min: 1 + max: 30 + spec: + default: 2 + description: Time in seconds for another request to be sent + required: false + variants: [] + description: Tune DNS query forwarding retry parameters + required: false + variants: [] + description: Specify UDP queries related settings + required: false + variants: []