client.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package wgctrl
  2. import (
  3. "errors"
  4. "os"
  5. "golang.zx2c4.com/wireguard/wgctrl/internal/wginternal"
  6. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  7. )
  8. // Expose an identical interface to the underlying packages.
  9. var _ wginternal.Client = &Client{}
  10. // A Client provides access to WireGuard device information.
  11. type Client struct {
  12. // Seamlessly use different wginternal.Client implementations to provide an
  13. // interface similar to wg(8).
  14. cs []wginternal.Client
  15. }
  16. // New creates a new Client.
  17. func New() (*Client, error) {
  18. cs, err := newClients()
  19. if err != nil {
  20. return nil, err
  21. }
  22. return &Client{
  23. cs: cs,
  24. }, nil
  25. }
  26. // Close releases resources used by a Client.
  27. func (c *Client) Close() error {
  28. for _, wgc := range c.cs {
  29. if err := wgc.Close(); err != nil {
  30. return err
  31. }
  32. }
  33. return nil
  34. }
  35. // Devices retrieves all WireGuard devices on this system.
  36. func (c *Client) Devices() ([]*wgtypes.Device, error) {
  37. var out []*wgtypes.Device
  38. for _, wgc := range c.cs {
  39. devs, err := wgc.Devices()
  40. if err != nil {
  41. return nil, err
  42. }
  43. out = append(out, devs...)
  44. }
  45. return out, nil
  46. }
  47. // Device retrieves a WireGuard device by its interface name.
  48. //
  49. // If the device specified by name does not exist or is not a WireGuard device,
  50. // an error is returned which can be checked using `errors.Is(err, os.ErrNotExist)`.
  51. func (c *Client) Device(name string) (*wgtypes.Device, error) {
  52. for _, wgc := range c.cs {
  53. d, err := wgc.Device(name)
  54. switch {
  55. case err == nil:
  56. return d, nil
  57. case errors.Is(err, os.ErrNotExist):
  58. continue
  59. default:
  60. return nil, err
  61. }
  62. }
  63. return nil, os.ErrNotExist
  64. }
  65. // ConfigureDevice configures a WireGuard device by its interface name.
  66. //
  67. // Because the zero value of some Go types may be significant to WireGuard for
  68. // Config fields, only fields which are not nil will be applied when
  69. // configuring a device.
  70. //
  71. // If the device specified by name does not exist or is not a WireGuard device,
  72. // an error is returned which can be checked using `errors.Is(err, os.ErrNotExist)`.
  73. func (c *Client) ConfigureDevice(name string, cfg wgtypes.Config) error {
  74. for _, wgc := range c.cs {
  75. err := wgc.ConfigureDevice(name, cfg)
  76. switch {
  77. case err == nil:
  78. return nil
  79. case errors.Is(err, os.ErrNotExist):
  80. continue
  81. default:
  82. return err
  83. }
  84. }
  85. return os.ErrNotExist
  86. }