Codebase list python-castellan / d768fbc
refactoring castellan configuration This change adds a module for listing configuration options and setting their defaults. It also changes the key manager base class to incorporate a configuration during creation. By default, the key manager will continue to use the global CONF object from the oslo.config package. For the most part, this change will be backwards compatible. The one exception is the creation of sample configuration files. Previously, importing castellan was sufficient to add these options to the global configuration object. Now, these options will need to be applied by using the castellan.options.list_opts function, or adding them through other means, to create sample configuration files. Similar applies for setting configuration before instantiating a key manager. changes * adding castellan.options with list_opts and set_defaults functions * changing KeyManager abc to include a configuration option to __init__ * changing barbican and not_implemented key managers to accept configuration parameters * adding tests for set_defaults function * fixing barbican tests to accomodate new configuration parameter * adding documentation about configuration usage * adding castellan configs to oslo entry point in setup.cfg * adding a genconfig target to tox for producing a sample castellan configuration file * adding the sample configuration file to the git ignore * renaming barbican option api_version to barbican_api_version Change-Id: I86d6d7d49a893beaae6f311060ec593e0482d889 Implements: blueprint improved-configuration-options Michael McCune 8 years ago
12 changed file(s) with 248 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
5050 *~
5151 .*.swp
5252 .*sw?
53
54 # generated configuration files
55 etc/castellan/castellan.conf.sample
56 etc/castellan/castellan-functional.conf.sample
1515 from oslo_config import cfg
1616 from oslo_utils import importutils
1717
18
1918 key_manager_opts = [
2019 cfg.StrOpt('api_class',
2120 default='castellan.key_manager.barbican_key_manager'
2322 help='The full class name of the key manager API class'),
2423 ]
2524
26 CONF = cfg.CONF
27 CONF.register_opts(key_manager_opts, group='key_manager')
2825
26 def API(configuration=None):
27 conf = configuration or cfg.CONF
28 conf.register_opts(key_manager_opts, group='key_manager')
2929
30 def API():
31 cls = importutils.import_class(CONF.key_manager.api_class)
32 return cls()
30 cls = importutils.import_class(conf.key_manager.api_class)
31 return cls(configuration=conf)
3434 cfg.StrOpt('barbican_endpoint',
3535 default='http://localhost:9311/',
3636 help='Use this endpoint to connect to Barbican'),
37 cfg.StrOpt('api_version',
37 cfg.StrOpt('barbican_api_version',
3838 default='v1',
3939 help='Version of the Barbican API'),
4040 ]
4141
42 CONF = cfg.CONF
4342 BARBICAN_OPT_GROUP = 'barbican'
44
45 CONF.register_opts(barbican_opts, group=BARBICAN_OPT_GROUP)
46
47 session.Session.register_conf_options(CONF, BARBICAN_OPT_GROUP)
4843
4944 LOG = logging.getLogger(__name__)
5045
5247 class BarbicanKeyManager(key_manager.KeyManager):
5348 """Key Manager Interface that wraps the Barbican client API."""
5449
55 def __init__(self):
50 def __init__(self, configuration):
5651 self._barbican_client = None
5752 self._base_url = None
53 self.conf = configuration
54 self.conf.register_opts(barbican_opts, group=BARBICAN_OPT_GROUP)
55 session.Session.register_conf_options(self.conf, BARBICAN_OPT_GROUP)
5856
5957 def _get_barbican_client(self, context):
6058 """Creates a client to connect to the Barbican service.
9189
9290 def _get_keystone_session(self, context):
9391 sess = session.Session.load_from_conf_options(
94 CONF, BARBICAN_OPT_GROUP)
95
96 self._barbican_endpoint = CONF.barbican.barbican_endpoint
92 self.conf, BARBICAN_OPT_GROUP)
93
94 self._barbican_endpoint = self.conf.barbican.barbican_endpoint
9795
9896 auth = token_endpoint.Token(self._barbican_endpoint,
9997 context.auth_token)
10199 return sess
102100
103101 def _create_base_url(self):
104 base_url = urllib.parse.urljoin(self._barbican_endpoint,
105 CONF.barbican.api_version)
102 base_url = urllib.parse.urljoin(
103 self._barbican_endpoint, self.conf.barbican.barbican_api_version)
106104 return base_url
107105
108106 def create_key(self, context, algorithm, length, expiration=None):
2828 A Key Manager is responsible for managing encryption keys for volumes. A
2929 Key Manager is responsible for creating, reading, and deleting keys.
3030 """
31
32 @abc.abstractmethod
33 def __init__(self, configuration):
34 """Instantiate a KeyManager object.
35
36 Creates a KeyManager object with implementation specific details
37 obtained from the supplied configuration.
38 """
39 pass
3140
3241 @abc.abstractmethod
3342 def create_key(self, context, algorithm, length, expiration=None):
2424
2525 """
2626
27 def __init__(self, configuration=None):
28 super(NotImplementedKeyManager, self).__init__(configuration)
29
2730 def create_key(self, context, algorithm='AES', length=256,
2831 expiration=None, **kwargs):
2932 raise NotImplementedError()
0 # Copyright (c) 2015 Red Hat, Inc.
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 from castellan import key_manager as km
16 try:
17 from castellan.key_manager import barbican_key_manager as bkm
18 except ImportError:
19 bkm = None
20
21
22 def set_defaults(conf, api_class=None, barbican_endpoint=None,
23 barbican_api_version=None):
24 '''Set defaults for configuration values.
25
26 Overrides the default options values.
27
28 :param conf: Config instance in which to set default options.
29
30 :param api_class: The full class name of the key manager API class.
31
32 :param barbican_endpoint: Use this endpoint to connect to Barbican.
33
34 :param barbican_api_version: Version of the Barbican API.
35 '''
36 conf.register_opts(km.key_manager_opts, group='key_manager')
37 if bkm:
38 conf.register_opts(bkm.barbican_opts, group=bkm.BARBICAN_OPT_GROUP)
39
40 if api_class is not None:
41 conf.set_default('api_class', api_class, group='key_manager')
42 if bkm is not None and barbican_endpoint is not None:
43 conf.set_default('barbican_endpoint', barbican_endpoint,
44 group=bkm.BARBICAN_OPT_GROUP)
45 if bkm is not None and barbican_api_version is not None:
46 conf.set_default('barbican_api_version', barbican_api_version,
47 group=bkm.BARBICAN_OPT_GROUP)
48
49
50 def list_opts():
51 '''Returns a list of oslo.config options available in the library.
52
53 The returned list includes all oslo.config options which may be registered
54 at runtime by the library.
55
56 Each element of the list is a tuple. The first element is the name of the
57 group under which the list of elements in the second element will be
58 registered. A group name of None corresponds to the [DEFAULT] group in
59 config files.
60
61 The purpose of this is to allow tools like the Oslo sample config file
62 generator to discover the options exposed to users by this library.
63
64 :returns: a list of (group_name, opts) tuples
65 '''
66 opts = [('key_manager', km.key_manager_opts)]
67 if bkm is not None:
68 opts.append((bkm.BARBICAN_OPT_GROUP, bkm.barbican_opts))
69 return opts
1717 """
1818
1919 import mock
20 from oslo_config import cfg
2021
2122 from castellan.common import exception
2223 from castellan.common.objects import symmetric_key as key_manager_key
2728 class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase):
2829
2930 def _create_key_manager(self):
30 return barbican_key_manager.BarbicanKeyManager()
31 return barbican_key_manager.BarbicanKeyManager(cfg.CONF)
3132
3233 def setUp(self):
3334 super(BarbicanKeyManagerTestCase, self).setUp()
0 # Copyright (c) 2015 Red Hat, Inc.
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 from oslo_config import cfg
16
17 from castellan.key_manager import barbican_key_manager as bkm
18 from castellan import options
19 from castellan.tests import base
20
21
22 class TestOptions(base.TestCase):
23
24 def test_set_defaults(self):
25 conf = cfg.ConfigOpts()
26
27 api_class = 'test.api.class'
28 options.set_defaults(conf, api_class=api_class)
29 self.assertEqual(api_class, conf.key_manager.api_class)
30
31 barbican_endpoint = 'http://test-server.org:9311/'
32 options.set_defaults(conf, barbican_endpoint=barbican_endpoint)
33 self.assertEqual(barbican_endpoint,
34 conf.get(bkm.BARBICAN_OPT_GROUP).barbican_endpoint)
35
36 barbican_api_version = 'vSomething'
37 options.set_defaults(conf, barbican_api_version=barbican_api_version)
38 self.assertEqual(barbican_api_version,
39 conf.get(bkm.BARBICAN_OPT_GROUP).barbican_api_version)
44 To use castellan in a project::
55
66 import castellan
7
8
9 Configuring castellan
10 ~~~~~~~~~~~~~~~~~~~~~
11
12 Castellan contains several options which control the key management
13 service usage and the configuration of that service. It also contains
14 functions to help configure the defaults and produce listings for use
15 with the ``oslo-config-generator`` application.
16
17 In general, castellan configuration is handled by passing an
18 ``oslo_config.cfg.ConfigOpts`` object into the
19 ``castellan.key_manager.API`` call when creating your key manager. By
20 default, when no ``ConfigOpts`` object is provided, the key manager will
21 use the global ``oslo_config.cfg.CONF`` object.
22
23 **Example. Using the global CONF object for configuration.**
24
25 .. code:: python
26
27 from castellan import key_manager
28
29 manager = key_manager.API()
30
31 **Example. Using a predetermined configuration object.**
32
33 .. code:: python
34
35 from oslo_config import cfg
36 from castellan import key_manager
37
38 conf = cfg.ConfigOpts()
39 manager = key_manager.API(configuration=conf)
40
41 Controlling default options
42 ---------------------------
43
44 To change the default behavior of castellan, and the key management service
45 it uses, the ``castellan.options`` module provides the ``set_defaults``
46 function. This function can be used at run-time to change the behavior of
47 the library or the key management service provider.
48
49 **Example. Changing the barbican endpoint.**
50
51 .. code:: python
52
53 from oslo_config import cfg
54 from castellan import options
55 from castellan import key_manager
56
57 conf = cfg.ConfigOpts()
58 options.set_defaults(conf, barbican_endpoint='http://192.168.0.1:9311/')
59 manager = key_manager.API(conf)
60
61 **Example. Changing the key manager provider while using the global
62 configuration.**
63
64 .. code:: python
65
66 from oslo_config import cfg
67 from castellan import options
68 from castellan import key_manager
69
70 options.set_defaults(cfg.CONF, api_class='some.other.KeyManager')
71 manager = key_manager.API()
72
73 Generating sample configuration files
74 -------------------------------------
75
76 Castellan includes a tox configuration for creating a sample configuration
77 file. This file will contain only the values that will be used by
78 castellan. To produce this file, run the following command from the
79 root of the castellan project directory:
80
81 .. code:: console
82
83 $ tox -e genconfig
84
85 Adding castellan to configuration files
86 ---------------------------------------
87
88 One common task for OpenStack projects is to create project configuration
89 files. Castellan provides a ``list_opts`` function in the
90 ``castellan.options`` module to aid in generating these files when using
91 the ``oslo-config-generator``. This function can be specified in the
92 :file:`setup.cfg` file of your project to inform oslo of the
93 configuration options. *Note, this will use the default values supplied
94 by the castellan package.*
95
96 **Example. Adding castellan to the oslo.config entry point.**
97
98 .. code:: ini
99
100 [entry_points]
101 oslo.config.opts =
102 castellan.config = castellan.options:list_opts
103
104 For more information on the oslo configuration generator, please see
105 http://docs.openstack.org/developer/oslo.config/generator.html
0 [DEFAULT]
1 output_file = etc/castellan/castellan.conf.sample
2 wrap_width = 79
3 namespace = castellan.config
2525 [entry_points]
2626 oslo.config.opts =
2727 castellan.tests.functional.config = castellan.tests.functional.config:list_opts
28 castellan.config = castellan.options:list_opts
2829
2930 [build_sphinx]
3031 source-dir = doc/source
3737 [testenv:genconfig]
3838 commands =
3939 oslo-config-generator --config-file=etc/castellan/functional-config-generator.conf
40 #TODO(kfarr): add config generator for main Castellan options
40 oslo-config-generator --config-file=etc/castellan/sample-config-generator.conf
4141
4242 [flake8]
4343 # H803 skipped on purpose per list discussion.