重构所有 cookbook 中的配置文件模板

Launchpad 蓝图 URL

https://blueprints.launchpad.net/openstack-chef/+spec/refactor-configuration-templates

问题描述

多年来,我们所有服务的配置文件模板都在不断增长,越来越难以确定将特定选项设置到配置文件中的位置。渲染后读取这些配置文件也是如此,因为它们包含比实际需要或使用的更多的选项和代码。此外,每当 OpenStack 服务项目添加或删除配置选项时,我们都需要手动添加一个属性、一些条件和一个模板条目。默认值的任何更改也是如此,要么根本没有反映在我们的配置文件中,要么被显式设置为相同的值,这只是不必要的代码。最后,由于我们的所有模板都是相当大的代码块,甚至包含从几年前导入的原始配置文件中的一些硬编码值,这并不利于跟上服务项目的多次更改。

提议的变更

OpenStack 服务配置文件的模板应该实现或使用一种逻辑,从正确定义的 chef 属性中自动设置所需的键值配置选项到适当的 section 中。

  • 需要定义并添加渲染正确配置文件的逻辑(如下例所示)

  • 用于或在配置模板中使用的属性需要检查和重构以适应此逻辑

  • 常用配置选项应该在一个地方处理

  • 模板渲染后,配置文件中应该只设置所需的配置选项

  • 仅对少数设置特定的配置选项应该从默认属性和 recipes 中删除(尤其是针对它们的 switchcases)并移动到文档中。虽然这意味着在删除原始 cookbook 中的一些 switchcases 和属性的意义上会失去一些功能,但这并不意味着完全丢失这些功能,而是将它们移动到文档中,以便在 wrapper cookbook 中轻松实现。

范围

本 spec 试图定义一个重构过程,该过程实现了一种更优雅的处理 OpenStack 服务配置文件的模板文件的方式,贯穿所有用于部署 OpenStack 的 cookbook。

最终用户影响

  • cookbook 的用户将能够更轻松地包装所有 OpenStack chef cookbook,并在需要时设置配置选项,而无需修补实际的模板。

  • 更改之前旧的 wrapper cookbook 将部分停止工作,需要相应地进行重构。对于通过属性包含服务配置选项的所有环境文件也是如此。

  • 读取配置文件将变得更容易,因为只有专门想要的和需要的选项才会包含在其中。

  • 用户可以通过属性在服务配置文件中添加环境和公司特定的注释。

开发者影响

cookbook 开发人员不需要为配置模板添加属性,也不应该需要更改现有属性以适应 OpenStack 服务项目不断变化的默认值。由于模板和属性文件中的大部分代码将通过此功能被删除或移动,因此阅读整个 cookbook 应该会更容易。因此,对于一个新手来说,在不花费数小时来理解所有属性如何协同工作的情况下,贡献代码可能会更容易(当然,前提是用于渲染模板的逻辑更容易理解)。

实现

负责人

主要负责人

<j-klare>

其他贡献者

工作项

  • 定义一个通用的模板结构,可以用于大多数配置文件

  • 所有配置选项的服务主配置文件看起来像这样

    [section] # 可选注释或描述 key = value (通常是简单的布尔值、数字或字符串) # 可选注释或描述 key = [ 可能很大的数组 ]

  • 创建一种逻辑来从正确设置的 chef 属性渲染配置文件

  • 属性可以看起来像这样,用于主配置文件(例如 nova 或 neutron.conf)

default['openstack'][service]['conf'][section][key] =
  value

没有注释

default['openstack'][service]['conf'][section]['debug'] =
  true

有注释

default['openstack'][service]['conf'][section]['debug'] =
  { set_to: true, comment: 'this option is the switch to enable/disable debug loggging' }

cookbook-openstack-common/templates/common.conf.erb

<% @service_config.each do |section, values| -%>
[<%= section %>]
  <% values.each do |key, value| -%>
    <% if value.class == Hash -%>
<%= "# {value['comment']}" -%>
<%= key %> = <%= value['set_to'] %>
    <% else -%>
<%= key %> = <%= value %>
    <% end -%>
  <% end -%>
<% end -%>

cookbook-openstack-compute/recipes/common.rb

...
# activesupport currently needs to be upgraded, since the one used in
# chef 12 is too old (3.2.19) and does not include the needed deep_merge
chef_gem 'activesupport' do
  action :upgrade
  version '4.2.4'
end
require 'active_support'
...

neutron_admin_password = get_password 'service', 'openstack-network'
identity_admin_endpoint = admin_endpoint 'identity-admin'
identity_uri = identity_uri_transform(identity_admin_endpoint)
...

secrets = {
            neutron: {
              admin_password: neutron_admin_password,
              ...
            },
            keystone_authtoken: {
              identity_uri: identity_uri,
              ...
            },
            ...
          }

# merge node attributes with secrets like passwords etc. for
# usage in template['/etc/nova/nova.conf']
nova_config_options =
  node['openstack']['compute']['conf'].deep_merge(secrets)

template '/etc/nova/nova.conf' do
  source 'common.conf.erb'
  cookbook 'openstack-common'
  owner node['openstack']['compute']['user']
  group node['openstack']['compute']['group']
  mode 00640
  variables(
    service_config: nova_config_options
  )
end
...

cookbook-openstack-compute/templates/nova.conf.erb – 不再需要

  • 将指向文档/配置参考的链接添加到所有配置文件

  • 重构当前使用的属性以适应该逻辑

  • 调整 specs

  • 定义创建工作堆栈所需的最小属性集,并将其余属性移动到文档中

  • 删除将配置选项设置为与默认值相同的属性

  • 在合适的时间传播不向后兼容的更改,而不会惹恼很多人

测试

  • 使用 rubocop 进行 lint 和样式测试(按原样)

  • 使用 chefspec 进行单元测试,特别关注测试配置模板的正确渲染(包括 sections)

  • 使用 chef provisioning 进行集成测试

文档影响

这些补丁应该将当前定义的很大一部分属性移动到文档中,作为特定设置的示例。

参考资料