diff --git a/examples/resources/routeros_interface_pppoe_server/import.sh b/examples/resources/routeros_interface_pppoe_server/import.sh new file mode 100644 index 00000000..538ebbf1 --- /dev/null +++ b/examples/resources/routeros_interface_pppoe_server/import.sh @@ -0,0 +1,5 @@ +#The ID can be found via API or the terminal +#The command for the terminal is -> :put [/interface/pppoe/server get [print show-ids]] +terraform import routeros_interface_pppoe_server.test *3 +#Or you can import a resource using one of its attributes +terraform import routeros_interface_pppoe_server.test "name=xxx" \ No newline at end of file diff --git a/examples/resources/routeros_interface_pppoe_server/resource.tf b/examples/resources/routeros_interface_pppoe_server/resource.tf new file mode 100644 index 00000000..03a0c627 --- /dev/null +++ b/examples/resources/routeros_interface_pppoe_server/resource.tf @@ -0,0 +1,7 @@ +resource "routeros_interface_pppoe_server" "test" { + comment = "comment" + disabled = true + name = "pppoe-in1" + user = "" + service = "" +} diff --git a/examples/resources/routeros_ip_ipsec_policy_group/resource.tf b/examples/resources/routeros_ip_ipsec_policy_group/resource.tf index a93364f5..f7262c16 100644 --- a/examples/resources/routeros_ip_ipsec_policy_group/resource.tf +++ b/examples/resources/routeros_ip_ipsec_policy_group/resource.tf @@ -1,3 +1,3 @@ resource "routeros_ip_ipsec_policy_group" "test" { - name = "test-group" + name = "test-group" } \ No newline at end of file diff --git a/routeros/provider.go b/routeros/provider.go index 7b813479..fc81b84a 100644 --- a/routeros/provider.go +++ b/routeros/provider.go @@ -178,6 +178,7 @@ func Provider() *schema.Provider { "routeros_interface_ovpn_client": ResourceOpenVPNClient(), "routeros_interface_ovpn_server": ResourceInterfaceOpenVPNServer(), "routeros_interface_pppoe_client": ResourceInterfacePPPoEClient(), + "routeros_interface_pppoe_server": ResourceInterfacePppoeServer(), "routeros_interface_veth": ResourceInterfaceVeth(), "routeros_interface_vlan": ResourceInterfaceVlan(), "routeros_interface_vrrp": ResourceInterfaceVrrp(), diff --git a/routeros/resource_interface_pppoe_server.go b/routeros/resource_interface_pppoe_server.go new file mode 100644 index 00000000..eb257223 --- /dev/null +++ b/routeros/resource_interface_pppoe_server.go @@ -0,0 +1,136 @@ +package routeros + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +/* + { + ".id": "*AD", + "comment": "comment", + "disabled": "false", + "name": "pppoe-in1", + "running": "false", + "service": "", + "user": "" + } +*/ + +// https://help.mikrotik.com/docs/spaces/ROS/pages/2031625/PPPoE#PPPoE-PPPoEServer +func ResourceInterfacePppoeServer() *schema.Resource { + resSchema := map[string]*schema.Schema{ + MetaResourcePath: PropResourcePath("/interface/pppoe-server"), + MetaId: PropId(Id), + + "authentication": { + Type: schema.TypeSet, + Optional: true, + Description: "Authentication algorithm.", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"mschap2", "mschap1", "chap", "pap"}, false), + }, + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + KeyComment: PropCommentRw, + "default_profile": { + Type: schema.TypeString, + Optional: true, + Description: "", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + KeyDisabled: PropDisabledRw, + KeyInterface: { + Type: schema.TypeString, + Optional: true, + Description: "Interface that the clients are connected to", + }, + "keepalive_timeout": { + Type: schema.TypeString, + Optional: true, + Description: "Defines the time period (in seconds) after which the router is starting to send keepalive " + + "packets every second. If there is no traffic and no keepalive responses arrive for that period of time " + + "(i.e. 2 * keepalive-timeout), the non responding client is proclaimed disconnected.", + DiffSuppressFunc: TimeEquall, + }, + "max_mru": { + Type: schema.TypeInt, + Optional: true, + Description: "Maximum Receive Unit. The optimal value is the MTU of the interface the tunnel is working " + + "over reduced by 20 (so, for 1500-byte Ethernet link, set the MTU to 1480 to avoid fragmentation of packets).", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "max_mtu": { + Type: schema.TypeInt, + Optional: true, + Description: "Maximum Transmission Unit. The optimal value is the MTU of the interface the tunnel is working " + + "over reduced by 20 (so, for 1500-byte Ethernet link, set the MTU to 1480 to avoid fragmentation of packets).", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "max_sessions": { + Type: schema.TypeInt, + Optional: true, + Description: "Maximum number of clients that the AC can serve. '0' = no limitations.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + "mrru": { + Type: schema.TypeString, + Optional: true, + Description: "Maximum packet size that can be received on the link. If a packet is bigger than tunnel MTU, " + + "it will be split into multiple packets, allowing full size IP or Ethernet packets to be sent over the " + + "tunnel.", + DiffSuppressFunc: AlwaysPresentNotUserProvided, + }, + KeyName: PropName(""), + "one_session_per_host": { + Type: schema.TypeBool, + Optional: true, + Description: "Allow only one session per host (determined by MAC address). If a host tries to establish " + + "a new session, the old one will be closed.", + }, + "pppoe_over_vlan_range": { + Type: schema.TypeInt, + Optional: true, + Description: "This setting allows a PPPoE server to operate over 802.1Q VLANs. By default, a PPPoE server " + + "only accepts untagged packets on its interface. However, in scenarios where clients are on separate " + + "VLANs, instead of creating multiple 802.1Q VLAN interfaces and bridging them together or configuring " + + "individual PPPoE servers for each VLAN, you can specify the necessary VLANs directly in the PPPoE server " + + "settings. When you specify the VLAN IDs, the PPPoE server will accept both untagged packets and 802.1Q " + + "tagged packets from clients, and it will reply using the same VLAN. This setting can also be applied " + + "to both CVLAN and SVLAN interfaces. For example, when the use-service-tag=yes option is used on a VLAN " + + "interface, enabling QinQ setups as well. The setting supports a range of VLAN IDs, as well as individual " + + "VLANs specified using comma-separated values. For example: pppoe-over-vlan-range=100-115,120,122,128-130.", + }, + KeyRunning: PropRunningRo, + "service": { + Type: schema.TypeString, + Optional: true, + Description: "This attribute is required in the ROS 7 version.", + }, + "service_name": { + Type: schema.TypeString, + Optional: true, + Description: "The PPPoE service name. Server will accept clients which sends PADI message with service-names " + + "that matches this setting or if service-name field in PADI message is not set.", + }, + "user": { + Type: schema.TypeString, + Optional: true, + Description: "This attribute is required in the ROS 7 version.", + }, + } + + return &schema.Resource{ + CreateContext: DefaultCreate(resSchema), + ReadContext: DefaultRead(resSchema), + UpdateContext: DefaultUpdate(resSchema), + DeleteContext: DefaultDelete(resSchema), + + Importer: &schema.ResourceImporter{ + StateContext: ImportStateCustomContext(resSchema), + }, + + Schema: resSchema, + } +} diff --git a/routeros/resource_interface_pppoe_server_test.go b/routeros/resource_interface_pppoe_server_test.go new file mode 100644 index 00000000..bae50cb1 --- /dev/null +++ b/routeros/resource_interface_pppoe_server_test.go @@ -0,0 +1,53 @@ +package routeros + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +const testInterfacePppoeServer = "routeros_interface_pppoe_server.test" + +func TestAccInterfacePppoeServerTest_basic(t *testing.T) { + t.Parallel() + 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/pppoe-server", "routeros_interface_pppoe_server"), + Steps: []resource.TestStep{ + { + Config: testAccInterfacePppoeServerConfig(), + Check: resource.ComposeTestCheckFunc( + testResourcePrimaryInstanceId(testInterfacePppoeServer), + resource.TestCheckResourceAttr(testInterfacePppoeServer, "comment", "comment"), + resource.TestCheckResourceAttr(testInterfacePppoeServer, "disabled", "true"), + resource.TestCheckResourceAttr(testInterfacePppoeServer, "name", "pppoe-in1"), + resource.TestCheckResourceAttr(testInterfacePppoeServer, "user", ""), + resource.TestCheckResourceAttr(testInterfacePppoeServer, "service", ""), + ), + }, + }, + }) + + }) + } +} + +func testAccInterfacePppoeServerConfig() string { + return fmt.Sprintf(`%v + +resource "routeros_interface_pppoe_server" "test" { + comment = "comment" + disabled = true + name = "pppoe-in1" + user = "" + service = "" +} +`, providerConfig) +}