Hello community,
here is the log from the commit of package python-castellan for openSUSE:Factory checked in at 2019-05-03 22:39:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-castellan (Old)
and /work/SRC/openSUSE:Factory/.python-castellan.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-castellan"
Fri May 3 22:39:59 2019 rev:8 rq:692817 version:1.2.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-castellan/python-castellan.changes 2018-10-09 15:53:40.722317479 +0200
+++ /work/SRC/openSUSE:Factory/.python-castellan.new.5148/python-castellan.changes 2019-05-03 22:40:01.654938630 +0200
@@ -1,0 +2,25 @@
+Mon Apr 8 13:56:51 UTC 2019 - cloud-devel@suse.de
+
+- update to version 1.2.2
+ - Bump HashiCorp Vault version for tests.
+ - Change openstack-dev to openstack-discuss
+ - fix tox python3 overrides
+ - Fix Vault K/V API compatibility.
+ - Add release note link in README
+ - Switch to stestr
+ - Add Castellan Oslo Config Driver.
+ - Fix length usage in VaultKeyManager.create_key.
+ - vault: add AppRole support
+ - Update reno for stable/rocky
+ - Update min tox version to 2.0
+ - Don't quote {posargs} in tox.ini
+ - Use template for lower-constraints
+ - Add method to wrap HashiCorp Vault HTTP API calls.
+ - Set py3 tests according to Stein runtimes.
+ - add python 3.6 unit test job
+ - vault: support configuration of KV mountpoint
+ - add python 3.7 unit test job
+ - import zuul job settings from project-config
+ - Add code to generate private keys
+
+-------------------------------------------------------------------
Old:
----
castellan-0.19.0.tar.gz
New:
----
castellan-1.2.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-castellan.spec ++++++
--- /var/tmp/diff_new_pack.E9P1Bf/_old 2019-05-03 22:40:02.474940334 +0200
+++ /var/tmp/diff_new_pack.E9P1Bf/_new 2019-05-03 22:40:02.474940334 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-castellan
#
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -12,50 +12,55 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: python-castellan
-Version: 0.19.0
+Version: 1.2.2
Release: 0
Summary: Generic Key Manager interface for OpenStack
License: Apache-2.0
Group: Development/Languages/Python
URL: https://launchpad.net/castellan
-Source0: https://files.pythonhosted.org/packages/source/c/castellan/castellan-0.19.0....
+Source0: https://files.pythonhosted.org/packages/source/c/castellan/castellan-1.2.2.t...
BuildRequires: openstack-macros
BuildRequires: python2-barbicanclient >= 4.5.2
BuildRequires: python2-cryptography >= 2.1
BuildRequires: python2-keystoneauth1 >= 3.4.0
-BuildRequires: python2-oslo.config >= 5.2.0
+BuildRequires: python2-oslo.config >= 6.4.0
BuildRequires: python2-oslo.log >= 3.36.0
BuildRequires: python2-oslotest
+BuildRequires: python2-pifpaf
BuildRequires: python2-python-subunit
+BuildRequires: python2-reno
BuildRequires: python2-setuptools
-BuildRequires: python2-testrepository
+BuildRequires: python2-stestr
BuildRequires: python2-testscenarios
BuildRequires: python2-testtools
BuildRequires: python3-barbicanclient >= 4.5.2
BuildRequires: python3-cryptography >= 2.1
BuildRequires: python3-keystoneauth1 >= 3.4.0
-BuildRequires: python3-oslo.config >= 5.2.0
+BuildRequires: python3-oslo.config >= 6.4.0
BuildRequires: python3-oslo.log >= 3.36.0
BuildRequires: python3-oslotest
+BuildRequires: python3-pifpaf
BuildRequires: python3-python-subunit
+BuildRequires: python3-reno
BuildRequires: python3-setuptools
-BuildRequires: python3-testrepository
+BuildRequires: python3-stestr
BuildRequires: python3-testscenarios
BuildRequires: python3-testtools
Requires: python-Babel >= 2.3.4
+Requires: python-barbicanclient >= 4.5.2
Requires: python-cryptography >= 2.1
Requires: python-keystoneauth1 >= 3.4.0
-Requires: python-oslo.config >= 5.2.0
+Requires: python-oslo.config >= 6.4.0
Requires: python-oslo.context >= 2.19.2
+Requires: python-oslo.i18n >= 3.15.3
Requires: python-oslo.log >= 3.36.0
-Requires: python-oslo.policy
-Requires: python-oslo.serialization
Requires: python-oslo.utils >= 3.33.0
+Requires: python-stevedore >= 1.20.0
BuildArch: noarch
%python_subpackages
@@ -73,9 +78,8 @@
This package contains the documentation
%prep
-%autosetup -p1 -n castellan-0.19.0
+%autosetup -p1 -n castellan-1.2.2
%py_req_cleanup
-sed -i 's/^warning-is-error.*/warning-is-error = 0/g' setup.cfg
%build
%{python_build}
@@ -88,11 +92,7 @@
%{python_install}
%check
-%{python_expand rm -rf .testrepository
-# Functional tests require a working Keystone infrastructure
-export OS_TEST_PATH=./castellan/tests/unit
-$python setup.py test
-}
+%python_exec -m stestr.cli run
%files %{python_files}
%license LICENSE
++++++ _service ++++++
--- /var/tmp/diff_new_pack.E9P1Bf/_old 2019-05-03 22:40:02.498940383 +0200
+++ /var/tmp/diff_new_pack.E9P1Bf/_new 2019-05-03 22:40:02.498940383 +0200
@@ -1,8 +1,8 @@
<services>
<service mode="disabled" name="renderspec">
- <param name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/rocky/opens...</param>
+ <param name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/stein/opens...</param>
<param name="output-name">python-castellan.spec</param>
- <param name="requirements">https://raw.githubusercontent.com/openstack/castellan/stable/rocky/requireme...</param>
+ <param name="requirements">https://raw.githubusercontent.com/openstack/castellan/stable/stein/requireme...</param>
<param name="changelog-email">cloud-devel@suse.de</param>
<param name="changelog-provider">gh,openstack,castellan</param>
</service>
++++++ castellan-0.19.0.tar.gz -> castellan-1.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/.stestr.conf new/castellan-1.2.2/.stestr.conf
--- old/castellan-0.19.0/.stestr.conf 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/.stestr.conf 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,4 @@
+[DEFAULT]
+test_path=./castellan/tests
+top_dir=./
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/.testr.conf new/castellan-1.2.2/.testr.conf
--- old/castellan-0.19.0/.testr.conf 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/.testr.conf 1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
- OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
- OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
- ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./castellan/tests} $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/.zuul.yaml new/castellan-1.2.2/.zuul.yaml
--- old/castellan-0.19.0/.zuul.yaml 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/.zuul.yaml 2019-02-28 19:02:40.000000000 +0100
@@ -51,18 +51,18 @@
jobs:
- castellan-functional-vault
- castellan-functional-devstack
- - openstack-tox-lower-constraints
- barbican-simple-crypto-devstack-tempest-castellan-from-git
gate:
jobs:
- castellan-functional-vault
- castellan-functional-devstack
- - openstack-tox-lower-constraints
- barbican-simple-crypto-devstack-tempest-castellan-from-git
templates:
- - openstack-python-jobs
- - openstack-python35-jobs
- - release-notes-jobs-python3
- - publish-openstack-docs-pti
- check-requirements
+ - openstack-lower-constraints-jobs
+ - openstack-python-jobs
+ - openstack-python36-jobs
+ - openstack-python37-jobs
- periodic-stable-jobs
+ - publish-openstack-docs-pti
+ - release-notes-jobs-python3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/AUTHORS new/castellan-1.2.2/AUTHORS
--- old/castellan-0.19.0/AUTHORS 2018-08-21 22:04:14.000000000 +0200
+++ new/castellan-1.2.2/AUTHORS 2019-02-28 19:06:34.000000000 +0100
@@ -7,6 +7,7 @@
Brianna Poulos
Chris Solis
Christopher Solis
+Corey Bryant
Dai Dang Van
Davanum Srinivas
Dave McCowan
@@ -17,6 +18,7 @@
Fernando Diaz
Flavio Percoco
James E. Blair
+James Page
Jamie Lennox
Jeremy Liu
Jeremy Stanley
@@ -27,7 +29,10 @@
Kaitlin Farr
Kiran_totad
Michael McCune
+Moises Guimaraes de Medeiros
+Moisés Guimarães de Medeiros
Monty Taylor
+Nguyen Van Trung
Niall Bunting
OpenStack Release Bot
Paul Bourke
@@ -38,9 +43,9 @@
Tim Kelsey
Tom Cocozzello
Van Hung Pham
+Vu Cong Tuan
Yushiro FURUKAWA
Zhao Lei
-Zuul
bhavani.cr
dane-fichter
gaofei
@@ -52,6 +57,8 @@
rajat29
sonu.kumar
ting.wang
+wu.chunyang
xhzhf
yushangbin
+zhangzs
“Fernando
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/ChangeLog new/castellan-1.2.2/ChangeLog
--- old/castellan-0.19.0/ChangeLog 2018-08-21 22:04:14.000000000 +0200
+++ new/castellan-1.2.2/ChangeLog 2019-02-28 19:06:34.000000000 +0100
@@ -1,13 +1,49 @@
CHANGES
=======
-0.19.0
+1.2.2
+-----
+
+* Set py3 tests according to Stein runtimes
+
+1.2.1
+-----
+
+* Fix length usage in VaultKeyManager.create\_key
+* add python 3.7 unit test job
+
+1.2.0
+-----
+
+* Change openstack-dev to openstack-discuss
+
+1.1.0
+-----
+
+* Add Castellan Oslo Config Driver
+* Use template for lower-constraints
+* Update min tox version to 2.0
+* vault: support configuration of KV mountpoint
+* vault: add AppRole support
+* Don't quote {posargs} in tox.ini
+
+1.0.0
+-----
+
+* Add method to wrap HashiCorp Vault HTTP API calls
+
+0.20.1
------
-* Add code to generate private keys
+* Bump HashiCorp Vault version for tests
+* Fix Vault K/V API compatibility
+* add python 3.6 unit test job
* import zuul job settings from project-config
-* Update UPPER\_CONSTRAINTS\_FILE for stable/rocky
-* Update .gitreview for stable/rocky
+* Update reno for stable/rocky
+* Switch to stestr
+* Add release note link in README
+* Add code to generate private keys
+* fix tox python3 overrides
0.18.0
------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/PKG-INFO new/castellan-1.2.2/PKG-INFO
--- old/castellan-0.19.0/PKG-INFO 2018-08-21 22:04:15.000000000 +0200
+++ new/castellan-1.2.2/PKG-INFO 2019-02-28 19:06:34.000000000 +0100
@@ -1,10 +1,10 @@
Metadata-Version: 1.1
Name: castellan
-Version: 0.19.0
+Version: 1.2.2
Summary: Generic Key Manager interface for OpenStack
Home-page: https://docs.openstack.org/castellan/latest/
Author: OpenStack
-Author-email: openstack-dev@lists.openstack.org
+Author-email: openstack-discuss@lists.openstack.org
License: UNKNOWN
Description: =========
Castellan
@@ -16,6 +16,7 @@
* Documentation: https://docs.openstack.org/castellan/latest
* Source: https://git.openstack.org/cgit/openstack/castellan
* Bugs: https://bugs.launchpad.net/castellan
+ * Release notes: https://docs.openstack.org/releasenotes/castellan
Team and repository tags
========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/README.rst new/castellan-1.2.2/README.rst
--- old/castellan-0.19.0/README.rst 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/README.rst 2019-02-28 19:02:40.000000000 +0100
@@ -8,6 +8,7 @@
* Documentation: https://docs.openstack.org/castellan/latest
* Source: https://git.openstack.org/cgit/openstack/castellan
* Bugs: https://bugs.launchpad.net/castellan
+* Release notes: https://docs.openstack.org/releasenotes/castellan
Team and repository tags
========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/RELEASENOTES.rst new/castellan-1.2.2/RELEASENOTES.rst
--- old/castellan-0.19.0/RELEASENOTES.rst 2018-08-21 22:04:15.000000000 +0200
+++ new/castellan-1.2.2/RELEASENOTES.rst 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-=========
-castellan
-=========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan/_config_driver.py new/castellan-1.2.2/castellan/_config_driver.py
--- old/castellan-0.19.0/castellan/_config_driver.py 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/castellan/_config_driver.py 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,141 @@
+# 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.
+
+r"""
+Castellan Oslo Config Driver
+----------------------------
+
+This driver is an oslo.config backend driver implemented with Castellan. It
+extends oslo.config's capabilities by enabling it to retrieve configuration
+values from a secret manager behind Castellan.
+
+The setup of a Castellan configuration source is as follow::
+
+ [DEFAULT]
+ config_source = castellan_config_group
+
+ [castellan_config_group]
+ driver = castellan
+ config_file = castellan.conf
+ mapping_file = mapping.conf
+
+In the following sessions, you can find more information about this driver's
+classes and its options.
+
+The Driver Class
+================
+
+.. autoclass:: CastellanConfigurationSourceDriver
+
+The Configuration Source Class
+==============================
+
+.. autoclass:: CastellanConfigurationSource
+
+"""
+from castellan.common.exception import KeyManagerError
+from castellan.common.exception import ManagedObjectNotFoundError
+from castellan import key_manager
+
+from oslo_config import cfg
+from oslo_config import sources
+from oslo_log import log
+
+LOG = log.getLogger(__name__)
+
+
+class CastellanConfigurationSourceDriver(sources.ConfigurationSourceDriver):
+ """A backend driver for configuration values served through castellan.
+
+ Required options:
+ - config_file: The castellan configuration file.
+
+ - mapping_file: A configuration/castellan_id mapping file. This file
+ creates connections between configuration options and
+ castellan ids. The group and option name remains the
+ same, while the value gets stored a secret manager behind
+ castellan and is replaced by its castellan id. The ids
+ will be used to fetch the values through castellan.
+ """
+
+ _castellan_driver_opts = [
+ cfg.StrOpt(
+ 'config_file',
+ required=True,
+ sample_default='etc/castellan/castellan.conf',
+ help=('The path to a castellan configuration file.'),
+ ),
+ cfg.StrOpt(
+ 'mapping_file',
+ required=True,
+ sample_default='etc/castellan/secrets_mapping.conf',
+ help=('The path to a configuration/castellan_id mapping file.'),
+ ),
+ ]
+
+ def list_options_for_discovery(self):
+ return self._castellan_driver_opts
+
+ def open_source_from_opt_group(self, conf, group_name):
+ conf.register_opts(self._castellan_driver_opts, group_name)
+
+ return CastellanConfigurationSource(
+ group_name,
+ conf[group_name].config_file,
+ conf[group_name].mapping_file)
+
+
+class CastellanConfigurationSource(sources.ConfigurationSource):
+ """A configuration source for configuration values served through castellan.
+
+ :param config_file: The path to a castellan configuration file.
+
+ :param mapping_file: The path to a configuration/castellan_id mapping file.
+ """
+
+ def __init__(self, group_name, config_file, mapping_file):
+ conf = cfg.ConfigOpts()
+ conf(args=[], default_config_files=[config_file])
+
+ self._name = group_name
+ self._mngr = key_manager.API(conf)
+ self._mapping = {}
+
+ cfg.ConfigParser(mapping_file, self._mapping).parse()
+
+ def get(self, group_name, option_name, opt):
+ try:
+ group_name = group_name or "DEFAULT"
+
+ castellan_id = self._mapping[group_name][option_name][0]
+
+ return (self._mngr.get("ctx", castellan_id).get_encoded().decode(),
+ cfg.LocationInfo(cfg.Locations.user, castellan_id))
+
+ except KeyError:
+ # no mapping 'option = castellan_id'
+ LOG.info("option '[%s] %s' not present in '[%s] mapping_file'",
+ group_name, option_name, self._name)
+
+ except KeyManagerError:
+ # bad mapping 'option =' without a castellan_id
+ LOG.warning("missing castellan_id for option "
+ "'[%s] %s' in '[%s] mapping_file'",
+ group_name, option_name, self._name)
+
+ except ManagedObjectNotFoundError:
+ # good mapping, but unknown castellan_id by secret manager
+ LOG.warning("invalid castellan_id for option "
+ "'[%s] %s' in '[%s] mapping_file'",
+ group_name, option_name, self._name)
+
+ return (sources._NoValue, None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan/key_manager/vault_key_manager.py new/castellan-1.2.2/castellan/key_manager/vault_key_manager.py
--- old/castellan-0.19.0/castellan/key_manager/vault_key_manager.py 2018-08-21 22:00:30.000000000 +0200
+++ new/castellan-1.2.2/castellan/key_manager/vault_key_manager.py 2019-02-28 19:02:40.000000000 +0100
@@ -29,6 +29,7 @@
from keystoneauth1 import loading
from oslo_config import cfg
from oslo_log import log as logging
+from oslo_utils import timeutils
import requests
import six
@@ -43,10 +44,19 @@
from castellan.key_manager import key_manager
DEFAULT_VAULT_URL = "http://127.0.0.1:8200"
+DEFAULT_MOUNTPOINT = "secret"
vault_opts = [
cfg.StrOpt('root_token_id',
help='root token for vault'),
+ cfg.StrOpt('approle_role_id',
+ help='AppRole role_id for authentication with vault'),
+ cfg.StrOpt('approle_secret_id',
+ help='AppRole secret_id for authentication with vault'),
+ cfg.StrOpt('kv_mountpoint',
+ default=DEFAULT_MOUNTPOINT,
+ help='Mountpoint of KV store in Vault to use, for example: '
+ '{}'.format(DEFAULT_MOUNTPOINT)),
cfg.StrOpt('vault_url',
default=DEFAULT_VAULT_URL,
help='Use this endpoint to connect to Vault, for example: '
@@ -88,17 +98,121 @@
loading.register_session_conf_options(self._conf, VAULT_OPT_GROUP)
self._session = requests.Session()
self._root_token_id = self._conf.vault.root_token_id
+ self._approle_role_id = self._conf.vault.approle_role_id
+ self._approle_secret_id = self._conf.vault.approle_secret_id
+ self._cached_approle_token_id = None
+ self._approle_token_ttl = None
+ self._approle_token_issue = None
+ self._kv_mountpoint = self._conf.vault.kv_mountpoint
self._vault_url = self._conf.vault.vault_url
if self._vault_url.startswith("https://"):
self._verify_server = self._conf.vault.ssl_ca_crt_file or True
else:
self._verify_server = False
+ self._vault_kv_version = None
def _get_url(self):
if not self._vault_url.endswith('/'):
self._vault_url += '/'
return self._vault_url
+ def _get_api_version(self):
+ if self._vault_kv_version:
+ return self._vault_kv_version
+
+ resource_url = '{}v1/sys/internal/ui/mounts/{}'.format(
+ self._get_url(),
+ self._kv_mountpoint
+ )
+ resp = self._do_http_request(self._session.get, resource_url)
+
+ if resp.status_code == requests.codes['not_found']:
+ self._vault_kv_version = '1'
+ else:
+ self._vault_kv_version = resp.json()['data']['options']['version']
+
+ return self._vault_kv_version
+
+ def _get_resource_url(self, key_id=None):
+ return '{}v1/{}/{}{}'.format(
+ self._get_url(),
+ self._kv_mountpoint,
+
+ '' if self._get_api_version() == '1' else
+ 'data/' if key_id else
+ 'metadata/', # no key_id is for listing and 'data/' doesn't works
+
+ key_id if key_id else '?list=true')
+
+ @property
+ def _approle_token_id(self):
+ if (all((self._approle_token_issue, self._approle_token_ttl)) and
+ timeutils.is_older_than(self._approle_token_issue,
+ self._approle_token_ttl)):
+ self._cached_approle_token_id = None
+ return self._cached_approle_token_id
+
+ def _build_auth_headers(self):
+ if self._root_token_id:
+ return {'X-Vault-Token': self._root_token_id}
+
+ if self._approle_token_id:
+ return {'X-Vault-Token': self._approle_token_id}
+
+ if self._approle_role_id:
+ params = {
+ 'role_id': self._approle_role_id
+ }
+ if self._approle_secret_id:
+ params['secret_id'] = self._approle_secret_id
+ approle_login_url = '{}v1/auth/approle/login'.format(
+ self._get_url()
+ )
+ token_issue_utc = timeutils.utcnow()
+ try:
+ resp = self._session.post(url=approle_login_url,
+ json=params,
+ verify=self._verify_server)
+ except requests.exceptions.Timeout as ex:
+ raise exception.KeyManagerError(six.text_type(ex))
+ except requests.exceptions.ConnectionError as ex:
+ raise exception.KeyManagerError(six.text_type(ex))
+ except Exception as ex:
+ raise exception.KeyManagerError(six.text_type(ex))
+
+ if resp.status_code in _EXCEPTIONS_BY_CODE:
+ raise exception.KeyManagerError(resp.reason)
+ if resp.status_code == requests.codes['forbidden']:
+ raise exception.Forbidden()
+
+ resp = resp.json()
+ self._cached_approle_token_id = resp['auth']['client_token']
+ self._approle_token_issue = token_issue_utc
+ self._approle_token_ttl = resp['auth']['lease_duration']
+ return {'X-Vault-Token': self._approle_token_id}
+
+ return {}
+
+ def _do_http_request(self, method, resource, json=None):
+ verify = self._verify_server
+ headers = self._build_auth_headers()
+
+ try:
+ resp = method(resource, headers=headers, json=json, verify=verify)
+ except requests.exceptions.Timeout as ex:
+ raise exception.KeyManagerError(six.text_type(ex))
+ except requests.exceptions.ConnectionError as ex:
+ raise exception.KeyManagerError(six.text_type(ex))
+ except Exception as ex:
+ raise exception.KeyManagerError(six.text_type(ex))
+
+ if resp.status_code in _EXCEPTIONS_BY_CODE:
+ raise exception.KeyManagerError(resp.reason)
+ if resp.status_code == requests.codes['forbidden']:
+ raise exception.Forbidden()
+
+ return resp
+
def create_key_pair(self, context, algorithm, length,
expiration=None, name=None):
"""Creates an asymmetric key pair."""
@@ -157,34 +271,22 @@
raise exception.KeyManagerError(
"Unknown type for value : %r" % value)
- headers = {'X-Vault-Token': self._root_token_id}
- try:
- resource_url = self._get_url() + 'v1/secret/' + key_id
- record = {
- 'type': type_value,
- 'value': binascii.hexlify(value.get_encoded()).decode('utf-8'),
- 'algorithm': (value.algorithm if hasattr(value, 'algorithm')
- else None),
- 'bit_length': (value.bit_length if hasattr(value, 'bit_length')
- else None),
- 'name': value.name,
- 'created': value.created
- }
- resp = self._session.post(resource_url,
- verify=self._verify_server,
- json=record,
- headers=headers)
- except requests.exceptions.Timeout as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except requests.exceptions.ConnectionError as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except Exception as ex:
- raise exception.KeyManagerError(six.text_type(ex))
-
- if resp.status_code in _EXCEPTIONS_BY_CODE:
- raise exception.KeyManagerError(resp.reason)
- if resp.status_code == requests.codes['forbidden']:
- raise exception.Forbidden()
+ record = {
+ 'type': type_value,
+ 'value': binascii.hexlify(value.get_encoded()).decode('utf-8'),
+ 'algorithm': (value.algorithm if hasattr(value, 'algorithm')
+ else None),
+ 'bit_length': (value.bit_length if hasattr(value, 'bit_length')
+ else None),
+ 'name': value.name,
+ 'created': value.created
+ }
+ if self._get_api_version() != '1':
+ record = {'data': record}
+
+ self._do_http_request(self._session.post,
+ self._get_resource_url(key_id),
+ json=record)
return key_id
@@ -196,13 +298,18 @@
msg = _("User is not authorized to use key manager.")
raise exception.Forbidden(msg)
+ if length % 8:
+ msg = _("Length must be multiple of 8.")
+ raise ValueError(msg)
+
key_id = uuid.uuid4().hex
- key_value = os.urandom(length or 32)
+ key_value = os.urandom((length or 256) // 8)
key = sym_key.SymmetricKey(algorithm,
- length or 32,
+ length or 256,
key_value,
key_id,
name or int(time.time()))
+
return self._store_key_value(key_id, key)
def store(self, context, key_value, **kwargs):
@@ -227,27 +334,16 @@
if not key_id:
raise exception.KeyManagerError('key identifier not provided')
- headers = {'X-Vault-Token': self._root_token_id}
- try:
- resource_url = self._get_url() + 'v1/secret/' + key_id
- resp = self._session.get(resource_url,
- verify=self._verify_server,
- headers=headers)
- except requests.exceptions.Timeout as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except requests.exceptions.ConnectionError as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except Exception as ex:
- raise exception.KeyManagerError(six.text_type(ex))
+ resp = self._do_http_request(self._session.get,
+ self._get_resource_url(key_id))
- if resp.status_code in _EXCEPTIONS_BY_CODE:
- raise exception.KeyManagerError(resp.reason)
- if resp.status_code == requests.codes['forbidden']:
- raise exception.Forbidden()
if resp.status_code == requests.codes['not_found']:
raise exception.ManagedObjectNotFoundError(uuid=key_id)
record = resp.json()['data']
+ if self._get_api_version() != '1':
+ record = record['data']
+
key = None if metadata_only else binascii.unhexlify(record['value'])
clazz = None
@@ -283,23 +379,9 @@
if not key_id:
raise exception.KeyManagerError('key identifier not provided')
- headers = {'X-Vault-Token': self._root_token_id}
- try:
- resource_url = self._get_url() + 'v1/secret/' + key_id
- resp = self._session.delete(resource_url,
- verify=self._verify_server,
- headers=headers)
- except requests.exceptions.Timeout as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except requests.exceptions.ConnectionError as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except Exception as ex:
- raise exception.KeyManagerError(six.text_type(ex))
+ resp = self._do_http_request(self._session.delete,
+ self._get_resource_url(key_id))
- if resp.status_code in _EXCEPTIONS_BY_CODE:
- raise exception.KeyManagerError(resp.reason)
- if resp.status_code == requests.codes['forbidden']:
- raise exception.Forbidden()
if resp.status_code == requests.codes['not_found']:
raise exception.ManagedObjectNotFoundError(uuid=key_id)
@@ -315,26 +397,13 @@
msg = _("Invalid secret type: %s") % object_type
raise exception.KeyManagerError(reason=msg)
- headers = {'X-Vault-Token': self._root_token_id}
- try:
- resource_url = self._get_url() + 'v1/secret/?list=true'
- resp = self._session.get(resource_url,
- verify=self._verify_server,
- headers=headers)
- keys = resp.json()['data']['keys']
- except requests.exceptions.Timeout as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except requests.exceptions.ConnectionError as ex:
- raise exception.KeyManagerError(six.text_type(ex))
- except Exception as ex:
- raise exception.KeyManagerError(six.text_type(ex))
+ resp = self._do_http_request(self._session.get,
+ self._get_resource_url())
- if resp.status_code in _EXCEPTIONS_BY_CODE:
- raise exception.KeyManagerError(resp.reason)
- if resp.status_code == requests.codes['forbidden']:
- raise exception.Forbidden()
if resp.status_code == requests.codes['not_found']:
keys = []
+ else:
+ keys = resp.json()['data']['keys']
objects = []
for obj_id in keys:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan/options.py new/castellan-1.2.2/castellan/options.py
--- old/castellan-0.19.0/castellan/options.py 2018-08-21 22:00:30.000000000 +0200
+++ new/castellan-1.2.2/castellan/options.py 2019-02-28 19:02:40.000000000 +0100
@@ -39,7 +39,9 @@
def set_defaults(conf, backend=None, barbican_endpoint=None,
barbican_api_version=None, auth_endpoint=None,
retry_delay=None, number_of_retries=None, verify_ssl=None,
- api_class=None, vault_root_token_id=None, vault_url=None,
+ api_class=None, vault_root_token_id=None,
+ vault_approle_role_id=None, vault_approle_secret_id=None,
+ vault_kv_mountpoint=None, vault_url=None,
vault_ssl_ca_crt_file=None, vault_use_ssl=None,
barbican_endpoint_type=None):
"""Set defaults for configuration values.
@@ -54,6 +56,10 @@
:param number_of_retries: Use this attribute to set number of retries.
:param verify_ssl: Use this to specify if ssl should be verified.
:param vault_root_token_id: Use this for the root token id for vault.
+ :param vault_approle_role_id: Use this for the approle role_id for vault.
+ :param vault_approle_secret_id: Use this for the approle secret_id
+ for vault.
+ :param vault_kv_mountpoint: Mountpoint of KV store in vault to use.
:param vault_url: Use this for the url for vault.
:param vault_use_ssl: Use this to force vault driver to use ssl.
:param vault_ssl_ca_crt_file: Use this for the CA file for vault.
@@ -98,6 +104,15 @@
if vault_root_token_id is not None:
conf.set_default('root_token_id', vault_root_token_id,
group=vkm.VAULT_OPT_GROUP)
+ if vault_approle_role_id is not None:
+ conf.set_default('approle_role_id', vault_approle_role_id,
+ group=vkm.VAULT_OPT_GROUP)
+ if vault_approle_secret_id is not None:
+ conf.set_default('approle_secret_id', vault_approle_secret_id,
+ group=vkm.VAULT_OPT_GROUP)
+ if vault_kv_mountpoint is not None:
+ conf.set_default('kv_mountpoint', vault_kv_mountpoint,
+ group=vkm.VAULT_OPT_GROUP)
if vault_url is not None:
conf.set_default('vault_url', vault_url,
group=vkm.VAULT_OPT_GROUP)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan/tests/functional/key_manager/test_vault_key_manager.py new/castellan-1.2.2/castellan/tests/functional/key_manager/test_vault_key_manager.py
--- old/castellan-0.19.0/castellan/tests/functional/key_manager/test_vault_key_manager.py 2018-08-21 22:00:30.000000000 +0200
+++ new/castellan-1.2.2/castellan/tests/functional/key_manager/test_vault_key_manager.py 2019-02-28 19:02:40.000000000 +0100
@@ -17,11 +17,13 @@
"""
import abc
import os
+import uuid
from oslo_config import cfg
from oslo_context import context
from oslo_utils import uuidutils
from oslotest import base
+import requests
from testtools import testcase
from castellan.common import exception
@@ -109,3 +111,129 @@
base.BaseTestCase):
def get_context(self):
return context.get_admin_context()
+
+
+TEST_POLICY = '''
+path "{backend}/*" {{
+ capabilities = ["create", "read", "update", "delete", "list"]
+}}
+
+path "sys/internal/ui/mounts/{backend}" {{
+ capabilities = ["read"]
+}}
+'''
+
+AUTH_ENDPOINT = 'v1/sys/auth/{auth_type}'
+POLICY_ENDPOINT = 'v1/sys/policy/{policy_name}'
+APPROLE_ENDPOINT = 'v1/auth/approle/role/{role_name}'
+
+
+class VaultKeyManagerAppRoleTestCase(VaultKeyManagerOSLOContextTestCase):
+
+ mountpoint = 'secret'
+
+ def _create_key_manager(self):
+ key_mgr = vault_key_manager.VaultKeyManager(cfg.CONF)
+
+ if ('VAULT_TEST_URL' not in os.environ or
+ 'VAULT_TEST_ROOT_TOKEN' not in os.environ):
+ raise testcase.TestSkipped('Missing Vault setup information')
+
+ self.root_token_id = os.environ['VAULT_TEST_ROOT_TOKEN']
+ self.vault_url = os.environ['VAULT_TEST_URL']
+
+ test_uuid = str(uuid.uuid4())
+ vault_policy = 'policy-{}'.format(test_uuid)
+ vault_approle = 'approle-{}'.format(test_uuid)
+
+ self.session = requests.Session()
+ self.session.headers.update({'X-Vault-Token': self.root_token_id})
+
+ self._mount_kv(self.mountpoint)
+ self._enable_approle()
+ self._create_policy(vault_policy)
+ self._create_approle(vault_approle, vault_policy)
+
+ key_mgr._approle_role_id, key_mgr._approle_secret_id = (
+ self._retrieve_approle(vault_approle)
+ )
+ key_mgr._kv_mountpoint = self.mountpoint
+ key_mgr._vault_url = self.vault_url
+ return key_mgr
+
+ def _mount_kv(self, vault_mountpoint):
+ backends = self.session.get(
+ '{}/v1/sys/mounts'.format(self.vault_url)).json()
+ if vault_mountpoint not in backends:
+ params = {
+ 'type': 'kv',
+ 'options': {
+ 'version': 2,
+ }
+ }
+ self.session.post(
+ '{}/v1/sys/mounts/{}'.format(self.vault_url,
+ vault_mountpoint),
+ json=params)
+
+ def _enable_approle(self):
+ params = {
+ 'type': 'approle'
+ }
+ self.session.post(
+ '{}/{}'.format(
+ self.vault_url,
+ AUTH_ENDPOINT.format(auth_type='approle')
+ ),
+ json=params,
+ )
+
+ def _create_policy(self, vault_policy):
+ params = {
+ 'rules': TEST_POLICY.format(backend=self.mountpoint),
+ }
+ self.session.put(
+ '{}/{}'.format(
+ self.vault_url,
+ POLICY_ENDPOINT.format(policy_name=vault_policy)
+ ),
+ json=params,
+ )
+
+ def _create_approle(self, vault_approle, vault_policy):
+ params = {
+ 'token_ttl': '60s',
+ 'token_max_ttl': '60s',
+ 'policies': [vault_policy],
+ 'bind_secret_id': 'true',
+ 'bound_cidr_list': '127.0.0.1/32'
+ }
+ self.session.post(
+ '{}/{}'.format(
+ self.vault_url,
+ APPROLE_ENDPOINT.format(role_name=vault_approle)
+ ),
+ json=params,
+ )
+
+ def _retrieve_approle(self, vault_approle):
+ approle_role_id = (
+ self.session.get(
+ '{}/v1/auth/approle/role/{}/role-id'.format(
+ self.vault_url,
+ vault_approle
+ )).json()['data']['role_id']
+ )
+ approle_secret_id = (
+ self.session.post(
+ '{}/v1/auth/approle/role/{}/secret-id'.format(
+ self.vault_url,
+ vault_approle
+ )).json()['data']['secret_id']
+ )
+ return (approle_role_id, approle_secret_id)
+
+
+class VaultKeyManagerAltMountpointTestCase(VaultKeyManagerAppRoleTestCase):
+
+ mountpoint = 'different-secrets'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan/tests/unit/test_config_driver.py new/castellan-1.2.2/castellan/tests/unit/test_config_driver.py
--- old/castellan-0.19.0/castellan/tests/unit/test_config_driver.py 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/castellan/tests/unit/test_config_driver.py 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,108 @@
+# 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.
+
+"""
+Functional test cases for the Castellan Oslo Config Driver.
+
+Note: This requires local running instance of Vault.
+"""
+import tempfile
+
+from oslo_config import cfg
+from oslo_config import fixture
+
+from oslotest import base
+
+from castellan import _config_driver
+from castellan.common.objects import opaque_data
+from castellan.tests.unit.key_manager import fake
+
+
+class CastellanSourceTestCase(base.BaseTestCase):
+
+ def setUp(self):
+ super(CastellanSourceTestCase, self).setUp()
+ self.driver = _config_driver.CastellanConfigurationSourceDriver()
+ self.conf = cfg.ConfigOpts()
+ self.conf_fixture = self.useFixture(fixture.Config(self.conf))
+
+ def test_incomplete_driver(self):
+ # The group exists, but does not specify the
+ # required options for this driver.
+ self.conf_fixture.load_raw_values(
+ group='incomplete_driver',
+ driver='castellan',
+ )
+ source = self.conf._open_source_from_opt_group('incomplete_driver')
+
+ self.assertIsNone(source)
+ self.assertEqual(self.conf.incomplete_driver.driver, 'castellan')
+
+ def test_complete_driver(self):
+ self.conf_fixture.load_raw_values(
+ group='castellan_source',
+ driver='castellan',
+ config_file='config.conf',
+ mapping_file='mapping.conf',
+ )
+
+ with base.mock.patch.object(
+ _config_driver,
+ 'CastellanConfigurationSource') as source_class:
+ self.driver.open_source_from_opt_group(
+ self.conf, 'castellan_source')
+
+ source_class.assert_called_once_with(
+ 'castellan_source',
+ self.conf.castellan_source.config_file,
+ self.conf.castellan_source.mapping_file)
+
+ def test_fetch_secret(self):
+ # fake KeyManager populated with secret
+ km = fake.fake_api()
+ secret_id = km.store("fake_context",
+ opaque_data.OpaqueData(b"super_secret!"))
+
+ # driver config
+ config = "[key_manager]\nbackend=vault"
+ mapping = "[DEFAULT]\nmy_secret=" + secret_id
+
+ # creating temp files
+ with tempfile.NamedTemporaryFile() as config_file:
+ config_file.write(config.encode("utf-8"))
+ config_file.flush()
+
+ with tempfile.NamedTemporaryFile() as mapping_file:
+ mapping_file.write(mapping.encode("utf-8"))
+ mapping_file.flush()
+
+ self.conf_fixture.load_raw_values(
+ group='castellan_source',
+ driver='castellan',
+ config_file=config_file.name,
+ mapping_file=mapping_file.name,
+ )
+
+ source = self.driver.open_source_from_opt_group(
+ self.conf,
+ 'castellan_source')
+
+ # replacing key_manager with fake one
+ source._mngr = km
+
+ # testing if the source is able to retrieve
+ # the secret value stored in the key_manager
+ # using the secret_id from the mapping file
+ self.assertEqual("super_secret!",
+ source.get("DEFAULT",
+ "my_secret",
+ cfg.StrOpt(""))[0])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan.egg-info/PKG-INFO new/castellan-1.2.2/castellan.egg-info/PKG-INFO
--- old/castellan-0.19.0/castellan.egg-info/PKG-INFO 2018-08-21 22:04:14.000000000 +0200
+++ new/castellan-1.2.2/castellan.egg-info/PKG-INFO 2019-02-28 19:06:34.000000000 +0100
@@ -1,10 +1,10 @@
Metadata-Version: 1.1
Name: castellan
-Version: 0.19.0
+Version: 1.2.2
Summary: Generic Key Manager interface for OpenStack
Home-page: https://docs.openstack.org/castellan/latest/
Author: OpenStack
-Author-email: openstack-dev@lists.openstack.org
+Author-email: openstack-discuss@lists.openstack.org
License: UNKNOWN
Description: =========
Castellan
@@ -16,6 +16,7 @@
* Documentation: https://docs.openstack.org/castellan/latest
* Source: https://git.openstack.org/cgit/openstack/castellan
* Bugs: https://bugs.launchpad.net/castellan
+ * Release notes: https://docs.openstack.org/releasenotes/castellan
Team and repository tags
========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan.egg-info/SOURCES.txt new/castellan-1.2.2/castellan.egg-info/SOURCES.txt
--- old/castellan-0.19.0/castellan.egg-info/SOURCES.txt 2018-08-21 22:04:15.000000000 +0200
+++ new/castellan-1.2.2/castellan.egg-info/SOURCES.txt 2019-02-28 19:06:34.000000000 +0100
@@ -1,6 +1,6 @@
.coveragerc
.mailmap
-.testr.conf
+.stestr.conf
.zuul.yaml
AUTHORS
CONTRIBUTING.rst
@@ -16,6 +16,7 @@
test-requirements.txt
tox.ini
castellan/__init__.py
+castellan/_config_driver.py
castellan/i18n.py
castellan/options.py
castellan.egg-info/PKG-INFO
@@ -63,6 +64,7 @@
castellan/tests/functional/key_manager/test_key_manager.py
castellan/tests/functional/key_manager/test_vault_key_manager.py
castellan/tests/unit/__init__.py
+castellan/tests/unit/test_config_driver.py
castellan/tests/unit/test_options.py
castellan/tests/unit/test_utils.py
castellan/tests/unit/credentials/__init__.py
@@ -100,11 +102,15 @@
playbooks/devstack/run.yaml
releasenotes/notes/add-vault-provider-29a4c19fe67ab51f.yaml
releasenotes/notes/deprecate-auth-endpoint-b91a3e67b5c7263f.yaml
+releasenotes/notes/fix-vault-create-key-b4340a3067cbd93c.yaml
releasenotes/notes/support-legacy-fixed-key-id-9fa897b547111610.yaml
+releasenotes/notes/vault-approle-support-5ea04daea07a152f.yaml
+releasenotes/notes/vault-kv-mountpoint-919eb547764a0c74.yaml
releasenotes/source/conf.py
releasenotes/source/index.rst
releasenotes/source/pike.rst
releasenotes/source/queens.rst
+releasenotes/source/rocky.rst
releasenotes/source/unreleased.rst
releasenotes/source/_static/.placeholder
releasenotes/source/_templates/.placeholder
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan.egg-info/entry_points.txt new/castellan-1.2.2/castellan.egg-info/entry_points.txt
--- old/castellan-0.19.0/castellan.egg-info/entry_points.txt 2018-08-21 22:04:14.000000000 +0200
+++ new/castellan-1.2.2/castellan.egg-info/entry_points.txt 2019-02-28 19:06:34.000000000 +0100
@@ -2,6 +2,9 @@
barbican = castellan.key_manager.barbican_key_manager:BarbicanKeyManager
vault = castellan.key_manager.vault_key_manager:VaultKeyManager
+[oslo.config.driver]
+castellan = castellan._config_driver:CastellanConfigurationSourceDriver
+
[oslo.config.opts]
castellan.config = castellan.options:list_opts
castellan.tests.functional.config = castellan.tests.functional.config:list_opts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan.egg-info/pbr.json new/castellan-1.2.2/castellan.egg-info/pbr.json
--- old/castellan-0.19.0/castellan.egg-info/pbr.json 2018-08-21 22:04:14.000000000 +0200
+++ new/castellan-1.2.2/castellan.egg-info/pbr.json 2019-02-28 19:06:34.000000000 +0100
@@ -1 +1 @@
-{"git_version": "a99da51", "is_release": true}
\ No newline at end of file
+{"git_version": "9a34dc9", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/castellan.egg-info/requires.txt new/castellan-1.2.2/castellan.egg-info/requires.txt
--- old/castellan-0.19.0/castellan.egg-info/requires.txt 2018-08-21 22:04:14.000000000 +0200
+++ new/castellan-1.2.2/castellan.egg-info/requires.txt 2019-02-28 19:06:34.000000000 +0100
@@ -2,7 +2,7 @@
Babel!=2.4.0,>=2.3.4
cryptography>=2.1
python-barbicanclient>=4.5.2
-oslo.config>=5.2.0
+oslo.config>=6.4.0
oslo.context>=2.19.2
oslo.i18n>=3.15.3
oslo.log>=3.36.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/lower-constraints.txt new/castellan-1.2.2/lower-constraints.txt
--- old/castellan-0.19.0/lower-constraints.txt 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/lower-constraints.txt 2019-02-28 19:02:40.000000000 +0100
@@ -33,7 +33,7 @@
netifaces==0.10.4
openstackdocstheme==1.18.1
os-client-config==1.28.0
-oslo.config==5.2.0
+oslo.config==6.4.0
oslo.context==2.19.2
oslo.i18n==3.15.3
oslo.log==3.36.0
@@ -66,7 +66,7 @@
Sphinx==1.6.2
sphinxcontrib-websupport==1.0.1
stevedore==1.20.0
-testrepository==0.0.18
+stestr==2.0.0
testscenarios==0.4
testtools==2.2.0
traceback2==1.4.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/releasenotes/notes/fix-vault-create-key-b4340a3067cbd93c.yaml new/castellan-1.2.2/releasenotes/notes/fix-vault-create-key-b4340a3067cbd93c.yaml
--- old/castellan-0.19.0/releasenotes/notes/fix-vault-create-key-b4340a3067cbd93c.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/releasenotes/notes/fix-vault-create-key-b4340a3067cbd93c.yaml 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,10 @@
+---
+fixes:
+ - |
+ Fixed VaultKeyManager.create_key() to consider the `length` param as bits
+ instead of bytes for the key length. This was causing a discrepancy between
+ keys generated by the HashiCorp Vault backend and the OpenStack Barbican
+ backend. Considering `km` as an instance of a key manager, the following
+ code `km.create_key(ctx, "AES", 256)` was generating a 256 bit AES key when
+ Barbican is configured as the backend, but generating a 2048 bit AES key
+ when Vault was configured as the backend.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/releasenotes/notes/reno.cache new/castellan-1.2.2/releasenotes/notes/reno.cache
--- old/castellan-0.19.0/releasenotes/notes/reno.cache 2018-08-21 22:04:15.000000000 +0200
+++ new/castellan-1.2.2/releasenotes/notes/reno.cache 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
----
-file-contents: {}
-notes: []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/releasenotes/notes/vault-approle-support-5ea04daea07a152f.yaml new/castellan-1.2.2/releasenotes/notes/vault-approle-support-5ea04daea07a152f.yaml
--- old/castellan-0.19.0/releasenotes/notes/vault-approle-support-5ea04daea07a152f.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/releasenotes/notes/vault-approle-support-5ea04daea07a152f.yaml 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ Added support for AppRole based authentication to the Vault
+ key manager configured using new approle_role_id and
+ optional approle_secret_id options.
+ (https://www.vaultproject.io/docs/auth/approle.html)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/releasenotes/notes/vault-kv-mountpoint-919eb547764a0c74.yaml new/castellan-1.2.2/releasenotes/notes/vault-kv-mountpoint-919eb547764a0c74.yaml
--- old/castellan-0.19.0/releasenotes/notes/vault-kv-mountpoint-919eb547764a0c74.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/releasenotes/notes/vault-kv-mountpoint-919eb547764a0c74.yaml 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Added configuration option to the Vault key manager to allow
+ the KV store mountpoint in Vault to be specified; the existing
+ default of 'secret' is maintained.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/releasenotes/source/index.rst new/castellan-1.2.2/releasenotes/source/index.rst
--- old/castellan-0.19.0/releasenotes/source/index.rst 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/releasenotes/source/index.rst 2019-02-28 19:02:40.000000000 +0100
@@ -6,5 +6,6 @@
:maxdepth: 1
unreleased
+ rocky
queens
pike
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/releasenotes/source/rocky.rst new/castellan-1.2.2/releasenotes/source/rocky.rst
--- old/castellan-0.19.0/releasenotes/source/rocky.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/castellan-1.2.2/releasenotes/source/rocky.rst 2019-02-28 19:02:40.000000000 +0100
@@ -0,0 +1,6 @@
+===================================
+ Rocky Series Release Notes
+===================================
+
+.. release-notes::
+ :branch: stable/rocky
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/requirements.txt new/castellan-1.2.2/requirements.txt
--- old/castellan-0.19.0/requirements.txt 2018-08-21 22:00:30.000000000 +0200
+++ new/castellan-1.2.2/requirements.txt 2019-02-28 19:02:40.000000000 +0100
@@ -6,7 +6,7 @@
Babel!=2.4.0,>=2.3.4 # BSD
cryptography>=2.1 # BSD/Apache-2.0
python-barbicanclient>=4.5.2 # Apache-2.0
-oslo.config>=5.2.0 # Apache-2.0
+oslo.config>=6.4.0 # Apache-2.0
oslo.context>=2.19.2 # Apache-2.0
oslo.i18n>=3.15.3 # Apache-2.0
oslo.log>=3.36.0 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/setup.cfg new/castellan-1.2.2/setup.cfg
--- old/castellan-0.19.0/setup.cfg 2018-08-21 22:04:15.000000000 +0200
+++ new/castellan-1.2.2/setup.cfg 2019-02-28 19:06:34.000000000 +0100
@@ -4,7 +4,7 @@
description-file =
README.rst
author = OpenStack
-author-email = openstack-dev@lists.openstack.org
+author-email = openstack-discuss@lists.openstack.org
home-page = https://docs.openstack.org/castellan/latest/
classifier =
Environment :: OpenStack
@@ -26,6 +26,8 @@
oslo.config.opts =
castellan.tests.functional.config = castellan.tests.functional.config:list_opts
castellan.config = castellan.options:list_opts
+oslo.config.driver =
+ castellan = castellan._config_driver:CastellanConfigurationSourceDriver
castellan.drivers =
barbican = castellan.key_manager.barbican_key_manager:BarbicanKeyManager
vault = castellan.key_manager.vault_key_manager:VaultKeyManager
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/test-requirements.txt new/castellan-1.2.2/test-requirements.txt
--- old/castellan-0.19.0/test-requirements.txt 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/test-requirements.txt 2019-02-28 19:02:40.000000000 +0100
@@ -9,7 +9,8 @@
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
openstackdocstheme>=1.18.1 # Apache-2.0
oslotest>=3.2.0 # Apache-2.0
-testrepository>=0.0.18 # Apache-2.0/BSD
+stestr>=2.0.0 # Apache-2.0
+fixtures>=3.0.0 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=2.2.0 # MIT
bandit>=1.1.0 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/tools/setup-vault-env.sh new/castellan-1.2.2/tools/setup-vault-env.sh
--- old/castellan-0.19.0/tools/setup-vault-env.sh 2018-08-21 22:00:30.000000000 +0200
+++ new/castellan-1.2.2/tools/setup-vault-env.sh 2019-02-28 19:02:40.000000000 +0100
@@ -1,7 +1,7 @@
#!/bin/bash
set -eux
if [ -z "$(which vault)" ]; then
- VAULT_VERSION=0.7.3
+ VAULT_VERSION=0.10.4
SUFFIX=zip
case `uname -s` in
Darwin)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/castellan-0.19.0/tox.ini new/castellan-1.2.2/tox.ini
--- old/castellan-0.19.0/tox.ini 2018-08-21 22:00:55.000000000 +0200
+++ new/castellan-1.2.2/tox.ini 2019-02-28 19:02:40.000000000 +0100
@@ -1,30 +1,31 @@
[tox]
-minversion = 1.6
-envlist = py35,py27,pep8
+minversion = 2.0
+envlist = py36,py27,pep8
skipsdist = True
[testenv]
-basepython = python3
usedevelop = True
install_command = pip install {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
OS_TEST_PATH=./castellan/tests/unit
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-commands = python setup.py testr --slowest --testr-args='{posargs}'
+commands = stestr run --slowest {posargs}
[testenv:py27]
basepython = python2.7
[testenv:pep8]
+basepython = python3
commands =
flake8
bandit -r castellan -x tests -s B105,B106,B107,B607
[testenv:bandit]
+basepython = python3
# This command runs the bandit security linter against the castellan
# codebase minus the tests directory. Some tests are being excluded to
# reduce the number of positives before a team inspection, and to ensure a
@@ -37,20 +38,30 @@
bandit -r castellan -x tests -s B105,B106,B107,B607
[testenv:venv]
+basepython = python3
commands = {posargs}
[testenv:debug]
+basepython = python3
commands = oslo_debug_helper {posargs}
[testenv:cover]
+basepython = python3
+setenv =
+ PYTHON=coverage run --source $project --parallel-mode
commands =
- python setup.py testr --coverage --testr-args='{posargs}'
- coverage report
+ stestr run {posargs}
+ coverage combine
+ coverage html -d cover
+ coverage xml -o cover/coverage.xml
+ coverage report
[testenv:docs]
+basepython = python3
commands = python setup.py build_sphinx
[testenv:releasenotes]
+basepython = python3
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[testenv:functional]
@@ -59,7 +70,7 @@
setenv =
VIRTUAL_ENV={envdir}
OS_TEST_PATH=./castellan/tests/functional
-commands = python setup.py testr --slowest --testr-args='{posargs}'
+commands = stestr run --slowest {posargs}
[testenv:functional-vault]
passenv = HOME
@@ -69,9 +80,10 @@
VIRTUAL_ENV={envdir}
OS_TEST_PATH=./castellan/tests/functional
commands =
- {toxinidir}/tools/setup-vault-env.sh pifpaf -e VAULT_TEST run vault -- python setup.py testr --slowest --testr-args='{posargs}'
+ {toxinidir}/tools/setup-vault-env.sh pifpaf -e VAULT_TEST run vault -- stestr run --slowest {posargs}
[testenv:genconfig]
+basepython = python3
commands =
oslo-config-generator --config-file=etc/castellan/functional-config-generator.conf
oslo-config-generator --config-file=etc/castellan/sample-config-generator.conf
@@ -87,6 +99,7 @@
import_exceptions = castellan.i18n
[testenv:lower-constraints]
+basepython = python3
deps =
-c{toxinidir}/lower-constraints.txt
-r{toxinidir}/test-requirements.txt