This patch update default value of OPENSTACK_KEYSTONE_DEFAULT_ROLE to 'member' from '_member_'. If a user tries to create a new project now it leads to "Could not find default role "_member_" in Keystone" error. Also long time ago keystone-bootstrap changed the default member role that is created to member from the legacy _member_ role. Any deployments that might still be using _member_ should set this explicitly. Closes-Bug: #1957173 Change-Id: I1fc7f44326b82ceb303f8d663ff0b42f0bdf7855
8.5 KiB
Defining default settings in code
Note
This page tries to explain the plan to define default values of horizon/openstack_dashboard settings in code. This includes a blueprint ini-based-configuration. This page will be updated once the effort is completed.
Planned Steps
- Define the default values of existing settings
- Revisit HORIZON_CONFIG
- Introduce
oslo.config
Define default values of existing settings
Currently all default values are defined in codes where they are consumed. This leads to the situation that it is not easy to know what are the default values and in a worse case default values defined in our codebase can have different default values.
As the first step toward ini-based-configuration, I propose to define all default values of existing settings in a single place per module. More specifically, the following modules are used:
openstack_dashboard.defaults
for openstack_dashboardhorizon.defaults
for horizonopenstack_auth.defaults
for openstack_auth
horizon.defaults
load
openstack_auth.defaults
and overrides openstack_auth
settings if necessary. Similarly,
openstack_dashboard.defaults
loads
horizon.defaults
and overrides horizon (and openstack_auth)
settings if necessary.
The current style of
getattr(settings, <foo>, <default value>)
will
be removed at the same time.
Note that HORIZON_CONFIG
is not touched in this step. It
will be covered in the next step.
Handling Django settings
Django provides a lot of settings and it is not practical to cover all in horizon. Only Django settings which horizon explicitly set will be defined in a dedicated python module.
The open question is how to maintain Django related settings in openstack_dashboard and horizon. How can we make them common? The following files are related:
- openstack_dashboard.settings (and local_settings.py)
- openstack_dashboard.test.settings
- horizon.test.settings
This will be considered as the final step of the ini-based-configuration effort after horizon and openstack_dashboard settings succeed to be migrated to oslo.config explained below.
Revisit HORIZON_CONFIG
HORIZON_CONFIG is an internal interface now and most/some(?) of them should not be exposed as config options. For example, the horizon plugin mechanism touches HORIZON_CONFIG to register horizon plugins.
It is better to expose only HORIZON_CONFIG settings which can be
really exposed to operators. For such settings, we should define new
settings in openstack_dashboard and can populate them into
HORIZON_CONFIG in settings.py
.
For example, ajax_poll_interval
in HORIZON_CONFIG can be
exposed to operators. In such case, we can define a new settings
AJAX_POLL_INTERVAL
in
openstack_dashboard/defaults.py
(or
horizon/defaults.py
).
Investigation is being summarized in an etherpad page.
Introduce oslo.config
local_settings.py will have a priority over oslo.config. This means
settings values from oslo.config will be loaded first and then
local_settings.py
and local_settings.d
will be
loaded in settings.py
.
Basic strategy of mapping
The current naming convention is random, so it sounds less reasonable to use the same name for oslo.config. oslo.config and python ini-based configuration mechanism provide a concept of category and there is no reason to use it. As category name, the categories of
/configuration/settings
(like keystone, glance) will be honored.For example, some keystone settings have a prefix
OPENSTACK_KEYSTONE_
like OPENSTACK_KEYSTONE_DEFAULT_ROLE. Some useKEYSTONE_
likeKEYSTONE_IDP_PROVIDER_ID
. Some do not (likeENFORCE_PASSWORD_CHECK
). In the oslo.config options, all prefixes will be dropped. The mapping will be:OPENSTACK_KEYSTONE_DEFAULT_ROLE
<->[keystone] default_role
KEYSTONE_IDP_PROVIDER_ID
<->[keystone] idp_provider_id
ENFORCE_PASSWORD_CHECK
<->[keystone] enforce_password_check
[default]
section is not used as much as possible. It will be used only for limited number of well-known options. Perhaps some common Django settings likeDEBUG
,LOGGING
will match this category.Opt classes defined in oslo.config are used as much as possible.
- StrOpt, IntOpt
- ListOpt
- MultiStrOpt
- DictOpt
A dictionary settings will be broken down into separate options. Good examples are
OPENSTACK_KEYSTONE_BACKEND
andOPENSTACK_NEUTRON_NETWORK
.OPENSTACK_KEYSTONE_BACKEND['name']
<->[keystone] backend_name
OPENSTACK_KEYSTONE_BACKEND['can_edit_user']
<->[keystone] backend_can_edit_user
OPENSTACK_KEYSTONE_BACKEND['can_edit_group']
<->[keystone] backend_can_edit_group
OPENSTACK_NEUTRON_NETWORK['enable_router']
<->[neutron] enable_router
OPENSTACK_NEUTRON_NETWORK['enable_ipv6']
<->[neutron] enable_ipv6
Automatic Mapping
The straight-forward approach is to have a dictionary from setting names to oslo.config options like:
{'OPENSTACK_KEYSTONE_DEFAULT_ROLE': ('keystone', 'default_role'),
'OPENSTACK_NEUTRON_NETWORK': {
'enable_router': ('neutron', 'enable_router'),
'enable_ipv6': ('neutron', 'enable_ipv6'),
... }
A key of the top-level dict is a name of Django settings. A corresponding value specifies oslo.config name by a list or a tuple where the first and second elements specify a section and a option name respectively.
When a value is a dict, this means a corresponding Django dict
setting is broken down into several oslo.config options. In the above
example, OPENSTACK_NEUTRON_NETWORK['enable_router']
is
mapped to [neutron] enable_router
.
Another idea is to introduce a new field to oslo.config classes. oslo-sample-generator might need to be updated. If this approach is really attractive, we can try this approach in future. The above dictionary-based approach will be used in the initial effort.
cfg.StrOpt('default_role',
='member',
default-setting='OPENSTACK_KEYSTONE_DEFAULT_ROLE',
djangohelp=...
)
cfg.BoolOpt('enable_router',
=True,
default=('OPENSTACK_NEUTRON_NETWORK', 'enable_router'),
django_settinghelp=....)
)
Special Considerations
LOGGING
LOGGING
setting is long enough. Python now recommend to
configure logging using python dict directly, but from operator/packager
perspective the legacy style of using the ini format sounds reasonable.
The ini format is also used in other OpenStack projects too. In this
effort, I propose to use the logging configuration via the ini format
file and specify the logging conf file in a oslo.config option
Adopting oslo.log might be a good candidate, but it is not covered by this effort. It can be explored as future possible improvement.
SECURITY_GROUP_RULES
SECURITY_GROUP_RULES
will be defined by YAML file. The
YAML file can be validated by JSON schema in future (out of the scope of
this effort)
all_tcp
, all_udp
and all_icmp
are the reserved keyword, so it looks better to split the first three
rules (all_tcp
to all_icmp
) and other
remaining rules. The remaining rules will be loaded from a YAML file.
For the first three rules, a boolean option to control their visibility
in the security group rule form will be introduces in oslo.config. I am
not sure this option is required or not, but as the first step of the
migration it is reasonable to provide all compatibilities.
Handling Django settings
Django (and django related packages) provide many settings. It is not a good idea to expose all of them via oslo.config. What should we expose?
The proposal here is to expose only settings which
openstack_dashboard expects to expose to deployers. Most Django settings
are internally used in openstack_dashboard/settings.py
.
Settings required for horizon plugins are already exposed via the plugin
settings, so there is no need to expose them. If deployers would like to
customize Django basic settings, they can still configure them via
local_settings.py
or local_settings.d
.