blob: 65e04e73936ca2698500c245f672a6465eb03309 [file] [log] [blame]
Jeremy Mowery8b664f72015-12-04 11:52:16 -07001from core.models import Service, TenantWithContainer
2from django.db import transaction
3
4VPN_KIND = "vpn"
5
Jeremy Mowery82760822016-01-08 16:36:22 -07006
Jeremy Mowery8b664f72015-12-04 11:52:16 -07007class VPNService(Service):
Jeremy Mowery82760822016-01-08 16:36:22 -07008 """Defines the Service for creating VPN servers."""
Jeremy Mowery8b664f72015-12-04 11:52:16 -07009 KIND = VPN_KIND
10
11 class Meta:
12 proxy = True
13 # The name used to find this service, all directories are named this
14 app_label = "vpn"
15 verbose_name = "VPN Service"
16
Jeremy Mowery82760822016-01-08 16:36:22 -070017
Jeremy Mowery7ced7382015-12-04 23:58:38 -070018class VPNTenant(TenantWithContainer):
Jeremy Mowery82760822016-01-08 16:36:22 -070019 """Defines the Tenant for creating VPN servers."""
Jeremy Mowery8b664f72015-12-04 11:52:16 -070020
21 class Meta:
22 proxy = True
23 verbose_name = "VPN Tenant"
24
25 KIND = VPN_KIND
26
27 sync_attributes = ("nat_ip", "nat_mac",)
28
Jeremy Mowery3f6adcd2016-02-21 15:36:32 -070029 default_attributes = {'vpn_subnet': None,
Jeremy Moweryfd081292016-02-07 17:07:55 -070030 'server_network': None,
31 'clients_can_see_each_other': True,
Jeremy Mowerye02d4b62016-01-10 15:21:52 -070032 'is_persistent': True,
Jeremy Mowery1eab4fa2016-02-02 17:17:20 -070033 'script': None,
Jeremy Mowery3f6adcd2016-02-21 15:36:32 -070034 'ca_crt': None}
Jeremy Mowery8b664f72015-12-04 11:52:16 -070035
36 def __init__(self, *args, **kwargs):
37 vpn_services = VPNService.get_service_objects().all()
38 if vpn_services:
39 self._meta.get_field(
40 "provider_service").default = vpn_services[0].id
41 super(VPNTenant, self).__init__(*args, **kwargs)
42
43 def save(self, *args, **kwargs):
44 super(VPNTenant, self).save(*args, **kwargs)
45 model_policy_vpn_tenant(self.pk)
46
47 def delete(self, *args, **kwargs):
48 self.cleanup_container()
49 super(VPNTenant, self).delete(*args, **kwargs)
50
51 @property
Jeremy Mowery8b664f72015-12-04 11:52:16 -070052 def addresses(self):
Jeremy Mowery5055c7b2016-01-08 17:25:33 -070053 """Mapping[str, str]: The ip, mac address, and subnet of the NAT network of this Tenant."""
Jeremy Mowery8b664f72015-12-04 11:52:16 -070054 if (not self.id) or (not self.instance):
55 return {}
56
57 addresses = {}
Jeremy Mowery8b664f72015-12-04 11:52:16 -070058 for ns in self.instance.ports.all():
59 if "nat" in ns.network.name.lower():
Jeremy Mowery5055c7b2016-01-08 17:25:33 -070060 addresses["ip"] = ns.ip
61 addresses["mac"] = ns.mac
Jeremy Mowery5055c7b2016-01-08 17:25:33 -070062 break
63
Jeremy Mowery8b664f72015-12-04 11:52:16 -070064 return addresses
65
66 # This getter is necessary because nat_ip is a sync_attribute
67 @property
68 def nat_ip(self):
Jeremy Mowery82760822016-01-08 16:36:22 -070069 """str: The IP of this Tenant on the NAT network."""
Jeremy Mowery5055c7b2016-01-08 17:25:33 -070070 return self.addresses.get("ip", None)
Jeremy Mowery8b664f72015-12-04 11:52:16 -070071
72 # This getter is necessary because nat_mac is a sync_attribute
73 @property
74 def nat_mac(self):
Jeremy Mowery82760822016-01-08 16:36:22 -070075 """str: The MAC address of this Tenant on the NAT network."""
Jeremy Mowery5055c7b2016-01-08 17:25:33 -070076 return self.addresses.get("mac", None)
Jeremy Mowerya9b673b2016-01-07 21:25:50 -070077
78 @property
Jeremy Moweryfd081292016-02-07 17:07:55 -070079 def server_network(self):
Jeremy Mowery82760822016-01-08 16:36:22 -070080 """str: The IP address of the server on the VPN."""
Jeremy Mowerybd2ed3a2016-01-05 16:52:43 -070081 return self.get_attribute(
Jeremy Moweryfd081292016-02-07 17:07:55 -070082 'server_network',
83 self.default_attributes['server_network'])
Jeremy Mowerybd2ed3a2016-01-05 16:52:43 -070084
Jeremy Moweryfd081292016-02-07 17:07:55 -070085 @server_network.setter
86 def server_network(self, value):
87 self.set_attribute("server_network", value)
Jeremy Mowerybd2ed3a2016-01-05 16:52:43 -070088
89 @property
Jeremy Moweryfd081292016-02-07 17:07:55 -070090 def vpn_subnet(self):
Jeremy Mowery82760822016-01-08 16:36:22 -070091 """str: The IP address of the client on the VPN."""
Jeremy Mowerybd2ed3a2016-01-05 16:52:43 -070092 return self.get_attribute(
Jeremy Moweryfd081292016-02-07 17:07:55 -070093 'vpn_subnet',
94 self.default_attributes['vpn_subnet'])
Jeremy Mowerybd2ed3a2016-01-05 16:52:43 -070095
Jeremy Moweryfd081292016-02-07 17:07:55 -070096 @vpn_subnet.setter
97 def vpn_subnet(self, value):
98 self.set_attribute("vpn_subnet", value)
Jeremy Mowerybd2ed3a2016-01-05 16:52:43 -070099
100 @property
Jeremy Mowery4a23e7d2016-01-06 15:16:33 -0700101 def is_persistent(self):
Jeremy Mowery82760822016-01-08 16:36:22 -0700102 """bool: True if the VPN connection is persistence, false otherwise."""
Jeremy Mowery4a23e7d2016-01-06 15:16:33 -0700103 return self.get_attribute(
104 "is_persistent",
105 self.default_attributes['is_persistent'])
106
107 @is_persistent.setter
108 def is_persistent(self, value):
109 self.set_attribute("is_persistent", value)
110
111 @property
Jeremy Moweryfd081292016-02-07 17:07:55 -0700112 def clients_can_see_each_other(self):
Jeremy Mowery82760822016-01-08 16:36:22 -0700113 """bool: True if the client can see the subnet of the server, false otherwise."""
Jeremy Mowery4a23e7d2016-01-06 15:16:33 -0700114 return self.get_attribute(
Jeremy Moweryfd081292016-02-07 17:07:55 -0700115 "clients_can_see_each_other",
116 self.default_attributes['clients_can_see_each_other'])
Jeremy Mowery4a23e7d2016-01-06 15:16:33 -0700117
Jeremy Moweryfd081292016-02-07 17:07:55 -0700118 @clients_can_see_each_other.setter
119 def clients_can_see_each_other(self, value):
120 self.set_attribute("clients_can_see_each_other", value)
Jeremy Mowery4a23e7d2016-01-06 15:16:33 -0700121
Jeremy Mowerye02d4b62016-01-10 15:21:52 -0700122 @property
Jeremy Mowery28223392016-01-25 20:51:11 -0700123 def script(self):
124 """string: The file name of the client script"""
Jeremy Mowery34aef752016-01-26 17:58:16 -0700125 return self.get_attribute("script", self.default_attributes['script'])
Jeremy Mowerye02d4b62016-01-10 15:21:52 -0700126
Jeremy Mowery28223392016-01-25 20:51:11 -0700127 @script.setter
128 def script(self, value):
129 self.set_attribute("script", value)
Jeremy Mowerye02d4b62016-01-10 15:21:52 -0700130
Jeremy Mowery1eab4fa2016-02-02 17:17:20 -0700131 @property
Jeremy Mowery3b1caba2016-02-02 23:53:50 -0700132 def ca_crt(self):
Jeremy Mowery1eab4fa2016-02-02 17:17:20 -0700133 """str: the string for the ca certificate"""
Jeremy Mowery3b1caba2016-02-02 23:53:50 -0700134 return self.get_attribute("ca_crt", self.default_attributes['ca_crt'])
Jeremy Mowery1eab4fa2016-02-02 17:17:20 -0700135
Jeremy Mowery3b1caba2016-02-02 23:53:50 -0700136 @ca_crt.setter
137 def ca_crt(self, value):
138 self.set_attribute("ca_crt", value)
139
Jeremy Mowery8b664f72015-12-04 11:52:16 -0700140
141def model_policy_vpn_tenant(pk):
Jeremy Mowery82760822016-01-08 16:36:22 -0700142 """Manages the contain for the VPN Tenant."""
Jeremy Mowery8b664f72015-12-04 11:52:16 -0700143 # This section of code is atomic to prevent race conditions
144 with transaction.atomic():
145 # We find all of the tenants that are waiting to update
146 tenant = VPNTenant.objects.select_for_update().filter(pk=pk)
147 if not tenant:
148 return
149 # Since this code is atomic it is safe to always use the first tenant
150 tenant = tenant[0]
151 tenant.manage_container()