Enable rgw trust forwarded https when https proxy
This option is required for server-side encryption to be allowed if radosgw is behind a reverse proxy, such as here when certificates are configured and apache2 is running. ref. https://docs.ceph.com/en/latest/radosgw/encryption/ It is safe to always enable when https is configured in the charm, because it will be securely behind the reverse proxy in the unit. This option must not be enabled when https is not configured in the charm, because this would allow clients to spoof headers. Closes-Bug: #2021560 Change-Id: I940f9b2f424a3d98936b5f185bf8f87b71091317
This commit is contained in:
parent
4484b0f0ed
commit
541ceec401
|
@ -295,6 +295,7 @@ class MonContext(context.CephContext):
|
||||||
'rgw_swift_versioning': config('rgw-swift-versioning-enabled'),
|
'rgw_swift_versioning': config('rgw-swift-versioning-enabled'),
|
||||||
'relaxed_s3_bucket_names': config('relaxed-s3-bucket-names'),
|
'relaxed_s3_bucket_names': config('relaxed-s3-bucket-names'),
|
||||||
'frontend': http_frontend,
|
'frontend': http_frontend,
|
||||||
|
'behind_https_proxy': https(),
|
||||||
}
|
}
|
||||||
|
|
||||||
# NOTE(dosaboy): these sections must correspond to what is supported in
|
# NOTE(dosaboy): these sections must correspond to what is supported in
|
||||||
|
|
|
@ -16,6 +16,9 @@ ms bind ipv6 = true
|
||||||
{% endif %}
|
{% endif %}
|
||||||
rgw swift versioning enabled = {{ rgw_swift_versioning }}
|
rgw swift versioning enabled = {{ rgw_swift_versioning }}
|
||||||
rgw relaxed s3 bucket names = {{ relaxed_s3_bucket_names }}
|
rgw relaxed s3 bucket names = {{ relaxed_s3_bucket_names }}
|
||||||
|
{% if behind_https_proxy -%}
|
||||||
|
rgw trust forwarded https = true
|
||||||
|
{% endif %}
|
||||||
{% if global -%}
|
{% if global -%}
|
||||||
# The following are user-provided options provided via the config-flags charm option.
|
# The following are user-provided options provided via the config-flags charm option.
|
||||||
# User-provided [global] section config
|
# User-provided [global] section config
|
||||||
|
|
|
@ -74,6 +74,7 @@ class HAProxyContextTests(CharmTestCase):
|
||||||
|
|
||||||
|
|
||||||
class MonContextTest(CharmTestCase):
|
class MonContextTest(CharmTestCase):
|
||||||
|
maxDiff = None
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(MonContextTest, self).setUp(context, TO_PATCH)
|
super(MonContextTest, self).setUp(context, TO_PATCH)
|
||||||
|
@ -95,10 +96,16 @@ class MonContextTest(CharmTestCase):
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@patch('charmhelpers.contrib.hahelpers.cluster.relation_ids')
|
||||||
|
@patch('charmhelpers.contrib.hahelpers.cluster.config_get')
|
||||||
@patch.object(ceph, 'config', lambda *args:
|
@patch.object(ceph, 'config', lambda *args:
|
||||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
||||||
@patch.object(context, 'ensure_host_resolvable_v6')
|
@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'
|
self.socket.gethostname.return_value = 'testhost'
|
||||||
mon_ctxt = context.MonContext()
|
mon_ctxt = context.MonContext()
|
||||||
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
||||||
|
@ -136,7 +143,8 @@ class MonContextTest(CharmTestCase):
|
||||||
'frontend': 'beast',
|
'frontend': 'beast',
|
||||||
'relaxed_s3_bucket_names': False,
|
'relaxed_s3_bucket_names': False,
|
||||||
'rgw_zonegroup': 'zonegroup1',
|
'rgw_zonegroup': 'zonegroup1',
|
||||||
'rgw_realm': 'realmX'
|
'rgw_realm': 'realmX',
|
||||||
|
'behind_https_proxy': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expect, mon_ctxt())
|
self.assertEqual(expect, mon_ctxt())
|
||||||
self.assertFalse(mock_ensure_rsv_v6.called)
|
self.assertFalse(mock_ensure_rsv_v6.called)
|
||||||
|
@ -148,10 +156,72 @@ class MonContextTest(CharmTestCase):
|
||||||
self.assertEqual(expect, mon_ctxt())
|
self.assertEqual(expect, mon_ctxt())
|
||||||
self.assertTrue(mock_ensure_rsv_v6.called)
|
self.assertTrue(mock_ensure_rsv_v6.called)
|
||||||
|
|
||||||
|
@patch('ceph_radosgw_context.https')
|
||||||
@patch.object(ceph, 'config', lambda *args:
|
@patch.object(ceph, 'config', lambda *args:
|
||||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
||||||
@patch.object(context, 'ensure_host_resolvable_v6')
|
@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'
|
self.socket.gethostname.return_value = 'testhost'
|
||||||
mon_ctxt = context.MonContext()
|
mon_ctxt = context.MonContext()
|
||||||
addresses = ['10.5.4.1 10.5.4.2 10.5.4.3']
|
addresses = ['10.5.4.1 10.5.4.2 10.5.4.3']
|
||||||
|
@ -190,7 +260,8 @@ class MonContextTest(CharmTestCase):
|
||||||
'frontend': 'beast',
|
'frontend': 'beast',
|
||||||
'relaxed_s3_bucket_names': False,
|
'relaxed_s3_bucket_names': False,
|
||||||
'rgw_zonegroup': 'zonegroup1',
|
'rgw_zonegroup': 'zonegroup1',
|
||||||
'rgw_realm': 'realmX'
|
'rgw_realm': 'realmX',
|
||||||
|
'behind_https_proxy': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expect, mon_ctxt())
|
self.assertEqual(expect, mon_ctxt())
|
||||||
self.assertFalse(mock_ensure_rsv_v6.called)
|
self.assertFalse(mock_ensure_rsv_v6.called)
|
||||||
|
@ -202,9 +273,13 @@ class MonContextTest(CharmTestCase):
|
||||||
self.assertEqual(expect, mon_ctxt())
|
self.assertEqual(expect, mon_ctxt())
|
||||||
self.assertTrue(mock_ensure_rsv_v6.called)
|
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:
|
@patch.object(ceph, 'config', lambda *args:
|
||||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
'{"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'
|
self.socket.gethostname.return_value = 'testhost'
|
||||||
mon_ctxt = context.MonContext()
|
mon_ctxt = context.MonContext()
|
||||||
self.relation_get.return_value = None
|
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.related_units.return_value = ['ceph/0', 'ceph/1', 'ceph/2']
|
||||||
self.assertEqual({}, mon_ctxt())
|
self.assertEqual({}, mon_ctxt())
|
||||||
|
|
||||||
|
@patch('charmhelpers.contrib.hahelpers.cluster.relation_ids')
|
||||||
|
@patch('charmhelpers.contrib.hahelpers.cluster.config_get')
|
||||||
@patch.object(ceph, 'config', lambda *args:
|
@patch.object(ceph, 'config', lambda *args:
|
||||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
'{"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'
|
self.socket.gethostname.return_value = 'testhost'
|
||||||
mon_ctxt = context.MonContext()
|
mon_ctxt = context.MonContext()
|
||||||
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
||||||
|
@ -253,13 +332,18 @@ class MonContextTest(CharmTestCase):
|
||||||
'frontend': 'beast',
|
'frontend': 'beast',
|
||||||
'relaxed_s3_bucket_names': False,
|
'relaxed_s3_bucket_names': False,
|
||||||
'rgw_zonegroup': 'zonegroup1',
|
'rgw_zonegroup': 'zonegroup1',
|
||||||
'rgw_realm': 'realmX'
|
'rgw_realm': 'realmX',
|
||||||
|
'behind_https_proxy': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expect, mon_ctxt())
|
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:
|
@patch.object(ceph, 'config', lambda *args:
|
||||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
'{"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'
|
self.socket.gethostname.return_value = 'testhost'
|
||||||
mon_ctxt = context.MonContext()
|
mon_ctxt = context.MonContext()
|
||||||
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
||||||
|
@ -298,7 +382,8 @@ class MonContextTest(CharmTestCase):
|
||||||
'frontend': 'beast',
|
'frontend': 'beast',
|
||||||
'relaxed_s3_bucket_names': False,
|
'relaxed_s3_bucket_names': False,
|
||||||
'rgw_zonegroup': 'zonegroup1',
|
'rgw_zonegroup': 'zonegroup1',
|
||||||
'rgw_realm': 'realmX'
|
'rgw_realm': 'realmX',
|
||||||
|
'behind_https_proxy': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expect, mon_ctxt())
|
self.assertEqual(expect, mon_ctxt())
|
||||||
|
|
||||||
|
@ -360,9 +445,13 @@ class MonContextTest(CharmTestCase):
|
||||||
_test_version = '16.2.0'
|
_test_version = '16.2.0'
|
||||||
context.validate_http_frontend('beast')
|
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:
|
@patch.object(ceph, 'config', lambda *args:
|
||||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
'{"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'
|
self.socket.gethostname.return_value = 'testhost'
|
||||||
mon_ctxt = context.MonContext()
|
mon_ctxt = context.MonContext()
|
||||||
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
addresses = ['10.5.4.1', '10.5.4.2', '10.5.4.3']
|
||||||
|
@ -401,7 +490,8 @@ class MonContextTest(CharmTestCase):
|
||||||
'frontend': 'beast',
|
'frontend': 'beast',
|
||||||
'relaxed_s3_bucket_names': False,
|
'relaxed_s3_bucket_names': False,
|
||||||
'rgw_zonegroup': 'zonegroup1',
|
'rgw_zonegroup': 'zonegroup1',
|
||||||
'rgw_realm': 'realmX'
|
'rgw_realm': 'realmX',
|
||||||
|
'behind_https_proxy': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expect, mon_ctxt())
|
self.assertEqual(expect, mon_ctxt())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue