Skip to content

Commit 5431e0c

Browse files
committed
TUN-5680: Adapt component tests for new service install based on token
1 parent 7065233 commit 5431e0c

File tree

4 files changed

+81
-14
lines changed

4 files changed

+81
-14
lines changed

component-tests/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ classic_hostname: "classic-tunnel-component-tests.example.com"
1414
origincert: "/Users/tunnel/.cloudflared/cert.pem"
1515
ingress:
1616
- hostname: named-tunnel-component-tests.example.com
17-
service: http_status:200
17+
service: hello_world
1818
- service: http_status:404
1919
```
2020

component-tests/config.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/usr/bin/env python
22
import copy
3+
import json
4+
import base64
35

46
from dataclasses import dataclass, InitVar
57

@@ -61,6 +63,23 @@ def __post_init__(self, additional_config):
6163
def get_url(self):
6264
return "https://" + self.ingress[0]['hostname']
6365

66+
def base_config(self):
67+
config = self.full_config.copy()
68+
69+
# removes the tunnel reference
70+
del(config["tunnel"])
71+
del(config["credentials-file"])
72+
73+
return config
74+
75+
def get_token(self):
76+
with open(self.credentials_file) as json_file:
77+
creds = json.load(json_file)
78+
token_dict = {"a": creds["AccountTag"], "t": creds["TunnelID"], "s": creds["TunnelSecret"]}
79+
token_json_str = json.dumps(token_dict)
80+
81+
return base64.b64encode(token_json_str.encode('utf-8'))
82+
6483

6584
@dataclass(frozen=True)
6685
class ClassicTunnelBaseConfig(BaseConfig):

component-tests/test_service.py

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python
22
import os
3+
import pathlib
34
import platform
45
import subprocess
56
from contextlib import contextmanager
@@ -9,7 +10,7 @@
910

1011
import test_logging
1112
from conftest import CfdModes
12-
from util import start_cloudflared, wait_tunnel_ready
13+
from util import start_cloudflared, wait_tunnel_ready, write_config
1314

1415

1516
def select_platform(plat):
@@ -43,6 +44,21 @@ def assert_log_file():
4344

4445
self.launchd_service_scenario(config, assert_log_file)
4546

47+
@select_platform("Darwin")
48+
@pytest.mark.skipif(os.path.exists(default_config_file()), reason=f"There is already a config file in default path")
49+
def test_launchd_service_with_token(self, tmp_path, component_tests_config):
50+
log_file = tmp_path / test_logging.default_log_file
51+
additional_config = {
52+
"logfile": str(log_file),
53+
}
54+
config = component_tests_config(additional_config=additional_config)
55+
56+
# service install doesn't install the config file but in this case we want to use some default settings
57+
# so we write the base config without the tunnel credentials and ID
58+
write_config(pathlib.Path(default_config_dir()), config.base_config())
59+
60+
self.launchd_service_scenario(config, use_token=True)
61+
4662
@select_platform("Darwin")
4763
@pytest.mark.skipif(os.path.exists(default_config_file()), reason=f"There is already a config file in default path")
4864
def test_launchd_service_rotating_log(self, tmp_path, component_tests_config):
@@ -60,12 +76,13 @@ def assert_rotating_log():
6076

6177
self.launchd_service_scenario(config, assert_rotating_log)
6278

63-
def launchd_service_scenario(self, config, extra_assertions):
64-
with self.run_service(Path(default_config_dir()), config):
79+
def launchd_service_scenario(self, config, extra_assertions=None, use_token=False):
80+
with self.run_service(Path(default_config_dir()), config, use_token=use_token):
6581
self.launchctl_cmd("list")
6682
self.launchctl_cmd("start")
6783
wait_tunnel_ready(tunnel_url=config.get_url())
68-
extra_assertions()
84+
if extra_assertions is not None:
85+
extra_assertions()
6986
self.launchctl_cmd("stop")
7087

7188
os.remove(default_config_file())
@@ -105,27 +122,50 @@ def assert_rotating_log():
105122

106123
self.sysv_service_scenario(config, tmp_path, assert_rotating_log)
107124

108-
def sysv_service_scenario(self, config, tmp_path, extra_assertions):
109-
with self.run_service(tmp_path, config, root=True):
125+
@select_platform("Linux")
126+
@pytest.mark.skipif(os.path.exists("/etc/cloudflared/config.yml"),
127+
reason=f"There is already a config file in default path")
128+
def test_sysv_service_with_token(self, tmp_path, component_tests_config):
129+
additional_config = {
130+
"loglevel": "debug",
131+
}
132+
133+
config = component_tests_config(additional_config=additional_config)
134+
135+
# service install doesn't install the config file but in this case we want to use some default settings
136+
# so we write the base config without the tunnel credentials and ID
137+
config_path = write_config(tmp_path, config.base_config())
138+
subprocess.run(["sudo", "cp", config_path, "/etc/cloudflared/config.yml"], check=True)
139+
140+
self.sysv_service_scenario(config, tmp_path, use_token=True)
141+
142+
def sysv_service_scenario(self, config, tmp_path, extra_assertions=None, use_token=False):
143+
with self.run_service(tmp_path, config, root=True, use_token=use_token):
110144
self.sysv_cmd("start")
111145
self.sysv_cmd("status")
112146
wait_tunnel_ready(tunnel_url=config.get_url())
113-
extra_assertions()
147+
if extra_assertions is not None:
148+
extra_assertions()
114149
self.sysv_cmd("stop")
115150

116151
# Service install copies config file to /etc/cloudflared/config.yml
117152
subprocess.run(["sudo", "rm", "/etc/cloudflared/config.yml"])
118153
self.sysv_cmd("status", success=False)
119154

120155
@contextmanager
121-
def run_service(self, tmp_path, config, root=False):
156+
def run_service(self, tmp_path, config, root=False, use_token=False):
157+
args = ["service", "install"]
158+
159+
if use_token:
160+
args.append(config.get_token())
161+
122162
try:
123163
service = start_cloudflared(
124-
tmp_path, config, cfd_args=["service", "install"], cfd_pre_args=[], capture_output=False, root=root)
164+
tmp_path, config, cfd_args=args, cfd_pre_args=[], capture_output=False, root=root, skip_config_flag=use_token)
125165
yield service
126166
finally:
127167
start_cloudflared(
128-
tmp_path, config, cfd_args=["service", "uninstall"], cfd_pre_args=[], capture_output=False, root=root)
168+
tmp_path, config, cfd_args=["service", "uninstall"], cfd_pre_args=[], capture_output=False, root=root, skip_config_flag=use_token)
129169

130170
def launchctl_cmd(self, action, success=True):
131171
cmd = subprocess.run(

component-tests/util.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,14 @@ def write_config(directory, config):
2121

2222

2323
def start_cloudflared(directory, config, cfd_args=["run"], cfd_pre_args=["tunnel"], new_process=False,
24-
allow_input=False, capture_output=True, root=False):
25-
config_path = write_config(directory, config.full_config)
24+
allow_input=False, capture_output=True, root=False, skip_config_flag=False):
25+
26+
config_path = None
27+
if not skip_config_flag:
28+
config_path = write_config(directory, config.full_config)
29+
2630
cmd = cloudflared_cmd(config, config_path, cfd_args, cfd_pre_args, root)
31+
2732
if new_process:
2833
return run_cloudflared_background(cmd, allow_input, capture_output)
2934
# 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):
3641
cmd += ["sudo"]
3742
cmd += [config.cloudflared_binary]
3843
cmd += cfd_pre_args
39-
cmd += ["--config", str(config_path)]
44+
45+
if config_path is not None:
46+
cmd += ["--config", str(config_path)]
47+
4048
cmd += cfd_args
4149
LOGGER.info(f"Run cmd {cmd} with config {config}")
4250
return cmd

0 commit comments

Comments
 (0)