MEschenbacher's Wireguard Saltstack Formula
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.4KB

  1. import yaml
  2. import os
  3. __virtualname__ = 'wg'
  4. def __virtual__():
  5. # do checks for startup
  6. return __virtualname__
  7. def create(name):
  8. """
  9. create a wireguard interface. This will fail if it already exists.
  10. """
  11. __salt__['cmd.run']('ip link add %s type wireguard' % (name,))
  12. return show(name)
  13. def delete(name):
  14. """
  15. delete a wireguard interface. This will fail if it does not exist.
  16. """
  17. return __salt__['cmd.run']('ip link del %s type wireguard' % (name,))
  18. def show(name=None, peer=None):
  19. if peer and not name:
  20. return 'If peer is given, name must also be given'
  21. if not name:
  22. return _wg_ifaces()
  23. elif peer:
  24. return _wg_ifaces().get(name).get('peers').get(peer)
  25. else:
  26. return _wg_ifaces().get(name)
  27. def showconf(name):
  28. return __salt__['cmd.run']('wg showconf %s' % (name,))
  29. def set(name, listen_port=None, fwmark=None, private_key=None, peer=None,
  30. preshared_key=None, endpoint=None, persistent_keepalive=None,
  31. allowed_ips=None, remove=False):
  32. s = 'wg set %s' % (name,)
  33. if remove:
  34. if not peer:
  35. return 'If remove is given, peer must also be given'
  36. return __salt__['cmd.run'](
  37. '%s peer %s remove' % (s, peer)
  38. )
  39. if listen_port:
  40. s = '%s listen-port %s' % (s, listen_port)
  41. if fwmark:
  42. s = '%s fwmark %s' % (s, fwmark)
  43. if private_key:
  44. assert os.stat(private_key)
  45. # TODO private key must be given as file
  46. s = '%s private-key %s' % (s, private_key)
  47. if peer:
  48. s = '%s peer %s' % (s, peer)
  49. if preshared_key:
  50. s = '%s preshared-key %s' % (s, preshared_key)
  51. if endpoint:
  52. s = '%s endpoint %s' % (s, endpoint)
  53. if persistent_keepalive:
  54. s = '%s persistent-keepalive %s' % (s, persistent_keepalive)
  55. if allowed_ips:
  56. s = '%s allowed-ips %s' % (s, allowed_ips)
  57. return __salt__['cmd.run'](s)
  58. def remove_peer(name, peer):
  59. return __salt__['cmd.run'](
  60. 'wg set %s peer %s remove' % (name, peer)
  61. )
  62. # def add_peer(name, public_key, allowed_ips=None):
  63. # base = 'wg set %s peer %s' % (name, peer)
  64. #
  65. # return __salt__['cmd.run'](
  66. # )
  67. def genkey():
  68. return __salt__['cmd.run']('wg genkey')
  69. def genpsk():
  70. return __salt__['cmd.run']('wg genpsk')
  71. def setconf(name, path):
  72. return __salt__['cmd.run']('wg setconf %s %s' % (name, path))
  73. def addconf(name, path):
  74. return __salt__['cmd.run']('wg addconf %s %s' % (name, path))
  75. def _wg_ifaces():
  76. """
  77. Parse output from 'wg show'
  78. """
  79. # from https://github.com/saltstack/salt/blob/develop/salt/modules/linux_ip.py
  80. tmp = dict()
  81. tmpiface = dict()
  82. ifaces = dict()
  83. out = __salt__['cmd.run']('wg', env={'WG_HIDE_KEYS': 'never'})
  84. for line in out.splitlines():
  85. if line.startswith('interface: '):
  86. k, v = _wg_splitline(line)
  87. ifaces[v] = dict(peers=dict())
  88. tmpiface = ifaces[v]
  89. tmp = tmpiface
  90. elif line.startswith('peer: '):
  91. k, v = _wg_splitline(line)
  92. tmpiface['peers'][v] = dict()
  93. tmp = tmpiface['peers'][v]
  94. elif line == '':
  95. continue
  96. k, v = _wg_splitline(line)
  97. if k == 'allowed ips':
  98. tmp[k] = [ s.strip() for s in v.split(',') ]
  99. else:
  100. tmp[k] = v
  101. return ifaces
  102. def _wg_splitline(line):
  103. parts = line.split(':', 1)
  104. return parts[0].strip(), parts[1].strip()