Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
9d92125a
Commit
9d92125a
authored
May 24, 2013
by
Michael DeHaan
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2989 from lorin/keystone_user
OpenStack Identity (keystone) user module
parents
6ed01d2d
dbd9d928
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
320 additions
and
0 deletions
+320
-0
library/cloud/keystone_user
+320
-0
No files found.
library/cloud/keystone_user
0 → 100644
View file @
9d92125a
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Based on Jimmy Tang's implementation
DOCUMENTATION
=
'''
---
module: keystone_user
short_description: Manage OpenStack Identity (keystone) users, tenants and roles
requirements: [ python-keystoneclient ]
examples:
- code: 'keystone_user: tenant=demo tenant_description="Default Tenant"'
description: Create a tenant
- code: 'keystone_user: user=john tenant=demo password=secrete'
description: Create a user
- code: 'keystone_user: role=admin user=john tenant=demo'
description: Apply the admin role to the john user in the demo tenant
author: Lorin Hochstein
'''
try
:
from
keystoneclient.v2_0
import
client
except
ImportError
:
keystoneclient_found
=
False
else
:
keystoneclient_found
=
True
def
authenticate
(
endpoint
,
token
,
login_user
,
login_password
):
"""Return a keystone client object"""
if
token
:
return
client
.
Client
(
endpoint
=
endpoint
,
token
=
token
)
else
:
return
client
.
Client
(
endpoint
=
endpoint
,
username
=
login_user
,
password
=
login_password
)
def
tenant_exists
(
keystone
,
tenant
):
""" Return True if tenant already exists"""
return
tenant
in
[
x
.
name
for
x
in
keystone
.
tenants
.
list
()]
def
user_exists
(
keystone
,
user
):
"""" Return True if user already exists"""
return
user
in
[
x
.
name
for
x
in
keystone
.
users
.
list
()]
def
get_tenant
(
keystone
,
name
):
""" Retrieve a tenant by name"""
tenants
=
[
x
for
x
in
keystone
.
tenants
.
list
()
if
x
.
name
==
name
]
count
=
len
(
tenants
)
if
count
==
0
:
raise
KeyError
(
"No keystone tenants with name
%
s"
%
name
)
elif
count
>
1
:
raise
ValueError
(
"
%
d tenants with name
%
s"
%
(
count
,
name
))
else
:
return
tenants
[
0
]
def
get_user
(
keystone
,
name
):
""" Retrieve a user by name"""
users
=
[
x
for
x
in
keystone
.
users
.
list
()
if
x
.
name
==
name
]
count
=
len
(
users
)
if
count
==
0
:
raise
KeyError
(
"No keystone users with name
%
s"
%
name
)
elif
count
>
1
:
raise
ValueError
(
"
%
d users with name
%
s"
%
(
count
,
name
))
else
:
return
users
[
0
]
def
get_role
(
keystone
,
name
):
""" Retrieve a role by name"""
roles
=
[
x
for
x
in
keystone
.
roles
.
list
()
if
x
.
name
==
name
]
count
=
len
(
roles
)
if
count
==
0
:
raise
KeyError
(
"No keystone roles with name
%
s"
%
name
)
elif
count
>
1
:
raise
ValueError
(
"
%
d roles with name
%
s"
%
(
count
,
name
))
else
:
return
roles
[
0
]
def
get_tenant_id
(
keystone
,
name
):
return
get_tenant
(
keystone
,
name
)
.
id
def
get_user_id
(
keystone
,
name
):
return
get_user
(
keystone
,
name
)
.
id
def
ensure_tenant_exists
(
keystone
,
tenant_name
,
tenant_description
,
check_mode
):
""" Ensure that a tenant exists.
Return (True, id) if a new tenant was created, (False, None) if it
already existed.
"""
# Check if tenant already exists
try
:
tenant
=
get_tenant
(
keystone
,
tenant_name
)
except
KeyError
:
# Tenant doesn't exist yet
pass
else
:
if
tenant
.
description
==
tenant_description
:
return
(
False
,
tenant
.
id
)
else
:
# We need to update the tenant description
if
check_mode
:
return
(
True
,
tenant
.
id
)
else
:
tenant
.
update
(
description
=
tenant_description
)
return
(
True
,
tenant
.
id
)
# We now know we will have to create a new tenant
if
check_mode
:
return
(
True
,
None
)
ks_tenant
=
keystone
.
tenants
.
create
(
tenant_name
=
tenant_name
,
description
=
tenant_description
,
enabled
=
True
)
return
(
True
,
ks_tenant
.
id
)
def
ensure_tenant_absent
(
keystone
,
tenant
,
check_mode
):
""" Ensure that a tenant does not exist
Return True if the tenant was removed, False if it didn't exist
in the first place
"""
if
not
tenant_exists
(
keystone
,
tenant
):
return
False
# We now know we will have to delete the tenant
if
check_mode
:
return
True
def
ensure_user_exists
(
keystone
,
user_name
,
password
,
email
,
tenant_name
,
check_mode
):
""" Check if user exists
Return (True, id) if a new user was created, (False, id) user alrady
exists
"""
# Check if tenant already exists
try
:
user
=
get_user
(
keystone
,
user_name
)
except
KeyError
:
# Tenant doesn't exist yet
pass
else
:
# User does exist, we're done
return
(
False
,
user
.
id
)
# We now know we will have to create a new user
if
check_mode
:
return
(
True
,
None
)
tenant
=
get_tenant
(
keystone
,
tenant_name
)
user
=
keystone
.
users
.
create
(
name
=
user_name
,
password
=
password
,
email
=
email
,
tenant_id
=
tenant
.
id
)
return
(
True
,
user
.
id
)
def
ensure_role_exists
(
keystone
,
user_name
,
tenant_name
,
role_name
,
check_mode
):
""" Check if role exists
Return (True, id) if a new role was created or if the role was newly
assigned to the user for the tenant. (False, id) if the role already
exists and was already assigned to the user ofr the tenant.
"""
# Check if the user has the role in the tenant
user
=
get_user
(
keystone
,
user_name
)
tenant
=
get_tenant
(
keystone
,
tenant_name
)
roles
=
[
x
for
x
in
keystone
.
roles
.
roles_for_user
(
user
,
tenant
)
if
x
.
name
==
role_name
]
count
=
len
(
roles
)
if
count
==
1
:
# If the role is in there, we are done
role
=
roles
[
0
]
return
(
False
,
role
.
id
)
elif
count
>
1
:
# Too many roles with the same name, throw an error
raise
ValueError
(
"
%
d roles with name
%
s"
%
(
count
,
role_name
))
# At this point, we know we will need to make changes
if
check_mode
:
return
(
True
,
None
)
# Get the role if it exists
try
:
role
=
get_role
(
keystone
,
role_name
)
except
KeyError
:
# Role doesn't exist yet
role
=
keystone
.
roles
.
create
(
role_name
)
# Associate the role with the user in the admin
keystone
.
roles
.
add_user_role
(
user
,
role
,
tenant
)
return
(
True
,
role
.
id
)
def
ensure_user_absent
(
keystone
,
user
,
check_mode
):
raise
NotImplementedError
(
"Not yet implemented"
)
def
ensure_role_absent
(
keystone
,
uesr
,
tenant
,
role
,
check_mode
):
raise
NotImplementedError
(
"Not yet implemented"
)
def
main
():
module
=
AnsibleModule
(
argument_spec
=
dict
(
user
=
dict
(
required
=
False
),
password
=
dict
(
required
=
False
),
tenant
=
dict
(
required
=
False
),
tenant_description
=
dict
(
required
=
False
),
email
=
dict
(
required
=
False
),
role
=
dict
(
required
=
False
),
state
=
dict
(
default
=
'present'
,
choices
=
[
'present'
,
'absent'
]),
endpoint
=
dict
(
required
=
False
,
default
=
"http://127.0.0.1:35357/v2.0"
),
token
=
dict
(
required
=
False
),
login_user
=
dict
(
required
=
False
),
login_password
=
dict
(
required
=
False
)
),
supports_check_mode
=
True
,
mutually_exclusive
=
[[
'token'
,
'login_user'
],
[
'token'
,
'login_password'
]]
)
if
not
keystoneclient_found
:
module
.
fail_json
(
msg
=
"the python-keystoneclient module is required"
)
user
=
module
.
params
[
'user'
]
password
=
module
.
params
[
'password'
]
tenant
=
module
.
params
[
'tenant'
]
tenant_description
=
module
.
params
[
'tenant_description'
]
email
=
module
.
params
[
'email'
]
role
=
module
.
params
[
'role'
]
state
=
module
.
params
[
'state'
]
endpoint
=
module
.
params
[
'endpoint'
]
token
=
module
.
params
[
'token'
]
login_user
=
module
.
params
[
'login_user'
]
login_password
=
module
.
params
[
'login_password'
]
keystone
=
authenticate
(
endpoint
,
token
,
login_user
,
login_password
)
check_mode
=
module
.
check_mode
try
:
d
=
dispatch
(
keystone
,
user
,
password
,
tenant
,
tenant_description
,
email
,
role
,
state
,
endpoint
,
token
,
login_user
,
login_password
,
check_mode
)
except
Exception
as
e
:
if
check_mode
:
# If we have a failure in check mode
module
.
exit_json
(
changed
=
True
,
msg
=
"exception:
%
s"
%
e
.
message
)
else
:
module
.
fail_json
(
msg
=
e
.
message
)
else
:
module
.
exit_json
(
**
d
)
def
dispatch
(
keystone
,
user
=
None
,
password
=
None
,
tenant
=
None
,
tenant_description
=
None
,
email
=
None
,
role
=
None
,
state
=
"present"
,
endpoint
=
None
,
token
=
None
,
login_user
=
None
,
login_password
=
None
,
check_mode
=
False
):
""" Dispatch to the appropriate method.
Returns a dict that will be passed to exit_json
tenant user role state
------ ---- ---- --------
X present ensure_tenant_exists
X absent ensure_tenant_absent
X X present ensure_user_exists
X X absent ensure_user_absent
X X X present ensure_role_exists
X X X absent ensure_role_absent
"""
changed
=
False
id
=
None
if
tenant
and
not
user
and
not
role
and
state
==
"present"
:
changed
,
id
=
ensure_tenant_exists
(
keystone
,
tenant
,
tenant_description
,
check_mode
)
elif
tenant
and
not
user
and
not
role
and
state
==
"absent"
:
changed
=
ensure_tenant_absent
(
keystone
,
tenant
,
check_mode
)
elif
tenant
and
user
and
not
role
and
state
==
"present"
:
changed
,
id
=
ensure_user_exists
(
keystone
,
user
,
password
,
email
,
tenant
,
check_mode
)
elif
tenant
and
user
and
not
role
and
state
==
"absent"
:
changed
=
ensure_user_absent
(
keystone
,
user
,
check_mode
)
elif
tenant
and
user
and
role
and
state
==
"present"
:
changed
,
id
=
ensure_role_exists
(
keystone
,
user
,
tenant
,
role
,
check_mode
)
elif
tenant
and
user
and
role
and
state
==
"absent"
:
changed
=
ensure_role_absent
(
keystone
,
user
,
tenant
,
role
,
check_mode
)
else
:
# Should never reach here
raise
ValueError
(
"Code should never reach here"
)
return
dict
(
changed
=
changed
,
id
=
id
)
# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
if
__name__
==
'__main__'
:
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment