From 50d1ca58fab6fa156542e65112a4adc94c703b5e Mon Sep 17 00:00:00 2001 From: Vaerh Date: Wed, 17 May 2023 23:04:59 +0300 Subject: [PATCH] feat: Add support for /interface/pppoe-client Fixes #202 --- .../routeros_interface_pppoe_client/import.sh | 3 + .../resource.tf | 8 + routeros/provider.go | 1 + routeros/resource_interface_pppoe_client.go | 160 ++++++++++++++++++ .../resource_interface_pppoe_client_test.go | 64 +++++++ 5 files changed, 236 insertions(+) create mode 100644 examples/resources/routeros_interface_pppoe_client/import.sh create mode 100644 examples/resources/routeros_interface_pppoe_client/resource.tf create mode 100644 routeros/resource_interface_pppoe_client.go create mode 100644 routeros/resource_interface_pppoe_client_test.go diff --git a/examples/resources/routeros_interface_pppoe_client/import.sh b/examples/resources/routeros_interface_pppoe_client/import.sh new file mode 100644 index 00000000..da89035d --- /dev/null +++ b/examples/resources/routeros_interface_pppoe_client/import.sh @@ -0,0 +1,3 @@ +#The ID can be found via API or the terminal +#The command for the terminal is -> :put [/interface/pppoe-client get [print show-ids]] +terraform import routeros_interface_pppoe_client.test "*0" diff --git a/examples/resources/routeros_interface_pppoe_client/resource.tf b/examples/resources/routeros_interface_pppoe_client/resource.tf new file mode 100644 index 00000000..b270bba6 --- /dev/null +++ b/examples/resources/routeros_interface_pppoe_client/resource.tf @@ -0,0 +1,8 @@ +resource "routeros_interface_pppoe_client" "test" { + interface = "ether1" + password = "StrongPass" + service_name = "pppoeservice" + name = "PPPoE-Out" + disabled = false + user = "MT-User" +} \ No newline at end of file diff --git a/routeros/provider.go b/routeros/provider.go index 404f4cc1..5082fb65 100644 --- a/routeros/provider.go +++ b/routeros/provider.go @@ -110,6 +110,7 @@ func Provider() *schema.Provider { "routeros_interface_ovpn_server": ResourceInterfaceOpenVPNServer(), "routeros_interface_veth": ResourceInterfaceVeth(), "routeros_interface_bonding": ResourceInterfaceBonding(), + "routeros_interface_pppoe_client": ResourceInterfacePPPoEClient(), // Aliases for interface objects to retain compatibility between original and fork "routeros_bridge": ResourceInterfaceBridge(), diff --git a/routeros/resource_interface_pppoe_client.go b/routeros/resource_interface_pppoe_client.go new file mode 100644 index 00000000..4a26bdad --- /dev/null +++ b/routeros/resource_interface_pppoe_client.go @@ -0,0 +1,160 @@ +package routeros + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +/* + { + ".id": "*1C", + "ac-name": "", + "add-default-route": "true", + "allow": "pap,chap,mschap1,mschap2", + "default-route-distance": "1", + "dial-on-demand": "false", + "disabled": "false", + "interface": "ether2", + "invalid": "false", + "keepalive-timeout": "10", + "max-mru": "auto", + "max-mtu": "auto", + "mrru": "disabled", + "name": "pppoe-out1", + "password": "", + "profile": "default", + "running": "false", + "service-name": "", + "use-peer-dns": "false", + "user": "" + } +*/ + +// https://help.mikrotik.com/docs/display/ROS/PPPoE#PPPoE-PPPoEClient +func ResourceInterfacePPPoEClient() *schema.Resource { + resSchema := map[string]*schema.Schema{ + MetaResourcePath: PropResourcePath("/interface/pppoe-client"), + MetaId: PropId(Id), + + "ac_name": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Access Concentrator name, this may be left blank and the client will connect to any " + + "access concentrator on the broadcast domain.", + }, + "add_default_route": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Enable/Disable whether to add default route automatically.", + }, + "allow": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Description: "Allowed authentication methods, by default all methods are allowed.", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"mschap2", "mschap1", "chap", "pap"}, false), + }, + }, + KeyComment: PropCommentRw, + "default_route_distance": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + Description: "sets distance value applied to auto created default route, if add-default-route is also " + + "selected.", + ValidateFunc: validation.IntBetween(0, 255), + }, + "dial_on_demand": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "connects to AC only when outbound traffic is generated. If selected, then route with " + + "gateway address from 10.112.112.0/24 network will be added while connection is not " + + "established.", + }, + KeyDisabled: PropDisabledRw, + "interface": { + Type: schema.TypeString, + Required: true, + Description: "Interface name on which client will run.", + }, + KeyInvalid: PropInvalidRo, + "keepalive_timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 10, + Description: "Sets keepalive timeout in seconds.", + }, + "max_mru": { + Type: schema.TypeString, + Optional: true, + Default: "auto", + Description: "Maximum Receive Unit.", + }, + "max_mtu": { + Type: schema.TypeString, + Optional: true, + Default: "auto", + Description: "Maximum Transmission Unit.", + }, + "mrru": { + Type: schema.TypeString, + Optional: true, + Default: "disabled", + Description: "Maximum packet size (512..65535 or disabled) 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.", + }, + KeyName: PropName("Name of the PPPoE interface."), + "password": { + Type: schema.TypeString, + Optional: true, + Default: "", + Sensitive: true, + Description: "Password used to authenticate.", + }, + "profile": { + Type: schema.TypeString, + Optional: true, + Default: "default", + Description: "Specifies which PPP profile configuration will be used when establishing the tunnel.", + }, + KeyRunning: PropRunningRo, + "service_name": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Specifies the service name set on the access concentrator, can be left blank to connect " + + "to any PPPoE server.", + }, + "use_peer_dns": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Enable/disable getting DNS settings from the peer.", + }, + "user": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Username used for authentication.", + }, + } + + return &schema.Resource{ + CreateContext: DefaultCreate(resSchema), + ReadContext: DefaultRead(resSchema), + UpdateContext: DefaultUpdate(resSchema), + DeleteContext: DefaultDelete(resSchema), + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: resSchema, + } +} diff --git a/routeros/resource_interface_pppoe_client_test.go b/routeros/resource_interface_pppoe_client_test.go new file mode 100644 index 00000000..e686565c --- /dev/null +++ b/routeros/resource_interface_pppoe_client_test.go @@ -0,0 +1,64 @@ +package routeros + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +const testInterfacePPPoEClientAddress = "routeros_interface_pppoe_client.test" + +func TestAccInterfacePPPoEClientTest_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/pppoe-client", "routeros_interface_pppoe_client"), + Steps: []resource.TestStep{ + { + Config: testAccInterfacePPPoEClientConfig(), + Check: resource.ComposeTestCheckFunc( + testAccCheckInterfacePPPoEClientExists(testInterfacePPPoEClientAddress), + resource.TestCheckResourceAttr(testInterfacePPPoEClientAddress, "name", "PPPoE-Out"), + ), + }, + }, + }) + }) + } +} + +func testAccCheckInterfacePPPoEClientExists(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 testAccInterfacePPPoEClientConfig() string { + return providerConfig + ` + +resource "routeros_interface_pppoe_client" "test" { + interface = "ether1" + password = "StrongPass" + service_name = "pppoeservice" + name = "PPPoE-Out" + disabled = false + user = "MT-User" +} +` +}