Quote "bad" passwords in 'astute.yaml' right before upload it to nodes

Astute uses Ruby 2.1 with YAML 'Psych' engine which is not compatible
with Ruby 1.9 'Psych' engine used by Hierra in Puppet to parse unquoted
strings of passwords started with prefixed numeral values.

This commit uses alternate version of 'YAML::dump' method with forced
quotation of strings according its value and attributes.

Also this commit should fix possible problem with unquoted strings
containing bad mac-addresses which started with two zeros.

This commit should be reverted after upgrading to Ruby 2.1 everywhere.

Change-Id: I7435da01016c4b2266210eb9422ea1fae87de7f8
Closes-Bug: #1494779
This commit is contained in:
Maksim Malchuk 2015-10-28 12:37:59 +03:00
parent 687458e949
commit ed8248db45
2 changed files with 48 additions and 4 deletions

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
require 'psych'
module Astute
class UploadFacts < PreDeploymentAction
@ -22,16 +24,32 @@ module Astute
private
# This is simple version of 'YAML::dump' with force quoting of strings started with prefixed numeral values
def safe_yaml_dump(obj)
visitor = Psych::Visitors::YAMLTree.new({})
visitor << obj
visitor.tree.grep(Psych::Nodes::Scalar).each do |node|
node.style = Psych::Nodes::Scalar::DOUBLE_QUOTED if
node.value =~ /^0[xbod0]+/i && node.plain && node.quoted
end
visitor.tree.yaml
end
def upload_facts(context, node)
# TODO: Should be changed to the default 'to_yaml' method only after upgrading
# to Ruby 2.1 everywhere on client nodes which used this YAML.
yaml_data = safe_yaml_dump(node)
Astute.logger.info "#{context.task_id}: storing metadata for node uid=#{node['uid']} "\
"role=#{node['role']}"
Astute.logger.debug "#{context.task_id}: stores metadata: #{node.to_yaml}"
Astute.logger.debug "#{context.task_id}: stores metadata: #{yaml_data}"
# This is synchronious RPC call, so we are sure that data were sent and processed remotely
upload_mclient = Astute::MClient.new(context, "uploadfile", [node['uid']])
upload_mclient.upload(
:path => "/etc/#{node['role']}.yaml",
:content => node.to_yaml,
:content => yaml_data,
:overwrite => true,
:parents => true,
:permissions => '0600'

View File

@ -31,7 +31,16 @@ describe Astute::UploadFacts do
'openstack_version_prev' => 'old_version',
'cobbler' => {
'profile' => 'centos-x86_64'
}
},
'password_1' => '0xABC123',
'password_2' => '0XABC123',
'password_3' => '0b101010',
'password_4' => '0B101010',
'password_5' => '0o123456',
'password_6' => '0O123456',
'password_7' => '0d123456',
'password_8' => '0D123456',
'mac_address' => '00:12:34:ab:cd:ef'
}
]
}
@ -49,7 +58,24 @@ describe Astute::UploadFacts do
it 'should upload facts using YAML format to nodes in <role>.yaml file' do
mclient.expects(:upload).with(
:path =>'/etc/controller.yaml',
:content => deploy_data.first.to_yaml,
:content => upload_facts.send(:safe_yaml_dump, deploy_data.first),
:overwrite => true,
:parents => true,
:permissions => '0600'
)
upload_facts.process(deploy_data, ctx)
end
it 'should upload valid YAML format to nodes in <role>.yaml file' do
valid_yaml_data = "---\nuid: '1'\nrole: controller\nopenstack_version_prev: old_version\ncobbler:\n profile: centos-x86_64\n"\
"password_1: \"0xABC123\"\npassword_2: \"0XABC123\"\npassword_3: \"0b101010\"\npassword_4: \"0B101010\"\n"\
"password_5: \"0o123456\"\npassword_6: \"0O123456\"\npassword_7: \"0d123456\"\npassword_8: \"0D123456\"\n"\
"mac_address: \"00:12:34:ab:cd:ef\"\n"
mclient.expects(:upload).with(
:path =>'/etc/controller.yaml',
:content => valid_yaml_data,
:overwrite => true,
:parents => true,
:permissions => '0600'