├── .github └── workflows │ └── release.yml ├── .gitignore ├── .goreleaser.yml ├── LICENSE ├── README.md ├── docs ├── data-sources │ ├── firewall_alias.md │ ├── firewall_category.md │ ├── firewall_filter.md │ ├── firewall_nat.md │ ├── interface.md │ ├── interface_all.md │ ├── interfaces_vlan.md │ ├── kea_peer.md │ ├── kea_reservation.md │ ├── kea_subnet.md │ ├── quagga_bgp_aspath.md │ ├── quagga_bgp_communitylist.md │ ├── quagga_bgp_neighbor.md │ ├── quagga_bgp_prefixlist.md │ ├── quagga_bgp_routemap.md │ ├── route.md │ ├── unbound_domain_override.md │ ├── unbound_forward.md │ ├── unbound_host_alias.md │ ├── unbound_host_override.md │ ├── wireguard_client.md │ └── wireguard_server.md ├── index.md └── resources │ ├── firewall_alias.md │ ├── firewall_category.md │ ├── firewall_filter.md │ ├── firewall_nat.md │ ├── interfaces_vlan.md │ ├── kea_peer.md │ ├── kea_reservation.md │ ├── kea_subnet.md │ ├── quagga_bgp_aspath.md │ ├── quagga_bgp_communitylist.md │ ├── quagga_bgp_neighbor.md │ ├── quagga_bgp_prefixlist.md │ ├── quagga_bgp_routemap.md │ ├── route.md │ ├── unbound_domain_override.md │ ├── unbound_forward.md │ ├── unbound_host_alias.md │ ├── unbound_host_override.md │ ├── wireguard_client.md │ └── wireguard_server.md ├── examples ├── data-sources │ └── opnsense_interface_all │ │ └── data-source.tf ├── provider │ └── provider.tf └── resources │ ├── opnsense_firewall_alias │ └── resource.tf │ ├── opnsense_firewall_category │ └── resource.tf │ ├── opnsense_firewall_filter │ └── resource.tf │ ├── opnsense_firewall_nat │ └── resource.tf │ ├── opnsense_interfaces_vlan │ └── resource.tf │ ├── opnsense_kea_peer │ └── resource.tf │ ├── opnsense_kea_reservation │ └── resource.tf │ ├── opnsense_kea_subnet │ └── resource.tf │ ├── opnsense_quagga_bgp_aspath │ └── resource.tf │ ├── opnsense_quagga_bgp_communitylist │ └── resource.tf │ ├── opnsense_quagga_bgp_neighbor │ └── resource.tf │ ├── opnsense_quagga_bgp_prefixlist │ └── resource.tf │ ├── opnsense_quagga_bgp_routemap │ └── resource.tf │ ├── opnsense_route │ └── resource.tf │ ├── opnsense_unbound_domain_override │ └── resource.tf │ ├── opnsense_unbound_forward │ └── resource.tf │ ├── opnsense_unbound_host_alias │ └── resource.tf │ ├── opnsense_unbound_host_override │ └── resource.tf │ ├── opnsense_wireguard_client │ └── resource.tf │ └── opnsense_wireguard_server │ └── resource.tf ├── go.mod ├── go.sum ├── internal ├── provider │ └── provider.go ├── service │ ├── firewall_alias_data_source.go │ ├── firewall_alias_resource.go │ ├── firewall_alias_schema.go │ ├── firewall_category_data_source.go │ ├── firewall_category_resource.go │ ├── firewall_category_schema.go │ ├── firewall_filter_data_source.go │ ├── firewall_filter_resource.go │ ├── firewall_filter_schema.go │ ├── firewall_nat_data_source.go │ ├── firewall_nat_resource.go │ ├── firewall_nat_schema.go │ ├── interface_all_data_source.go │ ├── interface_all_schema.go │ ├── interface_data_source.go │ ├── interface_schema.go │ ├── interfaces_vlan_data_source.go │ ├── interfaces_vlan_resource.go │ ├── interfaces_vlan_schema.go │ ├── kea_peer_data_source.go │ ├── kea_peer_resource.go │ ├── kea_peer_schema.go │ ├── kea_reservation_data_source.go │ ├── kea_reservation_resource.go │ ├── kea_reservation_schema.go │ ├── kea_subnet_data_source.go │ ├── kea_subnet_resource.go │ ├── kea_subnet_schema.go │ ├── quagga_bgp_aspath_data_source.go │ ├── quagga_bgp_aspath_resource.go │ ├── quagga_bgp_aspath_schema.go │ ├── quagga_bgp_communitylist_data_source.go │ ├── quagga_bgp_communitylist_resource.go │ ├── quagga_bgp_communitylist_schema.go │ ├── quagga_bgp_neighbor_data_source.go │ ├── quagga_bgp_neighbor_resource.go │ ├── quagga_bgp_neighbor_schema.go │ ├── quagga_bgp_prefixlist_data_source.go │ ├── quagga_bgp_prefixlist_resource.go │ ├── quagga_bgp_prefixlist_schema.go │ ├── quagga_bgp_routemap_data_source.go │ ├── quagga_bgp_routemap_resource.go │ ├── quagga_bgp_routemap_schema.go │ ├── route_data_source.go │ ├── route_resource.go │ ├── route_schema.go │ ├── unbound_domain_override_data_source.go │ ├── unbound_domain_override_resource.go │ ├── unbound_domain_override_schema.go │ ├── unbound_forward_data_source.go │ ├── unbound_forward_resource.go │ ├── unbound_forward_schema.go │ ├── unbound_host_alias_data_source.go │ ├── unbound_host_alias_resource.go │ ├── unbound_host_alias_schema.go │ ├── unbound_host_override_data_source.go │ ├── unbound_host_override_resource.go │ ├── unbound_host_override_schema.go │ ├── wireguard_client_data_source.go │ ├── wireguard_client_resource.go │ ├── wireguard_client_schema.go │ ├── wireguard_server_data_source.go │ ├── wireguard_server_resource.go │ └── wireguard_server_schema.go └── tools │ └── type_utils.go ├── main.go ├── templates ├── data-sources │ ├── firewall_alias.md.tmpl │ ├── firewall_category.md.tmpl │ ├── firewall_filter.md.tmpl │ ├── firewall_nat.md.tmpl │ ├── interface.md.tmpl │ ├── interface_all.md.tmpl │ ├── interfaces_vlan.md.tmpl │ ├── kea_peer.md.tmpl │ ├── kea_reservation.md.tmpl │ ├── kea_subnet.md.tmpl │ ├── quagga_bgp_aspath.md.tmpl │ ├── quagga_bgp_communitylist.md.tmpl │ ├── quagga_bgp_neighbor.md.tmpl │ ├── quagga_bgp_prefixlist.md.tmpl │ ├── quagga_bgp_routemap.md.tmpl │ ├── route.md.tmpl │ ├── unbound_domain_override.md.tmpl │ ├── unbound_forward.md.tmpl │ ├── unbound_host_alias.md.tmpl │ ├── unbound_host_override.md.tmpl │ ├── wireguard_client.md.tmpl │ └── wireguard_server.md.tmpl ├── index.md.tmpl └── resources │ ├── firewall_alias.md.tmpl │ ├── firewall_category.md.tmpl │ ├── firewall_filter.md.tmpl │ ├── firewall_nat.md.tmpl │ ├── interfaces_vlan.md.tmpl │ ├── kea_peer.md.tmpl │ ├── kea_reservation.md.tmpl │ ├── kea_subnet.md.tmpl │ ├── quagga_bgp_aspath.md.tmpl │ ├── quagga_bgp_communitylist.md.tmpl │ ├── quagga_bgp_neighbor.md.tmpl │ ├── quagga_bgp_prefixlist.md.tmpl │ ├── quagga_bgp_routemap.md.tmpl │ ├── route.md.tmpl │ ├── unbound_domain_override.md.tmpl │ ├── unbound_forward.md.tmpl │ ├── unbound_host_alias.md.tmpl │ ├── unbound_host_override.md.tmpl │ ├── wireguard_client.md.tmpl │ └── wireguard_server.md.tmpl ├── terraform-registry-manifest.json └── tools └── tools.go /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Terraform Provider release workflow. 2 | name: Release 3 | 4 | # This GitHub action creates a release when a tag that matches the pattern 5 | # "v*" (e.g. v0.1.0) is created. 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | # Releases need permissions to read and write the repository contents. 12 | # GitHub considers creating releases and uploading assets as writing contents. 13 | permissions: 14 | contents: write 15 | 16 | jobs: 17 | goreleaser: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 21 | with: 22 | # Allow goreleaser to access older tag information. 23 | fetch-depth: 0 24 | - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 25 | with: 26 | go-version-file: 'go.mod' 27 | cache: true 28 | - name: Import GPG key 29 | uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 30 | id: import_gpg 31 | with: 32 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} 33 | passphrase: ${{ secrets.PASSPHRASE }} 34 | - name: Run GoReleaser 35 | uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 36 | with: 37 | args: release --clean 38 | env: 39 | # GitHub sets the GITHUB_TOKEN secret automatically. 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | .DS_Store 4 | example.tf 5 | terraform.tfplan 6 | terraform.tfstate 7 | bin/ 8 | dist/ 9 | modules-dev/ 10 | /pkg/ 11 | website/.vagrant 12 | website/.bundle 13 | website/build 14 | website/node_modules 15 | .vagrant/ 16 | *.backup 17 | ./*.tfstate 18 | .terraform/ 19 | *.log 20 | *.bak 21 | *~ 22 | .*.swp 23 | .idea 24 | *.iml 25 | *.test 26 | *.iml 27 | 28 | website/vendor 29 | 30 | # Test exclusions 31 | !command/test-fixtures/**/*.tfstate 32 | !command/test-fixtures/**/.terraform/ 33 | 34 | # Keep windows files with windows line endings 35 | *.winfile eol=crlf -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # Visit https://goreleaser.com for documentation on how to customize this 2 | # behavior. 3 | version: 2 4 | before: 5 | hooks: 6 | # this is just an example and not a requirement for provider building/publishing 7 | - go mod tidy 8 | builds: 9 | - env: 10 | # goreleaser does not work with CGO, it could also complicate 11 | # usage by users in CI/CD systems like Terraform Cloud where 12 | # they are unable to install libraries. 13 | - CGO_ENABLED=0 14 | mod_timestamp: '{{ .CommitTimestamp }}' 15 | flags: 16 | - -trimpath 17 | ldflags: 18 | - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' 19 | goos: 20 | - freebsd 21 | - windows 22 | - linux 23 | - darwin 24 | goarch: 25 | - amd64 26 | - '386' 27 | - arm 28 | - arm64 29 | ignore: 30 | - goos: darwin 31 | goarch: '386' 32 | binary: '{{ .ProjectName }}_v{{ .Version }}' 33 | archives: 34 | - format: zip 35 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 36 | checksum: 37 | extra_files: 38 | - glob: 'terraform-registry-manifest.json' 39 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 40 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 41 | algorithm: sha256 42 | signs: 43 | - artifacts: checksum 44 | args: 45 | # if you are using this in a GitHub action or some other automated pipeline, you 46 | # need to pass the batch flag to indicate its not interactive. 47 | - "--batch" 48 | - "--local-user" 49 | - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key 50 | - "--output" 51 | - "${signature}" 52 | - "--detach-sign" 53 | - "${artifact}" 54 | release: 55 | extra_files: 56 | - glob: 'terraform-registry-manifest.json' 57 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 58 | # If you want to manually examine the release before its live, uncomment this line: 59 | # draft: true 60 | changelog: 61 | disable: true 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Luke Browning 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OPNsense Terraform Provider 2 | 3 | This provider seeks to support the *entire* OPNsense API. 4 | However, this provider does not, and will not, support resources 5 | not currently supported by the OPNsense API. If required, see if 6 | [dalet-oss/opnsense](https://github.com/dalet-oss/terraform-provider-opnsense) 7 | will support your needs. 8 | 9 | 10 | ⚠️ Please note that this provider is under active development, and makes no 11 | guarantee to be stable. For that reason, it is not currently recommended 12 | to use this provider in any production environment. If a feature is missing, 13 | but is documented in the OPNsense API, please raise an issue to indicate interest. 14 | 15 | -------------------------------------------------------------------------------- /docs/data-sources/firewall_alias.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_firewall_alias Data Source - terraform-provider-opnsense" 3 | subcategory: Firewall 4 | description: |- 5 | Aliases are named lists of networks, hosts or ports that can be used as one entity by selecting the alias name in the various supported sections of the firewall. These aliases are particularly useful to condense firewall rules and minimize changes. 6 | --- 7 | 8 | # opnsense_firewall_alias (Data Source) 9 | 10 | Aliases are named lists of networks, hosts or ports that can be used as one entity by selecting the alias name in the various supported sections of the firewall. These aliases are particularly useful to condense firewall rules and minimize changes. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `categories` (Set of String) Set of category IDs to apply. 22 | - `content` (Set of String) The content of the alias. Enter ISO 3166-1 country codes when `type = "geoip"` (e.g. `["CA", "FR"]`). Enter `___network`, or alias when `type = "networkgroup"` (e.g. `["__wan_network", "otheralias"]`). Enter OpenVPN group when `type = "authgroup"` (e.g. `["admins"]`). Set to `[]` when `type = "external"`. 23 | - `description` (String) Optional description here for your reference (not parsed). 24 | - `enabled` (Boolean) Enable this firewall alias. 25 | - `interface` (String) Choose on which interface this alias applies. Only applies (and must be set) when `type = "dynipv6host"`. 26 | - `ip_protocol` (String) Select the Internet Protocol version this alias applies to. Available values: `IPv4`, `IPv6`. Only applies when `type = "asn"`, `type = "geoip"`, or `type = "external"`. 27 | - `name` (String) The name must start with a letter or single underscore, be less than 32 characters and only consist of alphanumeric characters or underscores. Aliases can be nested using this name. 28 | - `stats` (Boolean) Whether to maintain a set of counters for each table entry. 29 | - `type` (String) The type of alias. 30 | - `update_freq` (Number) The frequency that the list will be refreshed, in days (e.g. for 30 hours, enter `1.25`). Only applies (and must be set) when `type = "urltable"`. 31 | 32 | -------------------------------------------------------------------------------- /docs/data-sources/firewall_category.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_firewall_category Data Source - terraform-provider-opnsense" 3 | subcategory: Firewall 4 | description: |- 5 | To ease maintenance of larger rulesets, OPNsense includes categories for the firewall. Each rule can contain one or more categories. 6 | --- 7 | 8 | # opnsense_firewall_category (Data Source) 9 | 10 | To ease maintenance of larger rulesets, OPNsense includes categories for the firewall. Each rule can contain one or more categories. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `auto` (Boolean) If set, this category will be removed when unused. 22 | - `color` (String) The color to use. Must be a hex color in format `rrggbb` (e.g. `ff0000`). 23 | - `name` (String) The name for this category. 24 | 25 | -------------------------------------------------------------------------------- /docs/data-sources/firewall_filter.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_firewall_filter Data Source - terraform-provider-opnsense" 3 | subcategory: Firewall 4 | description: |- 5 | Firewall filter rules can be used to restrict or allow traffic from and/or to specific networks as well as influence how traffic should be forwarded 6 | --- 7 | 8 | # opnsense_firewall_filter (Data Source) 9 | 10 | Firewall filter rules can be used to restrict or allow traffic from and/or to specific networks as well as influence how traffic should be forwarded 11 | 12 | ~> This resource requires the `os-firewall` plugin to be installed. It will *not* behave correctly if it is not installed. 13 | 14 | 15 | ## Schema 16 | 17 | ### Required 18 | 19 | - `id` (String) UUID of the resource. 20 | 21 | ### Read-Only 22 | 23 | - `action` (String) Choose what to do with packets that match the criteria specified below. Hint: the difference between block and reject is that with reject, a packet (TCP RST or ICMP port unreachable for UDP) is returned to the sender, whereas with block the packet is dropped silently. In either case, the original packet is discarded. Available values: `pass`, `block`, `reject`. 24 | - `description` (String) Optional description here for your reference (not parsed). Must be between 1 and 255 characters. Must be a character in set `[a-zA-Z0-9 .]`. 25 | - `destination` (Attributes) (see [below for nested schema](#nestedatt--destination)) 26 | - `direction` (String) Direction of the traffic. The default policy is to filter inbound traffic, which sets the policy to the interface originally receiving the traffic. Available values: `in`, `out`. 27 | - `enabled` (Boolean) Enable this firewall filter rule. 28 | - `gateway` (String) Leave as `""` to use the system routing table. Or choose a gateway to utilize policy based routing. 29 | - `interface` (Set of String) The interface(s) on which the packets must come in to match this rule. 30 | - `ip_protocol` (String) Select the Internet Protocol version this rule applies to. Available values: `inet`, `inet6`. 31 | - `log` (Boolean) Log packets that are handled by this rule. 32 | - `protocol` (String) Choose which IP protocol this rule should match. 33 | - `quick` (Boolean) If a packet matches a rule specifying quick, then that rule is considered the last matching rule and the specified action is taken. When a rule does not have quick enabled, the last matching rule wins. 34 | - `sequence` (Number) Specify the order of this filter rule. 35 | - `source` (Attributes) (see [below for nested schema](#nestedatt--source)) 36 | 37 | 38 | ### Nested Schema for `destination` 39 | 40 | Read-Only: 41 | 42 | - `invert` (Boolean) Use this option to invert the sense of the match. 43 | - `net` (String) Specify the IP address, CIDR or alias for the destination of the packet for this mapping. 44 | - `port` (String) Specify the port for the destination of the packet for this mapping. 45 | 46 | 47 | 48 | ### Nested Schema for `source` 49 | 50 | Read-Only: 51 | 52 | - `invert` (Boolean) Use this option to invert the sense of the match. 53 | - `net` (String) Specify the IP address, CIDR or alias for the source of the packet for this mapping. 54 | - `port` (String) Specify the source port for this rule. This is usually random and almost never equal to the destination port range (and should usually be `""`). 55 | 56 | -------------------------------------------------------------------------------- /docs/data-sources/firewall_nat.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_firewall_nat Data Source - terraform-provider-opnsense" 3 | subcategory: Firewall 4 | description: |- 5 | Network Address Translation (abbreviated to NAT) is a way to separate external and internal networks (WANs and LANs), and to share an external IP between clients on the internal network. 6 | --- 7 | 8 | # opnsense_firewall_nat (Data Source) 9 | 10 | Network Address Translation (abbreviated to NAT) is a way to separate external and internal networks (WANs and LANs), and to share an external IP between clients on the internal network. 11 | 12 | ~> This resource requires the `os-firewall` plugin to be installed. It will *not* behave correctly if it is not installed. 13 | 14 | 15 | ## Schema 16 | 17 | ### Required 18 | 19 | - `id` (String) UUID of the resource. 20 | 21 | ### Read-Only 22 | 23 | - `description` (String) Optional description here for your reference (not parsed). 24 | - `destination` (Attributes) (see [below for nested schema](#nestedatt--destination)) 25 | - `disable_nat` (Boolean) Enabling this option will disable NAT for traffic matching this rule and stop processing Outbound NAT rules. 26 | - `enabled` (Boolean) Enable this firewall NAT rule. 27 | - `interface` (String) The interface on which packets must come in to match this rule. 28 | - `ip_protocol` (String) Select the Internet Protocol version this rule applies to. Available values: `inet`, `inet6`. 29 | - `log` (Boolean) Log packets that are handled by this rule. 30 | - `protocol` (String) Choose which IP protocol this rule should match. 31 | - `sequence` (Number) Specify the order of this NAT rule. 32 | - `source` (Attributes) (see [below for nested schema](#nestedatt--source)) 33 | - `target` (Attributes) (see [below for nested schema](#nestedatt--target)) 34 | 35 | 36 | ### Nested Schema for `destination` 37 | 38 | Read-Only: 39 | 40 | - `invert` (Boolean) Use this option to invert the sense of the match. 41 | - `net` (String) Specify the IP address, CIDR or alias for the destination of the packet for this mapping. 42 | - `port` (String) Specify the port for the destination of the packet for this mapping. 43 | 44 | 45 | 46 | ### Nested Schema for `source` 47 | 48 | Read-Only: 49 | 50 | - `invert` (Boolean) Use this option to invert the sense of the match. 51 | - `net` (String) Specify the IP address, CIDR or alias for the source of the packet for this mapping. 52 | - `port` (String) Specify the source port for this rule. This is usually random and almost never equal to the destination port range (and should usually be `""`). 53 | 54 | 55 | 56 | ### Nested Schema for `target` 57 | 58 | Read-Only: 59 | 60 | - `ip` (String) Specify the IP address or alias for the packets to be mapped to. 61 | - `port` (String) Destination port number or well known name (imap, imaps, http, https, ...), for ranges use a dash. 62 | 63 | -------------------------------------------------------------------------------- /docs/data-sources/interface.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_interface Data Source - terraform-provider-opnsense" 3 | subcategory: Interfaces 4 | description: |- 5 | Interfaces can be used to get configurations of OPNsense interfaces. 6 | --- 7 | 8 | # opnsense_interface (Data Source) 9 | 10 | Interfaces can be used to get configurations of OPNsense interfaces. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `device` (String) Name of the interface device. 18 | 19 | ### Read-Only 20 | 21 | - `capabilities` (Set of String) List of capabilities the interface supports. 22 | - `flags` (Set of String) List of flags configured on the interface (equiv. to flags=xxxx in output of ifconfig). 23 | - `groups` (Set of String) List of groups the interface is a member of. 24 | - `ipv4` (Attributes List) (see [below for nested schema](#nestedatt--ipv4)) 25 | - `ipv6` (Attributes List) (see [below for nested schema](#nestedatt--ipv6)) 26 | - `is_physical` (Boolean) Whether the interface is physical or virtual. 27 | - `macaddr` (String) MAC address assigned to the interface. 28 | - `media` (String) Interface media type settings (see https://man.openbsd.org/ifmedia.4). 29 | - `media_raw` (String) User-friendly interface media type. 30 | - `mtu` (Number) Maximum Transmission Unit for the interface. This is typically 1500 bytes but can vary in some circumstances. 31 | - `options` (Set of String) List of options configured on the interface (equiv. to options=xx in output of ifconfig). 32 | - `status` (String) Status of the interface (e.g. `"active"`). 33 | - `supported_media` (Set of String) List of supported media type settings (see https://man.openbsd.org/ifmedia.4). 34 | 35 | 36 | ### Nested Schema for `ipv4` 37 | 38 | Read-Only: 39 | 40 | - `ipaddr` (String) IPv4 address assigned to the interface. 41 | - `subnetbits` (Number) Number of subnet bits (i.e. CIDR). 42 | - `tunnel` (Boolean) Whether IPv4 tunnelling is enabled. 43 | 44 | 45 | 46 | ### Nested Schema for `ipv6` 47 | 48 | Read-Only: 49 | 50 | - `autoconf` (Boolean) Whether auto-configuration is enabled for the address. 51 | - `deprecated` (Boolean) Whether the address is deprecated. 52 | - `ipaddr` (String) IPv6 address assigned to the interface. 53 | - `link_local` (Boolean) Whether the address is link-local. 54 | - `subnetbits` (Number) Number of subnet bits (i.e. CIDR). 55 | - `tentative` (Boolean) Whether the address is tentative. 56 | - `tunnel` (Boolean) Whether IPv6 tunnelling is enabled. 57 | 58 | -------------------------------------------------------------------------------- /docs/data-sources/interface_all.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_interface_all Data Source - terraform-provider-opnsense" 3 | subcategory: Interfaces 4 | description: |- 5 | InterfacesAll can be used to get a list of all configurations of OPNsense interfaces. Allows for custom filtering. 6 | --- 7 | 8 | # opnsense_interface_all (Data Source) 9 | 10 | InterfacesAll can be used to get a list of all configurations of OPNsense interfaces. Allows for custom filtering. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Get all interface configs 16 | data "opnsense_interface_all" "all" {} 17 | 18 | // Filter for a specific MAC address 19 | output "specific_mac" { 20 | value = [for i in data.opnsense_interface_all.all.interfaces : i if i.macaddr == "5a:dc:1f:24:12:c6"] 21 | } 22 | 23 | // Filter for specific device (advisable to use opnsense_interface instead) 24 | output "wireguard" { 25 | value = [for i in data.opnsense_interface_all.all.interfaces : i if i.device == "wg1"] 26 | } 27 | ``` 28 | 29 | 30 | ## Schema 31 | 32 | ### Read-Only 33 | 34 | - `interfaces` (Attributes List) A list of all interfaces present in OPNsense. (see [below for nested schema](#nestedatt--interfaces)) 35 | 36 | 37 | ### Nested Schema for `interfaces` 38 | 39 | Required: 40 | 41 | - `device` (String) Name of the interface device. 42 | 43 | Read-Only: 44 | 45 | - `capabilities` (Set of String) List of capabilities the interface supports. 46 | - `flags` (Set of String) List of flags configured on the interface (equiv. to flags=xxxx in output of ifconfig). 47 | - `groups` (Set of String) List of groups the interface is a member of. 48 | - `ipv4` (Attributes List) (see [below for nested schema](#nestedatt--interfaces--ipv4)) 49 | - `ipv6` (Attributes List) (see [below for nested schema](#nestedatt--interfaces--ipv6)) 50 | - `is_physical` (Boolean) Whether the interface is physical or virtual. 51 | - `macaddr` (String) MAC address assigned to the interface. 52 | - `media` (String) Interface media type settings (see https://man.openbsd.org/ifmedia.4). 53 | - `media_raw` (String) User-friendly interface media type. 54 | - `mtu` (Number) Maximum Transmission Unit for the interface. This is typically 1500 bytes but can vary in some circumstances. 55 | - `options` (Set of String) List of options configured on the interface (equiv. to options=xx in output of ifconfig). 56 | - `status` (String) Status of the interface (e.g. `"active"`). 57 | - `supported_media` (Set of String) List of supported media type settings (see https://man.openbsd.org/ifmedia.4). 58 | 59 | 60 | ### Nested Schema for `interfaces.ipv4` 61 | 62 | Read-Only: 63 | 64 | - `ipaddr` (String) IPv4 address assigned to the interface. 65 | - `subnetbits` (Number) Number of subnet bits (i.e. CIDR). 66 | - `tunnel` (Boolean) Whether IPv4 tunnelling is enabled. 67 | 68 | 69 | 70 | ### Nested Schema for `interfaces.ipv6` 71 | 72 | Read-Only: 73 | 74 | - `autoconf` (Boolean) Whether auto-configuration is enabled for the address. 75 | - `deprecated` (Boolean) Whether the address is deprecated. 76 | - `ipaddr` (String) IPv6 address assigned to the interface. 77 | - `link_local` (Boolean) Whether the address is link-local. 78 | - `subnetbits` (Number) Number of subnet bits (i.e. CIDR). 79 | - `tentative` (Boolean) Whether the address is tentative. 80 | - `tunnel` (Boolean) Whether IPv6 tunnelling is enabled. 81 | 82 | -------------------------------------------------------------------------------- /docs/data-sources/interfaces_vlan.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_interfaces_vlan Data Source - terraform-provider-opnsense" 3 | subcategory: Interfaces 4 | description: |- 5 | VLANs (Virtual LANs) can be used to segment a single physical network into multiple virtual networks. 6 | --- 7 | 8 | # opnsense_interfaces_vlan (Data Source) 9 | 10 | VLANs (Virtual LANs) can be used to segment a single physical network into multiple virtual networks. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `description` (String) Optional description here for your reference (not parsed). 22 | - `device` (String) Custom VLAN name. Custom names are possible, but only if the start of the name matches the required prefix and contains numeric characters or dots, e.g. `vlan0.1.2` or `qinq0.3.4`. 23 | - `parent` (String) VLAN capable interface to attach the VLAN to, e.g. `vtnet0`. 24 | - `priority` (Number) 802.1Q VLAN PCP (priority code point). 25 | - `tag` (Number) 802.1Q VLAN tag. 26 | 27 | -------------------------------------------------------------------------------- /docs/data-sources/kea_peer.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_kea_peer Data Source - terraform-provider-opnsense" 3 | subcategory: Kea 4 | description: |- 5 | Configure HA Peers for Kea. 6 | --- 7 | 8 | # opnsense_kea_peer (Data Source) 9 | 10 | Configure HA Peers for Kea. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the peer. 18 | 19 | ### Read-Only 20 | 21 | - `name` (String) Peer name, there should be one entry matching this machine's "This server name". 22 | - `role` (String) Peer's role. 23 | - `url` (String) URL of the server instance. 24 | 25 | -------------------------------------------------------------------------------- /docs/data-sources/kea_reservation.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_kea_reservation Data Source - terraform-provider-opnsense" 3 | subcategory: Kea 4 | description: |- 5 | Configure DHCP reservations for Kea. 6 | --- 7 | 8 | # opnsense_kea_reservation (Data Source) 9 | 10 | Configure DHCP reservations for Kea. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the reservation. 18 | 19 | ### Read-Only 20 | 21 | - `description` (String) Optional description here for your reference (not parsed). 22 | - `hostname` (String) Hostname to offer to the client. 23 | - `ip_address` (String) IP address to offer to the client. 24 | - `mac_address` (String) MAC/Ether address of the client in question. 25 | - `subnet_id` (String) Subnet ID the reservation belongs to. 26 | 27 | -------------------------------------------------------------------------------- /docs/data-sources/kea_subnet.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_kea_subnet Data Source - terraform-provider-opnsense" 3 | subcategory: Kea 4 | description: |- 5 | Configure DHCP subnets for Kea. 6 | --- 7 | 8 | # opnsense_kea_subnet (Data Source) 9 | 10 | Configure DHCP subnets for Kea. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Optional 20 | 21 | - `domain_name` (String) Domain name to offer to the client, set to this firewall's domain name when left empty. 22 | 23 | ### Read-Only 24 | 25 | - `auto_collect` (Boolean) Automatically update option data from the GUI for relevant attributes. When set, values for `routers`, `dns_servers` and `ntp_servers` will be ignored. 26 | - `description` (String) Optional description here for your reference (not parsed). 27 | - `dns_servers` (Set of String) DNS servers to offer to the clients. 28 | - `domain_search` (Set of String) Set of Domain Names to be used by the client to locate not-fully-qualified domain names. 29 | - `next_server` (String) Next server IP address. 30 | - `ntp_servers` (Set of String) Set of IP addresses indicating NTP (RFC 5905) servers available to the client. 31 | - `pools` (Set of String) Set of pools in range or subnet format (e.g. `"192.168.0.100 - 192.168.0.200"` , `"192.0.2.64/26"`). 32 | - `routers` (Set of String) Default gateways to offer to the clients. 33 | - `static_routes` (Attributes Set) Static routes that the client should install in its routing cache. (see [below for nested schema](#nestedatt--static_routes)) 34 | - `subnet` (String) Subnet in use (e.g. `"192.0.2.64/26"`). 35 | - `tfpt_server` (String) TFTP server address or fqdn. 36 | - `tftp_bootfile` (String) Boot filename to request. 37 | - `time_servers` (Set of String) Set of RFC 868 time servers available to the client. 38 | 39 | 40 | ### Nested Schema for `static_routes` 41 | 42 | Read-Only: 43 | 44 | - `destination_ip` (String) Destination IP address for static route. 45 | - `router_ip` (String) Gateway IP for static route. 46 | 47 | -------------------------------------------------------------------------------- /docs/data-sources/quagga_bgp_aspath.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_aspath Data Source - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure AS Path lists for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_aspath (Data Source) 9 | 10 | Configure AS Path lists for BGP. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `action` (String) Set permit for match or deny to negate the rule. 22 | - `as` (String) The AS pattern you want to match, regexp allowed (e.g. `.$` or `_1$`). It's not validated so please be careful! 23 | - `description` (String) An optional description for this AS path. 24 | - `enabled` (Boolean) Enable this AS path. 25 | - `number` (Number) The ACL rule number (0-4294967294); keep in mind that there are no sequence numbers with AS-Path lists. When you want to add a new line between you have to completely remove the ACL! 26 | 27 | -------------------------------------------------------------------------------- /docs/data-sources/quagga_bgp_communitylist.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_communitylist Data Source - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure community lists for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_communitylist (Data Source) 9 | 10 | Configure community lists for BGP. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `action` (String) Set permit for match or deny to negate the rule. 22 | - `community` (String) The community you want to match. You can also regex and it is not validated so please be careful. 23 | - `description` (String) An optional description for this prefix list. 24 | - `enabled` (Boolean) Enable this community list. 25 | - `number` (Number) Set the number of your Community-List. 1-99 are standard lists while 100-500 are expanded lists. 26 | - `seq_number` (Number) The ACL sequence number (10-99). 27 | 28 | -------------------------------------------------------------------------------- /docs/data-sources/quagga_bgp_neighbor.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_neighbor Data Source - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure neighbors for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_neighbor (Data Source) 9 | 10 | Configure neighbors for BGP. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `as_override` (Boolean) Override AS number of the originating router with the local AS number. This command is only allowed for eBGP peers. 22 | - `attribute_unchanged` (String) Specify attribute to be left unchanged when sending advertisements to a peer. Read more at FRR documentation. 23 | - `bfd` (Boolean) Enable BFD support for this neighbor. 24 | - `connect_timer` (Number) The time in seconds how fast a neighbor tries to reconnect. 25 | - `default_route` (Boolean) Enable to send Defaultroute. 26 | - `description` (String) An optional description for this neighbor. 27 | - `disable_connected_check` (Boolean) Enable to allow peerings between directly connected eBGP peers using loopback addresses. 28 | - `enabled` (Boolean) Enable this neighbor. 29 | - `hold_down` (Number) The time in seconds when a neighbor is considered dead. This is usually 3 times the keepalive timer. 30 | - `keep_alive` (Number) Enable Keepalive timer to check if the neighbor is still up. 31 | - `link_local_interface` (String) Interface to use for IPv6 link-local neighbours. Must be a valid OPNsense interface in lowercase (e.g. `wan`). Please refer to the FRR documentation for more information. 32 | - `local_ip` (String) The local IP connecting to the neighbor. This is only required for BGP authentication. 33 | - `md5_password` (String) The password for BGP authentication. 34 | - `multi_hop` (Boolean) Enable multi-hop. Specifying ebgp-multihop allows sessions with eBGP neighbors to establish when they are multiple hops away. When the neighbor is not directly connected and this knob is not enabled, the session will not establish. 35 | - `multi_protocol` (Boolean) Mark this neighbor as multiprotocol capable per RFC 2283. 36 | - `next_hop_self` (Boolean) Enable the next-hop-self command. 37 | - `next_hop_self_all` (Boolean) Add the parameter "all" after next-hop-self command. 38 | - `peer_ip` (String) The IP of your neighbor. 39 | - `prefix_list_in` (String) The prefix list ID for inbound direction. 40 | - `prefix_list_out` (String) The prefix list ID for outbound direction. 41 | - `remote_as` (Number) The neighbor AS. 42 | - `route_map_in` (String) The route map ID for inbound direction. 43 | - `route_map_out` (String) The route map ID for outbound direction. 44 | - `rr_client` (Boolean) Enable route reflector client. 45 | - `update_source` (String) Physical name of the IPv4 interface facing the peer. Must be a valid OPNsense interface in lowercase (e.g. `wan`). Please refer to the FRR documentation for more information. 46 | - `weight` (Number) Specify a default weight value for the neighbor’s routes. 47 | 48 | -------------------------------------------------------------------------------- /docs/data-sources/quagga_bgp_prefixlist.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_prefixlist Data Source - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure prefix lists for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_prefixlist (Data Source) 9 | 10 | Configure prefix lists for BGP. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `action` (String) Set permit for match or deny to negate the rule. 22 | - `description` (String) An optional description for this prefix list. 23 | - `enabled` (Boolean) Enable this prefix list. 24 | - `ip_version` (String) Set the IP version to use. 25 | - `name` (String) The name of this prefix list. 26 | - `network` (String) The network pattern you want to match. You can also add "ge" or "le" additions after the network statement. It's not validated so please be careful! 27 | - `number` (Number) The ACL sequence number (1-4294967294). 28 | 29 | -------------------------------------------------------------------------------- /docs/data-sources/quagga_bgp_routemap.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_routemap Data Source - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure route maps for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_routemap (Data Source) 9 | 10 | Configure route maps for BGP. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `action` (String) Set permit for match or deny to negate the rule. 22 | - `aspaths` (Set of String) Set the AS Path list IDs to use. 23 | - `community_lists` (Set of String) Set the community list IDs to use. 24 | - `description` (String) An optional description for this route map. 25 | - `enabled` (Boolean) Enable this route map. 26 | - `name` (String) The name of this route map. 27 | - `prefix_lists` (Set of String) Set the prefix list IDs to use. 28 | - `route_map_id` (Number) The Route-map ID between 1 and 65535. Be aware that the sorting will be done under the hood, so when you add an entry between it gets to the right position. 29 | - `set` (String) Free text field for your set, please be careful! You can set e.g. `local-preference 300` or `community 1:1` (http://www.nongnu.org/quagga/docs/docs-multi/Route-Map-Set-Command.html#Route-Map-Set-Command). Defaults to `""`. 30 | 31 | -------------------------------------------------------------------------------- /docs/data-sources/route.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_route Data Source - terraform-provider-opnsense" 3 | subcategory: Routes 4 | description: |- 5 | Routes can be used to teach your firewall which path it should take when forwarding packets to a specific network. 6 | --- 7 | 8 | # opnsense_route (Data Source) 9 | 10 | Routes can be used to teach your firewall which path it should take when forwarding packets to a specific network. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `description` (String) Optional description here for your reference (not parsed). 22 | - `enabled` (Boolean) Whether this route is enabled. 23 | - `gateway` (String) Which gateway this route applies, e.g. `WAN`. 24 | - `network` (String) Destination network for this static route. 25 | 26 | -------------------------------------------------------------------------------- /docs/data-sources/unbound_domain_override.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_domain_override Data Source - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Domain overrides can be used to forward queries for specific domains (and subsequent subdomains) to local or remote DNS servers. 6 | --- 7 | 8 | # opnsense_unbound_domain_override (Data Source) 9 | 10 | Domain overrides can be used to forward queries for specific domains (and subsequent subdomains) to local or remote DNS servers. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `description` (String) Optional description here for your reference (not parsed). 22 | - `domain` (String) Domain to override (NOTE: this does not have to be a valid TLD!), e.g. `test` or `mycompany.localdomain` or `1.168.192.in-addr.arpa`. 23 | - `enabled` (Boolean) Whether this route is enabled. 24 | - `server` (String) IP address of the authoritative DNS server for this domain, e.g. `192.168.100.100`. 25 | 26 | -------------------------------------------------------------------------------- /docs/data-sources/unbound_forward.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_forward Data Source - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Query Forwarding section allows for entering arbitrary nameservers to forward queries to. Can forward queries normally, or over TLS. 6 | --- 7 | 8 | # opnsense_unbound_forward (Data Source) 9 | 10 | Query Forwarding section allows for entering arbitrary nameservers to forward queries to. Can forward queries normally, or over TLS. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `domain` (String) If a domain is entered here, queries for this specific domain will be forwarded to the specified server. 22 | - `enabled` (Boolean) Whether this route is enabled. 23 | - `server_ip` (String) IP address of DNS server to forward all requests. 24 | - `server_port` (Number) Port of DNS server, for usual DNS use `53`, if you use DoT set it to `853`. 25 | - `verify_cn` (String) The Common Name of the DNS server (e.g. `dns.example.com`). This field is required to verify its TLS certificate. DNS-over-TLS is susceptible to man-in-the-middle attacks unless certificates can be verified. 26 | 27 | -------------------------------------------------------------------------------- /docs/data-sources/unbound_host_alias.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_host_alias Data Source - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Host aliases can be used to create alternative names for a Host. 6 | --- 7 | 8 | # opnsense_unbound_host_alias (Data Source) 9 | 10 | Host aliases can be used to create alternative names for a Host. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `description` (String) Optional description here for your reference (not parsed). 22 | - `domain` (String) Domain of the host, e.g. example.com 23 | - `enabled` (Boolean) Whether this route is enabled. 24 | - `hostname` (String) Name of the host, without the domain part. 25 | - `override` (String) The associated host override to apply this alias on. 26 | 27 | -------------------------------------------------------------------------------- /docs/data-sources/unbound_host_override.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_host_override Data Source - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Host overrides can be used to change DNS results from client queries or to add custom DNS records. 6 | --- 7 | 8 | # opnsense_unbound_host_override (Data Source) 9 | 10 | Host overrides can be used to change DNS results from client queries or to add custom DNS records. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `description` (String) Optional description here for your reference (not parsed). 22 | - `domain` (String) Domain of the host, e.g. example.com 23 | - `enabled` (Boolean) Whether this route is enabled. 24 | - `hostname` (String) Name of the host, without the domain part. Use `*` to create a wildcard entry. 25 | - `mx_host` (String) Host name of MX host, e.g. mail.example.com. 26 | - `mx_priority` (Number) Priority of MX record, e.g. 10. 27 | - `server` (String) IP address of the host, e.g. 192.168.100.100 or fd00:abcd::1. 28 | - `type` (String) Type of resource record. Available values: `A`, `AAAA`, `MX`. 29 | 30 | -------------------------------------------------------------------------------- /docs/data-sources/wireguard_client.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_wireguard_client Data Source - terraform-provider-opnsense" 3 | subcategory: Wireguard 4 | description: |- 5 | Client resources can be used to setup Wireguard clients. 6 | --- 7 | 8 | # opnsense_wireguard_client (Data Source) 9 | 10 | Client resources can be used to setup Wireguard clients. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `enabled` (Boolean) Whether this client config is enabled. 22 | - `keep_alive` (Number) The persistent keepalive interval in seconds. 23 | - `name` (String) Name of the client config. 24 | - `psk` (String, Sensitive) Shared secret (PSK) for this peer. 25 | - `public_key` (String) Public key of this client config. 26 | - `server_address` (String) The public IP address the endpoint listens to. 27 | - `server_port` (Number) The port the endpoint listens to. 28 | - `tunnel_address` (Set of String) List of addresses allowed to pass trough the tunnel adapter. 29 | 30 | -------------------------------------------------------------------------------- /docs/data-sources/wireguard_server.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_wireguard_server Data Source - terraform-provider-opnsense" 3 | subcategory: Wireguard 4 | description: |- 5 | Server resources can be used to setup Wireguard servers. 6 | --- 7 | 8 | # opnsense_wireguard_server (Data Source) 9 | 10 | Server resources can be used to setup Wireguard servers. 11 | 12 | 13 | ## Schema 14 | 15 | ### Required 16 | 17 | - `id` (String) UUID of the resource. 18 | 19 | ### Read-Only 20 | 21 | - `disable_routes` (Boolean) Disables installation of routes. 22 | - `dns` (Set of String) The interface specific DNS servers. 23 | - `enabled` (Boolean) Whether this server is enabled. 24 | - `gateway` (String) The gateway IP here when using Disable Routes feature. 25 | - `instance` (String) The instance number to give the wg interface a unique name (wgX). 26 | - `mtu` (Number) The interface MTU for this interface. Set to `-1` to use the MTU from main interface. 27 | - `name` (String) Name of the server. 28 | - `peers` (Set of String) List of peer IDs for this server. 29 | - `port` (Number) The fixed port for this instance to listen on. The standard port range starts at 51820. 30 | - `private_key` (String, Sensitive) Private key of this server. 31 | - `public_key` (String) Public key of this server. 32 | - `tunnel_address` (Set of String) List of addresses to configure on the tunnel adapter. 33 | 34 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "" 3 | page_title: "Provider: OPNsense" 4 | description: |- 5 | The OPNsense provider provides resources to interact with an OPNsense host. 6 | --- 7 | 8 | # OPNsense Provider 9 | 10 | ~> Please note that this provider is under active development, and makes no 11 | guarantee to be stable. For that reason, it is not currently recommended 12 | to use this provider in any production environment. If a feature is missing, 13 | but is documented in the OPNsense API, please raise an issue on the Github repo 14 | to indicate interest. 15 | 16 | The OPNsense provider is used to interact with resources (only) supported by 17 | the OPNsense API. This provider does not, and will not, support resources 18 | not currently supported by the OPNsense API. If required, see if 19 | [dalet-oss/opnsense](https://github.com/dalet-oss/terraform-provider-opnsense) 20 | will support your needs. 21 | 22 | The provider needs to be configured with the proper API credentials before it can be used. 23 | 24 | ## Getting Started 25 | 26 | To generate the API key & secret, follow the 27 | [OPNsense docs](https://docs.opnsense.org/development/how-tos/api.html#creating-keys). 28 | These can then be used to configure the provider. 29 | 30 | ## Example Usage 31 | 32 | ```terraform 33 | terraform { 34 | required_providers { 35 | opnsense = { 36 | version = "~> x.0" 37 | source = "browningluke/opnsense" 38 | } 39 | } 40 | } 41 | 42 | provider "opnsense" { 43 | uri = "https://opnsense.example.com" 44 | api_key = "..." 45 | api_secret = "..." 46 | } 47 | ``` 48 | 49 | 50 | ## Schema 51 | 52 | ### Required 53 | 54 | - `api_key` (String) The API key for a user. Alternatively, can be configured using the `OPNSENSE_API_KEY` environment variable. 55 | - `api_secret` (String) The API secret for a user. Alternatively, can be configured using the `OPNSENSE_API_SECRET` environment variable. 56 | - `uri` (String) The URI to an OPNsense host. Alternatively, can be configured using the `OPNSENSE_URI` environment variable. 57 | 58 | ### Optional 59 | 60 | - `allow_insecure` (Boolean) Allow insecure TLS connections. Alternatively, can be configured using the `OPNSENSE_ALLOW_INSECURE` environment variable. Defaults to `false`. 61 | - `max_backoff` (Number) Maximum backoff period in seconds after failed API calls. Alternatively, can be configured using the `OPNSENSE_MAX_BACKOFF` environment variable. 62 | - `min_backoff` (Number) Minimum backoff period in seconds after failed API calls. Alternatively, can be configured using the `OPNSENSE_MIN_BACKOFF` environment variable. 63 | - `retries` (Number) Maximum number of retries to perform when an API request fails. Alternatively, can be configured using the `OPNSENSE_RETRIES` environment variable. -------------------------------------------------------------------------------- /docs/resources/firewall_alias.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_firewall_alias Resource - terraform-provider-opnsense" 3 | subcategory: Firewall 4 | description: |- 5 | Aliases are named lists of networks, hosts or ports that can be used as one entity by selecting the alias name in the various supported sections of the firewall. These aliases are particularly useful to condense firewall rules and minimize changes. 6 | --- 7 | 8 | # opnsense_firewall_alias (Resource) 9 | 10 | Aliases are named lists of networks, hosts or ports that can be used as one entity by selecting the alias name in the various supported sections of the firewall. These aliases are particularly useful to condense firewall rules and minimize changes. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Network example 16 | resource "opnsense_firewall_alias" "example_one" { 17 | name = "example_one" 18 | 19 | type = "network" 20 | content = [ 21 | "10.8.0.1/24", 22 | "10.8.0.2/24" 23 | ] 24 | 25 | stats = true 26 | description = "Example" 27 | } 28 | 29 | // With category 30 | resource "opnsense_firewall_category" "example_one" { 31 | name = "example" 32 | color = "ffaa00" 33 | } 34 | 35 | resource "opnsense_firewall_alias" "example_two" { 36 | name = "example_two" 37 | 38 | type = "geoip" 39 | content = [ 40 | "FR", 41 | "CA", 42 | ] 43 | 44 | categories = [ 45 | opnsense_firewall_category.example_one.id 46 | ] 47 | 48 | description = "Example two" 49 | } 50 | ``` 51 | 52 | 53 | ## Schema 54 | 55 | ### Required 56 | 57 | - `name` (String) The name must start with a letter or single underscore, be less than 32 characters and only consist of alphanumeric characters or underscores. Aliases can be nested using this name. 58 | - `type` (String) The type of alias. 59 | 60 | ### Optional 61 | 62 | - `categories` (Set of String) Set of category IDs to apply. Defaults to `[]`. 63 | - `content` (Set of String) The content of the alias. Enter ISO 3166-1 country codes when `type = "geoip"` (e.g. `["CA", "FR"]`). Enter `___network`, or alias when `type = "networkgroup"` (e.g. `["__wan_network", "otheralias"]`). Enter OpenVPN group when `type = "authgroup"` (e.g. `["admins"]`). Set to `[]` when `type = "external"`. Defaults to `[]`. 64 | - `description` (String) Optional description here for your reference (not parsed). 65 | - `enabled` (Boolean) Enable this firewall alias. Defaults to `true`. 66 | - `interface` (String) Choose on which interface this alias applies. Only applies (and must be set) when `type = "dynipv6host"`. Defaults to `""`. 67 | - `ip_protocol` (String) Select the Internet Protocol version this alias applies to. Available values: `IPv4`, `IPv6`. Only applies when `type = "asn"`, `type = "geoip"`, or `type = "external"`. Defaults to `IPv4`. 68 | - `stats` (Boolean) Whether to maintain a set of counters for each table entry. 69 | - `update_freq` (Number) The frequency that the list will be refreshed, in days (e.g. for 30 hours, enter `1.25`). Only applies (and must be set) when `type = "urltable"`. Defaults to `-1`. 70 | 71 | ### Read-Only 72 | 73 | - `id` (String) UUID of the resource. 74 | 75 | ## Import 76 | 77 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_firewall_alias using the `id`. For example: 78 | 79 | ```terraform 80 | import { 81 | to = opnsense_firewall_alias.example 82 | id = "" 83 | } 84 | ``` 85 | 86 | Using `terraform import`, import opnsense_firewall_alias using the `id`. For example: 87 | 88 | ```console 89 | % terraform import opnsense_firewall_alias.example 90 | ``` -------------------------------------------------------------------------------- /docs/resources/firewall_category.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_firewall_category Resource - terraform-provider-opnsense" 3 | subcategory: Firewall 4 | description: |- 5 | To ease maintenance of larger rulesets, OPNsense includes categories for the firewall. Each rule can contain one or more categories. 6 | --- 7 | 8 | # opnsense_firewall_category (Resource) 9 | 10 | To ease maintenance of larger rulesets, OPNsense includes categories for the firewall. Each rule can contain one or more categories. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | resource "opnsense_firewall_category" "example_one" { 16 | name = "example" 17 | color = "ffaa00" 18 | } 19 | 20 | resource "opnsense_firewall_alias" "example_one" { 21 | name = "example" 22 | 23 | type = "geoip" 24 | content = [ 25 | "FR", 26 | "CA", 27 | ] 28 | 29 | categories = [ 30 | opnsense_firewall_category.example_one.id 31 | ] 32 | 33 | stats = true 34 | description = "Example" 35 | } 36 | ``` 37 | 38 | 39 | ## Schema 40 | 41 | ### Required 42 | 43 | - `name` (String) Enter a name for this category. 44 | 45 | ### Optional 46 | 47 | - `auto` (Boolean) If set, this category will be removed when unused. This is included for completeness, but will result in constant recreations if not attached to any rules, and thus it is advised to leave it as default. Defaults to `false`. 48 | - `color` (String) Pick a color to use. Must be a hex color in format `rrggbb` (e.g. `ff0000`). Defaults to `""`. 49 | 50 | ### Read-Only 51 | 52 | - `id` (String) UUID of the resource. 53 | 54 | ## Import 55 | 56 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_firewall_category using the `id`. For example: 57 | 58 | ```terraform 59 | import { 60 | to = opnsense_firewall_category.example 61 | id = "" 62 | } 63 | ``` 64 | 65 | Using `terraform import`, import opnsense_firewall_category using the `id`. For example: 66 | 67 | ```console 68 | % terraform import opnsense_firewall_category.example 69 | ``` -------------------------------------------------------------------------------- /docs/resources/interfaces_vlan.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_interfaces_vlan Resource - terraform-provider-opnsense" 3 | subcategory: Interfaces 4 | description: |- 5 | VLANs (Virtual LANs) can be used to segment a single physical network into multiple virtual networks. 6 | --- 7 | 8 | # opnsense_interfaces_vlan (Resource) 9 | 10 | VLANs (Virtual LANs) can be used to segment a single physical network into multiple virtual networks. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // OPNsense generates a device name 16 | resource "opnsense_interfaces_vlan" "vlan" { 17 | description = "Example vlan" 18 | tag = 10 19 | priority = 0 20 | parent = "vtnet0" 21 | } 22 | 23 | // Manually configure a device name 24 | resource "opnsense_interfaces_vlan" "vlan04" { 25 | description = "Example vlan 4" 26 | tag = 50 27 | priority = 5 28 | parent = "vtnet0" 29 | device = "vlan04" 30 | } 31 | ``` 32 | 33 | 34 | ## Schema 35 | 36 | ### Required 37 | 38 | - `parent` (String) VLAN capable interface to attach the VLAN to, e.g. `vtnet0`. 39 | - `tag` (Number) 802.1Q VLAN tag. 40 | 41 | ### Optional 42 | 43 | - `description` (String) Optional description here for your reference (not parsed). 44 | - `device` (String) Custom VLAN name. Custom names are possible, but only if the start of the name matches the required prefix and contains numeric characters or dots, e.g. `vlan0.1.2` or `qinq0.3.4`. Set to `""` to generate a device name. Defaults to `""` 45 | - `priority` (Number) 802.1Q VLAN PCP (priority code point). Defaults to `0`. 46 | 47 | ### Read-Only 48 | 49 | - `id` (String) UUID of the VLAN. 50 | 51 | ## Import 52 | 53 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_interfaces_vlan using the `id`. For example: 54 | 55 | ```terraform 56 | import { 57 | to = opnsense_interfaces_vlan.example 58 | id = "" 59 | } 60 | ``` 61 | 62 | Using `terraform import`, import opnsense_interfaces_vlan using the `id`. For example: 63 | 64 | ```console 65 | % terraform import opnsense_interfaces_vlan.example 66 | ``` -------------------------------------------------------------------------------- /docs/resources/kea_peer.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_kea_peer Resource - terraform-provider-opnsense" 3 | subcategory: Kea 4 | description: |- 5 | Configure HA Peers for Kea. 6 | --- 7 | 8 | # opnsense_kea_peer (Resource) 9 | 10 | Configure HA Peers for Kea. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Small example 16 | resource "opnsense_kea_peer" "example" { 17 | name = "example" 18 | role = "primary" 19 | url = "http://192.0.2.1:8001/" 20 | } 21 | ``` 22 | 23 | 24 | ## Schema 25 | 26 | ### Required 27 | 28 | - `name` (String) Peer name, there should be one entry matching this machine's "This server name". 29 | - `url` (String) URL of the server instance, which should use a different port than the control agent (e.g. `http://192.0.2.1:8001/`). 30 | 31 | ### Optional 32 | 33 | - `role` (String) Peer's role. Defaults to `"primary"`. 34 | 35 | ### Read-Only 36 | 37 | - `id` (String) UUID of the peer. 38 | 39 | ## Import 40 | 41 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_kea_peer using the `id`. For example: 42 | 43 | ```terraform 44 | import { 45 | to = opnsense_kea_peer.example 46 | id = "" 47 | } 48 | ``` 49 | 50 | Using `terraform import`, import opnsense_kea_peer using the `id`. For example: 51 | 52 | ```console 53 | % terraform import opnsense_kea_peer.example 54 | ``` -------------------------------------------------------------------------------- /docs/resources/kea_reservation.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_kea_reservation Resource - terraform-provider-opnsense" 3 | subcategory: Kea 4 | description: |- 5 | Configure DHCP reservations for Kea. 6 | --- 7 | 8 | # opnsense_kea_reservation (Resource) 9 | 10 | Configure DHCP reservations for Kea. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Small example 16 | resource "opnsense_kea_reservation" "test" { 17 | subnet_id = resource.opnsense_kea_subnet.lan.id 18 | 19 | ip_address = "10.8.2.102" 20 | mac_address = "00:25:96:12:34:55" 21 | 22 | description = "example host" 23 | } 24 | 25 | // LAN subnet example 26 | resource "opnsense_kea_subnet" "lan" { 27 | subnet = "10.8.0.0/16" 28 | description = "LAN" 29 | } 30 | ``` 31 | 32 | 33 | ## Schema 34 | 35 | ### Required 36 | 37 | - `ip_address` (String) IP address to offer to the client. 38 | - `mac_address` (String) MAC/Ether address of the client in question. 39 | - `subnet_id` (String) Subnet ID the reservation belongs to. 40 | 41 | ### Optional 42 | 43 | - `description` (String) Optional description here for your reference (not parsed). 44 | - `hostname` (String) Hostname to offer to the client. Defaults to `""`.. 45 | 46 | ### Read-Only 47 | 48 | - `id` (String) UUID of the reservation. 49 | 50 | ## Import 51 | 52 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_kea_reservation using the `id`. For example: 53 | 54 | ```terraform 55 | import { 56 | to = opnsense_kea_reservation.example 57 | id = "" 58 | } 59 | ``` 60 | 61 | Using `terraform import`, import opnsense_kea_reservation using the `id`. For example: 62 | 63 | ```console 64 | % terraform import opnsense_kea_reservation.example 65 | ``` -------------------------------------------------------------------------------- /docs/resources/quagga_bgp_aspath.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_aspath Resource - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure AS Path lists for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_aspath (Resource) 9 | 10 | Configure AS Path lists for BGP. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Configure an AS Path 16 | resource "opnsense_quagga_bgp_aspath" "example0" { 17 | enabled = false 18 | description = "aspath0" 19 | 20 | number = 123 21 | action = "permit" 22 | 23 | as = "_2$" 24 | } 25 | ``` 26 | 27 | 28 | ## Schema 29 | 30 | ### Required 31 | 32 | - `as` (String) The AS pattern you want to match, regexp allowed (e.g. `.$` or `_1$`). It's not validated so please be careful! 33 | - `number` (Number) The ACL rule number (0-4294967294); keep in mind that there are no sequence numbers with AS-Path lists. When you want to add a new line between you have to completely remove the ACL! 34 | 35 | ### Optional 36 | 37 | - `action` (String) Set permit for match or deny to negate the rule. Defaults to `"permit"`. 38 | - `description` (String) An optional description for this AS path. Defaults to `""`. 39 | - `enabled` (Boolean) Enable this AS path. Defaults to `true`. 40 | 41 | ### Read-Only 42 | 43 | - `id` (String) UUID of the AS path. 44 | 45 | ## Import 46 | 47 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_quagga_bgp_aspath using the `id`. For example: 48 | 49 | ```terraform 50 | import { 51 | to = opnsense_quagga_bgp_aspath.example 52 | id = "" 53 | } 54 | ``` 55 | 56 | Using `terraform import`, import opnsense_quagga_bgp_aspath using the `id`. For example: 57 | 58 | ```console 59 | % terraform import opnsense_quagga_bgp_aspath.example 60 | ``` -------------------------------------------------------------------------------- /docs/resources/quagga_bgp_communitylist.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_communitylist Resource - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure community lists for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_communitylist (Resource) 9 | 10 | Configure community lists for BGP. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Configure a community list 16 | resource "opnsense_quagga_bgp_communitylist" "example0" { 17 | enabled = false 18 | description = "communitylist0" 19 | 20 | number = 100 21 | seq_number = 99 22 | action = "deny" 23 | 24 | community = "example.*" 25 | } 26 | ``` 27 | 28 | 29 | ## Schema 30 | 31 | ### Required 32 | 33 | - `community` (String) The community you want to match. You can also regex and it is not validated so please be careful. 34 | - `number` (Number) Set the number of your Community-List. 1-99 are standard lists while 100-500 are expanded lists. 35 | - `seq_number` (Number) The ACL sequence number (10-99). 36 | 37 | ### Optional 38 | 39 | - `action` (String) Set permit for match or deny to negate the rule. Defaults to `"permit"`. 40 | - `description` (String) An optional description for this prefix list. Defaults to `""`. 41 | - `enabled` (Boolean) Enable this community list. Defaults to `true`. 42 | 43 | ### Read-Only 44 | 45 | - `id` (String) UUID of the community list. 46 | 47 | ## Import 48 | 49 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_quagga_bgp_communitylist using the `id`. For example: 50 | 51 | ```terraform 52 | import { 53 | to = opnsense_quagga_bgp_communitylist.example 54 | id = "" 55 | } 56 | ``` 57 | 58 | Using `terraform import`, import opnsense_quagga_bgp_communitylist using the `id`. For example: 59 | 60 | ```console 61 | % terraform import opnsense_quagga_bgp_communitylist.example 62 | ``` -------------------------------------------------------------------------------- /docs/resources/quagga_bgp_prefixlist.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_prefixlist Resource - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure prefix lists for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_prefixlist (Resource) 9 | 10 | Configure prefix lists for BGP. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Configure a prefix list 16 | resource "opnsense_quagga_bgp_prefixlist" "example0" { 17 | enabled = false 18 | 19 | description = "prefixlist0" 20 | name = "example0" 21 | 22 | number = 1234 23 | action = "permit" 24 | 25 | network = "10.10.0.0" 26 | } 27 | ``` 28 | 29 | 30 | ## Schema 31 | 32 | ### Required 33 | 34 | - `name` (String) The name of this prefix list. 35 | - `network` (String) The network pattern you want to match. You can also add "ge" or "le" additions after the network statement. It's not validated so please be careful! 36 | - `number` (Number) The ACL sequence number (1-4294967294). 37 | 38 | ### Optional 39 | 40 | - `action` (String) Set permit for match or deny to negate the rule. Defaults to `"permit"`. 41 | - `description` (String) An optional description for this prefix list. Defaults to `""`. 42 | - `enabled` (Boolean) Enable this prefix list. Defaults to `true`. 43 | - `ip_version` (String) Set the IP version to use. Defaults to `"IPv4"`. 44 | 45 | ### Read-Only 46 | 47 | - `id` (String) UUID of the prefix list. 48 | 49 | ## Import 50 | 51 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_quagga_bgp_prefixlist using the `id`. For example: 52 | 53 | ```terraform 54 | import { 55 | to = opnsense_quagga_bgp_prefixlist.example 56 | id = "" 57 | } 58 | ``` 59 | 60 | Using `terraform import`, import opnsense_quagga_bgp_prefixlist using the `id`. For example: 61 | 62 | ```console 63 | % terraform import opnsense_quagga_bgp_prefixlist.example 64 | ``` -------------------------------------------------------------------------------- /docs/resources/quagga_bgp_routemap.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_quagga_bgp_routemap Resource - terraform-provider-opnsense" 3 | subcategory: Quagga 4 | description: |- 5 | Configure route maps for BGP. 6 | --- 7 | 8 | # opnsense_quagga_bgp_routemap (Resource) 9 | 10 | Configure route maps for BGP. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Configure an AS Path 16 | resource "opnsense_quagga_bgp_aspath" "example0" { 17 | enabled = false 18 | description = "aspath0" 19 | 20 | number = 123 21 | action = "permit" 22 | 23 | as = "_2$" 24 | } 25 | 26 | // Configure a prefix list 27 | resource "opnsense_quagga_bgp_prefixlist" "example0" { 28 | enabled = false 29 | 30 | description = "prefixlist0" 31 | name = "example0" 32 | 33 | number = 1234 34 | action = "permit" 35 | 36 | network = "10.10.0.0" 37 | } 38 | // Configure a community list 39 | resource "opnsense_quagga_bgp_communitylist" "example0" { 40 | enabled = false 41 | description = "communitylist0" 42 | 43 | number = 100 44 | seq_number = 99 45 | action = "deny" 46 | 47 | community = "example.*" 48 | } 49 | 50 | // Configure a route map 51 | resource "opnsense_quagga_bgp_routemap" "example0" { 52 | enabled = false 53 | description = "routemap0" 54 | 55 | name = "example0" 56 | action = "deny" 57 | 58 | route_map_id = 100 59 | 60 | aspaths = [ 61 | opnsense_quagga_bgp_aspath.example0.id 62 | ] 63 | 64 | prefix_lists = [ 65 | opnsense_quagga_bgp_prefixlist.example0.id 66 | ] 67 | 68 | community_lists = [ 69 | opnsense_quagga_bgp_communitylist.example0.id 70 | ] 71 | 72 | set = "local-preference 300" 73 | } 74 | ``` 75 | 76 | 77 | ## Schema 78 | 79 | ### Required 80 | 81 | - `name` (String) The name of this route map. 82 | - `route_map_id` (Number) The Route-map ID between 1 and 65535. Be aware that the sorting will be done under the hood, so when you add an entry between it gets to the right position. 83 | 84 | ### Optional 85 | 86 | - `action` (String) Set permit for match or deny to negate the rule. Defaults to `"permit"`. 87 | - `aspaths` (Set of String) Set the AS Path list IDs to use. Defaults to `[]`. 88 | - `community_lists` (Set of String) Set the community list IDs to use. Defaults to `[]`. 89 | - `description` (String) An optional description for this route map. Defaults to `""`. 90 | - `enabled` (Boolean) Enable this route map. Defaults to `true`. 91 | - `prefix_lists` (Set of String) Set the prefix list IDs to use. Defaults to `[]`. 92 | - `set` (String) Free text field for your set, please be careful! You can set e.g. `local-preference 300` or `community 1:1` (http://www.nongnu.org/quagga/docs/docs-multi/Route-Map-Set-Command.html#Route-Map-Set-Command). Defaults to `""`. 93 | 94 | ### Read-Only 95 | 96 | - `id` (String) UUID of the route map. 97 | 98 | ## Import 99 | 100 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_quagga_bgp_routemap using the `id`. For example: 101 | 102 | ```terraform 103 | import { 104 | to = opnsense_quagga_bgp_routemap.example 105 | id = "" 106 | } 107 | ``` 108 | 109 | Using `terraform import`, import opnsense_quagga_bgp_routemap using the `id`. For example: 110 | 111 | ```console 112 | % terraform import opnsense_quagga_bgp_routemap.example 113 | ``` -------------------------------------------------------------------------------- /docs/resources/route.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_route Resource - terraform-provider-opnsense" 3 | subcategory: Routes 4 | description: |- 5 | Routes can be used to teach your firewall which path it should take when forwarding packets to a specific network. 6 | --- 7 | 8 | # opnsense_route (Resource) 9 | 10 | Routes can be used to teach your firewall which path it should take when forwarding packets to a specific network. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Enabled with description 16 | resource "opnsense_route" "one_route" { 17 | description = "Example route" 18 | gateway = "LAN_DHCP" 19 | network = "10.9.0.0/24" 20 | } 21 | 22 | // Disabled without description 23 | resource "opnsense_route" "two_route" { 24 | enabled = false 25 | 26 | gateway = "LAN" 27 | network = "10.10.0.0/24" 28 | } 29 | ``` 30 | 31 | 32 | ## Schema 33 | 34 | ### Required 35 | 36 | - `gateway` (String) Which gateway this route applies, e.g. `WAN`. Must be an existing gateway. 37 | - `network` (String) Destination network for this static route. 38 | 39 | ### Optional 40 | 41 | - `description` (String) Optional description here for your reference (not parsed). 42 | - `enabled` (Boolean) Enable this route. Defaults to `true`. 43 | 44 | ### Read-Only 45 | 46 | - `id` (String) UUID of the route. 47 | 48 | ## Import 49 | 50 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_route using the `id`. For example: 51 | 52 | ```terraform 53 | import { 54 | to = opnsense_route.example 55 | id = "" 56 | } 57 | ``` 58 | 59 | Using `terraform import`, import opnsense_route using the `id`. For example: 60 | 61 | ```console 62 | % terraform import opnsense_route.example 63 | ``` -------------------------------------------------------------------------------- /docs/resources/unbound_domain_override.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_domain_override Resource - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Domain overrides can be used to forward queries for specific domains (and subsequent subdomains) to local or remote DNS servers. 6 | --- 7 | 8 | # opnsense_unbound_domain_override (Resource) 9 | 10 | Domain overrides can be used to forward queries for specific domains (and subsequent subdomains) to local or remote DNS servers. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Enabled with description 16 | resource "opnsense_unbound_domain_override" "one_override" { 17 | enabled = true 18 | description = "Example override" 19 | 20 | domain = "example.lan" 21 | server = "192.168.1.1" 22 | } 23 | 24 | // Disabled without description 25 | resource "opnsense_unbound_domain_override" "two_override" { 26 | enabled = false 27 | 28 | domain = "example.arpa" 29 | server = "192.168.1.100" 30 | } 31 | ``` 32 | 33 | 34 | ## Schema 35 | 36 | ### Required 37 | 38 | - `domain` (String) Domain to override (NOTE: this does not have to be a valid TLD!), e.g. `test` or `mycompany.localdomain` or `1.168.192.in-addr.arpa`. 39 | - `server` (String) IP address of the authoritative DNS server for this domain, e.g. `192.168.100.100`. To use a nondefault port for communication, append an `@` with the port number. 40 | 41 | ### Optional 42 | 43 | - `description` (String) Optional description here for your reference (not parsed). 44 | - `enabled` (Boolean) Enable this domain override. Defaults to `true`. 45 | 46 | ### Read-Only 47 | 48 | - `id` (String) UUID of the host override. 49 | 50 | ## Import 51 | 52 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_unbound_domain_override using the `id`. For example: 53 | 54 | ```terraform 55 | import { 56 | to = opnsense_unbound_domain_override.example 57 | id = "" 58 | } 59 | ``` 60 | 61 | Using `terraform import`, import opnsense_unbound_domain_override using the `id`. For example: 62 | 63 | ```console 64 | % terraform import opnsense_unbound_domain_override.example 65 | ``` -------------------------------------------------------------------------------- /docs/resources/unbound_forward.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_forward Resource - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Query Forwarding section allows for entering arbitrary nameservers to forward queries to. Can forward queries normally, or over TLS. 6 | --- 7 | 8 | # opnsense_unbound_forward (Resource) 9 | 10 | Query Forwarding section allows for entering arbitrary nameservers to forward queries to. Can forward queries normally, or over TLS. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Query Forward 16 | resource "opnsense_unbound_forward" "query" { 17 | domain = "example.lan" 18 | server_ip = "192.168.1.2" 19 | server_port = 853 20 | } 21 | 22 | // DoT forward 23 | resource "opnsense_unbound_forward" "dot" { 24 | enabled = false 25 | type = "dot" 26 | 27 | domain = "example.dev" 28 | server_ip = "192.168.1.1" 29 | server_port = 53 30 | verify_cn = "example.dev" 31 | } 32 | ``` 33 | 34 | 35 | ## Schema 36 | 37 | ### Required 38 | 39 | - `domain` (String) If a domain is entered here, queries for this specific domain will be forwarded to the specified server. Set to `""` to forward all queries to the specified server. 40 | - `server_ip` (String) IP address of DNS server to forward all requests. 41 | 42 | ### Optional 43 | 44 | - `enabled` (Boolean) Enable this query forward. Defaults to `true`. 45 | - `server_port` (Number) Port of DNS server, for usual DNS use `53`, if you use DoT set it to `853`. Defaults to `53`. 46 | - `verify_cn` (String) The Common Name of the DNS server (e.g. `dns.example.com`). This field is required to verify its TLS certificate. DNS-over-TLS is susceptible to man-in-the-middle attacks unless certificates can be verified. Set to `""` to accept self-signed yet also potentially fraudulent certificates. Must be set when `type` is `dot`. 47 | 48 | ### Read-Only 49 | 50 | - `id` (String) UUID of the forward. 51 | 52 | ## Import 53 | 54 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_unbound_forward using the `id`. For example: 55 | 56 | ```terraform 57 | import { 58 | to = opnsense_unbound_forward.example 59 | id = "" 60 | } 61 | ``` 62 | 63 | Using `terraform import`, import opnsense_unbound_forward using the `id`. For example: 64 | 65 | ```console 66 | % terraform import opnsense_unbound_forward.example 67 | ``` -------------------------------------------------------------------------------- /docs/resources/unbound_host_alias.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_host_alias Resource - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Host aliases can be used to create alternative names for a Host 6 | --- 7 | 8 | # opnsense_unbound_host_alias (Resource) 9 | 10 | Host aliases can be used to create alternative names for a Host 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // 'A' record 16 | resource "opnsense_unbound_host_override" "a_override" { 17 | enabled = true 18 | description = "A record override" 19 | 20 | hostname = "*" 21 | domain = "example.com" 22 | server = "192.168.1.1" 23 | } 24 | 25 | // Enabled alias with description 26 | resource "opnsense_unbound_host_alias" "one_alias" { 27 | override = opnsense_unbound_host_override.a_override.id 28 | 29 | enabled = true 30 | hostname = "*" 31 | domain = "1.example.com" 32 | description = "Example 1" 33 | } 34 | 35 | // Disabled alias without description 36 | resource "opnsense_unbound_host_alias" "two_alias" { 37 | override = opnsense_unbound_host_override.a_override.id 38 | 39 | enabled = false 40 | hostname = "*" 41 | domain = "2.example.com" 42 | } 43 | ``` 44 | 45 | 46 | ## Schema 47 | 48 | ### Required 49 | 50 | - `domain` (String) Domain of the host, e.g. example.com. 51 | - `hostname` (String) Name of the host, without the domain part. Use `*` to create a wildcard entry. 52 | - `override` (String) The associated host override to apply this alias on. 53 | 54 | ### Optional 55 | 56 | - `description` (String) Optional description here for your reference (not parsed). 57 | - `enabled` (Boolean) Enable this alias for the selected host. Defaults to `true`. 58 | 59 | ### Read-Only 60 | 61 | - `id` (String) UUID of the host alias. 62 | 63 | ## Import 64 | 65 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_unbound_host_alias using the `id`. For example: 66 | 67 | ```terraform 68 | import { 69 | to = opnsense_unbound_host_alias.example 70 | id = "" 71 | } 72 | ``` 73 | 74 | Using `terraform import`, import opnsense_unbound_host_alias using the `id`. For example: 75 | 76 | ```console 77 | % terraform import opnsense_unbound_host_alias.example 78 | ``` -------------------------------------------------------------------------------- /docs/resources/unbound_host_override.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_unbound_host_override Resource - terraform-provider-opnsense" 3 | subcategory: Unbound 4 | description: |- 5 | Host overrides can be used to change DNS results from client queries or to add custom DNS records. 6 | --- 7 | 8 | # opnsense_unbound_host_override (Resource) 9 | 10 | Host overrides can be used to change DNS results from client queries or to add custom DNS records. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // 'A' record 16 | resource "opnsense_unbound_host_override" "a_override" { 17 | enabled = true 18 | description = "A record override" 19 | 20 | hostname = "*" 21 | domain = "example.com" 22 | server = "192.168.1.1" 23 | } 24 | 25 | // 'AAAA' record 26 | resource "opnsense_unbound_host_override" "aaaa_override" { 27 | enabled = true 28 | 29 | type = "AAAA" 30 | hostname = "*" 31 | domain = "example.com" 32 | server = "fd00:abcd::1" 33 | } 34 | 35 | // 'MX' record 36 | resource "opnsense_unbound_host_override" "mx_override" { 37 | enabled = false 38 | description = "MX record override" 39 | 40 | type = "MX" 41 | hostname = "*" 42 | domain = "example.com" 43 | 44 | mx_priority = 10 45 | mx_host = "mail.example.dev" 46 | } 47 | ``` 48 | 49 | 50 | ## Schema 51 | 52 | ### Required 53 | 54 | - `domain` (String) Domain of the host, e.g. example.com 55 | - `hostname` (String) Name of the host, without the domain part. Use `*` to create a wildcard entry. 56 | 57 | ### Optional 58 | 59 | - `description` (String) Optional description here for your reference (not parsed). 60 | - `enabled` (Boolean) Enable the override for this host. Defaults to `true`. 61 | - `mx_host` (String) Host name of MX host, e.g. mail.example.com. Must be set when `type` is `MX`. 62 | - `mx_priority` (Number) Priority of MX record, e.g. 10. Must be set when `type` is `MX`. 63 | - `server` (String) IP address of the host, e.g. 192.168.100.100 or fd00:abcd::1. Must be set when `type` is `A` or `AAAA`. 64 | - `type` (String) Type of resource record. Available values: `A`, `AAAA`, `MX`. Defaults to `A`. 65 | 66 | ### Read-Only 67 | 68 | - `id` (String) UUID of the host override. 69 | 70 | ## Import 71 | 72 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_unbound_host_override using the `id`. For example: 73 | 74 | ```terraform 75 | import { 76 | to = opnsense_unbound_host_override.example 77 | id = "" 78 | } 79 | ``` 80 | 81 | Using `terraform import`, import opnsense_unbound_host_override using the `id`. For example: 82 | 83 | ```console 84 | % terraform import opnsense_unbound_host_override.example 85 | ``` -------------------------------------------------------------------------------- /docs/resources/wireguard_client.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_wireguard_client Resource - terraform-provider-opnsense" 3 | subcategory: Wireguard 4 | description: |- 5 | Client resources can be used to setup Wireguard clients. 6 | --- 7 | 8 | # opnsense_wireguard_client (Resource) 9 | 10 | Client resources can be used to setup Wireguard clients. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Configure a peer 16 | resource "opnsense_wireguard_client" "example0" { 17 | enabled = false 18 | name = "example0" 19 | 20 | public_key = "/CPjuEdvHJulOIQ56TNyeNHkDJmRCMor4U9k68vMyac=" 21 | psk = "CJG05xgaLA8RiisoCAmp2U0v329LsIdK1GW4EMc9fmU=" 22 | 23 | tunnel_address = [ 24 | "192.168.1.1/32", 25 | "192.168.4.1/24", 26 | ] 27 | 28 | server_address = "10.10.10.10" 29 | server_port = "1234" 30 | } 31 | ``` 32 | 33 | 34 | ## Schema 35 | 36 | ### Required 37 | 38 | - `name` (String) Name of the client config. 39 | - `public_key` (String) Public key of this client config. Must be a 256-bit base64 string. 40 | - `tunnel_address` (Set of String) List of addresses allowed to pass trough the tunnel adapter. Please use CIDR notation like `"10.0.0.1/24"`. Defaults to `[]`. 41 | 42 | ### Optional 43 | 44 | - `enabled` (Boolean) Enable this client config. Defaults to `true`. 45 | - `keep_alive` (Number) The persistent keepalive interval in seconds. Defaults to `-1`. 46 | - `psk` (String, Sensitive) Shared secret (PSK) for this peer. You can generate a key using `wg genpsk` on a client with WireGuard installed. Must be a 256-bit base64 string. Defaults to `""`. 47 | - `server_address` (String) The public IP address the endpoint listens to. Defaults to `""`. 48 | - `server_port` (Number) The port the endpoint listens to. Defaults to `-1`. 49 | 50 | ### Read-Only 51 | 52 | - `id` (String) UUID of the client. 53 | 54 | ## Import 55 | 56 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_wireguard_client using the `id`. For example: 57 | 58 | ```terraform 59 | import { 60 | to = opnsense_wireguard_client.example 61 | id = "" 62 | } 63 | ``` 64 | 65 | Using `terraform import`, import opnsense_wireguard_client using the `id`. For example: 66 | 67 | ```console 68 | % terraform import opnsense_wireguard_client.example 69 | ``` -------------------------------------------------------------------------------- /docs/resources/wireguard_server.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "opnsense_wireguard_server Resource - terraform-provider-opnsense" 3 | subcategory: Wireguard 4 | description: |- 5 | Server resources can be used to setup Wireguard servers. 6 | --- 7 | 8 | # opnsense_wireguard_server (Resource) 9 | 10 | Server resources can be used to setup Wireguard servers. 11 | 12 | ## Example Usage 13 | 14 | ```terraform 15 | // Generate an wireguard_asymmetric_key 16 | // This uses the OJFord/wireguard provider 17 | resource "wireguard_asymmetric_key" "example0" { 18 | } 19 | 20 | // Configure a peer 21 | resource "opnsense_wireguard_client" "example0" { 22 | enabled = false 23 | name = "example0" 24 | 25 | public_key = "/CPjuEdvHJulOIQ56TNyeNHkDJmRCMor4U9k68vMyac=" 26 | psk = "CJG05xgaLA8RiisoCAmp2U0v329LsIdK1GW4EMc9fmU=" 27 | 28 | tunnel_address = [ 29 | "192.168.1.1/32", 30 | "192.168.4.1/24", 31 | ] 32 | 33 | server_address = "10.10.10.10" 34 | server_port = "1234" 35 | } 36 | 37 | // Configure the server 38 | resource "opnsense_wireguard_server" "example0" { 39 | name = "example0" 40 | 41 | private_key = wireguard_asymmetric_key.example0.private_key 42 | public_key = wireguard_asymmetric_key.example0.public_key 43 | 44 | dns = [ 45 | "1.1.1.1", 46 | "8.8.8.8" 47 | ] 48 | 49 | tunnel_address = [ 50 | "192.168.1.100/32", 51 | "10.10.0.0/24" 52 | ] 53 | 54 | peers = [ 55 | opnsense_wireguard_client.example0.id 56 | ] 57 | } 58 | ``` 59 | 60 | 61 | ## Schema 62 | 63 | ### Required 64 | 65 | - `name` (String) Name of the server. 66 | - `private_key` (String, Sensitive) Private key of this server. Must be a 256-bit base64 string. 67 | - `public_key` (String) Public key of this server. Must be a 256-bit base64 string. 68 | 69 | ### Optional 70 | 71 | - `disable_routes` (Boolean) Disables installation of routes. Usually you only enable this to do own routing decisions via a local gateway and gateway rules. Defaults to `false`. 72 | - `dns` (Set of String) The interface specific DNS servers. Defaults to `[]`. 73 | - `enabled` (Boolean) Enable this server. Defaults to `true`. 74 | - `gateway` (String) The gateway IP here when using Disable Routes feature. You also have to add this as a gateway in OPNsense. Must be set when `disable_routes` is `true`. Defaults to `""`. 75 | - `mtu` (Number) The interface MTU for this interface. Set to `-1` to use the MTU from main interface. Defaults to `-1`. 76 | - `peers` (Set of String) List of peer IDs for this server. Defaults to `[]`. 77 | - `port` (Number) The fixed port for this instance to listen on. The standard port range starts at 51820. Defaults to `-1`. 78 | - `tunnel_address` (Set of String) List of addresses to configure on the tunnel adapter. Please use CIDR notation like `"10.0.0.1/24"`. Defaults to `[]`. 79 | 80 | ### Read-Only 81 | 82 | - `id` (String) UUID of the server. 83 | - `instance` (String) The instance number to give the wg interface a unique name (wgX). 84 | 85 | ## Import 86 | 87 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import opnsense_wireguard_server using the `id`. For example: 88 | 89 | ```terraform 90 | import { 91 | to = opnsense_wireguard_server.example 92 | id = "" 93 | } 94 | ``` 95 | 96 | Using `terraform import`, import opnsense_wireguard_server using the `id`. For example: 97 | 98 | ```console 99 | % terraform import opnsense_wireguard_server.example 100 | ``` -------------------------------------------------------------------------------- /examples/data-sources/opnsense_interface_all/data-source.tf: -------------------------------------------------------------------------------- 1 | // Get all interface configs 2 | data "opnsense_interface_all" "all" {} 3 | 4 | // Filter for a specific MAC address 5 | output "specific_mac" { 6 | value = [for i in data.opnsense_interface_all.all.interfaces : i if i.macaddr == "5a:dc:1f:24:12:c6"] 7 | } 8 | 9 | // Filter for specific device (advisable to use opnsense_interface instead) 10 | output "wireguard" { 11 | value = [for i in data.opnsense_interface_all.all.interfaces : i if i.device == "wg1"] 12 | } 13 | -------------------------------------------------------------------------------- /examples/provider/provider.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | opnsense = { 4 | version = "~> x.0" 5 | source = "browningluke/opnsense" 6 | } 7 | } 8 | } 9 | 10 | provider "opnsense" { 11 | uri = "https://opnsense.example.com" 12 | api_key = "..." 13 | api_secret = "..." 14 | } 15 | -------------------------------------------------------------------------------- /examples/resources/opnsense_firewall_alias/resource.tf: -------------------------------------------------------------------------------- 1 | // Network example 2 | resource "opnsense_firewall_alias" "example_one" { 3 | name = "example_one" 4 | 5 | type = "network" 6 | content = [ 7 | "10.8.0.1/24", 8 | "10.8.0.2/24" 9 | ] 10 | 11 | stats = true 12 | description = "Example" 13 | } 14 | 15 | // With category 16 | resource "opnsense_firewall_category" "example_one" { 17 | name = "example" 18 | color = "ffaa00" 19 | } 20 | 21 | resource "opnsense_firewall_alias" "example_two" { 22 | name = "example_two" 23 | 24 | type = "geoip" 25 | content = [ 26 | "FR", 27 | "CA", 28 | ] 29 | 30 | categories = [ 31 | opnsense_firewall_category.example_one.id 32 | ] 33 | 34 | description = "Example two" 35 | } 36 | -------------------------------------------------------------------------------- /examples/resources/opnsense_firewall_category/resource.tf: -------------------------------------------------------------------------------- 1 | resource "opnsense_firewall_category" "example_one" { 2 | name = "example" 3 | color = "ffaa00" 4 | } 5 | 6 | resource "opnsense_firewall_alias" "example_one" { 7 | name = "example" 8 | 9 | type = "geoip" 10 | content = [ 11 | "FR", 12 | "CA", 13 | ] 14 | 15 | categories = [ 16 | opnsense_firewall_category.example_one.id 17 | ] 18 | 19 | stats = true 20 | description = "Example" 21 | } 22 | -------------------------------------------------------------------------------- /examples/resources/opnsense_firewall_filter/resource.tf: -------------------------------------------------------------------------------- 1 | resource "opnsense_firewall_filter" "example_one" { 2 | enabled = false 3 | 4 | sequence = 1 5 | action = "block" 6 | quick = false 7 | 8 | interface = [ 9 | "lan", 10 | "lo0", 11 | ] 12 | 13 | direction = "in" 14 | ip_protocol = "inet" 15 | protocol = "UDP" 16 | 17 | source = { 18 | net = "any" 19 | invert = true 20 | } 21 | 22 | destination = { 23 | net = "examplealias" 24 | port = "https" 25 | } 26 | 27 | log = false 28 | description = "example rule" 29 | } 30 | 31 | resource "opnsense_firewall_filter" "example_two" { 32 | action = "pass" 33 | interface = [ 34 | "wan", 35 | ] 36 | 37 | direction = "in" 38 | protocol = "TCP" 39 | 40 | source = { 41 | net = "wan" # This is equiv. to WAN Net 42 | } 43 | 44 | destination = { 45 | net = "10.8.0.1" 46 | port = "443" 47 | } 48 | 49 | description = "example rule" 50 | } 51 | 52 | resource "opnsense_firewall_filter" "example_three" { 53 | action = "pass" 54 | interface = [ 55 | "wan", 56 | ] 57 | 58 | direction = "out" 59 | protocol = "TCP" 60 | 61 | source = { 62 | net = "192.168.0.0/16" 63 | } 64 | 65 | destination = { 66 | net = "wanip" # This is equiv. to WAN Address 67 | port = "80-443" 68 | } 69 | 70 | description = "example rule" 71 | log = true 72 | } -------------------------------------------------------------------------------- /examples/resources/opnsense_firewall_nat/resource.tf: -------------------------------------------------------------------------------- 1 | resource "opnsense_firewall_nat" "example_one" { 2 | disable_nat = true 3 | 4 | interface = "wan" 5 | protocol = "TCP" 6 | 7 | target = { 8 | ip = "wanip" 9 | } 10 | 11 | log = true 12 | description = "Example" 13 | } 14 | 15 | resource "opnsense_firewall_nat" "example_two" { 16 | enabled = false 17 | 18 | interface = "wan" 19 | protocol = "TCP" 20 | 21 | source = { 22 | net = "wan" # This is equiv. to WAN Net 23 | } 24 | 25 | destination = { 26 | net = "10.8.0.1" 27 | port = "443" 28 | } 29 | 30 | target = { 31 | ip = "wanip" 32 | port = "http" 33 | } 34 | 35 | log = true 36 | description = "Example" 37 | } 38 | 39 | resource "opnsense_firewall_nat" "example_three" { 40 | interface = "wan" 41 | protocol = "TCP" 42 | 43 | source = { 44 | net = "192.168.0.0/16" # This is equiv. to WAN Net 45 | invert = true 46 | } 47 | 48 | destination = { 49 | net = "examplealias" 50 | port = "80-443" 51 | } 52 | 53 | target = { 54 | ip = "wanip" 55 | port = "443" 56 | } 57 | 58 | description = "Example" 59 | } 60 | -------------------------------------------------------------------------------- /examples/resources/opnsense_interfaces_vlan/resource.tf: -------------------------------------------------------------------------------- 1 | // OPNsense generates a device name 2 | resource "opnsense_interfaces_vlan" "vlan" { 3 | description = "Example vlan" 4 | tag = 10 5 | priority = 0 6 | parent = "vtnet0" 7 | } 8 | 9 | // Manually configure a device name 10 | resource "opnsense_interfaces_vlan" "vlan04" { 11 | description = "Example vlan 4" 12 | tag = 50 13 | priority = 5 14 | parent = "vtnet0" 15 | device = "vlan04" 16 | } 17 | -------------------------------------------------------------------------------- /examples/resources/opnsense_kea_peer/resource.tf: -------------------------------------------------------------------------------- 1 | // Small example 2 | resource "opnsense_kea_peer" "example" { 3 | name = "example" 4 | role = "primary" 5 | url = "http://192.0.2.1:8001/" 6 | } -------------------------------------------------------------------------------- /examples/resources/opnsense_kea_reservation/resource.tf: -------------------------------------------------------------------------------- 1 | // Small example 2 | resource "opnsense_kea_reservation" "test" { 3 | subnet_id = resource.opnsense_kea_subnet.lan.id 4 | 5 | ip_address = "10.8.2.102" 6 | mac_address = "00:25:96:12:34:55" 7 | 8 | description = "example host" 9 | } 10 | 11 | // LAN subnet example 12 | resource "opnsense_kea_subnet" "lan" { 13 | subnet = "10.8.0.0/16" 14 | description = "LAN" 15 | } -------------------------------------------------------------------------------- /examples/resources/opnsense_kea_subnet/resource.tf: -------------------------------------------------------------------------------- 1 | // Small example 2 | resource "opnsense_kea_subnet" "lan" { 3 | subnet = "10.8.0.0/16" 4 | description = "LAN" 5 | } 6 | 7 | // Full resource 8 | resource "opnsense_kea_subnet" "example" { 9 | subnet = "10.8.0.0/16" 10 | 11 | next_server = "10.8.0.1" 12 | 13 | auto_collect = false 14 | 15 | static_routes = [ 16 | { 17 | destination_ip = "10.10.10.10" 18 | router_ip = "10.8.0.1" 19 | }, 20 | { 21 | destination_ip = "10.10.10.11" 22 | router_ip = "10.8.50.1" 23 | } 24 | ] 25 | 26 | pools = [ 27 | "10.8.2.1-10.8.2.100", 28 | "10.8.2.101-10.8.2.200", 29 | "10.8.3.0/24" 30 | ] 31 | 32 | routers = [ 33 | "10.8.0.1", 34 | "10.8.50.2" 35 | ] 36 | 37 | dns_servers = [ 38 | "10.8.0.160", 39 | "10.8.0.161" 40 | ] 41 | 42 | domain_name = "example.com" 43 | 44 | domain_search = [ 45 | "search.example.com", 46 | "search2.example.com" 47 | ] 48 | 49 | ntp_servers = [ 50 | "10.10.101.10", 51 | "10.10.101.11" 52 | ] 53 | 54 | time_servers = [ 55 | "10.10.101.10", 56 | "10.10.101.11" 57 | ] 58 | 59 | tfpt_server = "tfpt.example.com" 60 | tftp_bootfile = "bootfile.txt" 61 | 62 | description = "EXAMPLE" 63 | } 64 | -------------------------------------------------------------------------------- /examples/resources/opnsense_quagga_bgp_aspath/resource.tf: -------------------------------------------------------------------------------- 1 | // Configure an AS Path 2 | resource "opnsense_quagga_bgp_aspath" "example0" { 3 | enabled = false 4 | description = "aspath0" 5 | 6 | number = 123 7 | action = "permit" 8 | 9 | as = "_2$" 10 | } 11 | -------------------------------------------------------------------------------- /examples/resources/opnsense_quagga_bgp_communitylist/resource.tf: -------------------------------------------------------------------------------- 1 | // Configure a community list 2 | resource "opnsense_quagga_bgp_communitylist" "example0" { 3 | enabled = false 4 | description = "communitylist0" 5 | 6 | number = 100 7 | seq_number = 99 8 | action = "deny" 9 | 10 | community = "example.*" 11 | } 12 | -------------------------------------------------------------------------------- /examples/resources/opnsense_quagga_bgp_neighbor/resource.tf: -------------------------------------------------------------------------------- 1 | // Configure a prefix list 2 | resource "opnsense_quagga_bgp_prefixlist" "example0" { 3 | enabled = false 4 | 5 | description = "prefixlist0" 6 | name = "example0" 7 | 8 | number = 1234 9 | action = "permit" 10 | 11 | network = "10.10.0.0" 12 | } 13 | 14 | // Configure a route map 15 | resource "opnsense_quagga_bgp_routemap" "example0" { 16 | enabled = false 17 | description = "routemap0" 18 | 19 | name = "example0" 20 | action = "deny" 21 | 22 | route_map_id = 100 23 | set = "local-preference 300" 24 | } 25 | 26 | // Configure a neighbor 27 | resource "opnsense_quagga_bgp_neighbor" "example0" { 28 | enabled = false 29 | 30 | description = "neighbor0" 31 | 32 | peer_ip = "1.1.1.1" 33 | remote_as = 255 34 | 35 | md5_password = "12345" 36 | weight = 1 37 | local_ip = "2.2.2.2" 38 | update_source = "wan" 39 | link_local_interface = "wireguard" 40 | 41 | next_hop_self = true 42 | next_hop_self_all = true 43 | multi_hop = true 44 | multi_protocol = true 45 | rr_client = true 46 | bfd = true 47 | 48 | keep_alive = 100 49 | hold_down = 10 50 | connect_timer = 10 51 | 52 | default_route = true 53 | as_override = true 54 | disable_connected_check = true 55 | attribute_unchanged = "as-path" 56 | 57 | prefix_list_in = opnsense_quagga_bgp_prefixlist.example0.id 58 | route_map_out = opnsense_quagga_bgp_routemap.example0.id 59 | } 60 | -------------------------------------------------------------------------------- /examples/resources/opnsense_quagga_bgp_prefixlist/resource.tf: -------------------------------------------------------------------------------- 1 | // Configure a prefix list 2 | resource "opnsense_quagga_bgp_prefixlist" "example0" { 3 | enabled = false 4 | 5 | description = "prefixlist0" 6 | name = "example0" 7 | 8 | number = 1234 9 | action = "permit" 10 | 11 | network = "10.10.0.0" 12 | } 13 | -------------------------------------------------------------------------------- /examples/resources/opnsense_quagga_bgp_routemap/resource.tf: -------------------------------------------------------------------------------- 1 | // Configure an AS Path 2 | resource "opnsense_quagga_bgp_aspath" "example0" { 3 | enabled = false 4 | description = "aspath0" 5 | 6 | number = 123 7 | action = "permit" 8 | 9 | as = "_2$" 10 | } 11 | 12 | // Configure a prefix list 13 | resource "opnsense_quagga_bgp_prefixlist" "example0" { 14 | enabled = false 15 | 16 | description = "prefixlist0" 17 | name = "example0" 18 | 19 | number = 1234 20 | action = "permit" 21 | 22 | network = "10.10.0.0" 23 | } 24 | // Configure a community list 25 | resource "opnsense_quagga_bgp_communitylist" "example0" { 26 | enabled = false 27 | description = "communitylist0" 28 | 29 | number = 100 30 | seq_number = 99 31 | action = "deny" 32 | 33 | community = "example.*" 34 | } 35 | 36 | // Configure a route map 37 | resource "opnsense_quagga_bgp_routemap" "example0" { 38 | enabled = false 39 | description = "routemap0" 40 | 41 | name = "example0" 42 | action = "deny" 43 | 44 | route_map_id = 100 45 | 46 | aspaths = [ 47 | opnsense_quagga_bgp_aspath.example0.id 48 | ] 49 | 50 | prefix_lists = [ 51 | opnsense_quagga_bgp_prefixlist.example0.id 52 | ] 53 | 54 | community_lists = [ 55 | opnsense_quagga_bgp_communitylist.example0.id 56 | ] 57 | 58 | set = "local-preference 300" 59 | } 60 | -------------------------------------------------------------------------------- /examples/resources/opnsense_route/resource.tf: -------------------------------------------------------------------------------- 1 | // Enabled with description 2 | resource "opnsense_route" "one_route" { 3 | description = "Example route" 4 | gateway = "LAN_DHCP" 5 | network = "10.9.0.0/24" 6 | } 7 | 8 | // Disabled without description 9 | resource "opnsense_route" "two_route" { 10 | enabled = false 11 | 12 | gateway = "LAN" 13 | network = "10.10.0.0/24" 14 | } 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /examples/resources/opnsense_unbound_domain_override/resource.tf: -------------------------------------------------------------------------------- 1 | // Enabled with description 2 | resource "opnsense_unbound_domain_override" "one_override" { 3 | enabled = true 4 | description = "Example override" 5 | 6 | domain = "example.lan" 7 | server = "192.168.1.1" 8 | } 9 | 10 | // Disabled without description 11 | resource "opnsense_unbound_domain_override" "two_override" { 12 | enabled = false 13 | 14 | domain = "example.arpa" 15 | server = "192.168.1.100" 16 | } 17 | -------------------------------------------------------------------------------- /examples/resources/opnsense_unbound_forward/resource.tf: -------------------------------------------------------------------------------- 1 | // Query Forward 2 | resource "opnsense_unbound_forward" "query" { 3 | domain = "example.lan" 4 | server_ip = "192.168.1.2" 5 | server_port = 853 6 | } 7 | 8 | // DoT forward 9 | resource "opnsense_unbound_forward" "dot" { 10 | enabled = false 11 | type = "dot" 12 | 13 | domain = "example.dev" 14 | server_ip = "192.168.1.1" 15 | server_port = 53 16 | verify_cn = "example.dev" 17 | } 18 | -------------------------------------------------------------------------------- /examples/resources/opnsense_unbound_host_alias/resource.tf: -------------------------------------------------------------------------------- 1 | // 'A' record 2 | resource "opnsense_unbound_host_override" "a_override" { 3 | enabled = true 4 | description = "A record override" 5 | 6 | hostname = "*" 7 | domain = "example.com" 8 | server = "192.168.1.1" 9 | } 10 | 11 | // Enabled alias with description 12 | resource "opnsense_unbound_host_alias" "one_alias" { 13 | override = opnsense_unbound_host_override.a_override.id 14 | 15 | enabled = true 16 | hostname = "*" 17 | domain = "1.example.com" 18 | description = "Example 1" 19 | } 20 | 21 | // Disabled alias without description 22 | resource "opnsense_unbound_host_alias" "two_alias" { 23 | override = opnsense_unbound_host_override.a_override.id 24 | 25 | enabled = false 26 | hostname = "*" 27 | domain = "2.example.com" 28 | } 29 | -------------------------------------------------------------------------------- /examples/resources/opnsense_unbound_host_override/resource.tf: -------------------------------------------------------------------------------- 1 | // 'A' record 2 | resource "opnsense_unbound_host_override" "a_override" { 3 | enabled = true 4 | description = "A record override" 5 | 6 | hostname = "*" 7 | domain = "example.com" 8 | server = "192.168.1.1" 9 | } 10 | 11 | // 'AAAA' record 12 | resource "opnsense_unbound_host_override" "aaaa_override" { 13 | enabled = true 14 | 15 | type = "AAAA" 16 | hostname = "*" 17 | domain = "example.com" 18 | server = "fd00:abcd::1" 19 | } 20 | 21 | // 'MX' record 22 | resource "opnsense_unbound_host_override" "mx_override" { 23 | enabled = false 24 | description = "MX record override" 25 | 26 | type = "MX" 27 | hostname = "*" 28 | domain = "example.com" 29 | 30 | mx_priority = 10 31 | mx_host = "mail.example.dev" 32 | } 33 | -------------------------------------------------------------------------------- /examples/resources/opnsense_wireguard_client/resource.tf: -------------------------------------------------------------------------------- 1 | // Configure a peer 2 | resource "opnsense_wireguard_client" "example0" { 3 | enabled = false 4 | name = "example0" 5 | 6 | public_key = "/CPjuEdvHJulOIQ56TNyeNHkDJmRCMor4U9k68vMyac=" 7 | psk = "CJG05xgaLA8RiisoCAmp2U0v329LsIdK1GW4EMc9fmU=" 8 | 9 | tunnel_address = [ 10 | "192.168.1.1/32", 11 | "192.168.4.1/24", 12 | ] 13 | 14 | server_address = "10.10.10.10" 15 | server_port = "1234" 16 | } 17 | -------------------------------------------------------------------------------- /examples/resources/opnsense_wireguard_server/resource.tf: -------------------------------------------------------------------------------- 1 | // Generate an wireguard_asymmetric_key 2 | // This uses the OJFord/wireguard provider 3 | resource "wireguard_asymmetric_key" "example0" { 4 | } 5 | 6 | // Configure a peer 7 | resource "opnsense_wireguard_client" "example0" { 8 | enabled = false 9 | name = "example0" 10 | 11 | public_key = "/CPjuEdvHJulOIQ56TNyeNHkDJmRCMor4U9k68vMyac=" 12 | psk = "CJG05xgaLA8RiisoCAmp2U0v329LsIdK1GW4EMc9fmU=" 13 | 14 | tunnel_address = [ 15 | "192.168.1.1/32", 16 | "192.168.4.1/24", 17 | ] 18 | 19 | server_address = "10.10.10.10" 20 | server_port = "1234" 21 | } 22 | 23 | // Configure the server 24 | resource "opnsense_wireguard_server" "example0" { 25 | name = "example0" 26 | 27 | private_key = wireguard_asymmetric_key.example0.private_key 28 | public_key = wireguard_asymmetric_key.example0.public_key 29 | 30 | dns = [ 31 | "1.1.1.1", 32 | "8.8.8.8" 33 | ] 34 | 35 | tunnel_address = [ 36 | "192.168.1.100/32", 37 | "10.10.0.0/24" 38 | ] 39 | 40 | peers = [ 41 | opnsense_wireguard_client.example0.id 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module terraform-provider-opnsense 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.23.1 6 | 7 | require ( 8 | github.com/browningluke/opnsense-go v0.10.0 9 | github.com/hashicorp/terraform-plugin-docs v0.19.4 10 | github.com/hashicorp/terraform-plugin-framework v1.12.0 11 | github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 12 | github.com/hashicorp/terraform-plugin-log v0.9.0 13 | ) 14 | 15 | require ( 16 | github.com/BurntSushi/toml v1.2.1 // indirect 17 | github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect 18 | github.com/Masterminds/goutils v1.1.1 // indirect 19 | github.com/Masterminds/semver/v3 v3.2.0 // indirect 20 | github.com/Masterminds/sprig/v3 v3.2.3 // indirect 21 | github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect 22 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 23 | github.com/armon/go-radix v1.0.0 // indirect 24 | github.com/bgentry/speakeasy v0.1.0 // indirect 25 | github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect 26 | github.com/cloudflare/circl v1.3.7 // indirect 27 | github.com/fatih/color v1.16.0 // indirect 28 | github.com/golang/protobuf v1.5.4 // indirect 29 | github.com/google/uuid v1.6.0 // indirect 30 | github.com/hashicorp/cli v1.1.6 // indirect 31 | github.com/hashicorp/errwrap v1.1.0 // indirect 32 | github.com/hashicorp/go-checkpoint v0.5.0 // indirect 33 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 34 | github.com/hashicorp/go-hclog v1.5.0 // indirect 35 | github.com/hashicorp/go-multierror v1.1.1 // indirect 36 | github.com/hashicorp/go-plugin v1.6.1 // indirect 37 | github.com/hashicorp/go-retryablehttp v0.7.4 // indirect 38 | github.com/hashicorp/go-uuid v1.0.3 // indirect 39 | github.com/hashicorp/go-version v1.7.0 // indirect 40 | github.com/hashicorp/hc-install v0.7.0 // indirect 41 | github.com/hashicorp/terraform-exec v0.21.0 // indirect 42 | github.com/hashicorp/terraform-json v0.22.1 // indirect 43 | github.com/hashicorp/terraform-plugin-go v0.24.0 // indirect 44 | github.com/hashicorp/terraform-registry-address v0.2.3 // indirect 45 | github.com/hashicorp/terraform-svchost v0.1.1 // indirect 46 | github.com/hashicorp/yamux v0.1.1 // indirect 47 | github.com/huandu/xstrings v1.3.3 // indirect 48 | github.com/imdario/mergo v0.3.15 // indirect 49 | github.com/mattn/go-colorable v0.1.13 // indirect 50 | github.com/mattn/go-isatty v0.0.20 // indirect 51 | github.com/mattn/go-runewidth v0.0.9 // indirect 52 | github.com/mitchellh/copystructure v1.2.0 // indirect 53 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 54 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 55 | github.com/oklog/run v1.0.0 // indirect 56 | github.com/posener/complete v1.2.3 // indirect 57 | github.com/shopspring/decimal v1.3.1 // indirect 58 | github.com/spf13/cast v1.5.0 // indirect 59 | github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 60 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 61 | github.com/yuin/goldmark v1.7.1 // indirect 62 | github.com/yuin/goldmark-meta v1.1.0 // indirect 63 | github.com/zclconf/go-cty v1.14.4 // indirect 64 | go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect 65 | golang.org/x/crypto v0.24.0 // indirect 66 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect 67 | golang.org/x/mod v0.17.0 // indirect 68 | golang.org/x/net v0.26.0 // indirect 69 | golang.org/x/sys v0.21.0 // indirect 70 | golang.org/x/text v0.16.0 // indirect 71 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 72 | google.golang.org/grpc v1.66.2 // indirect 73 | google.golang.org/protobuf v1.34.2 // indirect 74 | gopkg.in/yaml.v2 v2.3.0 // indirect 75 | gopkg.in/yaml.v3 v3.0.1 // indirect 76 | ) 77 | -------------------------------------------------------------------------------- /internal/service/firewall_alias_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &FirewallAliasDataSource{} 13 | 14 | func NewFirewallAliasDataSource() datasource.DataSource { 15 | return &FirewallAliasDataSource{} 16 | } 17 | 18 | // FirewallAliasDataSource defines the data source implementation. 19 | type FirewallAliasDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *FirewallAliasDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_firewall_alias" 25 | } 26 | 27 | func (d *FirewallAliasDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = FirewallAliasDataSourceSchema() 29 | } 30 | 31 | func (d *FirewallAliasDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *FirewallAliasDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *FirewallAliasResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get firewall alias from OPNsense unbound API 60 | resourceStruct, err := d.client.Firewall().GetAlias(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read firewall alias, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertFirewallAliasStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read firewall alias, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/firewall_category_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &FirewallCategoryDataSource{} 13 | 14 | func NewFirewallCategoryDataSource() datasource.DataSource { 15 | return &FirewallCategoryDataSource{} 16 | } 17 | 18 | // FirewallCategoryDataSource defines the data source implementation. 19 | type FirewallCategoryDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *FirewallCategoryDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_firewall_category" 25 | } 26 | 27 | func (d *FirewallCategoryDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = FirewallCategoryDataSourceSchema() 29 | } 30 | 31 | func (d *FirewallCategoryDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *FirewallCategoryDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *FirewallCategoryResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get firewall category from OPNsense unbound API 60 | resourceStruct, err := d.client.Firewall().GetCategory(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read firewall category, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertFirewallCategoryStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read firewall category, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/firewall_category_schema.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/browningluke/opnsense-go/pkg/firewall" 5 | dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 6 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 7 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" 8 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 9 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 10 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 11 | "github.com/hashicorp/terraform-plugin-framework/types" 12 | "terraform-provider-opnsense/internal/tools" 13 | ) 14 | 15 | // FirewallCategoryResourceModel describes the resource data model. 16 | type FirewallCategoryResourceModel struct { 17 | Automatic types.Bool `tfsdk:"auto"` 18 | Name types.String `tfsdk:"name"` 19 | Color types.String `tfsdk:"color"` 20 | 21 | Id types.String `tfsdk:"id"` 22 | } 23 | 24 | func FirewallCategoryResourceSchema() schema.Schema { 25 | return schema.Schema{ 26 | MarkdownDescription: "To ease maintenance of larger rulesets, OPNsense includes categories for the firewall. Each rule can contain one or more categories.", 27 | 28 | Attributes: map[string]schema.Attribute{ 29 | "auto": schema.BoolAttribute{ 30 | MarkdownDescription: "If set, this category will be removed when unused. This is included for completeness, but will result in constant recreations if not attached to any rules, and thus it is advised to leave it as default. Defaults to `false`.", 31 | Optional: true, 32 | Computed: true, 33 | Default: booldefault.StaticBool(false), 34 | }, 35 | "name": schema.StringAttribute{ 36 | MarkdownDescription: "Enter a name for this category.", 37 | Required: true, 38 | }, 39 | "color": schema.StringAttribute{ 40 | MarkdownDescription: "Pick a color to use. Must be a hex color in format `rrggbb` (e.g. `ff0000`). Defaults to `\"\"`.", 41 | Optional: true, 42 | Computed: true, 43 | Default: stringdefault.StaticString(""), 44 | }, 45 | "id": schema.StringAttribute{ 46 | Computed: true, 47 | MarkdownDescription: "UUID of the resource.", 48 | PlanModifiers: []planmodifier.String{ 49 | stringplanmodifier.UseStateForUnknown(), 50 | }, 51 | }, 52 | }, 53 | } 54 | } 55 | 56 | func FirewallCategoryDataSourceSchema() dschema.Schema { 57 | return dschema.Schema{ 58 | MarkdownDescription: "To ease maintenance of larger rulesets, OPNsense includes categories for the firewall. Each rule can contain one or more categories.", 59 | 60 | Attributes: map[string]dschema.Attribute{ 61 | "id": dschema.StringAttribute{ 62 | MarkdownDescription: "UUID of the resource.", 63 | Required: true, 64 | }, 65 | "auto": dschema.BoolAttribute{ 66 | MarkdownDescription: "If set, this category will be removed when unused.", 67 | Computed: true, 68 | }, 69 | "name": dschema.StringAttribute{ 70 | MarkdownDescription: "The name for this category.", 71 | Computed: true, 72 | }, 73 | "color": dschema.StringAttribute{ 74 | MarkdownDescription: "The color to use. Must be a hex color in format `rrggbb` (e.g. `ff0000`).", 75 | Computed: true, 76 | }, 77 | }, 78 | } 79 | } 80 | 81 | func convertFirewallCategorySchemaToStruct(d *FirewallCategoryResourceModel) (*firewall.Category, error) { 82 | return &firewall.Category{ 83 | Automatic: tools.BoolToString(d.Automatic.ValueBool()), 84 | Name: d.Name.ValueString(), 85 | Color: d.Color.ValueString(), 86 | }, nil 87 | } 88 | 89 | func convertFirewallCategoryStructToSchema(d *firewall.Category) (*FirewallCategoryResourceModel, error) { 90 | return &FirewallCategoryResourceModel{ 91 | Automatic: types.BoolValue(tools.StringToBool(d.Automatic)), 92 | Name: types.StringValue(d.Name), 93 | Color: types.StringValue(d.Color), 94 | }, nil 95 | } 96 | -------------------------------------------------------------------------------- /internal/service/firewall_filter_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &FirewallFilterDataSource{} 13 | 14 | func NewFirewallFilterDataSource() datasource.DataSource { 15 | return &FirewallFilterDataSource{} 16 | } 17 | 18 | // FirewallFilterDataSource defines the data source implementation. 19 | type FirewallFilterDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *FirewallFilterDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_firewall_filter" 25 | } 26 | 27 | func (d *FirewallFilterDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = FirewallFilterDataSourceSchema() 29 | } 30 | 31 | func (d *FirewallFilterDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *FirewallFilterDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *FirewallFilterResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get firewall filter from OPNsense unbound API 60 | resourceStruct, err := d.client.Firewall().GetFilter(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read firewall filter, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertFirewallFilterStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read firewall filter, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/firewall_nat_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &FirewallNATDataSource{} 13 | 14 | func NewFirewallNATDataSource() datasource.DataSource { 15 | return &FirewallNATDataSource{} 16 | } 17 | 18 | // FirewallNATDataSource defines the data source implementation. 19 | type FirewallNATDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *FirewallNATDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_firewall_nat" 25 | } 26 | 27 | func (d *FirewallNATDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = FirewallNATDataSourceSchema() 29 | } 30 | 31 | func (d *FirewallNATDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *FirewallNATDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *FirewallNATResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get firewall nat from OPNsense unbound API 60 | resourceStruct, err := d.client.Firewall().GetNAT(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read firewall nat, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertFirewallNATStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read firewall nat, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/interface_all_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &InterfaceAllDataSource{} 13 | 14 | func NewInterfaceAllDataSource() datasource.DataSource { 15 | return &InterfaceAllDataSource{} 16 | } 17 | 18 | // InterfaceAllDataSource defines the data source implementation. 19 | type InterfaceAllDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *InterfaceAllDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_interface_all" 25 | } 26 | 27 | func (d *InterfaceAllDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = InterfaceAllDataSourceSchema() 29 | } 30 | 31 | func (d *InterfaceAllDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *InterfaceAllDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *InterfaceAllDataSourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resources from OPNsense API 60 | resources, err := d.client.Diagnostics().GetInterfaceAll(ctx) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read interface, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | model, err := convertAllInterfaceConfigStructToSchema(resources) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read interface, got error: %s", err)) 72 | return 73 | } 74 | 75 | // Save updated data into Terraform state 76 | resp.Diagnostics.Append(resp.State.Set(ctx, &model)...) 77 | } 78 | -------------------------------------------------------------------------------- /internal/service/interface_all_schema.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "github.com/browningluke/opnsense-go/pkg/diagnostics" 6 | "github.com/hashicorp/terraform-plugin-framework/attr" 7 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 8 | "github.com/hashicorp/terraform-plugin-framework/types" 9 | ) 10 | 11 | type InterfaceAllDataSourceModel struct { 12 | Interfaces types.List `tfsdk:"interfaces"` 13 | } 14 | 15 | func InterfaceAllDataSourceSchema() schema.Schema { 16 | return schema.Schema{ 17 | MarkdownDescription: "InterfacesAll can be used to get a list of all configurations of OPNsense interfaces. Allows for custom filtering.", 18 | 19 | Attributes: map[string]schema.Attribute{ 20 | "interfaces": schema.ListNestedAttribute{ 21 | MarkdownDescription: "A list of all interfaces present in OPNsense.", 22 | NestedObject: schema.NestedAttributeObject{ 23 | Attributes: InterfaceDataSourceSchema().Attributes, 24 | }, 25 | Computed: true, 26 | }, 27 | }, 28 | } 29 | } 30 | 31 | func convertAllInterfaceConfigStructToSchema(d []diagnostics.Interface) (*InterfaceAllDataSourceModel, error) { 32 | var interfaces []InterfaceDataSourceModel 33 | for _, iface := range d { 34 | toSchema, err := convertInterfaceConfigStructToSchema(&iface) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | interfaces = append(interfaces, *toSchema) 40 | } 41 | 42 | // Create empty list first 43 | v, _ := types.ListValue( 44 | types.ObjectType{ 45 | AttrTypes: interfaceAttrTypes, 46 | }, 47 | []attr.Value{}, 48 | ) 49 | // Try to fill list 50 | if len(interfaces) > 0 { 51 | v, _ = types.ListValueFrom( 52 | context.Background(), 53 | types.ObjectType{ 54 | AttrTypes: interfaceAttrTypes, 55 | }, 56 | interfaces, 57 | ) 58 | } 59 | 60 | model := &InterfaceAllDataSourceModel{ 61 | Interfaces: v, 62 | } 63 | 64 | return model, nil 65 | } 66 | -------------------------------------------------------------------------------- /internal/service/interface_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &InterfaceDataSource{} 13 | 14 | func NewInterfaceDataSource() datasource.DataSource { 15 | return &InterfaceDataSource{} 16 | } 17 | 18 | // InterfaceDataSource defines the data source implementation. 19 | type InterfaceDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *InterfaceDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_interface" 25 | } 26 | 27 | func (d *InterfaceDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = InterfaceDataSourceSchema() 29 | } 30 | 31 | func (d *InterfaceDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *InterfaceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *InterfaceDataSourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Diagnostics().GetInterface(ctx, data.Device.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read interface, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | model, err := convertInterfaceConfigStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read interface, got error: %s", err)) 72 | return 73 | } 74 | 75 | // Save updated data into Terraform state 76 | resp.Diagnostics.Append(resp.State.Set(ctx, &model)...) 77 | } 78 | -------------------------------------------------------------------------------- /internal/service/interfaces_vlan_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | ) 11 | 12 | // Ensure provider defined types fully satisfy framework interfaces. 13 | var _ datasource.DataSource = &InterfacesVlanDataSource{} 14 | 15 | func NewInterfacesVlanDataSource() datasource.DataSource { 16 | return &InterfacesVlanDataSource{} 17 | } 18 | 19 | // InterfacesVlanDataSource defines the data source implementation. 20 | type InterfacesVlanDataSource struct { 21 | client opnsense.Client 22 | } 23 | 24 | func (d *InterfacesVlanDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 25 | resp.TypeName = req.ProviderTypeName + "_interfaces_vlan" 26 | } 27 | 28 | func (d *InterfacesVlanDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 29 | resp.Schema = InterfacesVlanDataSourceSchema() 30 | } 31 | 32 | func (d *InterfacesVlanDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 33 | // Prevent panic if the provider has not been configured. 34 | if req.ProviderData == nil { 35 | return 36 | } 37 | 38 | apiClient, ok := req.ProviderData.(*api.Client) 39 | if !ok { 40 | resp.Diagnostics.AddError( 41 | "Unexpected Resource Configure Type", 42 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 43 | ) 44 | return 45 | } 46 | 47 | d.client = opnsense.NewClient(apiClient) 48 | } 49 | 50 | func (d *InterfacesVlanDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 51 | var data *InterfacesVlanResourceModel 52 | 53 | // Read Terraform configuration data into the model 54 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 55 | 56 | if resp.Diagnostics.HasError() { 57 | return 58 | } 59 | 60 | // Get resource from OPNsense API 61 | resource, err := d.client.Interfaces().GetVlan(ctx, data.Id.ValueString()) 62 | if err != nil { 63 | resp.Diagnostics.AddError("Client Error", 64 | fmt.Sprintf("Unable to read vlan, got error: %s", err)) 65 | return 66 | } 67 | 68 | // Convert OPNsense struct to TF schema 69 | resourceModel, err := convertInterfacesVlanStructToSchema(resource) 70 | if err != nil { 71 | resp.Diagnostics.AddError("Client Error", 72 | fmt.Sprintf("Unable to read vlan, got error: %s", err)) 73 | return 74 | } 75 | 76 | // ID cannot be added by convert... func, have to add here 77 | resourceModel.Id = data.Id 78 | 79 | if data.Device.ValueString() == "" { 80 | resourceModel.Device = types.StringValue("") 81 | } 82 | 83 | // Save updated data into Terraform state 84 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 85 | } 86 | -------------------------------------------------------------------------------- /internal/service/kea_peer_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &KeaPeerDataSource{} 13 | 14 | func NewKeaPeerDataSource() datasource.DataSource { 15 | return &KeaPeerDataSource{} 16 | } 17 | 18 | // KeaPeerDataSource defines the data source implementation. 19 | type KeaPeerDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *KeaPeerDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_kea_peer" 25 | } 26 | 27 | func (d *KeaPeerDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = KeaPeerDataSourceSchema() 29 | } 30 | 31 | func (d *KeaPeerDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *KeaPeerDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *KeaPeerResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get kea peer from OPNsense unbound API 60 | resourceStruct, err := d.client.Kea().GetPeer(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read kea peer, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertKeaPeerStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read kea peer, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/kea_peer_schema.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/browningluke/opnsense-go/pkg/api" 5 | "github.com/browningluke/opnsense-go/pkg/kea" 6 | "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" 7 | dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 8 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 10 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 11 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 12 | "github.com/hashicorp/terraform-plugin-framework/schema/validator" 13 | "github.com/hashicorp/terraform-plugin-framework/types" 14 | ) 15 | 16 | // KeaPeerResourceModel describes the resource data model. 17 | type KeaPeerResourceModel struct { 18 | Name types.String `tfsdk:"name"` 19 | Url types.String `tfsdk:"url"` 20 | Role types.String `tfsdk:"role"` 21 | 22 | Id types.String `tfsdk:"id"` 23 | } 24 | 25 | func KeaPeerResourceSchema() schema.Schema { 26 | return schema.Schema{ 27 | MarkdownDescription: "Configure HA Peers for Kea.", 28 | 29 | Attributes: map[string]schema.Attribute{ 30 | "name": schema.StringAttribute{ 31 | MarkdownDescription: "Peer name, there should be one entry matching this machine's \"This server name\".", 32 | Required: true, 33 | }, 34 | "url": schema.StringAttribute{ 35 | MarkdownDescription: "URL of the server instance, which should use a different port than the control agent (e.g. `http://192.0.2.1:8001/`).", 36 | Required: true, 37 | }, 38 | "role": schema.StringAttribute{ 39 | MarkdownDescription: "Peer's role. Defaults to `\"primary\"`.", 40 | Optional: true, 41 | Computed: true, 42 | Validators: []validator.String{ 43 | stringvalidator.OneOf("primary", "standby"), 44 | }, 45 | Default: stringdefault.StaticString("primary"), 46 | }, 47 | "id": schema.StringAttribute{ 48 | Computed: true, 49 | MarkdownDescription: "UUID of the peer.", 50 | PlanModifiers: []planmodifier.String{ 51 | stringplanmodifier.UseStateForUnknown(), 52 | }, 53 | }, 54 | }, 55 | } 56 | } 57 | 58 | func KeaPeerDataSourceSchema() dschema.Schema { 59 | return dschema.Schema{ 60 | MarkdownDescription: "Configure HA Peers for Kea.", 61 | 62 | Attributes: map[string]dschema.Attribute{ 63 | "id": dschema.StringAttribute{ 64 | MarkdownDescription: "UUID of the peer.", 65 | Required: true, 66 | }, 67 | "name": schema.StringAttribute{ 68 | MarkdownDescription: "Peer name, there should be one entry matching this machine's \"This server name\".", 69 | Computed: true, 70 | }, 71 | "url": schema.StringAttribute{ 72 | MarkdownDescription: "URL of the server instance.", 73 | Computed: true, 74 | }, 75 | "role": schema.StringAttribute{ 76 | MarkdownDescription: "Peer's role.", 77 | Computed: true, 78 | }, 79 | }, 80 | } 81 | } 82 | 83 | func convertKeaPeerSchemaToStruct(d *KeaPeerResourceModel) (*kea.Peer, error) { 84 | return &kea.Peer{ 85 | Name: d.Name.ValueString(), 86 | Url: d.Url.ValueString(), 87 | Role: api.SelectedMap(d.Role.ValueString()), 88 | }, nil 89 | } 90 | 91 | func convertKeaPeerStructToSchema(d *kea.Peer) (*KeaPeerResourceModel, error) { 92 | return &KeaPeerResourceModel{ 93 | Name: types.StringValue(d.Name), 94 | Url: types.StringValue(d.Url), 95 | Role: types.StringValue(d.Role.String()), 96 | }, nil 97 | } 98 | -------------------------------------------------------------------------------- /internal/service/kea_reservation_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &KeaReservationDataSource{} 13 | 14 | func NewKeaReservationDataSource() datasource.DataSource { 15 | return &KeaReservationDataSource{} 16 | } 17 | 18 | // KeaReservationDataSource defines the data source implementation. 19 | type KeaReservationDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *KeaReservationDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_kea_reservation" 25 | } 26 | 27 | func (d *KeaReservationDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = KeaReservationDataSourceSchema() 29 | } 30 | 31 | func (d *KeaReservationDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *KeaReservationDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *KeaReservationResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get kea reservation from OPNsense unbound API 60 | resourceStruct, err := d.client.Kea().GetReservation(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read kea reservation, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertKeaReservationStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read kea reservation, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/kea_subnet_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &KeaSubnetDataSource{} 13 | 14 | func NewKeaSubnetDataSource() datasource.DataSource { 15 | return &KeaSubnetDataSource{} 16 | } 17 | 18 | // KeaSubnetDataSource defines the data source implementation. 19 | type KeaSubnetDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *KeaSubnetDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_kea_subnet" 25 | } 26 | 27 | func (d *KeaSubnetDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = KeaSubnetDataSourceSchema() 29 | } 30 | 31 | func (d *KeaSubnetDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *KeaSubnetDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *KeaSubnetResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get kea subnet from OPNsense unbound API 60 | resourceStruct, err := d.client.Kea().GetSubnet(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read kea subnet, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertKeaSubnetStructToSchema(resourceStruct) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read kea subnet, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/quagga_bgp_aspath_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &QuaggaBGPASPathDataSource{} 13 | 14 | func NewQuaggaBGPASPathDataSource() datasource.DataSource { 15 | return &QuaggaBGPASPathDataSource{} 16 | } 17 | 18 | // QuaggaBGPASPathDataSource defines the data source implementation. 19 | type QuaggaBGPASPathDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *QuaggaBGPASPathDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_quagga_bgp_aspath" 25 | } 26 | 27 | func (d *QuaggaBGPASPathDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = QuaggaBGPASPathDataSourceSchema() 29 | } 30 | 31 | func (d *QuaggaBGPASPathDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *QuaggaBGPASPathDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *QuaggaBGPASPathResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Quagga().GetBGPASPath(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read as path, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertQuaggaBGPASPathStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read as path, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/quagga_bgp_communitylist_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &QuaggaBGPCommunityListDataSource{} 13 | 14 | func NewQuaggaBGPCommunityListDataSource() datasource.DataSource { 15 | return &QuaggaBGPCommunityListDataSource{} 16 | } 17 | 18 | // QuaggaBGPCommunityListDataSource defines the data source implementation. 19 | type QuaggaBGPCommunityListDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *QuaggaBGPCommunityListDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_quagga_bgp_communitylist" 25 | } 26 | 27 | func (d *QuaggaBGPCommunityListDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = QuaggaBGPCommunityListDataSourceSchema() 29 | } 30 | 31 | func (d *QuaggaBGPCommunityListDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *QuaggaBGPCommunityListDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *QuaggaBGPCommunityListResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Quagga().GetBGPCommunityList(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read community list, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertQuaggaBGPCommunityListStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read community list, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/quagga_bgp_neighbor_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &QuaggaBGPNeighborDataSource{} 13 | 14 | func NewQuaggaBGPNeighborDataSource() datasource.DataSource { 15 | return &QuaggaBGPNeighborDataSource{} 16 | } 17 | 18 | // QuaggaBGPNeighborDataSource defines the data source implementation. 19 | type QuaggaBGPNeighborDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *QuaggaBGPNeighborDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_quagga_bgp_neighbor" 25 | } 26 | 27 | func (d *QuaggaBGPNeighborDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = QuaggaBGPNeighborDataSourceSchema() 29 | } 30 | 31 | func (d *QuaggaBGPNeighborDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *QuaggaBGPNeighborDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *QuaggaBGPNeighborResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Quagga().GetBGPNeighbor(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read neighbor, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertQuaggaBGPNeighborStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read neighbor, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/quagga_bgp_prefixlist_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &QuaggaBGPPrefixListDataSource{} 13 | 14 | func NewQuaggaBGPPrefixListDataSource() datasource.DataSource { 15 | return &QuaggaBGPPrefixListDataSource{} 16 | } 17 | 18 | // QuaggaBGPPrefixListDataSource defines the data source implementation. 19 | type QuaggaBGPPrefixListDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *QuaggaBGPPrefixListDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_quagga_bgp_prefixlist" 25 | } 26 | 27 | func (d *QuaggaBGPPrefixListDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = QuaggaBGPPrefixListDataSourceSchema() 29 | } 30 | 31 | func (d *QuaggaBGPPrefixListDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *QuaggaBGPPrefixListDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *QuaggaBGPPrefixListResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Quagga().GetBGPPrefixList(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read prefix list, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertQuaggaBGPPrefixListStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read prefix list, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/quagga_bgp_routemap_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &QuaggaBGPRouteMapDataSource{} 13 | 14 | func NewQuaggaBGPRouteMapDataSource() datasource.DataSource { 15 | return &QuaggaBGPRouteMapDataSource{} 16 | } 17 | 18 | // QuaggaBGPRouteMapDataSource defines the data source implementation. 19 | type QuaggaBGPRouteMapDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *QuaggaBGPRouteMapDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_quagga_bgp_routemap" 25 | } 26 | 27 | func (d *QuaggaBGPRouteMapDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = QuaggaBGPRouteMapDataSourceSchema() 29 | } 30 | 31 | func (d *QuaggaBGPRouteMapDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *QuaggaBGPRouteMapDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *QuaggaBGPRouteMapResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Quagga().GetBGPRouteMap(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read route map, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertQuaggaBGPRouteMapStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read route map, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/route_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &RouteDataSource{} 13 | 14 | func NewRouteDataSource() datasource.DataSource { 15 | return &RouteDataSource{} 16 | } 17 | 18 | // RouteDataSource defines the data source implementation. 19 | type RouteDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *RouteDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_route" 25 | } 26 | 27 | func (d *RouteDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = RouteDataSourceSchema() 29 | } 30 | 31 | func (d *RouteDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *RouteDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *RouteResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Routes().GetRoute(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read route, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertRouteStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read route, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/route_schema.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/browningluke/opnsense-go/pkg/api" 5 | "github.com/browningluke/opnsense-go/pkg/routes" 6 | dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 7 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 8 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" 9 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 10 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 11 | "github.com/hashicorp/terraform-plugin-framework/types" 12 | "terraform-provider-opnsense/internal/tools" 13 | ) 14 | 15 | // RouteResourceModel describes the resource data model. 16 | type RouteResourceModel struct { 17 | Enabled types.Bool `tfsdk:"enabled"` 18 | Description types.String `tfsdk:"description"` 19 | Gateway types.String `tfsdk:"gateway"` 20 | Network types.String `tfsdk:"network"` 21 | 22 | Id types.String `tfsdk:"id"` 23 | } 24 | 25 | func RouteResourceSchema() schema.Schema { 26 | return schema.Schema{ 27 | MarkdownDescription: "Routes can be used to teach your firewall which path it should take when forwarding packets to a specific network.", 28 | 29 | Attributes: map[string]schema.Attribute{ 30 | "enabled": schema.BoolAttribute{ 31 | MarkdownDescription: "Enable this route. Defaults to `true`.", 32 | Optional: true, 33 | Computed: true, 34 | Default: booldefault.StaticBool(true), 35 | }, 36 | "description": schema.StringAttribute{ 37 | MarkdownDescription: "Optional description here for your reference (not parsed).", 38 | Optional: true, 39 | }, 40 | "gateway": schema.StringAttribute{ 41 | MarkdownDescription: "Which gateway this route applies, e.g. `WAN`. Must be an existing gateway.", 42 | Required: true, 43 | }, 44 | "network": schema.StringAttribute{ 45 | MarkdownDescription: "Destination network for this static route.", 46 | Required: true, 47 | }, 48 | "id": schema.StringAttribute{ 49 | Computed: true, 50 | MarkdownDescription: "UUID of the route.", 51 | PlanModifiers: []planmodifier.String{ 52 | stringplanmodifier.UseStateForUnknown(), 53 | }, 54 | }, 55 | }, 56 | } 57 | } 58 | 59 | func RouteDataSourceSchema() dschema.Schema { 60 | return dschema.Schema{ 61 | MarkdownDescription: "Routes can be used to teach your firewall which path it should take when forwarding packets to a specific network.", 62 | 63 | Attributes: map[string]dschema.Attribute{ 64 | "id": dschema.StringAttribute{ 65 | MarkdownDescription: "UUID of the resource.", 66 | Required: true, 67 | }, 68 | "enabled": dschema.BoolAttribute{ 69 | MarkdownDescription: "Whether this route is enabled.", 70 | Computed: true, 71 | }, 72 | "description": dschema.StringAttribute{ 73 | MarkdownDescription: "Optional description here for your reference (not parsed).", 74 | Computed: true, 75 | }, 76 | "gateway": dschema.StringAttribute{ 77 | MarkdownDescription: "Which gateway this route applies, e.g. `WAN`.", 78 | Computed: true, 79 | }, 80 | "network": dschema.StringAttribute{ 81 | MarkdownDescription: "Destination network for this static route.", 82 | Computed: true, 83 | }, 84 | }, 85 | } 86 | } 87 | 88 | func convertRouteSchemaToStruct(d *RouteResourceModel) (*routes.Route, error) { 89 | return &routes.Route{ 90 | Disabled: tools.BoolToString(!d.Enabled.ValueBool()), 91 | Description: d.Description.ValueString(), 92 | Gateway: api.SelectedMap(d.Gateway.ValueString()), 93 | Network: d.Network.ValueString(), 94 | }, nil 95 | } 96 | 97 | func convertRouteStructToSchema(d *routes.Route) (*RouteResourceModel, error) { 98 | return &RouteResourceModel{ 99 | Enabled: types.BoolValue(!tools.StringToBool(d.Disabled)), 100 | Description: tools.StringOrNull(d.Description), 101 | Gateway: types.StringValue(d.Gateway.String()), 102 | Network: types.StringValue(d.Network), 103 | }, nil 104 | } 105 | -------------------------------------------------------------------------------- /internal/service/unbound_domain_override_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &UnboundDomainOverrideDataSource{} 13 | 14 | func NewUnboundDomainOverrideDataSource() datasource.DataSource { 15 | return &UnboundDomainOverrideDataSource{} 16 | } 17 | 18 | // UnboundDomainOverrideDataSource defines the data source implementation. 19 | type UnboundDomainOverrideDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *UnboundDomainOverrideDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_unbound_domain_override" 25 | } 26 | 27 | func (d *UnboundDomainOverrideDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = UnboundDomainOverrideDataSourceSchema() 29 | } 30 | 31 | func (d *UnboundDomainOverrideDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *UnboundDomainOverrideDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *UnboundDomainOverrideResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Unbound().GetDomainOverride(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read domain_override, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertUnboundDomainOverrideStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read domain_override, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/unbound_forward_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &UnboundForwardDataSource{} 13 | 14 | func NewUnboundForwardDataSource() datasource.DataSource { 15 | return &UnboundForwardDataSource{} 16 | } 17 | 18 | // UnboundForwardDataSource defines the data source implementation. 19 | type UnboundForwardDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *UnboundForwardDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_unbound_forward" 25 | } 26 | 27 | func (d *UnboundForwardDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = UnboundForwardDataSourceSchema() 29 | } 30 | 31 | func (d *UnboundForwardDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *UnboundForwardDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *UnboundForwardResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Unbound().GetForward(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read forward, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertUnboundForwardStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read forward, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/unbound_host_alias_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &UnboundHostAliasDataSource{} 13 | 14 | func NewUnboundHostAliasDataSource() datasource.DataSource { 15 | return &UnboundHostAliasDataSource{} 16 | } 17 | 18 | // UnboundHostAliasDataSource defines the data source implementation. 19 | type UnboundHostAliasDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *UnboundHostAliasDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_unbound_host_alias" 25 | } 26 | 27 | func (d *UnboundHostAliasDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = UnboundHostAliasDataSourceSchema() 29 | } 30 | 31 | func (d *UnboundHostAliasDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *UnboundHostAliasDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *UnboundHostAliasResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Unbound().GetHostAlias(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read host_alias, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertUnboundHostAliasStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read host_alias, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/unbound_host_override_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &UnboundHostOverrideDataSource{} 13 | 14 | func NewUnboundHostOverrideDataSource() datasource.DataSource { 15 | return &UnboundHostOverrideDataSource{} 16 | } 17 | 18 | // UnboundHostOverrideDataSource defines the data source implementation. 19 | type UnboundHostOverrideDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *UnboundHostOverrideDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_unbound_host_override" 25 | } 26 | 27 | func (d *UnboundHostOverrideDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = UnboundHostOverrideDataSourceSchema() 29 | } 30 | 31 | func (d *UnboundHostOverrideDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *UnboundHostOverrideDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *UnboundHostOverrideResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Unbound().GetHostOverride(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read host_override, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertUnboundHostOverrideStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read host_override, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/wireguard_client_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &WireguardClientDataSource{} 13 | 14 | func NewWireguardClientDataSource() datasource.DataSource { 15 | return &WireguardClientDataSource{} 16 | } 17 | 18 | // WireguardClientDataSource defines the data source implementation. 19 | type WireguardClientDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *WireguardClientDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_wireguard_client" 25 | } 26 | 27 | func (d *WireguardClientDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = WireguardClientDataSourceSchema() 29 | } 30 | 31 | func (d *WireguardClientDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *WireguardClientDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *WireguardClientResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Wireguard().GetClient(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read wg client, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertWireguardClientStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read wg client, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/service/wireguard_server_data_source.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/browningluke/opnsense-go/pkg/api" 7 | "github.com/browningluke/opnsense-go/pkg/opnsense" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | ) 10 | 11 | // Ensure provider defined types fully satisfy framework interfaces. 12 | var _ datasource.DataSource = &WireguardServerDataSource{} 13 | 14 | func NewWireguardServerDataSource() datasource.DataSource { 15 | return &WireguardServerDataSource{} 16 | } 17 | 18 | // WireguardServerDataSource defines the data source implementation. 19 | type WireguardServerDataSource struct { 20 | client opnsense.Client 21 | } 22 | 23 | func (d *WireguardServerDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 24 | resp.TypeName = req.ProviderTypeName + "_wireguard_server" 25 | } 26 | 27 | func (d *WireguardServerDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 28 | resp.Schema = WireguardServerDataSourceSchema() 29 | } 30 | 31 | func (d *WireguardServerDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 32 | // Prevent panic if the provider has not been configured. 33 | if req.ProviderData == nil { 34 | return 35 | } 36 | 37 | apiClient, ok := req.ProviderData.(*api.Client) 38 | if !ok { 39 | resp.Diagnostics.AddError( 40 | "Unexpected Resource Configure Type", 41 | fmt.Sprintf("Expected *opnsense.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), 42 | ) 43 | return 44 | } 45 | 46 | d.client = opnsense.NewClient(apiClient) 47 | } 48 | 49 | func (d *WireguardServerDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | var data *WireguardServerResourceModel 51 | 52 | // Read Terraform configuration data into the model 53 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 54 | 55 | if resp.Diagnostics.HasError() { 56 | return 57 | } 58 | 59 | // Get resource from OPNsense API 60 | resource, err := d.client.Wireguard().GetServer(ctx, data.Id.ValueString()) 61 | if err != nil { 62 | resp.Diagnostics.AddError("Client Error", 63 | fmt.Sprintf("Unable to read wg server, got error: %s", err)) 64 | return 65 | } 66 | 67 | // Convert OPNsense struct to TF schema 68 | resourceModel, err := convertWireguardServerStructToSchema(resource) 69 | if err != nil { 70 | resp.Diagnostics.AddError("Client Error", 71 | fmt.Sprintf("Unable to read wg server, got error: %s", err)) 72 | return 73 | } 74 | 75 | // ID cannot be added by convert... func, have to add here 76 | resourceModel.Id = data.Id 77 | 78 | // Save updated data into Terraform state 79 | resp.Diagnostics.Append(resp.State.Set(ctx, &resourceModel)...) 80 | } 81 | -------------------------------------------------------------------------------- /internal/tools/type_utils.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hashicorp/terraform-plugin-framework/attr" 7 | "github.com/hashicorp/terraform-plugin-framework/types" 8 | "github.com/hashicorp/terraform-plugin-framework/types/basetypes" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | // Ints 14 | 15 | func Int64ToString(i int64) string { 16 | return fmt.Sprintf("%d", i) 17 | } 18 | 19 | func StringToInt64(s string) int64 { 20 | i, err := strconv.ParseInt(s, 10, 64) 21 | if err == nil { 22 | return i 23 | } 24 | return -1 25 | } 26 | 27 | func StringToInt64Null(s string) types.Int64 { 28 | i, err := strconv.ParseInt(s, 10, 64) 29 | if err == nil { 30 | return types.Int64Value(i) 31 | } 32 | return types.Int64Null() 33 | } 34 | 35 | func Int64ToStringNegative(i int64) string { 36 | s := fmt.Sprintf("%d", i) 37 | if i == -1 { 38 | s = "" 39 | } 40 | return s 41 | } 42 | 43 | // Floats 44 | 45 | func Float64ToString(i float64) string { 46 | return fmt.Sprintf("%f", i) 47 | } 48 | 49 | func Float64ToStringNegative(i float64) string { 50 | s := fmt.Sprintf("%f", i) 51 | if i == -1 { 52 | s = "" 53 | } 54 | return s 55 | } 56 | 57 | func StringToFloat64(s string) float64 { 58 | i, err := strconv.ParseFloat(s, 64) 59 | if err == nil { 60 | return i 61 | } 62 | return -1 63 | } 64 | 65 | // Bools 66 | 67 | func BoolToString(b bool) string { 68 | if b { 69 | return "1" 70 | } else { 71 | return "0" 72 | } 73 | } 74 | 75 | func StringToBool(s string) bool { 76 | return s == "1" 77 | } 78 | 79 | // Strings 80 | 81 | func StringOrNull(s string) types.String { 82 | if s != "" { 83 | return types.StringValue(s) 84 | } else { 85 | return types.StringNull() 86 | } 87 | } 88 | 89 | // Sets 90 | 91 | func EmptySetValue(t attr.Type) types.Set { 92 | sv, _ := types.SetValue(t, []attr.Value{}) 93 | return sv 94 | } 95 | 96 | func StringSliceToSet(s []string) basetypes.SetValue { 97 | var list []attr.Value 98 | for _, i := range s { 99 | // OPNsense API always returns empty string in list of content, skip it. 100 | if i == "" { 101 | continue 102 | } 103 | list = append(list, basetypes.NewStringValue(i)) 104 | } 105 | typeList, _ := types.SetValue(types.StringType, list) 106 | 107 | return typeList 108 | } 109 | 110 | func SetToString(set types.Set, delim string) string { 111 | var strList []string 112 | set.ElementsAs(context.Background(), &strList, false) 113 | return strings.Join(strList, delim) 114 | } 115 | 116 | func SetToStringSlice(set types.Set) []string { 117 | var list []string 118 | set.ElementsAs(context.Background(), &list, false) 119 | return list 120 | } 121 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "github.com/hashicorp/terraform-plugin-framework/providerserver" 7 | "log" 8 | "terraform-provider-opnsense/internal/provider" 9 | ) 10 | 11 | //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs 12 | 13 | var ( 14 | version string = "dev" 15 | ) 16 | 17 | func main() { 18 | var debug bool 19 | 20 | flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve") 21 | flag.Parse() 22 | 23 | opts := providerserver.ServeOpts{ 24 | Address: "registry.terraform.io/browningluke/opnsense", 25 | Debug: debug, 26 | } 27 | 28 | err := providerserver.Serve(context.Background(), provider.New(version), opts) 29 | 30 | if err != nil { 31 | log.Fatal(err.Error()) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /templates/data-sources/firewall_alias.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/firewall_category.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/firewall_filter.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ~> This resource requires the `os-firewall` plugin to be installed. It will *not* behave correctly if it is not installed. 13 | 14 | {{ .SchemaMarkdown | trimspace }} 15 | 16 | {{ if .HasImport -}} 17 | ## Import 18 | 19 | Import is supported using the following syntax: 20 | 21 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 22 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/firewall_nat.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ~> This resource requires the `os-firewall` plugin to be installed. It will *not* behave correctly if it is not installed. 13 | 14 | {{ .SchemaMarkdown | trimspace }} 15 | 16 | {{ if .HasImport -}} 17 | ## Import 18 | 19 | Import is supported using the following syntax: 20 | 21 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 22 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/interface.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Interfaces 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/interface_all.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Interfaces 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/data-sources/" .Name "/data-source.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | {{ if .HasImport -}} 19 | ## Import 20 | 21 | Import is supported using the following syntax: 22 | 23 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 24 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/interfaces_vlan.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Interfaces 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/kea_peer.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Kea 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/kea_reservation.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Kea 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/kea_subnet.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Kea 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/quagga_bgp_aspath.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/quagga_bgp_communitylist.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/quagga_bgp_neighbor.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/quagga_bgp_prefixlist.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/quagga_bgp_routemap.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/route.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Routes 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/unbound_domain_override.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/unbound_forward.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/unbound_host_alias.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/unbound_host_override.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/wireguard_client.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Wireguard 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/data-sources/wireguard_server.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Wireguard 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | {{ .SchemaMarkdown | trimspace }} 13 | 14 | {{ if .HasImport -}} 15 | ## Import 16 | 17 | Import is supported using the following syntax: 18 | 19 | {{ printf "{{codefile \"shell\" %q}}" .ImportFile }} 20 | {{- end }} -------------------------------------------------------------------------------- /templates/index.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "" 3 | page_title: "Provider: OPNsense" 4 | description: |- 5 | The OPNsense provider provides resources to interact with an OPNsense host. 6 | --- 7 | 8 | # OPNsense Provider 9 | 10 | ~> Please note that this provider is under active development, and makes no 11 | guarantee to be stable. For that reason, it is not currently recommended 12 | to use this provider in any production environment. If a feature is missing, 13 | but is documented in the OPNsense API, please raise an issue on the Github repo 14 | to indicate interest. 15 | 16 | The OPNsense provider is used to interact with resources (only) supported by 17 | the OPNsense API. This provider does not, and will not, support resources 18 | not currently supported by the OPNsense API. If required, see if 19 | [dalet-oss/opnsense](https://github.com/dalet-oss/terraform-provider-opnsense) 20 | will support your needs. 21 | 22 | The provider needs to be configured with the proper API credentials before it can be used. 23 | 24 | ## Getting Started 25 | 26 | To generate the API key & secret, follow the 27 | [OPNsense docs](https://docs.opnsense.org/development/how-tos/api.html#creating-keys). 28 | These can then be used to configure the provider. 29 | 30 | ## Example Usage 31 | 32 | {{ tffile "examples/provider/provider.tf" }} 33 | 34 | {{ .SchemaMarkdown | trimspace }} -------------------------------------------------------------------------------- /templates/resources/firewall_alias.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/firewall_category.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/firewall_filter.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ~> This resource requires the `os-firewall` plugin to be installed. It will *not* behave correctly if it is not installed. 13 | 14 | ## Example Usage 15 | 16 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 17 | 18 | {{ .SchemaMarkdown | trimspace }} 19 | 20 | ## Import 21 | 22 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 23 | 24 | ```terraform 25 | import { 26 | to = {{.Name}}.example 27 | id = "" 28 | } 29 | ``` 30 | 31 | Using `terraform import`, import {{.Name}} using the `id`. For example: 32 | 33 | ```console 34 | % terraform import {{.Name}}.example 35 | ``` -------------------------------------------------------------------------------- /templates/resources/firewall_nat.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Firewall 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ~> This resource requires the `os-firewall` plugin to be installed. It will *not* behave correctly if it is not installed. 13 | 14 | ## Example Usage 15 | 16 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 17 | 18 | {{ .SchemaMarkdown | trimspace }} 19 | 20 | ## Import 21 | 22 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 23 | 24 | ```terraform 25 | import { 26 | to = {{.Name}}.example 27 | id = "" 28 | } 29 | ``` 30 | 31 | Using `terraform import`, import {{.Name}} using the `id`. For example: 32 | 33 | ```console 34 | % terraform import {{.Name}}.example 35 | ``` -------------------------------------------------------------------------------- /templates/resources/interfaces_vlan.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Interfaces 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/kea_peer.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Kea 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/kea_reservation.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Kea 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/kea_subnet.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Kea 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/quagga_bgp_aspath.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/quagga_bgp_communitylist.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/quagga_bgp_neighbor.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/quagga_bgp_prefixlist.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/quagga_bgp_routemap.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Quagga 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/route.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Routes 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/unbound_domain_override.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/unbound_forward.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/unbound_host_alias.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/unbound_host_override.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Unbound 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/wireguard_client.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Wireguard 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /templates/resources/wireguard_server.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" 3 | subcategory: Wireguard 4 | description: |- 5 | {{ .Description | plainmarkdown | trimspace | prefixlines " " }} 6 | --- 7 | 8 | # {{.Name}} ({{.Type}}) 9 | 10 | {{ .Description | trimspace }} 11 | 12 | ## Example Usage 13 | 14 | {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} 15 | 16 | {{ .SchemaMarkdown | trimspace }} 17 | 18 | ## Import 19 | 20 | In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import {{.Name}} using the `id`. For example: 21 | 22 | ```terraform 23 | import { 24 | to = {{.Name}}.example 25 | id = "" 26 | } 27 | ``` 28 | 29 | Using `terraform import`, import {{.Name}} using the `id`. For example: 30 | 31 | ```console 32 | % terraform import {{.Name}}.example 33 | ``` -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["6.0"] 5 | } 6 | } -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package tools 4 | 5 | import ( 6 | // Documentation generation 7 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" 8 | ) 9 | --------------------------------------------------------------------------------