mirror of https://github.com/h44z/wg-portal.git
				
				
				
			Mikrotik improvements (#521)
* allow to specify ignored interfaces (#514) * only set endpoint info for "responder" peers (#516)
This commit is contained in:
		
							parent
							
								
									6d2a5fa6de
								
							
						
					
					
						commit
						765fb09770
					
				|  | @ -11,6 +11,24 @@ core: | ||||||
|   create_default_peer: true |   create_default_peer: true | ||||||
|   self_provisioning_allowed: true |   self_provisioning_allowed: true | ||||||
| 
 | 
 | ||||||
|  | backend: | ||||||
|  |   # default backend decides where new interfaces are created | ||||||
|  |   default: mikrotik | ||||||
|  | 
 | ||||||
|  |   mikrotik: | ||||||
|  |     - id: mikrotik                   # unique id, not "local" | ||||||
|  |       display_name: RouterOS RB5009  # optional nice name | ||||||
|  |       api_url: https://10.10.10.10/rest | ||||||
|  |       api_user: wgportal | ||||||
|  |       api_password: a-super-secret-password | ||||||
|  |       api_verify_tls: false        # set to false only if using self-signed during testing | ||||||
|  |       api_timeout: 30s             # maximum request duration | ||||||
|  |       concurrency: 5               # limit parallel REST calls to device | ||||||
|  |       debug: false                 # verbose logging for this backend | ||||||
|  |       ignored_interfaces:          # ignore these interfaces during import | ||||||
|  |       - wgTest1 | ||||||
|  |       - wgTest2 | ||||||
|  | 
 | ||||||
| web: | web: | ||||||
|   site_title: My WireGuard Server |   site_title: My WireGuard Server | ||||||
|   site_company_name: My Company |   site_company_name: My Company | ||||||
|  | @ -195,3 +213,5 @@ auth: | ||||||
|       registration_enabled: true |       registration_enabled: true | ||||||
|       log_user_info: true |       log_user_info: true | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | For more information, check out the usage documentation (e.g. [General Configuration](../usage/general.md) or [Backends Configuration](../usage/backends.md)). | ||||||
|  |  | ||||||
|  | @ -184,6 +184,11 @@ The current MikroTik backend is in **BETA** and may not support all features. | ||||||
| - **Description:** The default backend to use for managing WireGuard interfaces.  | - **Description:** The default backend to use for managing WireGuard interfaces.  | ||||||
|   Valid options are: `local`, or other backend id's configured in the `mikrotik` section. |   Valid options are: `local`, or other backend id's configured in the `mikrotik` section. | ||||||
| 
 | 
 | ||||||
|  | ### `ignored_local_interfaces` | ||||||
|  | - **Default:** *(empty)* | ||||||
|  | - **Description:** A list of interface names to exclude when enumerating local interfaces. | ||||||
|  |   This is useful if you want to prevent certain interfaces from being imported from the local system. | ||||||
|  | 
 | ||||||
| ### Mikrotik | ### Mikrotik | ||||||
| 
 | 
 | ||||||
| The `mikrotik` array contains a list of MikroTik backend definitions. Each entry describes how to connect to a MikroTik RouterOS instance that hosts WireGuard interfaces. | The `mikrotik` array contains a list of MikroTik backend definitions. Each entry describes how to connect to a MikroTik RouterOS instance that hosts WireGuard interfaces. | ||||||
|  | @ -225,6 +230,11 @@ Below are the properties for each entry inside `backend.mikrotik`: | ||||||
| - **Default:** `5` | - **Default:** `5` | ||||||
| - **Description:** Maximum number of concurrent API requests the backend will issue when enumerating interfaces and their details. If `0` or negative, a sane default of `5` is used. | - **Description:** Maximum number of concurrent API requests the backend will issue when enumerating interfaces and their details. If `0` or negative, a sane default of `5` is used. | ||||||
| 
 | 
 | ||||||
|  | #### `ignored_interfaces` | ||||||
|  | - **Default:** *(empty)* | ||||||
|  | - **Description:** A list of interface names to exclude during interface enumeration. | ||||||
|  |   This is useful if you want to prevent specific interfaces from being imported from the MikroTik device. | ||||||
|  | 
 | ||||||
| #### `debug` | #### `debug` | ||||||
| - **Default:** `false` | - **Default:** `false` | ||||||
| - **Description:** Enable verbose debug logging for the MikroTik backend. | - **Description:** Enable verbose debug logging for the MikroTik backend. | ||||||
|  |  | ||||||
|  | @ -3,14 +3,13 @@ package wgcontroller | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"log/slog" | ||||||
| 	"slices" | 	"slices" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"log/slog" |  | ||||||
| 
 |  | ||||||
| 	"github.com/h44z/wg-portal/internal/config" | 	"github.com/h44z/wg-portal/internal/config" | ||||||
| 	"github.com/h44z/wg-portal/internal/domain" | 	"github.com/h44z/wg-portal/internal/domain" | ||||||
| 	"github.com/h44z/wg-portal/internal/lowlevel" | 	"github.com/h44z/wg-portal/internal/lowlevel" | ||||||
|  | @ -678,12 +677,16 @@ func (c *MikrotikController) updatePeer( | ||||||
| 	extras := pp.GetExtras().(domain.MikrotikPeerExtras) | 	extras := pp.GetExtras().(domain.MikrotikPeerExtras) | ||||||
| 	peerId := extras.Id | 	peerId := extras.Id | ||||||
| 
 | 
 | ||||||
| 	endpoint := pp.Endpoint | 	endpoint := ""           // by default, we have no endpoint (the peer does not initiate a connection)
 | ||||||
| 	endpointPort := "51820" // default port if not set
 | 	endpointPort := "0"      // by default, we have no endpoint port (the peer does not initiate a connection)
 | ||||||
|  | 	if !extras.IsResponder { // if the peer is not only a responder, it needs the endpoint to initiate a connection
 | ||||||
|  | 		endpoint = pp.Endpoint | ||||||
|  | 		endpointPort = "51820" // default port if not set
 | ||||||
| 		if s := strings.Split(endpoint, ":"); len(s) == 2 { | 		if s := strings.Split(endpoint, ":"); len(s) == 2 { | ||||||
| 			endpoint = s[0] | 			endpoint = s[0] | ||||||
| 			endpointPort = s[1] | 			endpointPort = s[1] | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	allowedAddressStr := domain.CidrsToString(pp.AllowedIPs) | 	allowedAddressStr := domain.CidrsToString(pp.AllowedIPs) | ||||||
| 	slog.Debug("updating Mikrotik peer", | 	slog.Debug("updating Mikrotik peer", | ||||||
|  |  | ||||||
|  | @ -84,6 +84,7 @@ func (c *ControllerManager) registerLocalController() error { | ||||||
| 		Config: config.BackendBase{ | 		Config: config.BackendBase{ | ||||||
| 			Id:                config.LocalBackendName, | 			Id:                config.LocalBackendName, | ||||||
| 			DisplayName:       "Local WireGuard Controller", | 			DisplayName:       "Local WireGuard Controller", | ||||||
|  | 			IgnoredInterfaces: c.cfg.Backend.IgnoredLocalInterfaces, | ||||||
| 		}, | 		}, | ||||||
| 		Implementation: localController, | 		Implementation: localController, | ||||||
| 	} | 	} | ||||||
|  | @ -118,17 +119,17 @@ func (c *ControllerManager) logRegisteredControllers() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *ControllerManager) GetControllerByName(backend domain.InterfaceBackend) InterfaceController { | func (c *ControllerManager) GetControllerByName(backend domain.InterfaceBackend) InterfaceController { | ||||||
| 	return c.getController(backend, "") | 	return c.getController(backend, "").Implementation | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *ControllerManager) GetController(iface domain.Interface) InterfaceController { | func (c *ControllerManager) GetController(iface domain.Interface) InterfaceController { | ||||||
| 	return c.getController(iface.Backend, iface.Identifier) | 	return c.getController(iface.Backend, iface.Identifier).Implementation | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *ControllerManager) getController( | func (c *ControllerManager) getController( | ||||||
| 	backend domain.InterfaceBackend, | 	backend domain.InterfaceBackend, | ||||||
| 	ifaceId domain.InterfaceIdentifier, | 	ifaceId domain.InterfaceIdentifier, | ||||||
| ) InterfaceController { | ) backendInstance { | ||||||
| 	if backend == "" { | 	if backend == "" { | ||||||
| 		// If no backend is specified, use the local controller.
 | 		// If no backend is specified, use the local controller.
 | ||||||
| 		// This might be the case for interfaces created in previous WireGuard Portal versions.
 | 		// This might be the case for interfaces created in previous WireGuard Portal versions.
 | ||||||
|  | @ -145,13 +146,13 @@ func (c *ControllerManager) getController( | ||||||
| 		slog.Warn("controller for backend not found, using local controller", | 		slog.Warn("controller for backend not found, using local controller", | ||||||
| 			"backend", backend, "interface", ifaceId) | 			"backend", backend, "interface", ifaceId) | ||||||
| 	} | 	} | ||||||
| 	return controller.Implementation | 	return controller | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *ControllerManager) GetAllControllers() []InterfaceController { | func (c *ControllerManager) GetAllControllers() []backendInstance { | ||||||
| 	var backendInstances = make([]InterfaceController, 0, len(c.controllers)) | 	var backendInstances = make([]backendInstance, 0, len(c.controllers)) | ||||||
| 	for instance := range maps.Values(c.controllers) { | 	for instance := range maps.Values(c.controllers) { | ||||||
| 		backendInstances = append(backendInstances, instance.Implementation) | 		backendInstances = append(backendInstances, instance) | ||||||
| 	} | 	} | ||||||
| 	return backendInstances | 	return backendInstances | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,26 +15,6 @@ import ( | ||||||
| 	"github.com/h44z/wg-portal/internal/domain" | 	"github.com/h44z/wg-portal/internal/domain" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // GetImportableInterfaces returns all physical interfaces that are available on the system.
 |  | ||||||
| // This function also returns interfaces that are already available in the database.
 |  | ||||||
| func (m Manager) GetImportableInterfaces(ctx context.Context) ([]domain.PhysicalInterface, error) { |  | ||||||
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var allPhysicalInterfaces []domain.PhysicalInterface |  | ||||||
| 	for _, wgBackend := range m.wg.GetAllControllers() { |  | ||||||
| 		physicalInterfaces, err := wgBackend.GetInterfaces(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		allPhysicalInterfaces = append(allPhysicalInterfaces, physicalInterfaces...) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return allPhysicalInterfaces, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetInterfaceAndPeers returns the interface and all peers for the given interface identifier.
 | // GetInterfaceAndPeers returns the interface and all peers for the given interface identifier.
 | ||||||
| func (m Manager) GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) ( | func (m Manager) GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) ( | ||||||
| 	*domain.Interface, | 	*domain.Interface, | ||||||
|  | @ -110,52 +90,62 @@ func (m Manager) GetUserInterfaces(ctx context.Context, _ domain.UserIdentifier) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ImportNewInterfaces imports all new physical interfaces that are available on the system.
 | // ImportNewInterfaces imports all new physical interfaces that are available on the system.
 | ||||||
|  | // If a filter is set, only interfaces that match the filter will be imported.
 | ||||||
| func (m Manager) ImportNewInterfaces(ctx context.Context, filter ...domain.InterfaceIdentifier) (int, error) { | func (m Manager) ImportNewInterfaces(ctx context.Context, filter ...domain.InterfaceIdentifier) (int, error) { | ||||||
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil { | 	if err := domain.ValidateAdminAccessRights(ctx); err != nil { | ||||||
| 		return 0, err | 		return 0, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	imported := 0 | 	var existingInterfaceIds []domain.InterfaceIdentifier | ||||||
| 	for _, wgBackend := range m.wg.GetAllControllers() { |  | ||||||
| 		physicalInterfaces, err := wgBackend.GetInterfaces(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// if no filter is given, exclude already existing interfaces
 |  | ||||||
| 		var excludedInterfaces []domain.InterfaceIdentifier |  | ||||||
| 		if len(filter) == 0 { |  | ||||||
| 	existingInterfaces, err := m.db.GetAllInterfaces(ctx) | 	existingInterfaces, err := m.db.GetAllInterfaces(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, err | 		return 0, err | ||||||
| 	} | 	} | ||||||
| 	for _, existingInterface := range existingInterfaces { | 	for _, existingInterface := range existingInterfaces { | ||||||
| 				excludedInterfaces = append(excludedInterfaces, existingInterface.Identifier) | 		existingInterfaceIds = append(existingInterfaceIds, existingInterface.Identifier) | ||||||
| 			} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 		for _, physicalInterface := range physicalInterfaces { | 	imported := 0 | ||||||
| 			if slices.Contains(excludedInterfaces, physicalInterface.Identifier) { | 	for _, wgBackend := range m.wg.GetAllControllers() { | ||||||
| 				continue | 		physicalInterfaces, err := wgBackend.Implementation.GetInterfaces(ctx) | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if len(filter) != 0 && !slices.Contains(filter, physicalInterface.Identifier) { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			slog.Info("importing new interface", "interface", physicalInterface.Identifier) |  | ||||||
| 
 |  | ||||||
| 			physicalPeers, err := wgBackend.GetPeers(ctx, physicalInterface.Identifier) |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return 0, err | 			return 0, err | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 			err = m.importInterface(ctx, wgBackend, &physicalInterface, physicalPeers) | 		for _, physicalInterface := range physicalInterfaces { | ||||||
|  | 			if slices.Contains(wgBackend.Config.IgnoredInterfaces, string(physicalInterface.Identifier)) { | ||||||
|  | 				slog.Info("ignoring interface due to backend filter restrictions", | ||||||
|  | 					"interface", physicalInterface.Identifier, "filter", wgBackend.Config.IgnoredInterfaces, | ||||||
|  | 					"backend", wgBackend.Config.Id) | ||||||
|  | 				continue // skip ignored interfaces
 | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if slices.Contains(existingInterfaceIds, physicalInterface.Identifier) { | ||||||
|  | 				continue // skip interfaces that already exist
 | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if len(filter) > 0 && !slices.Contains(filter, physicalInterface.Identifier) { | ||||||
|  | 				slog.Info("ignoring interface due to filter restrictions", | ||||||
|  | 					"interface", physicalInterface.Identifier, "filter", wgBackend.Config.IgnoredInterfaces, | ||||||
|  | 					"backend", wgBackend.Config.Id) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			slog.Info("importing new interface", | ||||||
|  | 				"interface", physicalInterface.Identifier, "backend", wgBackend.Config.Id) | ||||||
|  | 
 | ||||||
|  | 			physicalPeers, err := wgBackend.Implementation.GetPeers(ctx, physicalInterface.Identifier) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return 0, err | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			err = m.importInterface(ctx, wgBackend.Implementation, &physicalInterface, physicalPeers) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return 0, fmt.Errorf("import of %s failed: %w", physicalInterface.Identifier, err) | 				return 0, fmt.Errorf("import of %s failed: %w", physicalInterface.Identifier, err) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			slog.Info("imported new interface", "interface", physicalInterface.Identifier, "peers", len(physicalPeers)) | 			slog.Info("imported new interface", | ||||||
|  | 				"interface", physicalInterface.Identifier, "peers", len(physicalPeers), "backend", wgBackend.Config.Id) | ||||||
| 			imported++ | 			imported++ | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -221,9 +211,11 @@ func (m Manager) RestoreInterfaceState( | ||||||
| 			return fmt.Errorf("failed to load peers for %s: %w", iface.Identifier, err) | 			return fmt.Errorf("failed to load peers for %s: %w", iface.Identifier, err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		_, err = m.wg.GetController(iface).GetInterface(ctx, iface.Identifier) | 		controller := m.wg.GetController(iface) | ||||||
|  | 
 | ||||||
|  | 		_, err = controller.GetInterface(ctx, iface.Identifier) | ||||||
| 		if err != nil && !iface.IsDisabled() { | 		if err != nil && !iface.IsDisabled() { | ||||||
| 			slog.Debug("creating missing interface", "interface", iface.Identifier) | 			slog.Debug("creating missing interface", "interface", iface.Identifier, "backend", controller.GetId()) | ||||||
| 
 | 
 | ||||||
| 			// temporarily disable interface in database so that the current state is reflected correctly
 | 			// temporarily disable interface in database so that the current state is reflected correctly
 | ||||||
| 			_ = m.db.SaveInterface(ctx, iface.Identifier, | 			_ = m.db.SaveInterface(ctx, iface.Identifier, | ||||||
|  | @ -250,7 +242,8 @@ func (m Manager) RestoreInterfaceState( | ||||||
| 				return fmt.Errorf("failed to create physical interface %s: %w", iface.Identifier, err) | 				return fmt.Errorf("failed to create physical interface %s: %w", iface.Identifier, err) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			slog.Debug("restoring interface state", "interface", iface.Identifier, "disabled", iface.IsDisabled()) | 			slog.Debug("restoring interface state", | ||||||
|  | 				"interface", iface.Identifier, "disabled", iface.IsDisabled(), "backend", controller.GetId()) | ||||||
| 
 | 
 | ||||||
| 			// try to move interface to stored state
 | 			// try to move interface to stored state
 | ||||||
| 			_, err = m.saveInterface(ctx, &iface) | 			_, err = m.saveInterface(ctx, &iface) | ||||||
|  | @ -278,13 +271,13 @@ func (m Manager) RestoreInterfaceState( | ||||||
| 		for _, peer := range peers { | 		for _, peer := range peers { | ||||||
| 			switch { | 			switch { | ||||||
| 			case iface.IsDisabled() && iface.Backend == config.LocalBackendName: // if interface is disabled, delete all peers
 | 			case iface.IsDisabled() && iface.Backend == config.LocalBackendName: // if interface is disabled, delete all peers
 | ||||||
| 				if err := m.wg.GetController(iface).DeletePeer(ctx, iface.Identifier, | 				if err := controller.DeletePeer(ctx, iface.Identifier, | ||||||
| 					peer.Identifier); err != nil { | 					peer.Identifier); err != nil { | ||||||
| 					return fmt.Errorf("failed to remove peer %s for disabled interface %s: %w", | 					return fmt.Errorf("failed to remove peer %s for disabled interface %s: %w", | ||||||
| 						peer.Identifier, iface.Identifier, err) | 						peer.Identifier, iface.Identifier, err) | ||||||
| 				} | 				} | ||||||
| 			default: // update peer
 | 			default: // update peer
 | ||||||
| 				err := m.wg.GetController(iface).SavePeer(ctx, iface.Identifier, peer.Identifier, | 				err := controller.SavePeer(ctx, iface.Identifier, peer.Identifier, | ||||||
| 					func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error) { | 					func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error) { | ||||||
| 						domain.MergeToPhysicalPeer(pp, &peer) | 						domain.MergeToPhysicalPeer(pp, &peer) | ||||||
| 						return pp, nil | 						return pp, nil | ||||||
|  | @ -297,7 +290,7 @@ func (m Manager) RestoreInterfaceState( | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// remove non-wgportal peers
 | 		// remove non-wgportal peers
 | ||||||
| 		physicalPeers, _ := m.wg.GetController(iface).GetPeers(ctx, iface.Identifier) | 		physicalPeers, _ := controller.GetPeers(ctx, iface.Identifier) | ||||||
| 		for _, physicalPeer := range physicalPeers { | 		for _, physicalPeer := range physicalPeers { | ||||||
| 			isWgPortalPeer := false | 			isWgPortalPeer := false | ||||||
| 			for _, peer := range peers { | 			for _, peer := range peers { | ||||||
|  | @ -307,7 +300,7 @@ func (m Manager) RestoreInterfaceState( | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if !isWgPortalPeer { | 			if !isWgPortalPeer { | ||||||
| 				err := m.wg.GetController(iface).DeletePeer(ctx, iface.Identifier, | 				err := controller.DeletePeer(ctx, iface.Identifier, | ||||||
| 					domain.PeerIdentifier(physicalPeer.PublicKey)) | 					domain.PeerIdentifier(physicalPeer.PublicKey)) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					return fmt.Errorf("failed to remove non-wgportal peer %s from interface %s: %w", | 					return fmt.Errorf("failed to remove non-wgportal peer %s from interface %s: %w", | ||||||
|  | @ -551,6 +544,30 @@ func (m Manager) saveInterface(ctx context.Context, iface *domain.Interface) ( | ||||||
| 		return nil, fmt.Errorf("failed to save interface: %w", err) | 		return nil, fmt.Errorf("failed to save interface: %w", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// update the interface type of peers in db
 | ||||||
|  | 	peers, err := m.db.GetInterfacePeers(ctx, iface.Identifier) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("failed to load peers for interface %s: %w", iface.Identifier, err) | ||||||
|  | 	} | ||||||
|  | 	for _, peer := range peers { | ||||||
|  | 		err := m.db.SavePeer(ctx, peer.Identifier, func(_ *domain.Peer) (*domain.Peer, error) { | ||||||
|  | 			switch iface.Type { | ||||||
|  | 			case domain.InterfaceTypeAny: | ||||||
|  | 				peer.Interface.Type = domain.InterfaceTypeAny | ||||||
|  | 			case domain.InterfaceTypeClient: | ||||||
|  | 				peer.Interface.Type = domain.InterfaceTypeServer | ||||||
|  | 			case domain.InterfaceTypeServer: | ||||||
|  | 				peer.Interface.Type = domain.InterfaceTypeClient | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return &peer, nil | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("failed to update peer %s for interface %s: %w", peer.Identifier, | ||||||
|  | 				iface.Identifier, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if iface.IsDisabled() { | 	if iface.IsDisabled() { | ||||||
| 		physicalInterface, _ := m.wg.GetController(*iface).GetInterface(ctx, iface.Identifier) | 		physicalInterface, _ := m.wg.GetController(*iface).GetInterface(ctx, iface.Identifier) | ||||||
| 		fwMark := iface.FirewallMark | 		fwMark := iface.FirewallMark | ||||||
|  |  | ||||||
|  | @ -10,6 +10,12 @@ const LocalBackendName = "local" | ||||||
| type Backend struct { | type Backend struct { | ||||||
| 	Default string `yaml:"default"` // The default backend to use (defaults to the internal backend)
 | 	Default string `yaml:"default"` // The default backend to use (defaults to the internal backend)
 | ||||||
| 
 | 
 | ||||||
|  | 	// Local Backend-specific configuration
 | ||||||
|  | 
 | ||||||
|  | 	IgnoredLocalInterfaces []string `yaml:"ignored_local_interfaces"` // A list of interface names that should be ignored by this backend (e.g., "wg0")
 | ||||||
|  | 
 | ||||||
|  | 	// External Backend-specific configuration
 | ||||||
|  | 
 | ||||||
| 	Mikrotik []BackendMikrotik `yaml:"mikrotik"` | 	Mikrotik []BackendMikrotik `yaml:"mikrotik"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -42,6 +48,8 @@ func (b *Backend) Validate() error { | ||||||
| type BackendBase struct { | type BackendBase struct { | ||||||
| 	Id          string `yaml:"id"`           // A unique id for the backend
 | 	Id          string `yaml:"id"`           // A unique id for the backend
 | ||||||
| 	DisplayName string `yaml:"display_name"` // A display name for the backend
 | 	DisplayName string `yaml:"display_name"` // A display name for the backend
 | ||||||
|  | 
 | ||||||
|  | 	IgnoredInterfaces []string `yaml:"ignored_interfaces"` // A list of interface names that should be ignored by this backend (e.g., "wg0")
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetDisplayName returns the display name of the backend.
 | // GetDisplayName returns the display name of the backend.
 | ||||||
|  |  | ||||||
|  | @ -328,7 +328,7 @@ func MergeToPhysicalPeer(pp *PhysicalPeer, p *Peer) { | ||||||
| 			Id:              "", | 			Id:              "", | ||||||
| 			Name:            p.DisplayName, | 			Name:            p.DisplayName, | ||||||
| 			Comment:         p.Notes, | 			Comment:         p.Notes, | ||||||
| 			IsResponder:     false, | 			IsResponder:     p.Interface.Type == InterfaceTypeClient, | ||||||
| 			Disabled:        p.IsDisabled(), | 			Disabled:        p.IsDisabled(), | ||||||
| 			ClientEndpoint:  p.Endpoint.GetValue(), | 			ClientEndpoint:  p.Endpoint.GetValue(), | ||||||
| 			ClientAddress:   CidrsToString(p.Interface.Addresses), | 			ClientAddress:   CidrsToString(p.Interface.Addresses), | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue