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.

136 lines
3.7KB

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