Skip to content

Commit

Permalink
feat(routing): Manage Route Filters
Browse files Browse the repository at this point in the history
Fixes #330
  • Loading branch information
vaerh committed Jan 12, 2024
1 parent 1434d3a commit 0c29e53
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 16 deletions.
48 changes: 32 additions & 16 deletions routeros/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ func Provider() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"hosturl": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ROS_HOSTURL", "MIKROTIK_HOST"}, nil),
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc(
[]string{"ROS_HOSTURL", "MIKROTIK_HOST"},
nil,
),
Description: `URL of the MikroTik router, default is TLS connection to REST.
* API: api[s]://host[:port]
* api://router.local
Expand All @@ -32,32 +35,44 @@ func Provider() *schema.Provider {
`,
},
"username": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ROS_USERNAME", "MIKROTIK_USER"}, nil),
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc(
[]string{"ROS_USERNAME", "MIKROTIK_USER"},
nil,
),
Description: `Username for the MikroTik WEB/Winbox.
export ROS_USERNAME=admin or export MIKROTIK_USER=admin
`,
},
"password": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ROS_PASSWORD", "MIKROTIK_PASSWORD"}, nil),
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc(
[]string{"ROS_PASSWORD", "MIKROTIK_PASSWORD"},
nil,
),
Description: "Password for the MikroTik user.",
Sensitive: true,
},
"ca_certificate": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ROS_CA_CERTIFICATE", "MIKROTIK_CA_CERTIFICATE"}, nil),
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc(
[]string{"ROS_CA_CERTIFICATE", "MIKROTIK_CA_CERTIFICATE"},
nil,
),
Description: "Path to MikroTik's certificate authority file.",
},
"insecure": {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ROS_INSECURE", "MIKROTIK_INSECURE"}, false),
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc(
[]string{"ROS_INSECURE", "MIKROTIK_INSECURE"},
false,
),
Description: "Whether to verify the SSL certificate or not.",
},
},
Expand Down Expand Up @@ -166,9 +181,10 @@ func Provider() *schema.Provider {
"routeros_capsman_security": ResourceCapsManSecurity(),

// Routing
"routeros_routing_table": ResourceRoutingTable(),
"routeros_routing_bgp_connection": ResourceRoutingBGPConnection(),
"routeros_routing_bgp_template": ResourceRoutingBGPTemplate(),
"routeros_routing_filter_rule": ResourceRoutingFilterRule(),
"routeros_routing_table": ResourceRoutingTable(),

// OSPF
"routeros_routing_ospf_instance": ResourceRoutingOspfInstance(),
Expand Down
51 changes: 51 additions & 0 deletions routeros/resource_routing_filter_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package routeros

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

/*
{
".id": "*2",
"chain": "123",
"comment": "test",
"disabled": "true",
"inactive": "true",
"rule": "if (active) {accept}"
}
*/

// https://help.mikrotik.com/docs/display/ROS/Route+Selection+and+Filters
func ResourceRoutingFilterRule() *schema.Resource {
resSchema := map[string]*schema.Schema{
MetaResourcePath: PropResourcePath("/routing/filter/rule"),
MetaId: PropId(Id),

"chain": {
Type: schema.TypeString,
Required: true,
Description: "Chain name.",
},
KeyComment: PropCommentRw,
KeyDisabled: PropDisabledRw,
KeyInactive: PropInactiveRo,
"rule": {
Type: schema.TypeString,
Required: true,
Description: "Filter rule.",
},
}

return &schema.Resource{
CreateContext: DefaultCreate(resSchema),
ReadContext: DefaultRead(resSchema),
UpdateContext: DefaultUpdate(resSchema),
DeleteContext: DefaultDelete(resSchema),

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: resSchema,
}
}
48 changes: 48 additions & 0 deletions routeros/resource_routing_filter_rule_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package routeros

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

const testRoutingFilterRule = "routeros_routing_filter_rule.test"

func TestAccRoutingFilterRuleTest_basic(t *testing.T) {
for _, name := range testNames {
t.Run(name, func(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testSetTransportEnv(t, name)
},
ProviderFactories: testAccProviderFactories,
CheckDestroy: testCheckResourceDestroy("/routing/filter/rule", "routeros_routing_filter_rule"),
Steps: []resource.TestStep{
{
Config: testAccRoutingFilterRuleConfig(),
Check: resource.ComposeTestCheckFunc(
testResourcePrimaryInstanceId(testRoutingFilterRule),
resource.TestCheckResourceAttr(testRoutingFilterRule, "chain", "testChain"),
resource.TestCheckResourceAttr(testRoutingFilterRule, "rule", "if (dst in 192.168.1.0/24 && dst-len>24) {set distance +1; accept} else {set distance -1; accept}"),
resource.TestCheckResourceAttr(testRoutingFilterRule, "comment", "comment"),
resource.TestCheckResourceAttr(testRoutingFilterRule, "disabled", "true"),
),
},
},
})

})
}
}

func testAccRoutingFilterRuleConfig() string {
return providerConfig + `
resource "routeros_routing_filter_rule" "test" {
chain = "testChain"
rule = "if (dst in 192.168.1.0/24 && dst-len>24) {set distance +1; accept} else {set distance -1; accept}"
comment = "comment"
disabled = true
}
`
}

0 comments on commit 0c29e53

Please sign in to comment.