TUN-5680: Adapt component tests for new service install based on token
This commit is contained in:
parent
706523389c
commit
5431e0ca12
|
@ -14,7 +14,7 @@ classic_hostname: "classic-tunnel-component-tests.example.com"
|
||||||
origincert: "/Users/tunnel/.cloudflared/cert.pem"
|
origincert: "/Users/tunnel/.cloudflared/cert.pem"
|
||||||
ingress:
|
ingress:
|
||||||
- hostname: named-tunnel-component-tests.example.com
|
- hostname: named-tunnel-component-tests.example.com
|
||||||
service: http_status:200
|
service: hello_world
|
||||||
- service: http_status:404
|
- service: http_status:404
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import copy
|
import copy
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
|
||||||
from dataclasses import dataclass, InitVar
|
from dataclasses import dataclass, InitVar
|
||||||
|
|
||||||
|
@ -61,6 +63,23 @@ class NamedTunnelConfig(NamedTunnelBaseConfig):
|
||||||
def get_url(self):
|
def get_url(self):
|
||||||
return "https://" + self.ingress[0]['hostname']
|
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_token(self):
|
||||||
|
with open(self.credentials_file) as json_file:
|
||||||
|
creds = json.load(json_file)
|
||||||
|
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'))
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ClassicTunnelBaseConfig(BaseConfig):
|
class ClassicTunnelBaseConfig(BaseConfig):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
@ -9,7 +10,7 @@ import pytest
|
||||||
|
|
||||||
import test_logging
|
import test_logging
|
||||||
from conftest import CfdModes
|
from conftest import CfdModes
|
||||||
from util import start_cloudflared, wait_tunnel_ready
|
from util import start_cloudflared, wait_tunnel_ready, write_config
|
||||||
|
|
||||||
|
|
||||||
def select_platform(plat):
|
def select_platform(plat):
|
||||||
|
@ -43,6 +44,21 @@ class TestServiceMode:
|
||||||
|
|
||||||
self.launchd_service_scenario(config, assert_log_file)
|
self.launchd_service_scenario(config, assert_log_file)
|
||||||
|
|
||||||
|
@select_platform("Darwin")
|
||||||
|
@pytest.mark.skipif(os.path.exists(default_config_file()), reason=f"There is already a config file in default path")
|
||||||
|
def test_launchd_service_with_token(self, tmp_path, component_tests_config):
|
||||||
|
log_file = tmp_path / test_logging.default_log_file
|
||||||
|
additional_config = {
|
||||||
|
"logfile": str(log_file),
|
||||||
|
}
|
||||||
|
config = component_tests_config(additional_config=additional_config)
|
||||||
|
|
||||||
|
# service install doesn't install the config file but in this case we want to use some default settings
|
||||||
|
# so we write the base config without the tunnel credentials and ID
|
||||||
|
write_config(pathlib.Path(default_config_dir()), config.base_config())
|
||||||
|
|
||||||
|
self.launchd_service_scenario(config, use_token=True)
|
||||||
|
|
||||||
@select_platform("Darwin")
|
@select_platform("Darwin")
|
||||||
@pytest.mark.skipif(os.path.exists(default_config_file()), reason=f"There is already a config file in default path")
|
@pytest.mark.skipif(os.path.exists(default_config_file()), reason=f"There is already a config file in default path")
|
||||||
def test_launchd_service_rotating_log(self, tmp_path, component_tests_config):
|
def test_launchd_service_rotating_log(self, tmp_path, component_tests_config):
|
||||||
|
@ -60,11 +76,12 @@ class TestServiceMode:
|
||||||
|
|
||||||
self.launchd_service_scenario(config, assert_rotating_log)
|
self.launchd_service_scenario(config, assert_rotating_log)
|
||||||
|
|
||||||
def launchd_service_scenario(self, config, extra_assertions):
|
def launchd_service_scenario(self, config, extra_assertions=None, use_token=False):
|
||||||
with self.run_service(Path(default_config_dir()), config):
|
with self.run_service(Path(default_config_dir()), config, use_token=use_token):
|
||||||
self.launchctl_cmd("list")
|
self.launchctl_cmd("list")
|
||||||
self.launchctl_cmd("start")
|
self.launchctl_cmd("start")
|
||||||
wait_tunnel_ready(tunnel_url=config.get_url())
|
wait_tunnel_ready(tunnel_url=config.get_url())
|
||||||
|
if extra_assertions is not None:
|
||||||
extra_assertions()
|
extra_assertions()
|
||||||
self.launchctl_cmd("stop")
|
self.launchctl_cmd("stop")
|
||||||
|
|
||||||
|
@ -105,11 +122,29 @@ class TestServiceMode:
|
||||||
|
|
||||||
self.sysv_service_scenario(config, tmp_path, assert_rotating_log)
|
self.sysv_service_scenario(config, tmp_path, assert_rotating_log)
|
||||||
|
|
||||||
def sysv_service_scenario(self, config, tmp_path, extra_assertions):
|
@select_platform("Linux")
|
||||||
with self.run_service(tmp_path, config, root=True):
|
@pytest.mark.skipif(os.path.exists("/etc/cloudflared/config.yml"),
|
||||||
|
reason=f"There is already a config file in default path")
|
||||||
|
def test_sysv_service_with_token(self, tmp_path, component_tests_config):
|
||||||
|
additional_config = {
|
||||||
|
"loglevel": "debug",
|
||||||
|
}
|
||||||
|
|
||||||
|
config = component_tests_config(additional_config=additional_config)
|
||||||
|
|
||||||
|
# service install doesn't install the config file but in this case we want to use some default settings
|
||||||
|
# so we write the base config without the tunnel credentials and ID
|
||||||
|
config_path = write_config(tmp_path, config.base_config())
|
||||||
|
subprocess.run(["sudo", "cp", config_path, "/etc/cloudflared/config.yml"], check=True)
|
||||||
|
|
||||||
|
self.sysv_service_scenario(config, tmp_path, use_token=True)
|
||||||
|
|
||||||
|
def sysv_service_scenario(self, config, tmp_path, extra_assertions=None, use_token=False):
|
||||||
|
with self.run_service(tmp_path, config, root=True, use_token=use_token):
|
||||||
self.sysv_cmd("start")
|
self.sysv_cmd("start")
|
||||||
self.sysv_cmd("status")
|
self.sysv_cmd("status")
|
||||||
wait_tunnel_ready(tunnel_url=config.get_url())
|
wait_tunnel_ready(tunnel_url=config.get_url())
|
||||||
|
if extra_assertions is not None:
|
||||||
extra_assertions()
|
extra_assertions()
|
||||||
self.sysv_cmd("stop")
|
self.sysv_cmd("stop")
|
||||||
|
|
||||||
|
@ -118,14 +153,19 @@ class TestServiceMode:
|
||||||
self.sysv_cmd("status", success=False)
|
self.sysv_cmd("status", success=False)
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def run_service(self, tmp_path, config, root=False):
|
def run_service(self, tmp_path, config, root=False, use_token=False):
|
||||||
|
args = ["service", "install"]
|
||||||
|
|
||||||
|
if use_token:
|
||||||
|
args.append(config.get_token())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
service = start_cloudflared(
|
service = start_cloudflared(
|
||||||
tmp_path, config, cfd_args=["service", "install"], cfd_pre_args=[], capture_output=False, root=root)
|
tmp_path, config, cfd_args=args, cfd_pre_args=[], capture_output=False, root=root, skip_config_flag=use_token)
|
||||||
yield service
|
yield service
|
||||||
finally:
|
finally:
|
||||||
start_cloudflared(
|
start_cloudflared(
|
||||||
tmp_path, config, cfd_args=["service", "uninstall"], cfd_pre_args=[], capture_output=False, root=root)
|
tmp_path, config, cfd_args=["service", "uninstall"], cfd_pre_args=[], capture_output=False, root=root, skip_config_flag=use_token)
|
||||||
|
|
||||||
def launchctl_cmd(self, action, success=True):
|
def launchctl_cmd(self, action, success=True):
|
||||||
cmd = subprocess.run(
|
cmd = subprocess.run(
|
||||||
|
|
|
@ -21,9 +21,14 @@ def write_config(directory, config):
|
||||||
|
|
||||||
|
|
||||||
def start_cloudflared(directory, config, cfd_args=["run"], cfd_pre_args=["tunnel"], new_process=False,
|
def start_cloudflared(directory, config, cfd_args=["run"], cfd_pre_args=["tunnel"], new_process=False,
|
||||||
allow_input=False, capture_output=True, root=False):
|
allow_input=False, capture_output=True, root=False, skip_config_flag=False):
|
||||||
|
|
||||||
|
config_path = None
|
||||||
|
if not skip_config_flag:
|
||||||
config_path = write_config(directory, config.full_config)
|
config_path = write_config(directory, config.full_config)
|
||||||
|
|
||||||
cmd = cloudflared_cmd(config, config_path, cfd_args, cfd_pre_args, root)
|
cmd = cloudflared_cmd(config, config_path, cfd_args, cfd_pre_args, root)
|
||||||
|
|
||||||
if new_process:
|
if new_process:
|
||||||
return run_cloudflared_background(cmd, allow_input, capture_output)
|
return run_cloudflared_background(cmd, allow_input, capture_output)
|
||||||
# By setting check=True, it will raise an exception if the process exits with non-zero exit code
|
# By setting check=True, it will raise an exception if the process exits with non-zero exit code
|
||||||
|
@ -36,7 +41,10 @@ def cloudflared_cmd(config, config_path, cfd_args, cfd_pre_args, root):
|
||||||
cmd += ["sudo"]
|
cmd += ["sudo"]
|
||||||
cmd += [config.cloudflared_binary]
|
cmd += [config.cloudflared_binary]
|
||||||
cmd += cfd_pre_args
|
cmd += cfd_pre_args
|
||||||
|
|
||||||
|
if config_path is not None:
|
||||||
cmd += ["--config", str(config_path)]
|
cmd += ["--config", str(config_path)]
|
||||||
|
|
||||||
cmd += cfd_args
|
cmd += cfd_args
|
||||||
LOGGER.info(f"Run cmd {cmd} with config {config}")
|
LOGGER.info(f"Run cmd {cmd} with config {config}")
|
||||||
return cmd
|
return cmd
|
||||||
|
|
Loading…
Reference in New Issue