diff --git a/hooks/ceph_radosgw_context.py b/hooks/ceph_radosgw_context.py index c951fb61..e57ceef2 100644 --- a/hooks/ceph_radosgw_context.py +++ b/hooks/ceph_radosgw_context.py @@ -295,6 +295,7 @@ class MonContext(context.CephContext): 'rgw_swift_versioning': config('rgw-swift-versioning-enabled'), 'relaxed_s3_bucket_names': config('relaxed-s3-bucket-names'), 'frontend': http_frontend, + 'behind_https_proxy': https(), } # NOTE(dosaboy): these sections must correspond to what is supported in diff --git a/templates/ceph.conf b/templates/ceph.conf index d728ac03..d126b20b 100644 --- a/templates/ceph.conf +++ b/templates/ceph.conf @@ -16,6 +16,9 @@ ms bind ipv6 = true {% endif %} rgw swift versioning enabled = {{ rgw_swift_versioning }} rgw relaxed s3 bucket names = {{ relaxed_s3_bucket_names }} +{% if behind_https_proxy -%} +rgw trust forwarded https = true +{% endif %} {% if global -%} # The following are user-provided options provided via the config-flags charm option. # User-provided [global] section config diff --git a/unit_tests/test_ceph_radosgw_context.py b/unit_tests/test_ceph_radosgw_context.py index cfd07e07..f3f9553a 100644 --- a/unit_tests/test_ceph_radosgw_context.py +++ b/unit_tests/test_ceph_radosgw_context.py @@ -74,6 +74,7 @@ class HAProxyContextTests(CharmTestCase): class MonContextTest(CharmTestCase): + maxDiff = None def setUp(self): super(MonContextTest, self).setUp(context, TO_PATCH) @@ -95,10 +96,16 @@ class MonContextTest(CharmTestCase): else: return [] + @patch('charmhelpers.contrib.hahelpers.cluster.relation_ids') + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') @patch.object(ceph, 'config', lambda *args: '{"client.radosgw.gateway": {"rgw init timeout": 60}}') @patch.object(context, 'ensure_host_resolvable_v6') - def test_ctxt(self, mock_ensure_rsv_v6): + def test_ctxt( + self, mock_ensure_rsv_v6, mock_config_get, mock_relation_ids + ): + mock_relation_ids.return_value = [] + mock_config_get.side_effect = self.test_config.get self.socket.gethostname.return_value = 'testhost' mon_ctxt = context.MonContext() addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3'] @@ -136,7 +143,8 @@ class MonContextTest(CharmTestCase): 'frontend': 'beast', 'relaxed_s3_bucket_names': False, 'rgw_zonegroup': 'zonegroup1', - 'rgw_realm': 'realmX' + 'rgw_realm': 'realmX', + 'behind_https_proxy': False, } self.assertEqual(expect, mon_ctxt()) self.assertFalse(mock_ensure_rsv_v6.called) @@ -148,10 +156,72 @@ class MonContextTest(CharmTestCase): self.assertEqual(expect, mon_ctxt()) self.assertTrue(mock_ensure_rsv_v6.called) + @patch('ceph_radosgw_context.https') @patch.object(ceph, 'config', lambda *args: '{"client.radosgw.gateway": {"rgw init timeout": 60}}') @patch.object(context, 'ensure_host_resolvable_v6') - def test_list_of_addresses_from_ceph_proxy(self, mock_ensure_rsv_v6): + def test_ctxt_with_https_proxy(self, mock_ensure_rsv_v6, mock_https): + mock_https.return_value = True + self.socket.gethostname.return_value = 'testhost' + mon_ctxt = context.MonContext() + addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3'] + + def _relation_get(attr, unit, rid): + if attr == 'ceph-public-address': + return addresses.pop() + elif attr == 'auth': + return 'cephx' + elif attr == 'rgw.testhost_key': + return 'testkey' + elif attr == 'fsid': + return 'testfsid' + + self.relation_get.side_effect = _relation_get + self.relation_ids.return_value = ['mon:6'] + self.related_units.return_value = ['ceph/0', 'ceph/1', 'ceph/2'] + self.multisite.plain_list = self.plain_list_stub + self.determine_api_port.return_value = 70 + expect = { + 'auth_supported': 'cephx', + 'hostname': 'testhost', + 'mon_hosts': '10.5.4.1 10.5.4.2 10.5.4.3', + 'old_auth': False, + 'systemd_rgw': True, + 'unit_public_ip': '10.255.255.255', + 'use_syslog': 'false', + 'loglevel': 1, + 'port': 70, + 'client_radosgw_gateway': {'rgw init timeout': 60}, + 'ipv6': False, + 'rgw_zone': 'default', + 'fsid': 'testfsid', + 'rgw_swift_versioning': False, + 'frontend': 'beast', + 'relaxed_s3_bucket_names': False, + 'rgw_zonegroup': 'zonegroup1', + 'rgw_realm': 'realmX', + 'behind_https_proxy': True, + } + self.assertEqual(expect, mon_ctxt()) + self.assertFalse(mock_ensure_rsv_v6.called) + + self.test_config.set('prefer-ipv6', True) + addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3'] + expect['ipv6'] = True + expect['port'] = "[::]:%s" % (70) + self.assertEqual(expect, mon_ctxt()) + self.assertTrue(mock_ensure_rsv_v6.called) + + @patch('charmhelpers.contrib.hahelpers.cluster.relation_ids') + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') + @patch.object(ceph, 'config', lambda *args: + '{"client.radosgw.gateway": {"rgw init timeout": 60}}') + @patch.object(context, 'ensure_host_resolvable_v6') + def test_list_of_addresses_from_ceph_proxy( + self, mock_ensure_rsv_v6, mock_config_get, mock_relation_ids + ): + mock_relation_ids.return_value = [] + mock_config_get.side_effect = self.test_config.get self.socket.gethostname.return_value = 'testhost' mon_ctxt = context.MonContext() addresses = ['10.5.4.1 10.5.4.2 10.5.4.3'] @@ -190,7 +260,8 @@ class MonContextTest(CharmTestCase): 'frontend': 'beast', 'relaxed_s3_bucket_names': False, 'rgw_zonegroup': 'zonegroup1', - 'rgw_realm': 'realmX' + 'rgw_realm': 'realmX', + 'behind_https_proxy': False, } self.assertEqual(expect, mon_ctxt()) self.assertFalse(mock_ensure_rsv_v6.called) @@ -202,9 +273,13 @@ class MonContextTest(CharmTestCase): self.assertEqual(expect, mon_ctxt()) self.assertTrue(mock_ensure_rsv_v6.called) + @patch('charmhelpers.contrib.hahelpers.cluster.relation_ids') + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') @patch.object(ceph, 'config', lambda *args: '{"client.radosgw.gateway": {"rgw init timeout": 60}}') - def test_ctxt_missing_data(self): + def test_ctxt_missing_data(self, mock_config_get, mock_relation_ids): + mock_relation_ids.return_value = [] + mock_config_get.side_effect = self.test_config.get self.socket.gethostname.return_value = 'testhost' mon_ctxt = context.MonContext() self.relation_get.return_value = None @@ -212,9 +287,13 @@ class MonContextTest(CharmTestCase): self.related_units.return_value = ['ceph/0', 'ceph/1', 'ceph/2'] self.assertEqual({}, mon_ctxt()) + @patch('charmhelpers.contrib.hahelpers.cluster.relation_ids') + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') @patch.object(ceph, 'config', lambda *args: '{"client.radosgw.gateway": {"rgw init timeout": 60}}') - def test_ctxt_inconsistent_auths(self): + def test_ctxt_inconsistent_auths(self, mock_config_get, mock_relation_ids): + mock_relation_ids.return_value = [] + mock_config_get.side_effect = self.test_config.get self.socket.gethostname.return_value = 'testhost' mon_ctxt = context.MonContext() addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3'] @@ -253,13 +332,18 @@ class MonContextTest(CharmTestCase): 'frontend': 'beast', 'relaxed_s3_bucket_names': False, 'rgw_zonegroup': 'zonegroup1', - 'rgw_realm': 'realmX' + 'rgw_realm': 'realmX', + 'behind_https_proxy': False, } self.assertEqual(expect, mon_ctxt()) + @patch('charmhelpers.contrib.hahelpers.cluster.relation_ids') + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') @patch.object(ceph, 'config', lambda *args: '{"client.radosgw.gateway": {"rgw init timeout": 60}}') - def test_ctxt_consistent_auths(self): + def test_ctxt_consistent_auths(self, mock_config_get, mock_relation_ids): + mock_relation_ids.return_value = [] + mock_config_get.side_effect = self.test_config.get self.socket.gethostname.return_value = 'testhost' mon_ctxt = context.MonContext() addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3'] @@ -298,7 +382,8 @@ class MonContextTest(CharmTestCase): 'frontend': 'beast', 'relaxed_s3_bucket_names': False, 'rgw_zonegroup': 'zonegroup1', - 'rgw_realm': 'realmX' + 'rgw_realm': 'realmX', + 'behind_https_proxy': False, } self.assertEqual(expect, mon_ctxt()) @@ -360,9 +445,13 @@ class MonContextTest(CharmTestCase): _test_version = '16.2.0' context.validate_http_frontend('beast') + @patch('charmhelpers.contrib.hahelpers.cluster.relation_ids') + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') @patch.object(ceph, 'config', lambda *args: '{"client.radosgw.gateway": {"rgw init timeout": 60}}') - def test_ctxt_inconsistent_fsids(self): + def test_ctxt_inconsistent_fsids(self, mock_config_get, mock_relation_ids): + mock_relation_ids.return_value = [] + mock_config_get.side_effect = self.test_config.get self.socket.gethostname.return_value = 'testhost' mon_ctxt = context.MonContext() addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3'] @@ -401,7 +490,8 @@ class MonContextTest(CharmTestCase): 'frontend': 'beast', 'relaxed_s3_bucket_names': False, 'rgw_zonegroup': 'zonegroup1', - 'rgw_realm': 'realmX' + 'rgw_realm': 'realmX', + 'behind_https_proxy': False, } self.assertEqual(expect, mon_ctxt())