blob: a62c07cc21b0a602ec6f4c880396fddd2775585d [file] [log] [blame]
Jeremy Mowery4cdec802015-12-04 13:50:05 -07001import os
2import sys
Jeremy Mowery37d8a432016-02-07 17:07:55 -07003import time
4
5from django.db.models import F, Q
Jeremy Mowery3384d2d2016-01-05 00:30:24 -07006from services.vpn.models import VPNTenant
Jeremy Mowery37d8a432016-02-07 17:07:55 -07007from synchronizers.base.SyncInstanceUsingAnsible import \
8 SyncInstanceUsingAnsible
Jeremy Mowery4cdec802015-12-04 13:50:05 -07009
10parentdir = os.path.join(os.path.dirname(__file__), "..")
11sys.path.insert(0, parentdir)
12
Jeremy Mowery37d8a432016-02-07 17:07:55 -070013
Jeremy Mowery4cdec802015-12-04 13:50:05 -070014class SyncVPNTenant(SyncInstanceUsingAnsible):
Jeremy Mowery4cf74cf2016-01-08 16:36:22 -070015 """Class for syncing a VPNTenant using Ansible."""
Jeremy Mowery4cdec802015-12-04 13:50:05 -070016 provides = [VPNTenant]
17 observes = VPNTenant
18 requested_interval = 0
19 template_name = "sync_vpntenant.yaml"
Jeremy Mowery594b7962016-01-24 19:42:30 -070020 service_key_name = "/opt/xos/synchronizers/vpn/vpn_private_key"
Jeremy Mowery4cdec802015-12-04 13:50:05 -070021
22 def __init__(self, *args, **kwargs):
23 super(SyncVPNTenant, self).__init__(*args, **kwargs)
24
25 def fetch_pending(self, deleted):
26 if (not deleted):
27 objs = VPNTenant.get_tenant_objects().filter(
28 Q(enacted__lt=F('updated')) | Q(enacted=None), Q(lazy_blocked=False))
29 else:
30 objs = VPNTenant.get_deleted_tenant_objects()
31
32 return objs
33
Jeremy Mowery37d8a432016-02-07 17:07:55 -070034 def get_extra_attributes(self, tenant):
35 return {"server_key": tenant.server_key,
36 "is_persistent": tenant.is_persistent,
37 "vpn_subnet": tenant.vpn_subnet,
38 "server_network": tenant.server_network,
39 "clients_can_see_each_other": tenant.clients_can_see_each_other,
Jeremy Mowery34133002016-02-11 18:15:25 -070040 "ca_crt": tenant.ca_crt,
41 "server_crt": self.get_escaped_ca_crt(tenant),
Jeremy Mowery37d8a432016-02-07 17:07:55 -070042 "dh": tenant.dh
43 }
Jeremy Mowery6cacf1b2016-01-05 17:50:56 -070044
Jeremy Moweryfadbb202016-02-10 00:50:51 -070045 def get_escaped_ca_crt(self, tenant):
46 result = list()
Jeremy Mowery34133002016-02-11 18:15:25 -070047 for line in tenant.server_crt:
Jeremy Moweryf1aa7862016-02-11 17:49:03 -070048 result.append("\"" + line + "\"")
Jeremy Moweryfadbb202016-02-10 00:50:51 -070049
50 return result
51
Jeremy Moweryda2c3132016-01-10 15:21:52 -070052 def create_client_script(self, tenant):
Jeremy Mowery0111e922016-01-25 20:51:11 -070053 script = open("/opt/xos/core/static/vpn/" + str(tenant.script), 'w')
Jeremy Moweryda2c3132016-01-10 15:21:52 -070054 # write the configuration portion
Jeremy Moweryd8288c42016-02-12 00:19:31 -070055 script.write("printf \"%b\" \"")
Jeremy Moweryda2c3132016-01-10 15:21:52 -070056 for line in self.generate_client_conf(tenant).splitlines():
57 script.write(line + r"\n")
58 script.write("\" > client.conf\n")
Jeremy Moweryd8288c42016-02-12 00:19:31 -070059 script.write("printf \"%b\" \"")
Jeremy Mowery37d8a432016-02-07 17:07:55 -070060 for line in self.generate_login().splitlines():
61 script.write(line + r"\n")
62 script.write("\" > login.up\n")
Jeremy Moweryd8288c42016-02-12 00:19:31 -070063 script.write("printf \"%b\" \"")
Jeremy Mowery37d8a432016-02-07 17:07:55 -070064 for line in tenant.ca_crt:
Jeremy Mowery072f08a2016-02-09 23:30:57 -070065 script.write(line.rstrip() + r"\n")
Jeremy Mowery37d8a432016-02-07 17:07:55 -070066 script.write("\" > ca.crt\n")
Jeremy Moweryda2c3132016-01-10 15:21:52 -070067 # make sure openvpn is installed
68 script.write("apt-get update\n")
69 script.write("apt-get install openvpn\n")
Jeremy Mowery9d131a02016-01-26 18:17:30 -070070 script.write("openvpn client.conf &\n")
Jeremy Moweryda2c3132016-01-10 15:21:52 -070071 # close the script
72 script.close()
73
Jeremy Mowery0111e922016-01-25 20:51:11 -070074 def run_playbook(self, o, fields):
75 self.create_client_script(o)
76 super(SyncVPNTenant, self).run_playbook(o, fields)
77
Jeremy Mowery37d8a432016-02-07 17:07:55 -070078 def generate_login(self):
79 return str(time.time()) + "\npassword\n"
80
Jeremy Mowery6cacf1b2016-01-05 17:50:56 -070081 def generate_client_conf(self, tenant):
Jeremy Mowery4cf74cf2016-01-08 16:36:22 -070082 """str: Generates the client configuration to use to connect to this VPN server.
83
84 Args:
85 tenant (VPNTenant): The tenant to generate the client configuration for.
Jeremy Mowery8c52f562016-01-09 10:45:36 -070086
Jeremy Mowery4cf74cf2016-01-08 16:36:22 -070087 """
Jeremy Mowery37d8a432016-02-07 17:07:55 -070088 conf = ("client\n" +
89 "auth-user-pass login.up\n" +
90 "dev tun\n" +
91 "proto udp\n" +
92 "remote " + str(tenant.nat_ip) + " 1194\n" +
93 "resolv-retry infinite\n" +
94 "nobind\n" +
95 "ca ca.crt\n" +
96 "comp-lzo\n" +
97 "verb 3\n")
98
Jeremy Mowery8c52f562016-01-09 10:45:36 -070099 if tenant.is_persistent:
Jeremy Mowery8c52f562016-01-09 10:45:36 -0700100 conf += "persist-tun\n"
Jeremy Mowery37d8a432016-02-07 17:07:55 -0700101 conf += "persist-key\n"
Jeremy Mowery8c52f562016-01-09 10:45:36 -0700102
Jeremy Mowery6cacf1b2016-01-05 17:50:56 -0700103 return conf