diff --git a/routeros/mikrotik_serialize.go b/routeros/mikrotik_serialize.go index 78594750..f65ca176 100644 --- a/routeros/mikrotik_serialize.go +++ b/routeros/mikrotik_serialize.go @@ -60,9 +60,9 @@ func isEmpty(propName string, schemaProp *schema.Schema, d *schema.ResourceData, } return confValue.IsNull() case schema.TypeList: - return len(v.([]interface{})) == 0 + return len(v.([]interface{})) == 0 && confValue.IsNull() case schema.TypeSet: - return v.(*schema.Set).Len() == 0 + return v.(*schema.Set).Len() == 0 && confValue.IsNull() case schema.TypeMap: return len(v.(map[string]interface{})) == 0 default: diff --git a/routeros/provider.go b/routeros/provider.go index 2126efef..4bf98cde 100644 --- a/routeros/provider.go +++ b/routeros/provider.go @@ -98,6 +98,7 @@ func Provider() *schema.Provider { "routeros_ip_dns": ResourceDns(), "routeros_ip_dns_record": ResourceDnsRecord(), "routeros_ip_service": ResourceIpService(), + "routeros_ip_neighbor_discovery_settings": ResourceIpNeighborDiscoverySettings(), "routeros_ipv6_address": ResourceIPv6Address(), "routeros_ipv6_dhcp_client": ResourceIPv6DhcpClient(), "routeros_ipv6_dhcp_client_option": ResourceIPv6DhcpClientOption(), diff --git a/routeros/resource_system_ip_neighbor_discovery.go b/routeros/resource_system_ip_neighbor_discovery.go new file mode 100644 index 00000000..a5501f62 --- /dev/null +++ b/routeros/resource_system_ip_neighbor_discovery.go @@ -0,0 +1,79 @@ +package routeros + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +/* +{ + "discover-interface-list": "LAN", + "lldp-med-net-policy-vlan": "disabled", + "mode": "tx-and-rx", + "protocol": "cdp,lldp,mndp" +} +*/ + +// https://help.mikrotik.com/docs/display/ROS/MAC+server +func ResourceIpNeighborDiscoverySettings() *schema.Resource { + resSchema := map[string]*schema.Schema{ + MetaResourcePath: PropResourcePath("/ip/neighbor/discovery-settings"), + MetaId: PropId(Id), + + "discover_interface_list": { + Type: schema.TypeString, + Optional: true, + Description: "Interface list on which members the discovery protocol will run on.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "lldp_med_net_policy_vlan": { + Type: schema.TypeString, + Optional: true, + Description: `Advertised VLAN ID for LLDP-MED Network Policy TLV. This allows assigning a VLAN ID for + LLDP-MED capable devices, such as VoIP phones. The TLV will only be added to interfaces where LLDP-MED + capable devices are discovered. Other TLV values are predefined and cannot be changed: + + - Application Type - Voice + - VLAN Type - Tagged + - L2 Priority - 0 + - DSCP Priority - 0 + + When used together with the bridge interface, the (R/M)STP protocol should be enabled with protocol-mode setting. + + Additionally, other neighbor discovery protocols (e.g. CDP) should be excluded using protocol setting to + avoid LLDP-MED misconfiguration.`, + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "mode": { + Type: schema.TypeString, + Optional: true, + Description: "Selects the neighbor discovery packet sending and receiving mode. The setting is " + + "available since RouterOS version 7.7.", + ValidateFunc: validation.StringInSlice([]string{"rx-only", "tx-only", "tx-and-rx"}, false), + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "protocol": { + Type: schema.TypeSet, + Optional: true, + Description: "List of used discovery protocols.", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"cdp", "lldp", "mndp"}, false), + }, + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + } + + return &schema.Resource{ + CreateContext: DefaultSystemCreate(resSchema), + ReadContext: DefaultSystemRead(resSchema), + UpdateContext: DefaultSystemUpdate(resSchema), + DeleteContext: DefaultSystemDelete(resSchema), + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: resSchema, + } +} diff --git a/routeros/resource_system_ip_neighbor_discovery_test.go b/routeros/resource_system_ip_neighbor_discovery_test.go new file mode 100644 index 00000000..2507ae2a --- /dev/null +++ b/routeros/resource_system_ip_neighbor_discovery_test.go @@ -0,0 +1,51 @@ +package routeros + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +const testIpNeighborDiscoverySettings = "routeros_ip_neighbor_discovery_settings.test" + +func TestAccIpNeighborDiscoverySettingsTest_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, + Steps: []resource.TestStep{ + { + Config: testAccIpNeighborDiscoverySettingsConfig("static", "1", "rx-only", `[]`), + Check: resource.ComposeTestCheckFunc( + testResourcePrimaryInstanceId(testIpNeighborDiscoverySettings), + resource.TestCheckResourceAttr(testIpNeighborDiscoverySettings, "discover_interface_list", "static"), + ), + }, + { + Config: testAccIpNeighborDiscoverySettingsConfig("LAN", "disabled", "tx-and-rx", `["cdp", "lldp", "mndp"]`), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(testIpNeighborDiscoverySettings, "discover_interface_list", "LAN"), + ), + }, + }, + }) + }) + } +} + +func testAccIpNeighborDiscoverySettingsConfig(iflist, lldp, mode, proto string) string { + return fmt.Sprintf(`%v + +resource "routeros_ip_neighbor_discovery_settings" "test" { + discover_interface_list = "%v" + lldp_med_net_policy_vlan = "%v" + mode = "%v" + protocol = %v +} +`, providerConfig, iflist, lldp, mode, proto) +}