MEschenbacher's Wireguard Saltstack Formula
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

146 lines
4.2KB

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