Skip to content

Commit

Permalink
Added interface bonding
Browse files Browse the repository at this point in the history
  • Loading branch information
mrhamburg committed Jun 13, 2023
1 parent 01972ef commit 78b05a2
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 0 deletions.
4 changes: 4 additions & 0 deletions examples/resources/routeros_interface_bonding/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "routeros_interface_bonding" "test_bonding" {
name = "test_bonding"
slaves = "ether1"
}
8 changes: 8 additions & 0 deletions examples/resources/routeros_routing_ospf_area/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
resource "routeros_routing_ospf_instance" "test_routing_ospf_instance" {
name = "test_routing_ospf_instance"
}

resource "routeros_routing_ospf_area" "test_routing_ospf_area" {
name = "test_routing_ospf_area"
instance = routeros_routing_ospf_instance.test_routing_ospf_instance.name
}
3 changes: 3 additions & 0 deletions examples/resources/routeros_routing_ospf_instance/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "routeros_routing_ospf_instance" "test_routing_ospf_instance" {
name = "test_routing_ospf_instance"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "routeros_routing_ospf_instance" "test_routing_ospf_instance" {
name = "test_routing_ospf_instance"
}

resource "routeros_routing_ospf_area" "test_routing_ospf_area" {
name = "test_routing_ospf_area"
instance = routeros_routing_ospf_instance.test_routing_ospf_instance.name
}

resource "routeros_routing_ospf_interface_template" "test_routing_ospf_interface_template" {
area = routeros_routing_ospf_area.test_routing_ospf_area.name
}
1 change: 1 addition & 0 deletions routeros/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func Provider() *schema.Provider {
"routeros_interface_list": ResourceInterfaceList(),
"routeros_interface_list_member": ResourceInterfaceListMember(),
"routeros_interface_ovpn_server": ResourceInterfaceOpenVPNServer(),
"routeros_interface_bonding": ResourceInterfaceBonding(),

// Aliases for interface objects to retain compatibility between original and fork
"routeros_bridge": ResourceInterfaceBridge(),
Expand Down
137 changes: 137 additions & 0 deletions routeros/resource_interface_bonding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package routeros

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

// ResourceInterfaceBonding https://wiki.mikrotik.com/wiki/Manual:Interface/Bonding
func ResourceInterfaceBonding() *schema.Resource {
resSchema := map[string]*schema.Schema{
MetaResourcePath: PropResourcePath("/interface/bonding"),
MetaId: PropId(Name),

KeyComment: PropCommentRw,
KeyDisabled: PropDisabledRw,
KeyName: PropNameForceNewRw,
KeyArp: PropArpRw,
"mtu": {
Type: schema.TypeString,
Default: "1500",
Optional: true,
Description: "Maximum Transmit Unit in bytes. Must be smaller or equal to the smallest L2MTU value of a bonding slave.",
},
"arp_interval": {
Type: schema.TypeString,
Optional: true,
// Default: "100ms",
Computed: true,
Description: "Time in milliseconds which defines how often to monitor ARP requests",
DiffSuppressFunc: TimeEquall,
},
"arp_ip_targets": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "IP target address which will be monitored if link-monitoring is set to " +
"arp. You can specify multiple IP addresses.",
},
"down_delay": {
Type: schema.TypeString,
Optional: true,
// Default: "0s",
Computed: true,
Description: "If a link failure has been detected, bonding interface is disabled for " +
"down-delay time. Value should be a multiple of mii-interval, otherwise it will be rounded down to the nearest value.",
DiffSuppressFunc: TimeEquall,
},
"forced_mac_address": {
Type: schema.TypeString,
Optional: true,
Description: "By default, bonding interface will use MAC address of the first selected slave interface. " +
"This property allows to configure static MAC address for the bond interface.",
},
"lacp_rate": {
Type: schema.TypeString,
Optional: true,
// Default: "2m5s",
Computed: true,
Description: "Link Aggregation Control Protocol rate specifies how often to exchange with LACPDUs between bonding peer. " +
"Used to determine whether link is up or other changes have occurred in the network. LACP tries to adapt to these changes providing failover.",
DiffSuppressFunc: TimeEquall,
},
"link_monitoring": {
Type: schema.TypeString,
Default: "mii",
Optional: true,
Description: "Method to use for monitoring the link (whether it is up or down)",
ValidateFunc: validation.StringInSlice([]string{"arp", "mii", "none"}, true),
},
"min_links": {
Type: schema.TypeInt,
//Default: 0,
Optional: true,
Description: "How many active slave links needed for bonding to become active",
ValidateFunc: validation.IntBetween(0, 4294967295),
},
"mii_interval": {
Type: schema.TypeString,
Optional: true,
// Default: "100ms",
Computed: true,
Description: "How often to monitor the link for failures (parameter used only if link-monitoring is mii)",
DiffSuppressFunc: TimeEquall,
},
"mode": {
Type: schema.TypeString,
Default: "balance-rr",
Optional: true,
Description: "Specifies one of the bonding policies",
ValidateFunc: validation.StringInSlice([]string{"802.3ad", "active-backup", "balance-alb",
"balance-rr", "balance-tlb", "balance-xor", "broadcast"}, true),
},
"primary": {
Type: schema.TypeString,
Optional: true,
Default: "none",
Description: "Controls the primary interface between active slave ports, works only for active-backup, balance-tlb and balance-alb modes.",
},
"slaves": {
Type: schema.TypeString,
Required: true,
//Default: "none",
Description: "At least two ethernet-like interfaces separated by a comma, which will be used for bonding",
},
"up_delay": {
Type: schema.TypeString,
Optional: true,
// Default: "0s",
Computed: true,
Description: "If a link has been brought up, bonding interface is disabled for up-delay time and after this " +
"time it is enabled. Value should be a multiple of mii-interval, otherwise it will be rounded down to the nearest value.",
DiffSuppressFunc: TimeEquall,
},
"transmit_hash_policy": {
Type: schema.TypeString,
Optional: true,
Default: "layer-2",
Description: "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes",
ValidateFunc: validation.StringInSlice([]string{"layer-2", "layer-2-and-3", "layer-3-and-4"}, true),
},
}

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

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

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

import (
"fmt"
"testing"

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

const testInterfaceBondingInstance = "routeros_interface_bonding.test_bonding"

func TestAccInterfaceBondingTest_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("/interface/bonding", "routeros_interface_bonding"),
Steps: []resource.TestStep{
{
Config: testAccInterfaceBondingConfig(),
Check: resource.ComposeTestCheckFunc(
testAccCheckInterfaceBondingExists(testInterfaceBondingInstance),
resource.TestCheckResourceAttr(testInterfaceBondingInstance, "name", "test_bonding"),
),
},
},
})

})
}
}

func testAccCheckInterfaceBondingExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("not found: %s", name)
}

if rs.Primary.ID == "" {
return fmt.Errorf("no id is set")
}

return nil
}
}

func testAccInterfaceBondingConfig() string {
return `
provider "routeros" {
insecure = true
}
resource "routeros_interface_bonding" "test_bonding" {
name = "test_bonding"
slaves = "ether1"
}
`
}

0 comments on commit 78b05a2

Please sign in to comment.