Update merge_yaml implementation
Switch to the upstream merge_yaml_settings version. Change-Id: Ie78868937a90e0c1af24221ca43849c0c4b9cdbf
This commit is contained in:
2
deployment_scripts/puppet/modules/contrail/.gitignore
vendored
Normal file
2
deployment_scripts/puppet/modules/contrail/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
spec/fixtures
|
||||
Gemfile.lock
|
||||
2
deployment_scripts/puppet/modules/contrail/Gemfile
Normal file
2
deployment_scripts/puppet/modules/contrail/Gemfile
Normal file
@@ -0,0 +1,2 @@
|
||||
gem 'puppetlabs_spec_helper'
|
||||
gem 'puppet'
|
||||
1
deployment_scripts/puppet/modules/contrail/Rakefile
Normal file
1
deployment_scripts/puppet/modules/contrail/Rakefile
Normal file
@@ -0,0 +1 @@
|
||||
require 'puppetlabs_spec_helper/rake_tasks'
|
||||
@@ -0,0 +1,124 @@
|
||||
require 'yaml'
|
||||
|
||||
Puppet::Type.type(:ceilometer_pipeline_section).provide(:ruby) do
|
||||
|
||||
attr_accessor :resource
|
||||
|
||||
# Alias to the yaml file path
|
||||
# @return [String]
|
||||
def yaml_file_path
|
||||
resource[:path]
|
||||
end
|
||||
|
||||
# Alias to the array name
|
||||
# @return [String]
|
||||
def array_name
|
||||
resource[:array_name]
|
||||
end
|
||||
|
||||
# Alias to the section name
|
||||
# @return [String]
|
||||
def section_name
|
||||
resource[:section_name]
|
||||
end
|
||||
|
||||
# The exiting data read from the YAML file
|
||||
# @return [Hash]
|
||||
def existing_data
|
||||
return @yaml_file_existing_data if @yaml_file_existing_data
|
||||
begin
|
||||
@yaml_file_existing_data = YAML.load_file resource[:path]
|
||||
fail "YAML data should be a hash in the file: '#{yaml_file_path}'!" unless @yaml_file_existing_data.is_a? Hash
|
||||
@yaml_file_existing_data
|
||||
rescue => exception
|
||||
warn "Could not read the YAML file: '#{yaml_file_path}' #{exception}"
|
||||
@yaml_file_existing_data = {}
|
||||
end
|
||||
end
|
||||
|
||||
# Write the expected data to the YAML file
|
||||
def yaml_file_write
|
||||
File.open(yaml_file_path, 'w') do |file|
|
||||
file.puts YAML.dump expected_data
|
||||
end
|
||||
end
|
||||
|
||||
# The expected YAML data with updated hardware_source section
|
||||
# @return [Hash]
|
||||
def expected_data
|
||||
return @yaml_file_expected_data if @yaml_file_expected_data
|
||||
@yaml_file_expected_data = Marshal.load Marshal.dump existing_data
|
||||
@yaml_file_expected_data[array_name] = [] unless @yaml_file_expected_data[array_name]
|
||||
if resource[:ensure] == :present
|
||||
modify_section @yaml_file_expected_data
|
||||
else
|
||||
remove_section @yaml_file_expected_data
|
||||
end
|
||||
@yaml_file_expected_data
|
||||
end
|
||||
|
||||
# Update the selected section in the
|
||||
# provided YAML data or add a new section if
|
||||
# it's missing.
|
||||
# @param [Hash] data
|
||||
def modify_section(data)
|
||||
sources = data.fetch array_name, []
|
||||
target_section = section data
|
||||
if target_section
|
||||
target_section.clear
|
||||
target_section.merge! resource[:data]
|
||||
target_section['name'] = section_name
|
||||
else
|
||||
sources << new_section
|
||||
end
|
||||
sources
|
||||
end
|
||||
|
||||
# Extract rhe hardware_source section from the data
|
||||
# @param [Hash] data
|
||||
# @return [Hash]
|
||||
def section(data)
|
||||
sources = data.fetch array_name, []
|
||||
sources.find do |source|
|
||||
next unless source.is_a? Hash
|
||||
source['name'] == section_name
|
||||
end
|
||||
end
|
||||
|
||||
# Remove the hardware_source section from the data
|
||||
# @param [Hash] data
|
||||
def remove_section(data)
|
||||
sources = data.fetch array_name, []
|
||||
sources.reject! do |source|
|
||||
source['name'] == section_name
|
||||
end
|
||||
sources
|
||||
end
|
||||
|
||||
# Generate a new hardware_source section
|
||||
# @return [Hash]
|
||||
def new_section
|
||||
section = resource[:data]
|
||||
section['name'] = section_name
|
||||
section
|
||||
end
|
||||
|
||||
#####
|
||||
|
||||
def exists?
|
||||
if resource[:ensure] == :absent
|
||||
!section(existing_data).nil?
|
||||
else
|
||||
existing_data == expected_data
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
yaml_file_write
|
||||
end
|
||||
|
||||
def destroy
|
||||
yaml_file_write
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,42 +0,0 @@
|
||||
require 'yaml'
|
||||
require 'deep_merge'
|
||||
|
||||
Puppet::Type.type(:merge_yaml_settings).provide(:ruby) do
|
||||
desc "Support for merging yaml configuration files."
|
||||
|
||||
def create
|
||||
merged_settings = get_merged_settings
|
||||
write_to_file(@resource[:path], merged_settings.to_yaml.gsub( "x5c", "\\" )) if not (merged_settings.empty?)
|
||||
end
|
||||
|
||||
def destroy
|
||||
File.unlink(@resource[:path])
|
||||
end
|
||||
|
||||
def exists?
|
||||
get_dict(@resource[:sample_settings]) == get_merged_settings
|
||||
end
|
||||
|
||||
def get_merged_settings
|
||||
sample_settings = get_dict(@resource[:sample_settings])
|
||||
override_settings = get_dict(@resource[:override_settings])
|
||||
sample_settings.deep_merge(override_settings)
|
||||
end
|
||||
|
||||
def write_to_file(filename, content)
|
||||
debug "writing content #{content} to the file #{filename}"
|
||||
begin
|
||||
File.open(filename, "w") { |f| f.puts content }
|
||||
rescue
|
||||
raise Puppet::Error, "merge_yaml_settings: the file #{filename} can not be written!"
|
||||
end
|
||||
end
|
||||
|
||||
def get_dict(obj)
|
||||
return obj if obj.is_a?(Hash)
|
||||
YAML.load_file(obj) rescue {}
|
||||
end
|
||||
|
||||
private :get_merged_settings, :get_dict, :write_to_file
|
||||
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
Puppet::Type.newtype(:ceilometer_pipeline_section) do
|
||||
ensurable do
|
||||
defaultvalues
|
||||
defaultto :present
|
||||
end
|
||||
|
||||
newparam(:name) do
|
||||
desc 'The unique name of the resource'
|
||||
isnamevar
|
||||
end
|
||||
|
||||
newparam(:path) do
|
||||
validate do |value|
|
||||
fail 'The path should be absolute!' unless Puppet::Util.absolute_path? value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:array_name) do
|
||||
desc 'The name of the array to search section in'
|
||||
defaultto { 'sources' }
|
||||
end
|
||||
|
||||
newparam(:section_name) do
|
||||
desc 'The name of the section to update'
|
||||
defaultto { 'contrail_source' }
|
||||
end
|
||||
|
||||
newparam(:data) do
|
||||
desc 'Directly pass the section structure'
|
||||
validate do |value|
|
||||
fail 'The data structure should be a hash!' unless value.is_a? Hash
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,21 +0,0 @@
|
||||
Puppet::Type.newtype(:merge_yaml_settings) do
|
||||
|
||||
desc = "Type to merge yaml configuration files"
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name)
|
||||
|
||||
newparam(:path) do
|
||||
desc "Path for destination settings file"
|
||||
end
|
||||
|
||||
newparam(:sample_settings) do
|
||||
desc "Path or Hash containing source settings"
|
||||
end
|
||||
|
||||
newparam(:override_settings) do
|
||||
desc "Path or Hash containing custom settings"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -261,13 +261,23 @@ class contrail::controller {
|
||||
|
||||
if ($ceilometer_enabled) {
|
||||
package { 'ceilometer-plugin-contrail': } ->
|
||||
merge_yaml_settings { 'contrail_ceilometer_pipeline_yaml':
|
||||
ensure => present,
|
||||
path => '/etc/ceilometer/pipeline.yaml',
|
||||
sample_settings => '/etc/ceilometer/pipeline.yaml',
|
||||
override_settings => $custom_yaml_settings,
|
||||
require => Package['ceilometer-plugin-contrail'],
|
||||
|
||||
ceilometer_pipeline_section { 'contrail_ceilometer_pipeline_yaml_source' :
|
||||
ensure => 'present',
|
||||
path => '/etc/ceilometer/pipeline.yaml',
|
||||
data => $custom_yaml_settings['sources'],
|
||||
section_name => 'contrail_source',
|
||||
array_name => 'sources',
|
||||
} ->
|
||||
|
||||
ceilometer_pipeline_section { 'contrail_ceilometer_pipeline_yaml_sink' :
|
||||
ensure => 'present',
|
||||
path => '/etc/ceilometer/pipeline.yaml',
|
||||
data => $custom_yaml_settings['sinks'],
|
||||
section_name => 'contrail_sink',
|
||||
array_name => 'sinks',
|
||||
}
|
||||
|
||||
if $contrail::ceilometer_ha_mode {
|
||||
service {'ceilometer-agent-central':
|
||||
ensure => running,
|
||||
@@ -276,7 +286,7 @@ class contrail::controller {
|
||||
hasstatus => true,
|
||||
hasrestart => true,
|
||||
provider => 'pacemaker',
|
||||
subscribe => Merge_yaml_settings['contrail_ceilometer_pipeline_yaml'],
|
||||
tag => 'ceilometer',
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -284,14 +294,14 @@ class contrail::controller {
|
||||
service { 'ceilometer-polling':
|
||||
ensure => running,
|
||||
enable => true,
|
||||
subscribe => Merge_yaml_settings['contrail_ceilometer_pipeline_yaml'],
|
||||
tag => 'ceilometer',
|
||||
}
|
||||
}
|
||||
if !defined(Service['ceilometer-api']) {
|
||||
service { 'ceilometer-api':
|
||||
ensure => running,
|
||||
enable => true,
|
||||
subscribe => Merge_yaml_settings['contrail_ceilometer_pipeline_yaml'],
|
||||
tag => 'ceilometer',
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,4 +309,6 @@ class contrail::controller {
|
||||
Contrailplugin_ini_config<||> ~> File['/etc/neutron/plugin.ini']
|
||||
Heat_config<||> ~> Service['heat-engine']
|
||||
Nova_config<||> ~> Service['nova-api']
|
||||
Ceilometer_pipeline_section <||> ~>
|
||||
Service <| tag == 'ceilometer' |>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
require 'puppetlabs_spec_helper/module_spec_helper'
|
||||
require 'puppet'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.mock_framework = :rspec
|
||||
end
|
||||
|
||||
def puppet_debug_override
|
||||
return unless ENV['SPEC_PUPPET_DEBUG']
|
||||
Puppet::Util::Log.level = :debug
|
||||
Puppet::Util::Log.newdestination(:console)
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Puppet::Type.type(:ceilometer_pipeline_section).provider(:ruby) do
|
||||
|
||||
let(:section_data) do
|
||||
{
|
||||
'name' => 'contrail_source',
|
||||
'a' => '1',
|
||||
'b' => {
|
||||
'c' => [1, 2, 3],
|
||||
'd' => '2',
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type.type(:ceilometer_pipeline_section).new(
|
||||
:name => 'test',
|
||||
:path => '/tmp/test.yaml',
|
||||
:data => section_data,
|
||||
:provider => :ruby,
|
||||
)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
resource.provider
|
||||
end
|
||||
|
||||
subject { provider }
|
||||
|
||||
it { is_expected.not_to be_nil }
|
||||
|
||||
def get_source(data, name)
|
||||
data['sources'].find { |host| host['name'] == name }
|
||||
end
|
||||
|
||||
context 'data modification' do
|
||||
|
||||
it 'can add a new section with a custom data' do
|
||||
data = {'sources' => []}
|
||||
subject.modify_section data
|
||||
expect(get_source data, 'contrail_source').to eq(section_data)
|
||||
end
|
||||
|
||||
it 'can update the existing section with a custom data' do
|
||||
data = {
|
||||
'sources' => [
|
||||
{
|
||||
'name' => 'contrail_source',
|
||||
'a' => '1',
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
subject.modify_section data
|
||||
expect(get_source data, 'contrail_source').to eq(section_data)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Puppet::Type.type(:ceilometer_pipeline_section) do
|
||||
|
||||
subject do
|
||||
Puppet::Type.type(:ceilometer_pipeline_section)
|
||||
end
|
||||
|
||||
it 'should exist' do
|
||||
is_expected.not_to be_nil
|
||||
end
|
||||
|
||||
describe 'basic structure' do
|
||||
it 'should be able to create an instance' do
|
||||
expect(subject.new(
|
||||
:name => 'test',
|
||||
:path => '/tmp/test.yaml',
|
||||
)).to_not be_nil
|
||||
end
|
||||
|
||||
[:name, :path, :array_name, :section_name, :data].each do |param|
|
||||
it "should have a #{param} parameter" do
|
||||
expect(subject.validparameter?(param)).to be_truthy
|
||||
end
|
||||
|
||||
it "should have documentation for its #{param} parameter" do
|
||||
expect(subject.paramclass(param).doc).to be_a String
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user