Merge ~cgrabowski/maas:vault-proxy into maas:master

Proposed by Christian Grabowski
Status: Rejected
Rejected by: Adam Collard
Proposed branch: ~cgrabowski/maas:vault-proxy
Merge into: maas:master
Diff against target: 172 lines (+81/-11)
2 files modified
src/maasserver/bootsources.py (+36/-10)
src/maasserver/tests/test_bootsources.py (+45/-1)
Reviewer Review Type Date Requested Status
Adam Collard (community) Disapprove
MAAS Lander Needs Fixing
Review via email: mp+435400@code.launchpad.net

Commit message

account for no_proxy set on test host

LP:2002111 manage no_proxy better in bootsources
Signed-off-by: Adam Collard <email address hidden>

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b vault-proxy lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/1725/consoleText
COMMIT: b1c3a662782de5fd08cf1cb326723943838a9c9f

review: Needs Fixing
Revision history for this message
Adam Collard (adam-collard) wrote :

Thanks for trying to get this over the line - i hadn't seen this branch when i pushed a revised commit on my branch - https://code.launchpad.net/~adam-collard/maas/+git/maas/+merge/435387

I took the approach of patching out no_proxy in the environ before running the tests.

review: Disapprove

Unmerged commits

b1c3a66... by Christian Grabowski

account for no_proxy set on test host

0a04d97... by Adam Collard

LP:2002111 manage no_proxy better in bootsources

Signed-off-by: Adam Collard <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/bootsources.py b/src/maasserver/bootsources.py
2index c58b19a..58c6cb7 100644
3--- a/src/maasserver/bootsources.py
4+++ b/src/maasserver/bootsources.py
5@@ -97,6 +97,15 @@ def get_boot_sources():
6 return [source.to_dict() for source in BootSource.objects.all()]
7
8
9+def _upsert_no_proxy_env(env, entry):
10+ """Updates $no_proxy appropriately."""
11+ if no_proxy := env.get("no_proxy"):
12+ if entry not in no_proxy.split(","):
13+ env["no_proxy"] = f"{no_proxy},{entry}"
14+ else:
15+ env["no_proxy"] = entry
16+
17+
18 @transactional
19 def get_simplestreams_env():
20 """Get environment that should be used with simplestreams."""
21@@ -106,24 +115,28 @@ def get_simplestreams_env():
22 if http_proxy is not None:
23 env["http_proxy"] = http_proxy
24 env["https_proxy"] = http_proxy
25+ if no_proxy := os.environ.get("no_proxy"):
26+ env["no_proxy"] = no_proxy
27 # When the proxy environment variables are set they effect the
28 # entire process, including controller refresh. When the region
29 # needs to refresh itself it sends itself results over HTTP to
30 # 127.0.0.1.
31- no_proxy_hosts = "127.0.0.1,localhost"
32+ no_proxy_hosts = ["127.0.0.1", "localhost"]
33 # When using a proxy and using an image mirror, we may not want
34 # to use the proxy to download the images, as they could be
35 # located in the local network, hence it makes no sense to use
36 # it. With this, we add the image mirror location(s) to the
37 # no proxy variable, which ensures MAAS contacts the mirror
38 # directly instead of through the proxy.
39- no_proxy = Config.objects.get_config("boot_images_no_proxy")
40- if no_proxy:
41- sources = get_boot_sources()
42- for source in sources:
43- host = urlparse(source["url"]).netloc.split(":")[0]
44- no_proxy_hosts = ",".join((no_proxy_hosts, host))
45- env["no_proxy"] = no_proxy_hosts
46+ if Config.objects.get_config("boot_images_no_proxy"):
47+ no_proxy_hosts.extend(
48+ [
49+ urlparse(source["url"]).hostname
50+ for source in get_boot_sources()
51+ ]
52+ )
53+ for host in no_proxy_hosts:
54+ _upsert_no_proxy_env(env, host)
55 else:
56 # The proxy is disabled, let's not accidentally use proxy from
57 # encompassing environment.
58@@ -134,12 +147,24 @@ def get_simplestreams_env():
59
60 def set_simplestreams_env():
61 """Set the environment that simplestreams needs."""
62+ bodged_env = get_simplestreams_env()
63+ pristine_env = {k: os.environ.get(k) for k in bodged_env}
64 # We simply set the env variables here as another simplestreams-based
65 # import might be running concurrently (bootresources._import_resources)
66 # and we don't want to use the environment_variables context manager that
67 # would reset the environment variables (they are global to the entire
68 # process) while the other import is still running.
69- os.environ.update(get_simplestreams_env())
70+ os.environ.update(bodged_env)
71+ return pristine_env
72+
73+
74+def restore_pristine_env(pristine_env):
75+ """Restored the environment that simplestreams needs' bodged."""
76+ for key, value in pristine_env.items():
77+ if value is None and key in os.environ:
78+ del os.environ[key]
79+ else:
80+ os.environ[key] = value
81
82
83 def get_os_info_from_boot_sources(os):
84@@ -353,7 +378,7 @@ def cache_boot_sources():
85
86 # FIXME: This modifies the environment of the entire process, which is Not
87 # Cool. We should integrate with simplestreams in a more Pythonic manner.
88- yield deferToDatabase(set_simplestreams_env)
89+ pristine_env = yield deferToDatabase(set_simplestreams_env)
90
91 errors = []
92 sources = yield deferToDatabase(get_sources)
93@@ -392,6 +417,7 @@ def cache_boot_sources():
94 else:
95 yield deferToDatabase(_update_cache, source, descriptions)
96
97+ yield deferToDatabase(restore_pristine_env, pristine_env)
98 yield deferToDatabase(check_commissioning_series_selected)
99
100 component = COMPONENT.REGION_IMAGE_IMPORT
101diff --git a/src/maasserver/tests/test_bootsources.py b/src/maasserver/tests/test_bootsources.py
102index b37e025..bc2534d 100644
103--- a/src/maasserver/tests/test_bootsources.py
104+++ b/src/maasserver/tests/test_bootsources.py
105@@ -365,8 +365,11 @@ class TestPrivateCacheBootSources(MAASTransactionServerTestCase):
106 )
107 factory.make_BootSource(keyring_data=b"1234")
108 cache_boot_sources()
109+ no_proxy_hosts = "127.0.0.1,localhost"
110+ if environ.get("no_proxy"):
111+ no_proxy_hosts = f"{environ['no_proxy']},{no_proxy_hosts}"
112 self.assertEqual(
113- (proxy_address, proxy_address, "127.0.0.1,localhost"),
114+ (proxy_address, proxy_address, no_proxy_hosts),
115 (
116 capture.env["http_proxy"],
117 capture.env["https_proxy"],
118@@ -386,6 +389,8 @@ class TestPrivateCacheBootSources(MAASTransactionServerTestCase):
119 )
120 cache_boot_sources()
121 no_proxy_hosts = "127.0.0.1,localhost,192.168.1.100"
122+ if environ.get("no_proxy"):
123+ no_proxy_hosts = f"{environ['no_proxy']},{no_proxy_hosts}"
124 self.assertEqual(
125 (proxy_address, proxy_address, no_proxy_hosts),
126 (
127@@ -395,6 +400,45 @@ class TestPrivateCacheBootSources(MAASTransactionServerTestCase):
128 ),
129 )
130
131+ def test_retains_existing_no_proxy(self):
132+ proxy_address = factory.make_name("proxy")
133+ Config.objects.set_config("http_proxy", proxy_address)
134+ Config.objects.set_config("boot_images_no_proxy", True)
135+ capture = patch_and_capture_env_for_download_all_image_descriptions(
136+ self
137+ )
138+ factory.make_BootSource(
139+ keyring_data=b"1234", url="http://192.168.1.100:8080/ephemeral-v3/"
140+ )
141+ with patch.dict("os.environ", {"no_proxy": "http://my.direct.host"}):
142+ cache_boot_sources()
143+ no_proxy_hosts = (
144+ "http://my.direct.host,127.0.0.1,localhost,192.168.1.100"
145+ )
146+ self.assertEqual(no_proxy_hosts, capture.env["no_proxy"])
147+
148+ def test_restores_proxy_settings_post_call(self):
149+ proxy_address = factory.make_name("proxy")
150+ Config.objects.set_config("http_proxy", proxy_address)
151+ Config.objects.set_config("boot_images_no_proxy", True)
152+ mock_download = self.patch(
153+ bootsources, "download_all_image_descriptions"
154+ )
155+ mock_download.return_value = make_boot_image_mapping()
156+
157+ with patch.dict(
158+ "os.environ",
159+ {
160+ "no_proxy": "my.no_proxy",
161+ "http_proxy": "my.http_proxy",
162+ "https_proxy": "my.https_proxy",
163+ },
164+ ):
165+ cache_boot_sources()
166+ self.assertEqual(environ.get("no_proxy"), "my.no_proxy")
167+ self.assertEqual(environ.get("http_proxy"), "my.http_proxy")
168+ self.assertEqual(environ.get("https_proxy"), "my.https_proxy")
169+
170 def test_passes_user_agent_with_maas_version(self):
171 mock_download = self.patch(
172 bootsources, "download_all_image_descriptions"

Subscribers

People subscribed via source and target branches