[openstack-dev] [puppet][keystone] How to uniquely name Keystone v3 resources in puppet?
Rich Megginson
rmeggins at redhat.com
Mon Jun 22 14:02:34 UTC 2015
The problem with puppet-keystone and Keystone v3 domains is naming of
puppet resources contained within domains - users, groups, projects.
Suppose you have an admin user in domain "dom1" and an admin user in
domain "dom2". How do you declare these in puppet? You can't do
keystone_user { 'admin': domain => 'dom1'}
and
keystone_user { 'admin': domain => 'dom2'}
AFAIK, resource names in puppet have to be unique. I have introduced
the string "::" as the domain delimiter in puppet code. This allows you
to "fully qualify" resource names with the domain in all domain scoped
resources.
keystone_user { 'admin::dom1': }
and
keystone_user { 'admin': domain => 'dom2'}
This is a valid puppet manifest - the resource names are unique.
How do I refer to the "admin" user? For example, I want to have a role
assignment:
keystone_user_role { 'admin::dom2 at project::somedomain': roles =>
['adminrole'] }
How do I have an autorequire for the user? That is, I can't know, in
the autorequire method in the keystone_user_role.rb type code, if the
resource name is going to be 'admin' or 'admin::dom2'. If I just do
autorequire for ['admin'], that will cause problems if a) there is no
'admin' user because all 'admin' users are fully qualified b) the user
named 'admin' is the one in dom1
I could avoid using autorequire and force the use of explicit requires
=> 'name' in every keystone_user_role, but that would break existing
manifests.
I could use autorequire, but force manifest writers to be consistent
with fully qualified resource naming. That is, the manifest writer
would have to know that the resource name of the admin user in dom1 is
always 'admin::dom1' and the resource name of the admin user in dom2 is
always 'admin', and they must be used that way, consistently,
everywhere, even in deeply nested classes/defines.
Another problem is with the puppet provider self.instances method. This
method queries all of the external resources of a given type and
constructs something like a named puppet resource representing the
external resource. For example: the keystone_user self.instances does
'openstack user list --long' and creates named puppet resources.
What happens if openstack user list --long returns admin in dom1 and
admin in dom2? How does self.instances name these uniquely? If it
always names these "fully qualified" with ::domain, this will cause
problems. This could be handled with some extra logic:
1) If name is unique (i.e. there is only one user named 'admin' in all
domains), then just create the resource with the name 'admin' - no
::domain. This would require self.instances to keep track of every
returned resource e.g. collect all of the list results in a hash, and
only instantiate the resources once it is known that the name is unique.
2) If the resource is in the designated "default domain" (i.e. the
domain id matches [identity] default_domain_id, or 'default' if
[identity] default_domain_id not configured), then use the name without
the domain
2 seems like the intuitive way to go - works well with existing
manifests which are not yet domain aware, and things like puppet
resource keystone_user [name] will almost always work as expected. But
this means that manifest writers have to know that all puppet-keystone
manifests and code need to know what the domain name corresponding to
the default_domain_id is, and know that the resource in that domain
should always be referred to as 'name', not 'name::domain'. For
example, if you have user 'someuser' in domain 'Default', and domain
'Default' is the default domain with an id of 'default', all resources
should should use keystone_user { 'name': } and keystone_user_role {
'name at project': }
self.instances could return the fully qualified name _and_ the short
name, where the short name is the resource in the default domain. This
might cause confusion with puppet resource 'resource_name', when the
user sees both 'admin' and 'admin::dom1' but at least the user will see
one or the other, and both "puppet resource keystone_user admin" and
"puppet resource keystone_user admin::dom1" will work. This would
require some minor adjustment to the currently proposed patches for the
self.instances - self.instances would need to be aware of the default
domain and construct short names for those resources, and self.prefetch
would also need to know to use the shortnamed resource for the default
domain. In this case, the short name would be an "alias" for the fully
qualified name, sort of like a dns query where both the shortnames and
fqdns are returned.
More information about the OpenStack-dev
mailing list