diff --git a/routeros/provider_schema_helpers.go b/routeros/provider_schema_helpers.go index 132b66fa..f4cf3861 100644 --- a/routeros/provider_schema_helpers.go +++ b/routeros/provider_schema_helpers.go @@ -530,7 +530,7 @@ var ( // Prevents the need of hardcode values for default values, as those are harder to track over time/versions of // routeros AlwaysPresentNotUserProvided = func(k, old, new string, d *schema.ResourceData) bool { - if old != "" && new == "" { + if old != "" && d.GetRawConfig().GetAttr(k).IsNull() { return true } return false diff --git a/routeros/resource_interface_ethernet.go b/routeros/resource_interface_ethernet.go index 501c0765..2cbb60dd 100644 --- a/routeros/resource_interface_ethernet.go +++ b/routeros/resource_interface_ethernet.go @@ -44,10 +44,6 @@ import ( } */ -const poeOutField = "poe_out" -const cableSettingsField = "cable_settings" -const runningCheckField = "disable_running_check" - // ResourceInterfaceEthernet is the schema for ethernet interfaces // https://help.mikrotik.com/docs/display/ROS/Ethernet#Ethernet-Properties func ResourceInterfaceEthernet() *schema.Resource { @@ -118,11 +114,11 @@ func ResourceInterfaceEthernet() *schema.Resource { }, KeyDisabled: PropDisabledRw, "disable_running_check": { - Type: schema.TypeBool, + Type: schema.TypeBool, + Optional: true, Description: `Disable running check. If this value is set to 'no', the router automatically detects whether the NIC is connected with a device in the network or not. Default value is 'yes' because older NICs do not support it. (only applicable to x86)`, - Default: true, - Optional: true, + DiffSuppressFunc: AlwaysPresentNotUserProvided, }, "factory_name": { Type: schema.TypeString, @@ -171,19 +167,59 @@ func ResourceInterfaceEthernet() *schema.Resource { Description: "Original Media Access Control number of an interface. (read only)", Computed: true, }, - poeOutField: { + "poe_lldp_enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "An option that enables LLDP for managing devices.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "poe_out": { Type: schema.TypeString, - Description: "PoE settings: (https://wiki.mikrotik.com/wiki/Manual:PoE-Out)", - Default: "off", Optional: true, + Description: "PoE settings: (https://wiki.mikrotik.com/wiki/Manual:PoE-Out)", ValidateFunc: validation.StringInSlice([]string{"auto-on", "forced-on", "off"}, false), DiffSuppressFunc: AlwaysPresentNotUserProvided, }, "poe_priority": { - Type: schema.TypeInt, - Description: "PoE settings: (https://wiki.mikrotik.com/wiki/Manual:PoE-Out)", + Type: schema.TypeInt, + Optional: true, + Description: "PoE settings: (https://wiki.mikrotik.com/wiki/Manual:PoE-Out)", + ValidateFunc: validation.IntBetween(0, 99), + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "poe_voltage": { + Type: schema.TypeString, + Optional: true, + Description: "An option that allows us to manually control the voltage outputs on the PoE port.", + ValidateFunc: validation.StringInSlice([]string{"auto", "high", "low"}, false), + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "power_cycle_interval": { + Type: schema.TypeString, + Optional: true, + Description: "An options that disables PoE-Out power for 5s between the specified intervals.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "power_cycle_ping_enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "An option that enables ping watchdog of power cycles on the port if a host does not respond to ICMP or MAC-Telnet packets.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "power_cycle_ping_address": { + Type: schema.TypeString, Optional: true, - ValidateFunc: validation.IntBetween(0, 99), + Description: "An address to monitor.", + ValidateFunc: validation.IsIPAddress, + RequiredWith: []string{"power_cycle_ping_enabled"}, + }, + "power_cycle_ping_timeout": { + Type: schema.TypeString, + Optional: true, + Description: "If the host does not respond over the specified period, the PoE-Out port is switched off for 5s.", + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return AlwaysPresentNotUserProvided(k, old, new, d) || TimeEquall(k, old, new, d) + }, }, "running": { Type: schema.TypeBool, @@ -200,17 +236,18 @@ func ResourceInterfaceEthernet() *schema.Resource { DiffSuppressFunc: AlwaysPresentNotUserProvided, }, "sfp_rate_select": { - Type: schema.TypeString, - Optional: true, - Description: `Allows to control rate select pin for SFP ports. Values: high | low`, - Default: "high", - ValidateFunc: validation.StringInSlice([]string{"high", "low"}, false), + Type: schema.TypeString, + Optional: true, + Description: `Allows to control rate select pin for SFP ports. Values: high | low`, + ValidateFunc: validation.StringInSlice([]string{"high", "low"}, false), + DiffSuppressFunc: AlwaysPresentNotUserProvided, }, "sfp_shutdown_temperature": { - Type: schema.TypeInt, + Type: schema.TypeInt, + Optional: true, Description: "The temperature in Celsius at which the interface will be temporarily turned off due to too high detected SFP module temperature (introduced v6.48)." + "The default value for SFP/SFP+/SFP28 interfaces is 95, and for QSFP+/QSFP28 interfaces 80 (introduced v7.6).", - Optional: true, + DiffSuppressFunc: AlwaysPresentNotUserProvided, }, "slave": { Type: schema.TypeBool, @@ -288,26 +325,6 @@ func updateEthernetInterface(ctx context.Context, s map[string]*schema.Schema, d return diag.FromErr(err) } - // Router won't accept poe-out parameter if the interface does not support it. - poeDesiredState := d.Get(poeOutField) - _, supportsPoE := ethernetInterface[SnakeToKebab(poeOutField)] - switch { - // if the user has specified it, but it's not supported, lets error out - case poeDesiredState != "off" && !supportsPoE: - return diag.FromErr(errors.New("can't configure PoE, router does not supports it")) - // if the router does not support PoE, avoid sending the parameter as it returns an error. - case !supportsPoE: - s[MetaSkipFields].Default = skipFieldInSchema(s[MetaSkipFields].Default, poeOutField) - } - - if _, supportsCableSettings := ethernetInterface[SnakeToKebab(cableSettingsField)]; !supportsCableSettings { - s[MetaSkipFields].Default = skipFieldInSchema(s[MetaSkipFields].Default, cableSettingsField) - } - - if _, supportsRunningCheck := ethernetInterface[SnakeToKebab(runningCheckField)]; !supportsRunningCheck { - s[MetaSkipFields].Default = skipFieldInSchema(s[MetaSkipFields].Default, runningCheckField) - } - d.SetId(ethernetInterface.GetID(Id)) if updateDiag := ResourceUpdate(ctx, s, d, m); updateDiag.HasError() { return updateDiag diff --git a/routeros/resource_ip_dns.go b/routeros/resource_ip_dns.go index e12a7876..db4f2e00 100644 --- a/routeros/resource_ip_dns.go +++ b/routeros/resource_ip_dns.go @@ -32,6 +32,15 @@ func ResourceDns() *schema.Resource { MetaResourcePath: PropResourcePath("/ip/dns"), MetaId: PropId(Name), + "address_list_extra_time": { + Type: schema.TypeString, + Optional: true, + Description: "", + ValidateFunc: ValidationTime, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return AlwaysPresentNotUserProvided(k, old, new, d) || TimeEquall(k, old, new, d) + }, + }, "allow_remote_requests": { Type: schema.TypeBool, Optional: true, diff --git a/routeros/resource_radius.go b/routeros/resource_radius.go index 539740a3..989e8d50 100644 --- a/routeros/resource_radius.go +++ b/routeros/resource_radius.go @@ -1,15 +1,10 @@ package routeros import ( - "context" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -const vrfKey = "vrf" - // https://help.mikrotik.com/docs/display/ROS/RADIUS#RADIUS-RADIUSClient func ResourceRadius() *schema.Resource { resSchema := map[string]*schema.Schema{ @@ -131,16 +126,17 @@ func ResourceRadiusIncoming() *schema.Resource { Description: "The port number to listen for the requests on.", ValidateFunc: validation.IntBetween(0, 65535), }, - vrfKey: { - Type: schema.TypeString, - Optional: true, - Description: "VRF on which service is listening for incoming connections. This option is available in RouterOS starting from version 7.4.", + "vrf": { + Type: schema.TypeString, + Optional: true, + Description: "VRF on which service is listening for incoming connections. This option is available in RouterOS starting from version 7.4.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, }, } return &schema.Resource{ CreateContext: DefaultSystemCreate(resSchema), - ReadContext: compatibleSystemRead(resSchema), + ReadContext: DefaultSystemRead(resSchema), UpdateContext: DefaultSystemUpdate(resSchema), DeleteContext: DefaultSystemDelete(resSchema), @@ -151,14 +147,3 @@ func ResourceRadiusIncoming() *schema.Resource { Schema: resSchema, } } - -func compatibleSystemRead(s map[string]*schema.Schema) schema.ReadContextFunc { - return func (ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - diags := SystemResourceRead(ctx, s, d, m) - if _, exists := d.GetOk(vrfKey); exists { - s[vrfKey].Default = "main" - } - - return diags - } -}