diff options
-rwxr-xr-x | bin/swift-dispersion-populate | 57 | ||||
-rw-r--r-- | doc/manpages/swift-dispersion-populate.1 | 2 | ||||
-rw-r--r-- | doc/source/overview_auth.rst | 90 | ||||
-rw-r--r-- | swift/common/middleware/keystoneauth.py | 27 |
4 files changed, 132 insertions, 44 deletions
diff --git a/bin/swift-dispersion-populate b/bin/swift-dispersion-populate index a475e40e4..93ca6ee2c 100755 --- a/bin/swift-dispersion-populate +++ b/bin/swift-dispersion-populate @@ -101,6 +101,10 @@ Usage: %%prog [options] [conf_file] parser.add_option('--insecure', action='store_true', default=False, help='Allow accessing insecure keystone server. ' 'The keystone\'s certificate will not be verified.') + parser.add_option('--no-overlap', action='store_true', default=False, + help='No overlap of partitions if running populate \ + more than once. Will increase coverage by amount shown \ + in dispersion.conf file') options, args = parser.parse_args() if args: @@ -144,6 +148,19 @@ Usage: %%prog [options] [conf_file] container_ring = Ring(swift_dir, ring_name='container') parts_left = dict((x, x) for x in xrange(container_ring.partition_count)) + + if options.no_overlap: + with connpool.item() as conn: + containers = [cont['name'] for cont in conn.get_account( + prefix='dispersion_', full_listing=True)[1]] + containers_listed = len(containers) + if containers_listed > 0: + for container in containers: + partition, _junk = container_ring.get_nodes(account, + container) + if partition in parts_left: + del parts_left[partition] + item_type = 'containers' created = 0 retries_done = 0 @@ -152,9 +169,9 @@ Usage: %%prog [options] [conf_file] begun = next_report = time() next_report += 2 suffix = 0 - while need_to_queue >= 1: + while need_to_queue >= 1 and parts_left: container = 'dispersion_%d' % suffix - part, _junk = container_ring.get_nodes(account, container) + part = container_ring.get_part(account, container) if part in parts_left: if suffix >= options.container_suffix_start: coropool.spawn(put_container, connpool, container, report) @@ -168,7 +185,13 @@ Usage: %%prog [options] [conf_file] elapsed, elapsed_unit = get_time_units(time() - begun) print '\r\x1B[KCreated %d containers for dispersion reporting, ' \ '%d%s, %d retries' % \ - (need_to_create, round(elapsed), elapsed_unit, retries_done) + ((need_to_create - need_to_queue), round(elapsed), elapsed_unit, + retries_done) + if options.no_overlap: + con_coverage = container_ring.partition_count - len(parts_left) + print '\r\x1B[KTotal container coverage is now %.2f%%.' % \ + ((float(con_coverage) / container_ring.partition_count + * 100)) stdout.flush() if object_populate: @@ -176,6 +199,23 @@ Usage: %%prog [options] [conf_file] put_container(connpool, container, None) object_ring = Ring(swift_dir, ring_name='object') parts_left = dict((x, x) for x in xrange(object_ring.partition_count)) + + if options.no_overlap: + with connpool.item() as conn: + obj_container = [cont_b['name'] for cont_b in conn.get_account( + prefix=container, full_listing=True)[1]] + if obj_container: + with connpool.item() as conn: + objects = [o['name'] for o in + conn.get_container(container, + prefix='dispersion_', + full_listing=True)[1]] + for my_object in objects: + partition = object_ring.get_part(account, container, + my_object) + if partition in parts_left: + del parts_left[partition] + item_type = 'objects' created = 0 retries_done = 0 @@ -184,9 +224,9 @@ Usage: %%prog [options] [conf_file] begun = next_report = time() next_report += 2 suffix = 0 - while need_to_queue >= 1: + while need_to_queue >= 1 and parts_left: obj = 'dispersion_%d' % suffix - part, _junk = object_ring.get_nodes(account, container, obj) + part = object_ring.get_part(account, container, obj) if part in parts_left: if suffix >= options.object_suffix_start: coropool.spawn( @@ -201,5 +241,10 @@ Usage: %%prog [options] [conf_file] elapsed, elapsed_unit = get_time_units(time() - begun) print '\r\x1B[KCreated %d objects for dispersion reporting, ' \ '%d%s, %d retries' % \ - (need_to_create, round(elapsed), elapsed_unit, retries_done) + ((need_to_create - need_to_queue), round(elapsed), elapsed_unit, + retries_done) + if options.no_overlap: + obj_coverage = object_ring.partition_count - len(parts_left) + print '\r\x1B[KTotal object coverage is now %.2f%%.' % \ + ((float(obj_coverage) / object_ring.partition_count * 100)) stdout.flush() diff --git a/doc/manpages/swift-dispersion-populate.1 b/doc/manpages/swift-dispersion-populate.1 index 01c5fe329..dd45e4e8e 100644 --- a/doc/manpages/swift-dispersion-populate.1 +++ b/doc/manpages/swift-dispersion-populate.1 @@ -72,6 +72,8 @@ Only run object population Only run container population .IP "\fB--object-only\fR" Only run object population +.IP "\fB--no-overlap\fR" +Increase coverage by amount in dispersion_coverage option with no overlap of existing partitions (if run more than once) .SH CONFIGURATION .PD 0 diff --git a/doc/source/overview_auth.rst b/doc/source/overview_auth.rst index 2bb00d73c..3b631692d 100644 --- a/doc/source/overview_auth.rst +++ b/doc/source/overview_auth.rst @@ -109,29 +109,33 @@ receive the auth token and a URL to the Swift system. Keystone Auth ------------- -Swift is able to authenticate against OpenStack keystone via the -:mod:`swift.common.middleware.keystoneauth` middleware. +Swift is able to authenticate against OpenStack Keystone_ via the +:ref:`keystoneauth` middleware. -In order to use the ``keystoneauth`` middleware the ``authtoken`` -middleware from keystonemiddleware will need to be configured. +In order to use the ``keystoneauth`` middleware the ``auth_token`` +middleware from KeystoneMiddleware_ will need to be configured. The ``authtoken`` middleware performs the authentication token validation and retrieves actual user authentication information. It -can be found in the keystonemiddleware distribution. +can be found in the KeystoneMiddleware_ distribution. -The ``keystoneauth`` middleware performs authorization and mapping the -``keystone`` roles to Swift's ACLs. +The :ref:`keystoneauth` middleware performs authorization and mapping the +Keystone roles to Swift's ACLs. + +.. _KeystoneMiddleware: http://docs.openstack.org/developer/keystonemiddleware/ +.. _Keystone: http://docs.openstack.org/developer/keystone/ Configuring Swift to use Keystone ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Configuring Swift to use Keystone is relatively straight -forward. The first step is to ensure that you have the auth_token -middleware installed, distributed with keystone it can either be -dropped in your python path or installed via the keystone package. +Configuring Swift to use Keystone_ +is relatively straight forward. The first +step is to ensure that you have the ``auth_token`` middleware installed. It can +either be dropped in your python path or installed via the KeystoneMiddleware_ +package. You need at first make sure you have a service endpoint of type -``object-store`` in keystone pointing to your Swift proxy. For example +``object-store`` in Keystone pointing to your Swift proxy. For example having this in your ``/etc/keystone/default_catalog.templates`` :: catalog.RegionOne.object_store.name = Swift Service @@ -161,8 +165,10 @@ add the configuration for the authtoken middleware:: include_service_catalog = False The actual values for these variables will need to be set depending on -your situation. For more information, please refer to the Keystone -documentation on the ``auth_token`` middleware, but in short: +your situation. For more information, please refer to the `Keystone +auth_token middleware documentation +<http://docs.openstack.org/developer/keystonemiddleware/middlewarearchitecture.html#configuration>`_, +but in short: * Those variables beginning with ``auth_`` point to the Keystone Admin service. This information is used by the middleware to actually @@ -171,20 +177,23 @@ documentation on the ``auth_token`` middleware, but in short: * The admin auth credentials (``admin_user``, ``admin_tenant_name``, ``admin_password``) will be used to retrieve an admin token. That token will be used to authorize user tokens behind the scenes. -* cache is set to ``swift.cache``. This means that the middleware +* ``cache`` is set to ``swift.cache``. This means that the middleware will get the Swift memcache from the request environment. -* include_service_catalog defaults to True if not set. This means +* ``include_service_catalog`` defaults to ``True`` if not set. This means that when validating a token, the service catalog is retrieved - and stored in the X-Service-Catalog header. Since Swift does not - use the X-Service-Catalog header, there is no point in getting - the service catalog. We recommend you set include_service_catalog - to False. + and stored in the ``X-Service-Catalog`` header. Since Swift does not + use the ``X-Service-Catalog`` header, there is no point in getting + the service catalog. We recommend you set ``include_service_catalog`` + to ``False``. +* If you wish to authenticate using Keystone's v3 API you must set the + ``auth_version`` option to ``v3.0``. .. note:: If support is required for unvalidated users (as with anonymous - access) or for tempurl/formpost middleware, authtoken will need + access or making capabilities requests using :ref:`discoverability`) or + for tempurl/formpost middleware, authtoken will need to be configured with delay_auth_decision set to 1. and you can finally add the keystoneauth configuration:: @@ -193,13 +202,40 @@ and you can finally add the keystoneauth configuration:: use = egg:swift#keystoneauth operator_roles = admin, swiftoperator -By default the only users able to give ACL or to Create other -containers are the ones who has the Keystone role specified in the -``operator_roles`` setting. +Access control using keystoneauth +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default the only users able to perform operations (e.g. create a container) +on an account are those having a Keystone role for the corresponding Keystone +project that matches one of the roles specified in the ``operator_roles`` +option. + +Users who have one of the ``operator_roles`` will be able to set container ACLs +to grant other users permission to read and/or write objects in specific +containers, using ``X-Container-Read`` and ``X-Container-Write`` headers +respectively. In addition to the ACL formats described +:mod:`here <swift.common.middleware.acl>`, keystoneauth supports ACLs using the +format:: + + other_project_id:other_user_id. + +where ``other_project_id`` is the UUID of a Keystone project and +``other_user_id`` is the UUID of a Keystone user. This will allow the other +user to access a container provided their token is scoped on the other +project. Both ``other_project_id`` and ``other_user_id`` may be replaced with +the wildcard character ``*`` which will match any project or user respectively. + +Be sure to use Keystone UUIDs rather than names in container ACLs. + +.. note:: + + For backwards compatibility, keystoneauth will by default grant container + ACLs expressed as ``other_project_name:other_user_name`` (i.e. using + Keystone names rather than UUIDs) in the special case when both the other + project and the other user are in Keystone's default domain and the project + being accessed is also in the default domain. -This user who have one of those role will be able to give ACLs to -other users on containers, see the documentation on ACL here -:mod:`swift.common.middleware.acl`. + For further information see :ref:`keystoneauth` Users with the Keystone role defined in ``reseller_admin_role`` (``ResellerAdmin`` by default) can operate on any account. The auth system diff --git a/swift/common/middleware/keystoneauth.py b/swift/common/middleware/keystoneauth.py index d342084ea..46a8367b5 100644 --- a/swift/common/middleware/keystoneauth.py +++ b/swift/common/middleware/keystoneauth.py @@ -79,20 +79,25 @@ class KeystoneAuth(object): reseller_prefix = NEWAUTH The keystoneauth middleware supports cross-tenant access control using - the syntax <tenant>:<user> in container Access Control Lists (ACLs). For - a request to be granted by an ACL, <tenant> must match the UUID of the - tenant to which the request token is scoped and <user> must match the - UUID of the user authenticated by the request token. + the syntax ``<tenant>:<user>`` to specify a grantee in container Access + Control Lists (ACLs). For a request to be granted by an ACL, the grantee + ``<tenant>`` must match the UUID of the tenant to which the request + token is scoped and the grantee ``<user>`` must match the UUID of the + user authenticated by the request token. Note that names must no longer be used in cross-tenant ACLs because with the introduction of domains in keystone names are no longer globally - unique. For backwards compatibility, ACLs using names will be granted by - keystoneauth when it can be established that both the grantee and the - tenant being accessed are either not yet in a domain (e.g. the request - token has been obtained via the keystone v2 API) or are both in the - default domain to which legacy accounts would have been migrated. The id - of the default domain is specified by the config option - ``default_domain_id``: + unique. + + For backwards compatibility, ACLs using names will be granted by + keystoneauth when it can be established that the grantee tenant, + the grantee user and the tenant being accessed are either not yet in a + domain (e.g. the request token has been obtained via the keystone v2 + API) or are all in the default domain to which legacy accounts would + have been migrated. The default domain is identified by its UUID, + which by default has the value ``default``. This can be changed by + setting the ``default_domain_id`` option in the keystoneauth + configuration:: default_domain_id = default |