cloudflare/cloudflared

Public

mirrored from https://github.com/cloudflare/cloudflaredAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2026.5.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

component-tests/setup.py

156lines · modeblame

9d3a7bd0Nuno Diegues5 years ago1#!/usr/bin/env python
2import argparse
3import base64
4import json
5import os
6import subprocess
7import uuid
8
9import CloudFlare
10import yaml
11from retrying import retry
12
13from constants import MAX_RETRIES, BACKOFF_SECS
14from util import LOGGER
15
16
17def get_config_from_env():
18config_content = base64.b64decode(get_env("COMPONENT_TESTS_CONFIG_CONTENT")).decode('utf-8')
19return yaml.safe_load(config_content)
20
21
22def get_config_from_file():
23config_path = get_env("COMPONENT_TESTS_CONFIG")
24with open(config_path, 'r') as infile:
25return yaml.safe_load(infile)
26
27
28def persist_config(config):
29config_path = get_env("COMPONENT_TESTS_CONFIG")
30with open(config_path, 'w') as outfile:
31yaml.safe_dump(config, outfile)
32
33
34def persist_origin_cert(config):
35origincert = get_env("COMPONENT_TESTS_ORIGINCERT")
36path = config["origincert"]
37with open(path, 'w') as outfile:
38outfile.write(origincert)
39return path
40
41
42@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)
43def create_tunnel(config, origincert_path, random_uuid):
44# Delete any previous existing credentials file. If the agent keeps files around (that's the case in Windows) then
45# cloudflared tunnel create will refuse to create the tunnel because it does not want to overwrite credentials
46# files.
47credentials_path = config["credentials_file"]
48try:
49os.remove(credentials_path)
50except OSError:
51pass
52
53tunnel_name = "cfd_component_test-" + random_uuid
54create_cmd = [config["cloudflared_binary"], "tunnel", "--origincert", origincert_path, "create",
55"--credentials-file", credentials_path, tunnel_name]
56LOGGER.info(f"Creating tunnel with {create_cmd}")
57subprocess.run(create_cmd, check=True)
58
59list_cmd = [config["cloudflared_binary"], "tunnel", "--origincert", origincert_path, "list", "--name",
60tunnel_name, "--output", "json"]
61LOGGER.info(f"Listing tunnel with {list_cmd}")
62cloudflared = subprocess.run(list_cmd, check=True, capture_output=True)
63return json.loads(cloudflared.stdout)[0]["id"]
64
65
66@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)
67def delete_tunnel(config):
68credentials_path = config["credentials_file"]
69delete_cmd = [config["cloudflared_binary"], "tunnel", "--origincert", config["origincert"], "delete",
70"--credentials-file", credentials_path, "-f", config["tunnel"]]
71LOGGER.info(f"Deleting tunnel with {delete_cmd}")
72subprocess.run(delete_cmd, check=True)
73
74
75@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)
76def create_dns(config, hostname, type, content):
33baad35Chung-Ting2 years ago77cf = CloudFlare.CloudFlare(debug=False, token=get_env("DNS_API_TOKEN"))
9d3a7bd0Nuno Diegues5 years ago78cf.zones.dns_records.post(
79config["zone_tag"],
80data={'name': hostname, 'type': type, 'content': content, 'proxied': True}
81)
82
83
84def create_named_dns(config, random_uuid):
85hostname = "named-" + random_uuid + "." + config["zone_domain"]
86create_dns(config, hostname, "CNAME", config["tunnel"] + ".cfargotunnel.com")
87return hostname
88
89
90@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)
91def delete_dns(config, hostname):
33baad35Chung-Ting2 years ago92cf = CloudFlare.CloudFlare(debug=False, token=get_env("DNS_API_TOKEN"))
9d3a7bd0Nuno Diegues5 years ago93zone_tag = config["zone_tag"]
94dns_records = cf.zones.dns_records.get(zone_tag, params={'name': hostname})
95if len(dns_records) > 0:
96cf.zones.dns_records.delete(zone_tag, dns_records[0]['id'])
97
98
99def write_file(content, path):
100with open(path, 'w') as outfile:
101outfile.write(content)
102
103
104def get_env(env_name):
105val = os.getenv(env_name)
106if val is None:
107raise Exception(f"{env_name} is not set")
108return val
109
110
111def create():
112"""
113Creates the necessary resources for the components test to run.
114- Creates a named tunnel with a random name.
115- Creates a random CNAME DNS entry for that tunnel.
116
117Those created resources are added to the config (obtained from an environment variable).
118The resulting configuration is persisted for the tests to use.
119"""
120config = get_config_from_env()
121origincert_path = persist_origin_cert(config)
122
123random_uuid = str(uuid.uuid4())
124config["tunnel"] = create_tunnel(config, origincert_path, random_uuid)
125config["ingress"] = [
126{
127"hostname": create_named_dns(config, random_uuid),
128"service": "hello_world"
129},
130{
131"service": "http_status:404"
132}
133]
134
135persist_config(config)
136
137
138def cleanup():
139"""
140Reads the persisted configuration that was created previously.
141Deletes the resources that were created there.
142"""
143config = get_config_from_file()
144delete_tunnel(config)
145delete_dns(config, config["ingress"][0]["hostname"])
146
147
148if __name__ == '__main__':
149parser = argparse.ArgumentParser(description='setup component tests')
150parser.add_argument('--type', choices=['create', 'cleanup'], default='create')
151args = parser.parse_args()
152
153if args.type == 'create':
154create()
155else:
156cleanup()