Skip to content

Commit

Permalink
Merge pull request #176 from DawoudMahmud/interface_wireguard_peer
Browse files Browse the repository at this point in the history
[Feature] Add Interface Wireguard Peer resource type
  • Loading branch information
ddelnano authored Aug 11, 2023
2 parents 095ab71 + 4213855 commit 8bc1906
Show file tree
Hide file tree
Showing 6 changed files with 637 additions and 0 deletions.
91 changes: 91 additions & 0 deletions client/interface_wireguard_peer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package client

import (
"github.com/go-routeros/routeros"
)

type InterfaceWireguardPeer struct {
Id string `mikrotik:".id"`
AllowedAddress string `mikrotik:"allowed-address"`
Comment string `mikrotik:"comment"`
Disabled bool `mikrotik:"disabled"`
EndpointAddress string `mikrotik:"endpoint-address"`
EndpointPort int64 `mikrotik:"endpoint-port"`
Interface string `mikrotik:"interface"`
PersistentKeepalive int64 `mikrotik:"persistent-keepalive"`
PresharedKey string `mikrotik:"preshared-key"`
PublicKey string `mikrotik:"public-key"`
}

func (i *InterfaceWireguardPeer) ActionToCommand(action Action) string {
return map[Action]string{
Add: "/interface/wireguard/peers/add",
Find: "/interface/wireguard/peers/print",
List: "/interface/wireguard/peers/print",
Update: "/interface/wireguard/peers/set",
Delete: "/interface/wireguard/peers/remove",
}[action]
}

func (i *InterfaceWireguardPeer) IDField() string {
return ".id"
}

func (i *InterfaceWireguardPeer) ID() string {
return i.Id
}

func (i *InterfaceWireguardPeer) SetID(id string) {
i.Id = id
}

func (i *InterfaceWireguardPeer) AfterAddHook(r *routeros.Reply) {
i.Id = r.Done.Map["ret"]
}

func (i *InterfaceWireguardPeer) FindField() string {
return "interface"
}

func (i *InterfaceWireguardPeer) FindFieldValue() string {
return i.Interface
}

func (i *InterfaceWireguardPeer) DeleteField() string {
return "numbers"
}

func (i *InterfaceWireguardPeer) DeleteFieldValue() string {
return i.Id
}

func (client Mikrotik) AddInterfaceWireguardPeer(i *InterfaceWireguardPeer) (*InterfaceWireguardPeer, error) {
res, err := client.Add(i)
if err != nil {
return nil, err
}

return res.(*InterfaceWireguardPeer), nil
}

func (client Mikrotik) FindInterfaceWireguardPeer(interfaceName string) (*InterfaceWireguardPeer, error) {
res, err := client.Find(&InterfaceWireguardPeer{Interface: interfaceName})
if err != nil {
return nil, err
}

return res.(*InterfaceWireguardPeer), nil
}

func (client Mikrotik) UpdateInterfaceWireguardPeer(i *InterfaceWireguardPeer) (*InterfaceWireguardPeer, error) {
res, err := client.Update(i)
if err != nil {
return nil, err
}

return res.(*InterfaceWireguardPeer), nil
}

func (client Mikrotik) DeleteInterfaceWireguardPeer(id string) error {
return client.Delete(&InterfaceWireguardPeer{Id: id})
}
79 changes: 79 additions & 0 deletions client/interface_wireguard_peer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package client

import (
"reflect"
"testing"

"github.com/stretchr/testify/require"
)

func TestFindInterfaceWireguardPeer_onNonExistantInterfacePeer(t *testing.T) {
SkipIfRouterOSV6OrEarlier(t, sysResources)
c := NewClient(GetConfigFromEnv())

interfaceName := "Interface peer does not exist"
_, err := c.FindInterfaceWireguardPeer(interfaceName)

require.Truef(t, IsNotFoundError(err),
"Expecting to receive NotFound error for Interface peer `%q`, instead error was nil.", interfaceName)
}

func TestInterfaceWireguardPeer_Crud(t *testing.T) {
SkipIfRouterOSV6OrEarlier(t, sysResources)
c := NewClient(GetConfigFromEnv())

name := "new_interface_wireguard"
interfaceWireguard := &InterfaceWireguard{
Name: name,
Disabled: false,
ListenPort: 10000,
Mtu: 10001,
PrivateKey: "YOi0P0lTTiN8hAQvuRET23Srb+U7C52iOZokj0CCSkM=",
Comment: "new interface from test",
}

createdInterface, err := c.Add(interfaceWireguard)
if err != nil {
t.Errorf("expected no error, got %v", err)
return
}
defer func() {
err = c.Delete(interfaceWireguard)
if err != nil {
t.Errorf("expected no error, got %v", err)
}
}()

interfaceWireguardPeer := &InterfaceWireguardPeer{
Interface: createdInterface.(*InterfaceWireguard).Name,
Disabled: false,
Comment: "new interface from test",
}

created, err := c.Add(interfaceWireguardPeer)
if err != nil {
t.Errorf("expected no error, got %v", err)
return
}
defer func() {
err = c.Delete(interfaceWireguardPeer)
if err != nil {
t.Errorf("expected no error, got %v", err)
}
}()
findInterface := &InterfaceWireguardPeer{}
findInterface.Interface = createdInterface.(*InterfaceWireguard).Name
found, err := c.Find(findInterface)
if err != nil {
t.Errorf("expected no error, got %v", err)
return
}

if _, ok := found.(Resource); !ok {
t.Error("expected found resource to implement Resource interface, but it doesn't")
return
}
if !reflect.DeepEqual(created, found) {
t.Error("expected created and found resources to be equal, but they aren't")
}
}
28 changes: 28 additions & 0 deletions docs/resources/interface_wireguard_peer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# mikrotik_interface_wireguard_peer (Resource)
Creates a Mikrotik Interface Wireguard Peer only supported by RouterOS v7+.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `interface` (String) Name of the WireGuard interface the peer belongs to.

### Optional

- `allowed_address` (String) List of IP (v4 or v6) addresses with CIDR masks from which incoming traffic for this peer is allowed and to which outgoing traffic for this peer is directed. The catch-all 0.0.0.0/0 may be specified for matching all IPv4 addresses, and ::/0 may be specified for matching all IPv6 addresses.
- `comment` (String) Short description of the peer.
- `disabled` (Boolean) Boolean for whether or not the interface peer is disabled.
- `endpoint_address` (String) An endpoint IP or hostname can be left blank to allow remote connection from any address.
- `endpoint_port` (Number) An endpoint port can be left blank to allow remote connection from any port.
- `persistent_keepalive` (Number) A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from a peer, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds.
- `preshared_key` (String) A base64 preshared key. Optional, and may be omitted. This option adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography, for post-quantum resistance.
- `public_key` (String) The remote peer's calculated public key.

### Read-Only

- `id` (String) Identifier of this resource assigned by RouterOS


1 change: 1 addition & 0 deletions mikrotik/provider_framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (p *ProviderFramework) Resources(ctx context.Context) []func() resource.Res
NewInterfaceWireguardResource,
NewSchedulerResource,
NewScriptResource,
NewInterfaceWireguardPeerResource,
}
}

Expand Down
Loading

0 comments on commit 8bc1906

Please sign in to comment.