129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
#!/usr/bin/env python
|
|
import copy
|
|
import json
|
|
import base64
|
|
|
|
from dataclasses import dataclass, InitVar
|
|
|
|
from constants import METRICS_PORT, PROXY_DNS_PORT
|
|
|
|
# frozen=True raises exception when assigning to fields. This emulates immutability
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class BaseConfig:
|
|
cloudflared_binary: str
|
|
no_autoupdate: bool = True
|
|
metrics: str = f'localhost:{METRICS_PORT}'
|
|
|
|
def merge_config(self, additional):
|
|
config = copy.copy(additional)
|
|
config['no-autoupdate'] = self.no_autoupdate
|
|
config['metrics'] = self.metrics
|
|
return config
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class NamedTunnelBaseConfig(BaseConfig):
|
|
# The attributes of the parent class are ordered before attributes in this class,
|
|
# so we have to use default values here and check if they are set in __post_init__
|
|
tunnel: str = None
|
|
credentials_file: str = None
|
|
ingress: list = None
|
|
|
|
def __post_init__(self):
|
|
if self.tunnel is None:
|
|
raise TypeError("Field tunnel is not set")
|
|
if self.credentials_file is None:
|
|
raise TypeError("Field credentials_file is not set")
|
|
if self.ingress is None:
|
|
raise TypeError("Field ingress is not set")
|
|
|
|
def merge_config(self, additional):
|
|
config = super(NamedTunnelBaseConfig, self).merge_config(additional)
|
|
config['tunnel'] = self.tunnel
|
|
config['credentials-file'] = self.credentials_file
|
|
# In some cases we want to override default ingress, such as in config tests
|
|
if 'ingress' not in config:
|
|
config['ingress'] = self.ingress
|
|
return config
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class NamedTunnelConfig(NamedTunnelBaseConfig):
|
|
full_config: dict = None
|
|
additional_config: InitVar[dict] = {}
|
|
|
|
def __post_init__(self, additional_config):
|
|
# Cannot call set self.full_config because the class is frozen, instead, we can use __setattr__
|
|
# https://docs.python.org/3/library/dataclasses.html#frozen-instances
|
|
object.__setattr__(self, 'full_config',
|
|
self.merge_config(additional_config))
|
|
|
|
def get_url(self):
|
|
return "https://" + self.ingress[0]['hostname']
|
|
|
|
def base_config(self):
|
|
config = self.full_config.copy()
|
|
|
|
# removes the tunnel reference
|
|
del(config["tunnel"])
|
|
del(config["credentials-file"])
|
|
|
|
return config
|
|
|
|
def get_tunnel_id(self):
|
|
return self.full_config["tunnel"]
|
|
|
|
def get_token(self):
|
|
creds = self.get_credentials_json()
|
|
token_dict = {"a": creds["AccountTag"], "t": creds["TunnelID"], "s": creds["TunnelSecret"]}
|
|
token_json_str = json.dumps(token_dict)
|
|
return base64.b64encode(token_json_str.encode('utf-8'))
|
|
|
|
def get_credentials_json(self):
|
|
with open(self.credentials_file) as json_file:
|
|
return json.load(json_file)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ClassicTunnelBaseConfig(BaseConfig):
|
|
hostname: str = None
|
|
origincert: str = None
|
|
|
|
def __post_init__(self):
|
|
if self.hostname is None:
|
|
raise TypeError("Field tunnel is not set")
|
|
if self.origincert is None:
|
|
raise TypeError("Field credentials_file is not set")
|
|
|
|
def merge_config(self, additional):
|
|
config = super(ClassicTunnelBaseConfig, self).merge_config(additional)
|
|
config['hostname'] = self.hostname
|
|
config['origincert'] = self.origincert
|
|
return config
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ClassicTunnelConfig(ClassicTunnelBaseConfig):
|
|
full_config: dict = None
|
|
additional_config: InitVar[dict] = {}
|
|
|
|
def __post_init__(self, additional_config):
|
|
# Cannot call set self.full_config because the class is frozen, instead, we can use __setattr__
|
|
# https://docs.python.org/3/library/dataclasses.html#frozen-instances
|
|
object.__setattr__(self, 'full_config',
|
|
self.merge_config(additional_config))
|
|
|
|
def get_url(self):
|
|
return "https://" + self.hostname
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ProxyDnsConfig(BaseConfig):
|
|
full_config = {
|
|
"port": PROXY_DNS_PORT,
|
|
"no-autoupdate": True,
|
|
}
|
|
|