Merge "Enable Ceph Radosgw tenant namespacing"
This commit is contained in:
commit
030189a81d
21
README.md
21
README.md
@ -228,3 +228,24 @@ a zone that is currently read-only can be switched to read/write mode by either
|
|||||||
promoting it to be the current master or by using the 'readwrite' action:
|
promoting it to be the current master or by using the 'readwrite' action:
|
||||||
|
|
||||||
juju run-action -m us-east --wait rgw-us-east/0 readwrite
|
juju run-action -m us-east --wait rgw-us-east/0 readwrite
|
||||||
|
|
||||||
|
Tenant Namespacing
|
||||||
|
------------------
|
||||||
|
|
||||||
|
By default, Ceph Rados Gateway puts all tenant buckets into the same global
|
||||||
|
namespace, disallowing multiple tenants to have buckets with the same name.
|
||||||
|
Tenant namespacing can be enabled in this charm by deploying with configuration
|
||||||
|
like:
|
||||||
|
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: cs:ceph-radosgw
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
namespace-tenants: True
|
||||||
|
|
||||||
|
Enabling tenant namespacing will place all tenant buckets into their own
|
||||||
|
namespace under their tenant id, as well as adding the tenant's ID parameter to
|
||||||
|
the Keystone endpoint registration to allow seamless integration with OpenStack.
|
||||||
|
Tenant namespacing cannot be toggled on in an existing installation as it will
|
||||||
|
remove tenant access to existing buckets. Toggling this option on an already
|
||||||
|
deployed Rados Gateway will have no effect.
|
15
config.yaml
15
config.yaml
@ -317,3 +317,18 @@ options:
|
|||||||
description: |
|
description: |
|
||||||
Name of RADOS Gateway Zone to create for multi-site replication. This
|
Name of RADOS Gateway Zone to create for multi-site replication. This
|
||||||
option must be specific to the local site e.g. us-west or us-east.
|
option must be specific to the local site e.g. us-west or us-east.
|
||||||
|
namespace-tenants:
|
||||||
|
type: boolean
|
||||||
|
default: False
|
||||||
|
description: |
|
||||||
|
Enable tenant namespacing. If tenant namespacing is enabled, keystone
|
||||||
|
tenants will be implicitly added to a matching tenant in radosgw, in
|
||||||
|
addition to updating the catalog URL to allow radosgw to support
|
||||||
|
publicly-readable containers and temporary URLS. This namespacing
|
||||||
|
also allows multiple tenants to create buckets with the same names,
|
||||||
|
as the bucket names are namespaced into the tenant namespaces in the
|
||||||
|
RADOS gateway.
|
||||||
|
|
||||||
|
This configuration option will not be enabled on a charm upgrade, and
|
||||||
|
cannot be toggled on in an existing installation as it will remove
|
||||||
|
tenant access to existing buckets.
|
||||||
|
@ -33,6 +33,7 @@ from charmhelpers.core.hookenv import (
|
|||||||
relation_get,
|
relation_get,
|
||||||
relation_ids,
|
relation_ids,
|
||||||
unit_public_ip,
|
unit_public_ip,
|
||||||
|
leader_get,
|
||||||
)
|
)
|
||||||
from charmhelpers.contrib.network.ip import (
|
from charmhelpers.contrib.network.ip import (
|
||||||
format_ipv6_addr,
|
format_ipv6_addr,
|
||||||
@ -104,6 +105,7 @@ class IdentityServiceContext(context.IdentityServiceContext):
|
|||||||
if config('admin-roles'):
|
if config('admin-roles'):
|
||||||
ctxt['user_roles'] += (',' + config('admin-roles'))
|
ctxt['user_roles'] += (',' + config('admin-roles'))
|
||||||
ctxt['cache_size'] = config('cache-size')
|
ctxt['cache_size'] = config('cache-size')
|
||||||
|
ctxt['namespace_tenants'] = leader_get('namespace_tenants')
|
||||||
if self.context_complete(ctxt):
|
if self.context_complete(ctxt):
|
||||||
return ctxt
|
return ctxt
|
||||||
return {}
|
return {}
|
||||||
|
@ -170,6 +170,14 @@ def install():
|
|||||||
install_packages()
|
install_packages()
|
||||||
if not os.path.exists('/etc/ceph'):
|
if not os.path.exists('/etc/ceph'):
|
||||||
os.makedirs('/etc/ceph')
|
os.makedirs('/etc/ceph')
|
||||||
|
if is_leader():
|
||||||
|
leader_set(namespace_tenants=config('namespace-tenants'))
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.hook('upgrade-charm.real')
|
||||||
|
def upgrade_charm():
|
||||||
|
if is_leader() and not leader_get('namespace_tenants'):
|
||||||
|
leader_set(namespace_tenants=False)
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('config-changed')
|
@hooks.hook('config-changed')
|
||||||
@ -294,6 +302,12 @@ def identity_joined(relid=None):
|
|||||||
|
|
||||||
port = config('port')
|
port = config('port')
|
||||||
admin_url = '%s:%i/swift' % (canonical_url(CONFIGS, ADMIN), port)
|
admin_url = '%s:%i/swift' % (canonical_url(CONFIGS, ADMIN), port)
|
||||||
|
if leader_get('namespace_tenants'):
|
||||||
|
internal_url = '%s:%s/swift/v1/AUTH_$(project_id)s' % \
|
||||||
|
(canonical_url(CONFIGS, INTERNAL), port)
|
||||||
|
public_url = '%s:%s/swift/v1/AUTH_$(project_id)s' % \
|
||||||
|
(canonical_url(CONFIGS, PUBLIC), port)
|
||||||
|
else:
|
||||||
internal_url = '%s:%s/swift/v1' % \
|
internal_url = '%s:%s/swift/v1' % \
|
||||||
(canonical_url(CONFIGS, INTERNAL), port)
|
(canonical_url(CONFIGS, INTERNAL), port)
|
||||||
public_url = '%s:%s/swift/v1' % \
|
public_url = '%s:%s/swift/v1' % \
|
||||||
|
@ -7,3 +7,5 @@ find . -name '__pycache__' -prune -exec rm -rf "{}" \;
|
|||||||
|
|
||||||
# Re-install dependencies to deal with py2->py3 switch for charm
|
# Re-install dependencies to deal with py2->py3 switch for charm
|
||||||
./hooks/install_deps
|
./hooks/install_deps
|
||||||
|
|
||||||
|
./hooks/upgrade-charm.real
|
||||||
|
1
hooks/upgrade-charm.real
Symbolic link
1
hooks/upgrade-charm.real
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
hooks.py
|
@ -55,6 +55,10 @@ rgw keystone accepted admin roles = {{ admin_roles }}
|
|||||||
rgw keystone token cache size = {{ cache_size }}
|
rgw keystone token cache size = {{ cache_size }}
|
||||||
rgw s3 auth use keystone = true
|
rgw s3 auth use keystone = true
|
||||||
rgw s3 auth order = local, external
|
rgw s3 auth order = local, external
|
||||||
|
{% if namespace_tenants %}
|
||||||
|
rgw swift account in url = true
|
||||||
|
rgw keystone implicit tenants = true
|
||||||
|
{% endif %}
|
||||||
{% else -%}
|
{% else -%}
|
||||||
rgw swift url = http://{{ unit_public_ip }}
|
rgw swift url = http://{{ unit_public_ip }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
44
tests/bundles/bionic-queens-namespaced.yaml
Normal file
44
tests/bundles/bionic-queens-namespaced.yaml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
options:
|
||||||
|
source: &source distro
|
||||||
|
series: bionic
|
||||||
|
applications:
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: ceph-radosgw
|
||||||
|
num_units: 1
|
||||||
|
series: bionic
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: "mem=2048"
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,10G'
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
osd-devices: '/srv/ceph /dev/test-non-existent'
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
auth-supported: 'none'
|
||||||
|
percona-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/percona-cluster
|
||||||
|
num_units: 1
|
||||||
|
keystone:
|
||||||
|
expose: True
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
relations:
|
||||||
|
- - keystone:shared-db
|
||||||
|
- percona-cluster:shared-db
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
44
tests/bundles/bionic-rocky-namespaced.yaml
Normal file
44
tests/bundles/bionic-rocky-namespaced.yaml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
options:
|
||||||
|
source: &source cloud:bionic-rocky
|
||||||
|
series: bionic
|
||||||
|
applications:
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: ceph-radosgw
|
||||||
|
series: bionic
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: "mem=2048"
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,10G'
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
osd-devices: '/srv/ceph /dev/test-non-existent'
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
auth-supported: 'none'
|
||||||
|
percona-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/percona-cluster
|
||||||
|
num_units: 1
|
||||||
|
keystone:
|
||||||
|
expose: True
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
relations:
|
||||||
|
- - keystone:shared-db
|
||||||
|
- percona-cluster:shared-db
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
44
tests/bundles/bionic-stein-namespaced.yaml
Normal file
44
tests/bundles/bionic-stein-namespaced.yaml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
options:
|
||||||
|
source: &source cloud:bionic-stein
|
||||||
|
series: bionic
|
||||||
|
applications:
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: ceph-radosgw
|
||||||
|
series: bionic
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: "mem=2048"
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,10G'
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
osd-devices: '/srv/ceph /dev/test-non-existent'
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
auth-supported: 'none'
|
||||||
|
percona-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/percona-cluster
|
||||||
|
num_units: 1
|
||||||
|
keystone:
|
||||||
|
expose: True
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
relations:
|
||||||
|
- - keystone:shared-db
|
||||||
|
- percona-cluster:shared-db
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
44
tests/bundles/xenial-mitaka-namespaced.yaml
Normal file
44
tests/bundles/xenial-mitaka-namespaced.yaml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
options:
|
||||||
|
source: &source distro
|
||||||
|
series: xenial
|
||||||
|
applications:
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: ceph-radosgw
|
||||||
|
series: xenial
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: "mem=2048"
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,10G'
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
osd-devices: '/srv/ceph /dev/test-non-existent'
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
auth-supported: 'none'
|
||||||
|
percona-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/percona-cluster
|
||||||
|
num_units: 1
|
||||||
|
keystone:
|
||||||
|
expose: True
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
relations:
|
||||||
|
- - keystone:shared-db
|
||||||
|
- percona-cluster:shared-db
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
@ -1,12 +1,16 @@
|
|||||||
charm_name: ceph-radosgw
|
charm_name: ceph-radosgw
|
||||||
gate_bundles:
|
gate_bundles:
|
||||||
- bionic-stein
|
- bionic-stein
|
||||||
|
- bionic-stein-namespaced
|
||||||
- bionic-rocky
|
- bionic-rocky
|
||||||
|
- bionic-rocky-namespaced
|
||||||
- bionic-queens
|
- bionic-queens
|
||||||
|
- bionic-queens-namespaced
|
||||||
- xenial-queens
|
- xenial-queens
|
||||||
- xenial-pike
|
- xenial-pike
|
||||||
- xenial-ocata
|
- xenial-ocata
|
||||||
- xenial-mitaka
|
- xenial-mitaka
|
||||||
|
- xenial-mitaka-namespaced
|
||||||
- trusty-mitaka
|
- trusty-mitaka
|
||||||
smoke_bundles:
|
smoke_bundles:
|
||||||
- bionic-stein
|
- bionic-stein
|
||||||
|
@ -31,6 +31,7 @@ TO_PATCH = [
|
|||||||
'unit_public_ip',
|
'unit_public_ip',
|
||||||
'determine_api_port',
|
'determine_api_port',
|
||||||
'cmp_pkgrevno',
|
'cmp_pkgrevno',
|
||||||
|
'leader_get',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
self.config.side_effect = self.test_config.get
|
self.config.side_effect = self.test_config.get
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
self.cmp_pkgrevno.return_value = 1
|
self.cmp_pkgrevno.return_value = 1
|
||||||
|
self.leader_get.return_value = False
|
||||||
|
|
||||||
@patch.object(charmhelpers.contrib.openstack.context,
|
@patch.object(charmhelpers.contrib.openstack.context,
|
||||||
'filter_installed_packages', return_value=['absent-pkg'])
|
'filter_installed_packages', return_value=['absent-pkg'])
|
||||||
@ -124,6 +126,74 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
'auth_port': 5432,
|
'auth_port': 5432,
|
||||||
'auth_protocol': 'http',
|
'auth_protocol': 'http',
|
||||||
'auth_type': 'keystone',
|
'auth_type': 'keystone',
|
||||||
|
'namespace_tenants': False,
|
||||||
|
'cache_size': '42',
|
||||||
|
'service_host': '127.0.0.4',
|
||||||
|
'service_port': 9876,
|
||||||
|
'service_protocol': 'http',
|
||||||
|
}
|
||||||
|
if cmp_pkgrevno_side_effects and cmp_pkgrevno_side_effects[1] >= 0:
|
||||||
|
expect['user_roles'] = 'Babel'
|
||||||
|
expect['admin_roles'] = 'Dart'
|
||||||
|
else:
|
||||||
|
expect['user_roles'] = 'Babel,Dart'
|
||||||
|
if jewel_installed:
|
||||||
|
expect['auth_keystone_v3_supported'] = True
|
||||||
|
self.assertEqual(expect, ids_ctxt())
|
||||||
|
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context,
|
||||||
|
'filter_installed_packages', return_value=['absent-pkg'])
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context, 'format_ipv6_addr')
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context, 'context_complete')
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context, 'relation_get')
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context, 'related_units')
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context, 'relation_ids')
|
||||||
|
@patch.object(charmhelpers.contrib.openstack.context, 'log')
|
||||||
|
def test_ids_ctxt_with_namespace(self, _log, _rids, _runits, _rget,
|
||||||
|
_ctxt_comp, _format_ipv6_addr,
|
||||||
|
_filter_installed_packages,
|
||||||
|
jewel_installed=False,
|
||||||
|
cmp_pkgrevno_side_effects=None):
|
||||||
|
self.cmp_pkgrevno.side_effect = (cmp_pkgrevno_side_effects
|
||||||
|
if cmp_pkgrevno_side_effects
|
||||||
|
else [-1, -1])
|
||||||
|
self.test_config.set('operator-roles', 'Babel')
|
||||||
|
self.test_config.set('admin-roles', 'Dart')
|
||||||
|
self.test_config.set('cache-size', '42')
|
||||||
|
self.test_relation.set({'admin_token': 'ubuntutesting'})
|
||||||
|
self.relation_ids.return_value = ['identity-service:5']
|
||||||
|
self.related_units.return_value = ['keystone/0']
|
||||||
|
_format_ipv6_addr.return_value = False
|
||||||
|
_rids.return_value = 'rid1'
|
||||||
|
_runits.return_value = 'runit'
|
||||||
|
_ctxt_comp.return_value = True
|
||||||
|
self.leader_get.return_value = True
|
||||||
|
id_data = {
|
||||||
|
'service_port': 9876,
|
||||||
|
'service_host': '127.0.0.4',
|
||||||
|
'service_tenant_id': '2852107b8f8f473aaf0d769c7bbcf86b',
|
||||||
|
'service_domain_id': '8e50f28a556911e8aaeed33789425d23',
|
||||||
|
'auth_host': '127.0.0.5',
|
||||||
|
'auth_port': 5432,
|
||||||
|
'service_tenant': 'ten',
|
||||||
|
'service_username': 'admin',
|
||||||
|
'service_password': 'adminpass',
|
||||||
|
}
|
||||||
|
_rget.return_value = id_data
|
||||||
|
ids_ctxt = context.IdentityServiceContext()
|
||||||
|
expect = {
|
||||||
|
'admin_domain_id': '8e50f28a556911e8aaeed33789425d23',
|
||||||
|
'admin_password': 'adminpass',
|
||||||
|
'admin_tenant_id': '2852107b8f8f473aaf0d769c7bbcf86b',
|
||||||
|
'admin_tenant_name': 'ten',
|
||||||
|
'admin_token': 'ubuntutesting',
|
||||||
|
'admin_user': 'admin',
|
||||||
|
'api_version': '2.0',
|
||||||
|
'auth_host': '127.0.0.5',
|
||||||
|
'auth_port': 5432,
|
||||||
|
'auth_protocol': 'http',
|
||||||
|
'auth_type': 'keystone',
|
||||||
|
'namespace_tenants': True,
|
||||||
'cache_size': '42',
|
'cache_size': '42',
|
||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
'service_port': 9876,
|
'service_port': 9876,
|
||||||
@ -185,6 +255,7 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
'auth_port': 5432,
|
'auth_port': 5432,
|
||||||
'auth_protocol': 'http',
|
'auth_protocol': 'http',
|
||||||
'auth_type': 'keystone',
|
'auth_type': 'keystone',
|
||||||
|
'namespace_tenants': False,
|
||||||
'cache_size': '42',
|
'cache_size': '42',
|
||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
'service_port': 9876,
|
'service_port': 9876,
|
||||||
@ -247,6 +318,7 @@ class IdentityServiceContextTest(CharmTestCase):
|
|||||||
'auth_port': 5432,
|
'auth_port': 5432,
|
||||||
'auth_protocol': 'http',
|
'auth_protocol': 'http',
|
||||||
'auth_type': 'keystone',
|
'auth_type': 'keystone',
|
||||||
|
'namespace_tenants': False,
|
||||||
'cache_size': '42',
|
'cache_size': '42',
|
||||||
'service_domain_id': '8e50f28a556911e8aaeed33789425d23',
|
'service_domain_id': '8e50f28a556911e8aaeed33789425d23',
|
||||||
'service_host': '127.0.0.4',
|
'service_host': '127.0.0.4',
|
||||||
|
@ -145,11 +145,28 @@ class CephRadosGWTests(CharmTestCase):
|
|||||||
ceph_hooks.APACHE_PACKAGES
|
ceph_hooks.APACHE_PACKAGES
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_install(self):
|
@patch.object(ceph_hooks, 'leader_set')
|
||||||
|
@patch.object(ceph_hooks, 'is_leader')
|
||||||
|
def test_install(self, is_leader, leader_set):
|
||||||
_install_packages = self.patch('install_packages')
|
_install_packages = self.patch('install_packages')
|
||||||
|
is_leader.return_value = True
|
||||||
ceph_hooks.install()
|
ceph_hooks.install()
|
||||||
self.assertTrue(self.execd_preinstall.called)
|
self.assertTrue(self.execd_preinstall.called)
|
||||||
self.assertTrue(_install_packages.called)
|
self.assertTrue(_install_packages.called)
|
||||||
|
is_leader.assert_called_once()
|
||||||
|
leader_set.assert_called_once_with(namespace_tenants=False)
|
||||||
|
|
||||||
|
@patch.object(ceph_hooks, 'leader_set')
|
||||||
|
@patch.object(ceph_hooks, 'is_leader')
|
||||||
|
def test_install_without_namespacing(self, is_leader, leader_set):
|
||||||
|
_install_packages = self.patch('install_packages')
|
||||||
|
is_leader.return_value = True
|
||||||
|
self.test_config.set('namespace-tenants', True)
|
||||||
|
ceph_hooks.install()
|
||||||
|
self.assertTrue(self.execd_preinstall.called)
|
||||||
|
self.assertTrue(_install_packages.called)
|
||||||
|
is_leader.assert_called_once()
|
||||||
|
leader_set.assert_called_once_with(namespace_tenants=True)
|
||||||
|
|
||||||
@patch.object(ceph_hooks, 'certs_joined')
|
@patch.object(ceph_hooks, 'certs_joined')
|
||||||
@patch.object(ceph_hooks, 'update_nrpe_config')
|
@patch.object(ceph_hooks, 'update_nrpe_config')
|
||||||
@ -231,19 +248,22 @@ class CephRadosGWTests(CharmTestCase):
|
|||||||
ceph_hooks.gateway_relation()
|
ceph_hooks.gateway_relation()
|
||||||
self.relation_set.assert_called_with(hostname='10.0.0.1', port=80)
|
self.relation_set.assert_called_with(hostname='10.0.0.1', port=80)
|
||||||
|
|
||||||
|
@patch.object(ceph_hooks, 'leader_get')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
||||||
lambda *args: 'ceph-radosgw')
|
lambda *args: 'ceph-radosgw')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.config')
|
@patch('charmhelpers.contrib.openstack.ip.config')
|
||||||
def test_identity_joined_early_version(self, _config):
|
def test_identity_joined_early_version(self, _config, _leader_get):
|
||||||
self.cmp_pkgrevno.return_value = -1
|
self.cmp_pkgrevno.return_value = -1
|
||||||
|
_leader_get.return_value = False
|
||||||
ceph_hooks.identity_joined()
|
ceph_hooks.identity_joined()
|
||||||
self.sys.exit.assert_called_with(1)
|
self.sys.exit.assert_called_with(1)
|
||||||
|
|
||||||
|
@patch.object(ceph_hooks, 'leader_get')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
||||||
lambda *args: 'ceph-radosgw')
|
lambda *args: 'ceph-radosgw')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.resolve_address')
|
@patch('charmhelpers.contrib.openstack.ip.resolve_address')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.config')
|
@patch('charmhelpers.contrib.openstack.ip.config')
|
||||||
def test_identity_joined(self, _config, _resolve_address):
|
def test_identity_joined(self, _config, _resolve_address, _leader_get):
|
||||||
|
|
||||||
def _test_identify_joined(expected):
|
def _test_identify_joined(expected):
|
||||||
self.related_units = ['unit/0']
|
self.related_units = ['unit/0']
|
||||||
@ -251,6 +271,7 @@ class CephRadosGWTests(CharmTestCase):
|
|||||||
_resolve_address.return_value = 'myserv'
|
_resolve_address.return_value = 'myserv'
|
||||||
_config.side_effect = self.test_config.get
|
_config.side_effect = self.test_config.get
|
||||||
self.test_config.set('region', 'region1')
|
self.test_config.set('region', 'region1')
|
||||||
|
_leader_get.return_value = False
|
||||||
ceph_hooks.identity_joined(relid='rid')
|
ceph_hooks.identity_joined(relid='rid')
|
||||||
self.relation_set.assert_called_with(
|
self.relation_set.assert_called_with(
|
||||||
service='swift',
|
service='swift',
|
||||||
@ -270,18 +291,55 @@ class CephRadosGWTests(CharmTestCase):
|
|||||||
self.test_config.set('admin-roles', input.get('admin', ''))
|
self.test_config.set('admin-roles', input.get('admin', ''))
|
||||||
_test_identify_joined(input['expected'])
|
_test_identify_joined(input['expected'])
|
||||||
|
|
||||||
|
@patch.object(ceph_hooks, 'leader_get')
|
||||||
|
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
||||||
|
lambda *args: 'ceph-radosgw')
|
||||||
|
@patch('charmhelpers.contrib.openstack.ip.resolve_address')
|
||||||
|
@patch('charmhelpers.contrib.openstack.ip.config')
|
||||||
|
def test_identity_joined_namespaced(self, _config,
|
||||||
|
_resolve_address, _leader_get):
|
||||||
|
_leader_get.return_value = True
|
||||||
|
|
||||||
|
def _test_identify_joined(expected):
|
||||||
|
self.related_units = ['unit/0']
|
||||||
|
self.cmp_pkgrevno.return_value = 1
|
||||||
|
_resolve_address.return_value = 'myserv'
|
||||||
|
_config.side_effect = self.test_config.get
|
||||||
|
self.test_config.set('region', 'region1')
|
||||||
|
_leader_get.return_value = True
|
||||||
|
ceph_hooks.identity_joined(relid='rid')
|
||||||
|
self.relation_set.assert_called_with(
|
||||||
|
service='swift',
|
||||||
|
region='region1',
|
||||||
|
public_url='http://myserv:80/swift/v1/AUTH_$(project_id)s',
|
||||||
|
internal_url='http://myserv:80/swift/v1/AUTH_$(project_id)s',
|
||||||
|
requested_roles=expected,
|
||||||
|
relation_id='rid',
|
||||||
|
admin_url='http://myserv:80/swift')
|
||||||
|
|
||||||
|
inputs = [{'operator': 'foo', 'admin': 'bar', 'expected': 'foo,bar'},
|
||||||
|
{'operator': 'foo', 'expected': 'foo'},
|
||||||
|
{'admin': 'bar', 'expected': 'bar'},
|
||||||
|
{'expected': ''}]
|
||||||
|
for input in inputs:
|
||||||
|
self.test_config.set('operator-roles', input.get('operator', ''))
|
||||||
|
self.test_config.set('admin-roles', input.get('admin', ''))
|
||||||
|
_test_identify_joined(input['expected'])
|
||||||
|
|
||||||
|
@patch.object(ceph_hooks, 'leader_get')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
@patch('charmhelpers.contrib.openstack.ip.service_name',
|
||||||
lambda *args: 'ceph-radosgw')
|
lambda *args: 'ceph-radosgw')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.is_clustered')
|
@patch('charmhelpers.contrib.openstack.ip.is_clustered')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.unit_get')
|
@patch('charmhelpers.contrib.openstack.ip.unit_get')
|
||||||
@patch('charmhelpers.contrib.openstack.ip.config')
|
@patch('charmhelpers.contrib.openstack.ip.config')
|
||||||
def test_identity_joined_public_name(self, _config, _unit_get,
|
def test_identity_joined_public_name(self, _config, _unit_get,
|
||||||
_is_clustered):
|
_is_clustered, _leader_get):
|
||||||
self.related_units = ['unit/0']
|
self.related_units = ['unit/0']
|
||||||
_config.side_effect = self.test_config.get
|
_config.side_effect = self.test_config.get
|
||||||
self.test_config.set('os-public-hostname', 'files.example.com')
|
self.test_config.set('os-public-hostname', 'files.example.com')
|
||||||
_unit_get.return_value = 'myserv'
|
_unit_get.return_value = 'myserv'
|
||||||
_is_clustered.return_value = False
|
_is_clustered.return_value = False
|
||||||
|
_leader_get.return_value = False
|
||||||
ceph_hooks.identity_joined(relid='rid')
|
ceph_hooks.identity_joined(relid='rid')
|
||||||
self.relation_set.assert_called_with(
|
self.relation_set.assert_called_with(
|
||||||
service='swift',
|
service='swift',
|
||||||
|
Loading…
Reference in New Issue
Block a user