Merge ~mitchburton/landscape-charm:2059194-respect-juju-proxy-settings into landscape-charm:main

Proposed by Mitch Burton
Status: Merged
Approved by: Mitch Burton
Approved revision: fbbc33e330a6148c065f43570d89d4ed842d34d6
Merged at revision: dfc4418011daa43a9ce051259a2dcf4bbd0d19e1
Proposed branch: ~mitchburton/landscape-charm:2059194-respect-juju-proxy-settings
Merge into: landscape-charm:main
Diff against target: 148 lines (+57/-7)
2 files modified
src/charm.py (+37/-4)
tests/test_charm.py (+20/-3)
Reviewer Review Type Date Requested Status
Ardavan Behnia Approve
Landscape Pending
Review via email: mp+464054@code.launchpad.net

Commit message

use JUJU_*_PROXY env vars on bootstrap

Description of the change

This change uses the juju proxy-related model configs to populate Landscape's proxy configuration on initial setup. After initial setup, the proper way to change them is through the Landscape UI.

Don't use `make build` to test this, as it'll be too late to update the model config (there's no "model-config-changed" hook, unfortunately) and this only happens on initial bootstrap anyways. Do this instead. It's nice to have an actual proxy to test with, too, but you can _only_ set juju-no-proxy if you don't have one.

  1. make clean
  2. charmcraft pack
  3. juju add-model landscape-charm-dev
  4. juju model-config juju-http-proxy=http://<proxy_ip>:<proxy_port> juju-https-proxy=http://<proxy_ip>:<proxy_port> juju-no-proxy=127.0.0.1,localhost,::1,10.76.244.0/24
  5. juju deploy ./bundle.yaml
  6. log into Landscape via haproxy's IP address and click on "settings" for the account. Ensure that the proxy settings appear there.

There's currently an in-review MR for landscape-server that makes the appserver process actually respect these settings.

To post a comment you must log in.
Revision history for this message
Ardavan Behnia (abehnia) wrote :

Manually checked with (squid) and without proxy, left a small question inline.

review: Needs Information
Revision history for this message
Ardavan Behnia (abehnia) :
Revision history for this message
Mitch Burton (mitchburton) wrote :

Response to inline.

Revision history for this message
Ardavan Behnia (abehnia) wrote :

LGTM, left a comment.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/charm.py b/src/charm.py
2index 9b4f2de..17c1413 100755
3--- a/src/charm.py
4+++ b/src/charm.py
5@@ -16,7 +16,9 @@ import logging
6 import os
7 import subprocess
8 from base64 import b64decode, b64encode, binascii
9+from functools import cached_property
10 from subprocess import CalledProcessError, check_call
11+from typing import List
12
13 import yaml
14
15@@ -53,7 +55,6 @@ from settings_files import (
16 generate_secret_token,
17 merge_service_conf,
18 prepend_default_settings,
19- SecretTokenMissing,
20 update_db_conf,
21 update_default_settings,
22 update_service_conf,
23@@ -104,6 +105,12 @@ OIDC_CONFIG_VALS = (
24 "oidc_logout_url",
25 )
26
27+PROXY_ENV_MAPPING = {
28+ "JUJU_CHARM_HTTP_PROXY": "--with-http-proxy",
29+ "JUJU_CHARM_HTTPS_PROXY": "--with-https-proxy",
30+ "JUJU_CHARM_NO_PROXY": "--with-no-proxy",
31+}
32+
33
34 class LandscapeServerCharm(CharmBase):
35 """Charm the service."""
36@@ -485,14 +492,40 @@ class LandscapeServerCharm(CharmBase):
37 self.unit.status = ActiveStatus("Unit is ready")
38 self._update_ready_status()
39
40+ @cached_property
41+ def _proxy_settings(self) -> List[str]:
42+ """Determines the current proxy settings from the juju-related environment
43+ variables.
44+
45+ :returns: A list of proxy settings arguments suitable for passing to
46+ `SCHEMA_SCRIPT`.
47+ """
48+ settings = []
49+
50+ for juju_env_var, schema_arg_name in PROXY_ENV_MAPPING.items():
51+ value = os.environ.get(juju_env_var)
52+
53+ if value:
54+ settings.append(schema_arg_name)
55+ settings.append(value)
56+
57+ return settings
58+
59 def _migrate_schema_bootstrap(self):
60 """
61 Migrates schema along with the bootstrap command which ensures that the
62- databases along with the landscape user exists. In addition creates
63- admin if configured. Returns True on success
64+ databases and the landscape user exists, and that proxy settings are set.
65+ In addition, creates admin if configured.
66+
67+ :returns: True on success.
68 """
69+ call = [SCHEMA_SCRIPT, "--bootstrap"]
70+
71+ if self._proxy_settings:
72+ call.extend(self._proxy_settings)
73+
74 try:
75- check_call([SCHEMA_SCRIPT, "--bootstrap"])
76+ check_call(call)
77 self._bootstrap_account()
78 return True
79 except CalledProcessError as e:
80diff --git a/tests/test_charm.py b/tests/test_charm.py
81index e44e8ab..62cf96c 100644
82--- a/tests/test_charm.py
83+++ b/tests/test_charm.py
84@@ -75,7 +75,7 @@ class TestCharm(unittest.TestCase):
85 mocks["check_call"].assert_any_call(
86 ["add-apt-repository", "-y", ppa])
87 mocks["check_call"].assert_any_call(
88- ["apt-mark", "hold", "landscape-hashids"])
89+ ["apt-mark", "hold", "landscape-hashids", "landscape-server"])
90 mocks["apt"].add_package.assert_called_once_with(
91 ["landscape-server", "landscape-hashids"], update_cache=True,
92 )
93@@ -507,6 +507,9 @@ class TestCharm(unittest.TestCase):
94 "password": "testpass",
95 },
96 }
97+ peer_relation_id = self.harness.add_relation("replicas", "landscape-server")
98+ self.harness.update_relation_data(
99+ peer_relation_id, "landscape-server", {"leader-ip": "test"})
100
101 with patch("charm.check_call"):
102 with patch(
103@@ -838,6 +841,10 @@ class TestCharm(unittest.TestCase):
104 def test_on_config_changed_no_smtp_change(self, _):
105 self.harness.charm._update_ready_status = Mock()
106 self.harness.charm._configure_smtp = Mock()
107+ peer_relation_id = self.harness.add_relation("replicas", "landscape-server")
108+ self.harness.update_relation_data(
109+ peer_relation_id, "landscape-server", {"leader-ip": "test"})
110+
111 self.harness.update_config({"smtp_relay_host": ""})
112
113 self.harness.charm._configure_smtp.assert_not_called()
114@@ -847,6 +854,10 @@ class TestCharm(unittest.TestCase):
115 def test_on_config_changed_smtp_change(self, _):
116 self.harness.charm._update_ready_status = Mock()
117 self.harness.charm._configure_smtp = Mock()
118+ peer_relation_id = self.harness.add_relation("replicas", "landscape-server")
119+ self.harness.update_relation_data(
120+ peer_relation_id, "landscape-server", {"leader-ip": "test"})
121+
122 self.harness.update_config({"smtp_relay_host": "smtp.example.com"})
123
124 self.harness.charm._configure_smtp.assert_called_once_with(
125@@ -956,7 +967,10 @@ class TestCharm(unittest.TestCase):
126 self.harness.charm._stored.running = False
127 prev_status = self.harness.charm.unit.status
128
129- with patch("charm.apt", spec_set=apt) as apt_mock:
130+ with (
131+ patch("charm.apt", spec_set=apt) as apt_mock,
132+ patch("charm.check_call")
133+ ):
134 pkg_mock = Mock()
135 apt_mock.DebianPackage.from_apt_cache.return_value = pkg_mock
136 self.harness.charm._upgrade(event)
137@@ -987,7 +1001,10 @@ class TestCharm(unittest.TestCase):
138 event = Mock(spec_set=ActionEvent)
139 self.harness.charm._stored.running = False
140
141- with patch("charm.apt", spec_set=apt) as apt_mock:
142+ with (
143+ patch("charm.apt", spec_set=apt) as apt_mock,
144+ patch("charm.check_call")
145+ ):
146 pkg_mock = Mock()
147 apt_mock.DebianPackage.from_apt_cache.return_value = pkg_mock
148 pkg_mock.ensure.side_effect = PackageNotFoundError("ouch")

Subscribers

People subscribed via source and target branches

to all changes: