Initial keystone-credentials interface

Create the interface for keystone-credentials (identity-credentials)
This commit is contained in:
David Ames 2016-05-02 15:56:20 -07:00
commit e0df0b3bbf
6 changed files with 197 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.tox

21
copyright Normal file
View File

@ -0,0 +1,21 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0
Files: *
Copyright: 2015, Canonical Ltd.
License: Apache-2.0
License: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
.
On Debian-based systems the full text of the Apache version 2.0 license
can be found in `/usr/share/common-licenses/Apache-2.0'.

16
interface.yaml Normal file
View File

@ -0,0 +1,16 @@
name: keystone-credentials
summary: >
Interface for integrating with Keystone identity credentials
Charms use this relation to obtain keystone credentials
without creating a service catalog entry. Set 'username'
only on the relation and keystone will set defaults and
return authentication details. Possible relation settings:
username: Username to be created.
project: Project (tenant) name to be created. Defaults to services
project.
requested_roles: Comma delimited list of roles to be created
requested_grants: Comma delimited list of roles to be granted.
Defaults to Admin role.
domain: Keystone v3 domain the user will be created in. Defaults
to the Default domain.
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>

131
requires.py Normal file
View File

@ -0,0 +1,131 @@
#!/usr/bin/python
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from charms.reactive import RelationBase
from charms.reactive import hook
from charms.reactive import scopes
class KeystoneRequires(RelationBase):
scope = scopes.GLOBAL
# These remote data fields will be automatically mapped to accessors
# with a basic documentation string provided.
auto_accessors = ['private-address', 'credentials_host',
'credentials_protocol', 'credentials_port',
'credentials_project', 'credentials_username',
'credentials_password', 'credentials_project_id',
'api_version', 'auth_host', 'auth_protocol', 'auth_port',
'region', 'ca_cert', 'https_keystone']
@hook('{requires:keystone-credentials}-relation-joined')
def joined(self):
self.set_state('{relation_name}.connected')
self.update_state()
def update_state(self):
"""Update the states of the relations based on the data that the
relation has.
If the :meth:`base_data_complete` is False then all of the states
are removed. Otherwise, the individual states are set according to
their own data methods.
"""
base_complete = self.base_data_complete()
states = {
'{relation_name}.available': True,
'{relation_name}.available.ssl': self.ssl_data_complete(),
'{relation_name}.available.auth': self.auth_data_complete()
}
for k, v in states.items():
if base_complete and v:
self.set_state(k)
else:
self.remove_state(k)
@hook('{requires:keystone-credentials}-relation-changed')
def changed(self):
self.update_state()
@hook('{requires:keystone-credentials}-relation-{broken,departed}')
def departed(self):
self.update_state()
def base_data_complete(self):
data = {
'private-address': self.private_address(),
'credentials_host': self.credentials_host(),
'credentials_protocol': self.credentials_protocol(),
'credentials_port': self.credentials_port(),
'api_version': self.api_version(),
'auth_host': self.auth_host(),
'auth_protocol': self.auth_protocol(),
'auth_port': self.auth_port(),
}
if all(data.values()):
return True
return False
def auth_data_complete(self):
data = {
'credentials_project': self.credentials_project(),
'credentials_username': self.credentials_username(),
'credentials_password': self.credentials_password(),
'credentials_project_id': self.credentials_project_id(),
}
if all(data.values()):
return True
return False
def ssl_data_complete(self):
data = {
'https_keystone': self.https_keystone(),
'ca_cert': self.ca_cert(),
}
for value in data.values():
if not value or value == '__null__':
return False
return True
def request_credentials(self, username, project=None, region=None,
requested_roles=None, requested_grants=None,
domain=None):
"""
Request credentials from Keystone
:side effect: set requested paramaters on the identity-credentials
relation
Required parameter
:param username: Username to be created.
Optional parametrs
:param project: Project (tenant) name to be created. Defaults to
services project.
:param requested_roles: Comma delimited list of roles to be created
:param requested_grants: Comma delimited list of roles to be granted.
Defaults to Admin role.
:param domain: Keystone v3 domain the user will be created in. Defaults
to the Default domain.
"""
relation_info = {
'username': username,
'project': project,
'requested_roles': requested_roles,
'requested_grants': requested_grants,
'domain': domain,
}
self.set_local(**relation_info)
self.set_remote(**relation_info)

3
test-requirements.txt Normal file
View File

@ -0,0 +1,3 @@
flake8>=2.2.4,<=2.4.1
os-testr>=0.4.1
charm-tools

25
tox.ini Normal file
View File

@ -0,0 +1,25 @@
[tox]
envlist = lint,py27
skipsdist = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
install_command =
pip install --allow-unverified python-apt {opts} {packages}
commands = ostestr {posargs}
[testenv:py27]
basepython = python2.7
deps = -r{toxinidir}/test-requirements.txt
[testenv:lint]
basepython = python2.7
deps = -r{toxinidir}/test-requirements.txt
commands = flake8 {posargs}
[testenv:venv]
commands = {posargs}
[flake8]
ignore = E402,E226