From 97c4ff1c15474a94f4c5c7b76e0dad944b15b0a7 Mon Sep 17 00:00:00 2001 From: dn Date: Mon, 17 Jun 2024 14:57:40 +0200 Subject: [PATCH 1/3] added ipv6 filter data entry Signed-off-by: dn --- ..._firewall.go => datasource_ip_firewall.go} | 23 +- ...go => datasource_ip_firewall_addr_list.go} | 2 +- ...er.go => datasource_ip_firewall_filter.go} | 2 +- ...le.go => datasource_ip_firewall_mangle.go} | 2 +- ...l_nat.go => datasource_ip_firewall_nat.go} | 2 +- ...test.go => datasource_ip_firewall_test.go} | 10 +- routeros/datasource_ipv6_firewall.go | 76 ++++++ routeros/datasource_ipv6_firewall_filter.go | 248 ++++++++++++++++++ routeros/provider.go | 6 +- 9 files changed, 350 insertions(+), 21 deletions(-) rename routeros/{datasource_firewall.go => datasource_ip_firewall.go} (73%) rename routeros/{datasource_firewall_addr_list.go => datasource_ip_firewall_addr_list.go} (94%) rename routeros/{datasource_firewall_filter.go => datasource_ip_firewall_filter.go} (99%) rename routeros/{datasource_firewall_mangle.go => datasource_ip_firewall_mangle.go} (99%) rename routeros/{datasource_firewall_nat.go => datasource_ip_firewall_nat.go} (99%) rename routeros/{datasource_firewall_test.go => datasource_ip_firewall_test.go} (67%) create mode 100644 routeros/datasource_ipv6_firewall.go create mode 100644 routeros/datasource_ipv6_firewall_filter.go diff --git a/routeros/datasource_firewall.go b/routeros/datasource_ip_firewall.go similarity index 73% rename from routeros/datasource_firewall.go rename to routeros/datasource_ip_firewall.go index 850b3119..3fc4a04b 100644 --- a/routeros/datasource_firewall.go +++ b/routeros/datasource_ip_firewall.go @@ -2,15 +2,16 @@ package routeros import ( "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -var firewallSections = []string{"address_list", "nat", "mangle", "rules"} +var ipfirewallSections = []string{"address_list", "nat", "mangle", "rules"} -func DatasourceFirewall() *schema.Resource { +func DatasourceIPFirewall() *schema.Resource { return &schema.Resource{ - ReadContext: datasourceFirewallFilterRead, + ReadContext: datasourceIPFirewallFilterRead, Description: `This datasource contains all supported firewall resources: - address_list - nat @@ -18,22 +19,22 @@ func DatasourceFirewall() *schema.Resource { - rules (aka filter) `, Schema: map[string]*schema.Schema{ - "address_list": getFirewallAddrListSchema(), - "mangle": getFirewallMangleSchema(), - "nat": getFirewallNatSchema(), - "rules": getFirewallFilterSchema(), + "address_list": getIPFirewallAddrListSchema(), + "mangle": getIPFirewallMangleSchema(), + "nat": getIPFirewallNatSchema(), + "rules": getIPFirewallFilterSchema(), }, } } -func datasourceFirewallFilterRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func datasourceIPFirewallFilterRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics basePath := "/ip/firewall/" - s := DatasourceFirewall().Schema + s := DatasourceIPFirewall().Schema var isEmpty = true - for _, section := range firewallSections { + for _, section := range ipfirewallSections { isEmpty = isEmpty && len(d.Get(section).([]interface{})) == 0 } @@ -48,7 +49,7 @@ func datasourceFirewallFilterRead(ctx context.Context, d *schema.ResourceData, m } } - for _, section := range firewallSections { + for _, section := range ipfirewallSections { if len(d.Get(section).([]interface{})) == 0 { continue } diff --git a/routeros/datasource_firewall_addr_list.go b/routeros/datasource_ip_firewall_addr_list.go similarity index 94% rename from routeros/datasource_firewall_addr_list.go rename to routeros/datasource_ip_firewall_addr_list.go index 0c96ea89..a1d6fe0c 100644 --- a/routeros/datasource_firewall_addr_list.go +++ b/routeros/datasource_ip_firewall_addr_list.go @@ -2,7 +2,7 @@ package routeros import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -func getFirewallAddrListSchema() *schema.Schema { +func getIPFirewallAddrListSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Computed: true, diff --git a/routeros/datasource_firewall_filter.go b/routeros/datasource_ip_firewall_filter.go similarity index 99% rename from routeros/datasource_firewall_filter.go rename to routeros/datasource_ip_firewall_filter.go index 3efd4bc6..04ce20e2 100644 --- a/routeros/datasource_firewall_filter.go +++ b/routeros/datasource_ip_firewall_filter.go @@ -2,7 +2,7 @@ package routeros import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -func getFirewallFilterSchema() *schema.Schema { +func getIPFirewallFilterSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Computed: true, diff --git a/routeros/datasource_firewall_mangle.go b/routeros/datasource_ip_firewall_mangle.go similarity index 99% rename from routeros/datasource_firewall_mangle.go rename to routeros/datasource_ip_firewall_mangle.go index 210b0e59..2df36f4b 100644 --- a/routeros/datasource_firewall_mangle.go +++ b/routeros/datasource_ip_firewall_mangle.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func getFirewallMangleSchema() *schema.Schema { +func getIPFirewallMangleSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Computed: true, diff --git a/routeros/datasource_firewall_nat.go b/routeros/datasource_ip_firewall_nat.go similarity index 99% rename from routeros/datasource_firewall_nat.go rename to routeros/datasource_ip_firewall_nat.go index 3a799127..7dd0ae93 100644 --- a/routeros/datasource_firewall_nat.go +++ b/routeros/datasource_ip_firewall_nat.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func getFirewallNatSchema() *schema.Schema { +func getIPFirewallNatSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Computed: true, diff --git a/routeros/datasource_firewall_test.go b/routeros/datasource_ip_firewall_test.go similarity index 67% rename from routeros/datasource_firewall_test.go rename to routeros/datasource_ip_firewall_test.go index 539bff8a..3cd56dca 100644 --- a/routeros/datasource_firewall_test.go +++ b/routeros/datasource_ip_firewall_test.go @@ -6,9 +6,9 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) -const testDatasourceFirewall = "data.routeros_firewall.fw" +const testDatasourceIpFirewall = "data.routeros_ip_firewall.fw" -func TestAccDatasourceFirewallTest_basic(t *testing.T) { +func TestAccDatasourceIpFirewallTest_basic(t *testing.T) { for _, name := range testNames { t.Run(name, func(t *testing.T) { resource.Test(t, resource.TestCase{ @@ -19,9 +19,9 @@ func TestAccDatasourceFirewallTest_basic(t *testing.T) { ProviderFactories: testAccProviderFactories, Steps: []resource.TestStep{ { - Config: testAccDatasourceFirewallConfig(), + Config: testAccDatasourceIpFirewallConfig(), Check: resource.ComposeTestCheckFunc( - testResourcePrimaryInstanceId(testDatasourceFirewall), + testResourcePrimaryInstanceId(testDatasourceIpFirewall), ), }, }, @@ -31,7 +31,7 @@ func TestAccDatasourceFirewallTest_basic(t *testing.T) { } } -func testAccDatasourceFirewallConfig() string { +func testAccDatasourceIpFirewallConfig() string { return providerConfig + ` data "routeros_firewall" "fw" { address_list {} diff --git a/routeros/datasource_ipv6_firewall.go b/routeros/datasource_ipv6_firewall.go new file mode 100644 index 00000000..f1c9d107 --- /dev/null +++ b/routeros/datasource_ipv6_firewall.go @@ -0,0 +1,76 @@ +package routeros + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ipv6firewallSections = []string{"rules"} + +func DatasourceIPv6Firewall() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceIPv6FirewallFilterRead, + Description: `This datasource contains all supported firewall resources: +- rules (aka filter) +`, + Schema: map[string]*schema.Schema{ + "rules": getIPv6FirewallFilterSchema(), + }, + } +} + +func datasourceIPv6FirewallFilterRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + var diags diag.Diagnostics + basePath := "/ipv6/firewall/" + + s := DatasourceIPv6Firewall().Schema + + var isEmpty = true + for _, section := range ipv6firewallSections { + isEmpty = isEmpty && len(d.Get(section).([]interface{})) == 0 + } + + if isEmpty { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "You must specify at least one return section of the resource.", + Detail: "Please specify one or more sections of the firewall, information from which will be " + + "returned as a result of the data source query: rules{}, nat { filter = {...}}, etc.", + }, + } + } + + for _, section := range ipv6firewallSections { + if len(d.Get(section).([]interface{})) == 0 { + continue + } + + path := basePath + // The filtering section is named 'rules' to avoid confusion: filter { filter = { ... }}. + if section == "rules" { + path += "filter" + } else { + // Kebab case! + path += SnakeToKebab(section) + } + + // Snake case! + var res []MikrotikItem + + for _, sectionResourceData := range d.Get(section).([]interface{}) { + filter := sectionResourceData.(map[string]interface{})[KeyFilter].(map[string]interface{}) + + r, err := ReadItemsFiltered(buildReadFilter(filter), path, m.(Client)) + if err != nil { + return diag.FromErr(err) + } + + res = append(res, *r...) + } + diags = append(diags, MikrotikResourceDataToTerraformDatasource(&res, section, s, d)...) + } + return diags +} diff --git a/routeros/datasource_ipv6_firewall_filter.go b/routeros/datasource_ipv6_firewall_filter.go new file mode 100644 index 00000000..5af3f6c6 --- /dev/null +++ b/routeros/datasource_ipv6_firewall_filter.go @@ -0,0 +1,248 @@ +package routeros + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +func getIPv6FirewallFilterSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + KeyFilter: PropFilterRw, + "id": { + Type: schema.TypeString, + Computed: true, + }, + "action": { + Type: schema.TypeString, + Computed: true, + }, + "bytes": { + Type: schema.TypeInt, + Computed: true, + }, + "chain": { + Type: schema.TypeString, + Computed: true, + }, + KeyComment: { + Type: schema.TypeString, + Computed: true, + }, + "connection_bytes": { + Type: schema.TypeString, + Computed: true, + }, + "connection_limit": { + Type: schema.TypeString, + Computed: true, + }, + "connection_mark": { + Type: schema.TypeString, + Computed: true, + }, + "connection_nat_state": { + Type: schema.TypeString, + Computed: true, + }, + "connection_rate": { + Type: schema.TypeString, + Computed: true, + }, + "connection_state": { + Type: schema.TypeString, + Computed: true, + }, + "connection_type": { + Type: schema.TypeString, + Computed: true, + }, + "content": { + Type: schema.TypeString, + Computed: true, + }, + KeyDisabled: { + Type: schema.TypeBool, + Computed: true, + }, + "dscp": { + Type: schema.TypeInt, + Computed: true, + }, + "dst_address": { + Type: schema.TypeString, + Computed: true, + }, + "dst_address_list": { + Type: schema.TypeString, + Computed: true, + }, + "dst_address_type": { + Type: schema.TypeString, + Computed: true, + }, + "dst_limit": { + Type: schema.TypeString, + Computed: true, + }, + "dst_port": { + Type: schema.TypeString, + Computed: true, + }, + KeyDynamic: { + Type: schema.TypeBool, + Computed: true, + }, + "icmp_options": { + Type: schema.TypeString, + Computed: true, + }, + "in_bridge_port": { + Type: schema.TypeString, + Computed: true, + }, + "in_bridge_port_list": { + Type: schema.TypeString, + Computed: true, + }, + "in_interface": { + Type: schema.TypeString, + Computed: true, + }, + "in_interface_list": { + Type: schema.TypeString, + Computed: true, + }, + "ingress_priority": { + Type: schema.TypeInt, + Computed: true, + }, + "invalid": { + Type: schema.TypeBool, + Computed: true, + }, + "ipsec_policy": { + Type: schema.TypeString, + Computed: true, + }, + "limit": { + Type: schema.TypeString, + Computed: true, + }, + "log": { + Type: schema.TypeBool, + Computed: true, + }, + "log_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "nth": { + Type: schema.TypeString, + Computed: true, + }, + "out_bridge_port": { + Type: schema.TypeString, + Computed: true, + }, + "out_bridge_port_list": { + Type: schema.TypeString, + Computed: true, + }, + "out_interface": { + Type: schema.TypeString, + Computed: true, + }, + "out_interface_list": { + Type: schema.TypeString, + Computed: true, + }, + "packets": { + Type: schema.TypeInt, + Computed: true, + }, + "packet_mark": { + Type: schema.TypeString, + Computed: true, + }, + "packet_size": { + Type: schema.TypeString, + Computed: true, + }, + "per_connection_classifier": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeString, + Computed: true, + }, + "priority": { + Type: schema.TypeInt, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "random": { + Type: schema.TypeInt, + Computed: true, + }, + "reject_with": { + Type: schema.TypeString, + Computed: true, + }, + "routing_table": { + Type: schema.TypeString, + Computed: true, + }, + "routing_mark": { + Type: schema.TypeString, + Computed: true, + }, + "src_address": { + Type: schema.TypeString, + Computed: true, + }, + "src_address_list": { + Type: schema.TypeString, + Computed: true, + }, + "src_address_type": { + Type: schema.TypeString, + Computed: true, + }, + "src_port": { + Type: schema.TypeString, + Computed: true, + }, + "src_mac_address": { + Type: schema.TypeString, + Computed: true, + }, + "tcp_flags": { + Type: schema.TypeString, + Computed: true, + }, + "tcp_mss": { + Type: schema.TypeString, + Computed: true, + }, + "time": { + Type: schema.TypeString, + Computed: true, + }, + "tls_host": { + Type: schema.TypeString, + Computed: true, + }, + "ttl": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + } +} diff --git a/routeros/provider.go b/routeros/provider.go index b10e7b4e..896bde55 100644 --- a/routeros/provider.go +++ b/routeros/provider.go @@ -285,16 +285,20 @@ func Provider() *schema.Provider { }, DataSourcesMap: map[string]*schema.Resource{ "routeros_files": DatasourceFiles(), - "routeros_firewall": DatasourceFirewall(), "routeros_interfaces": DatasourceInterfaces(), "routeros_ip_addresses": DatasourceIPAddresses(), "routeros_ip_arp": DatasourceIpArp(), "routeros_ip_dhcp_server_leases": DatasourceIpDhcpServerLeases(), + "routeros_ip_firewall": DatasourceIPFirewall(), "routeros_ip_routes": DatasourceIPRoutes(), "routeros_ip_services": DatasourceIPServices(), "routeros_ipv6_addresses": DatasourceIPv6Addresses(), + "routeros_ipv6_firewall": DatasourceIPv6Firewall(), "routeros_system_resource": DatasourceSystemResource(), "routeros_x509": DatasourceX509(), + + // Aliases for entries that have been renamed + "routeros_firewall": DatasourceIPFirewall(), }, ConfigureContextFunc: NewClient, } From 85707d2d9af167b2599f1bc2f8c83a80a9e953d6 Mon Sep 17 00:00:00 2001 From: dn Date: Tue, 18 Jun 2024 11:09:33 +0200 Subject: [PATCH 2/3] fixed test Signed-off-by: dn --- routeros/datasource_ip_firewall_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routeros/datasource_ip_firewall_test.go b/routeros/datasource_ip_firewall_test.go index 3cd56dca..28a934a9 100644 --- a/routeros/datasource_ip_firewall_test.go +++ b/routeros/datasource_ip_firewall_test.go @@ -33,7 +33,7 @@ func TestAccDatasourceIpFirewallTest_basic(t *testing.T) { func testAccDatasourceIpFirewallConfig() string { return providerConfig + ` -data "routeros_firewall" "fw" { +data "routeros_ip_firewall" "fw" { address_list {} mangle {} nat {} From cb5ad50907d624fb1b2bad0d8558a8088d1d01fd Mon Sep 17 00:00:00 2001 From: Vaerh Date: Thu, 27 Jun 2024 23:12:35 +0300 Subject: [PATCH 3/3] docs: Small changes for the current PR --- .../routeros_firewall/data-source.tf | 32 ------------------- .../routeros_ip_firewall/data-source.tf | 32 +++++++++++++++++++ routeros/datasource_ip_firewall.go | 6 ++-- templates/data-sources/firewall.md.tmpl | 5 +++ 4 files changed, 40 insertions(+), 35 deletions(-) delete mode 100644 examples/data-sources/routeros_firewall/data-source.tf create mode 100644 examples/data-sources/routeros_ip_firewall/data-source.tf create mode 100644 templates/data-sources/firewall.md.tmpl diff --git a/examples/data-sources/routeros_firewall/data-source.tf b/examples/data-sources/routeros_firewall/data-source.tf deleted file mode 100644 index f6aaba79..00000000 --- a/examples/data-sources/routeros_firewall/data-source.tf +++ /dev/null @@ -1,32 +0,0 @@ -data "routeros_firewall" "fw" { - rules { - filter = { - chain = "input" - comment = "rule_2" - } - } - - rules { - filter = { - chain = "forward" - } - } - - nat {} -} - -output "rules" { - value = [for value in data.routeros_firewall.fw.rules: [value.id, value.src_address]] -} - -output "nat" { - value = [for value in data.routeros_firewall.fw.nat: [value.id, value.comment]] -} - -resource "routeros_firewall" "rule_3" { - action = "accept" - chain = "input" - comment = "rule_3" - src_address = "192.168.0.5" - place_before = "${data.routeros_firewall_filter.fw.rules[0].id}" -} diff --git a/examples/data-sources/routeros_ip_firewall/data-source.tf b/examples/data-sources/routeros_ip_firewall/data-source.tf new file mode 100644 index 00000000..714a7bbf --- /dev/null +++ b/examples/data-sources/routeros_ip_firewall/data-source.tf @@ -0,0 +1,32 @@ +data "routeros_ip_firewall" "fw" { + rules { + filter = { + chain = "input" + comment = "rule_2" + } + } + + rules { + filter = { + chain = "forward" + } + } + + nat {} +} + +output "rules" { + value = [for value in data.routeros_ip_firewall.fw.rules: [value.id, value.src_address]] +} + +output "nat" { + value = [for value in data.routeros_ip_firewall.fw.nat: [value.id, value.comment]] +} + +resource "routeros_ip_firewall" "rule_3" { + action = "accept" + chain = "input" + comment = "rule_3" + src_address = "192.168.0.5" + place_before = "${data.routeros_ip_firewall_filter.fw.rules[0].id}" +} diff --git a/routeros/datasource_ip_firewall.go b/routeros/datasource_ip_firewall.go index 3fc4a04b..d0d081a6 100644 --- a/routeros/datasource_ip_firewall.go +++ b/routeros/datasource_ip_firewall.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -var ipfirewallSections = []string{"address_list", "nat", "mangle", "rules"} +var ipFirewallSections = []string{"address_list", "nat", "mangle", "rules"} func DatasourceIPFirewall() *schema.Resource { return &schema.Resource{ @@ -34,7 +34,7 @@ func datasourceIPFirewallFilterRead(ctx context.Context, d *schema.ResourceData, s := DatasourceIPFirewall().Schema var isEmpty = true - for _, section := range ipfirewallSections { + for _, section := range ipFirewallSections { isEmpty = isEmpty && len(d.Get(section).([]interface{})) == 0 } @@ -49,7 +49,7 @@ func datasourceIPFirewallFilterRead(ctx context.Context, d *schema.ResourceData, } } - for _, section := range ipfirewallSections { + for _, section := range ipFirewallSections { if len(d.Get(section).([]interface{})) == 0 { continue } diff --git a/templates/data-sources/firewall.md.tmpl b/templates/data-sources/firewall.md.tmpl new file mode 100644 index 00000000..7f8d0822 --- /dev/null +++ b/templates/data-sources/firewall.md.tmpl @@ -0,0 +1,5 @@ +# {{.Name}} ({{.Type}}) +--- + +#### This is an alias for backwards compatibility between plugin versions. +Please see documentation for [routeros_ip_firewall](ip_firewall.md)