2021-03-08 14:09:10 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
import copy
|
|
|
|
|
2021-03-08 15:42:49 +00:00
|
|
|
from dataclasses import dataclass, InitVar
|
2021-03-08 14:09:10 +00:00
|
|
|
|
|
|
|
from constants import METRICS_PORT
|
|
|
|
|
|
|
|
# frozen=True raises exception when assigning to fields. This emulates immutability
|
2021-03-08 15:42:49 +00:00
|
|
|
|
|
|
|
|
2021-03-08 14:09:10 +00:00
|
|
|
@dataclass(frozen=True)
|
2021-03-11 13:49:09 +00:00
|
|
|
class BaseConfig:
|
|
|
|
cloudflared_binary: str
|
2021-03-08 14:09:10 +00:00
|
|
|
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)
|
2021-03-11 13:49:09 +00:00
|
|
|
class NamedTunnelBaseConfig(BaseConfig):
|
2021-03-08 14:09:10 +00:00
|
|
|
# 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
|
2021-03-08 15:42:49 +00:00
|
|
|
ingress: list = None
|
2021-03-08 14:09:10 +00:00
|
|
|
|
|
|
|
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")
|
2021-03-08 15:42:49 +00:00
|
|
|
if self.ingress is None:
|
|
|
|
raise TypeError("Field ingress is not set")
|
2021-03-08 14:09:10 +00:00
|
|
|
|
|
|
|
def merge_config(self, additional):
|
|
|
|
config = super(NamedTunnelBaseConfig, self).merge_config(additional)
|
|
|
|
config['tunnel'] = self.tunnel
|
|
|
|
config['credentials-file'] = self.credentials_file
|
2021-03-08 15:42:49 +00:00
|
|
|
# In some cases we want to override default ingress, such as in config tests
|
|
|
|
if 'ingress' not in config:
|
|
|
|
config['ingress'] = self.ingress
|
2021-03-08 14:09:10 +00:00
|
|
|
return config
|
|
|
|
|
|
|
|
|
2021-03-08 15:42:49 +00:00
|
|
|
@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']
|
|
|
|
|
|
|
|
|
2021-03-08 14:09:10 +00:00
|
|
|
@dataclass(frozen=True)
|
2021-03-11 13:49:09 +00:00
|
|
|
class ClassicTunnelBaseConfig(BaseConfig):
|
2021-03-08 14:09:10 +00:00
|
|
|
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)
|
2021-03-08 15:42:49 +00:00
|
|
|
config['hostname'] = self.hostname
|
2021-03-08 14:09:10 +00:00
|
|
|
config['origincert'] = self.origincert
|
|
|
|
return config
|
|
|
|
|
|
|
|
|
2021-03-08 15:42:49 +00:00
|
|
|
@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
|