* change facts file destination from '/etc/naily.facts' to '/etc/astute.yaml'

* refactoring;
* remove unused mcollective agent 'nailyfact';
* update tests.
This commit is contained in:
Vladmir Sharhsov(warpc) 2013-09-23 09:18:10 +04:00
parent cede3f1c75
commit 7dd6afe074
7 changed files with 29 additions and 198 deletions

View File

@ -24,7 +24,6 @@ require 'astute/ext/deep_copy'
require 'astute/config'
require 'astute/logparser'
require 'astute/orchestrator'
require 'astute/metadata'
require 'astute/deployment_engine'
require 'astute/network'
require 'astute/puppetd'

View File

@ -19,12 +19,6 @@ class Astute::DeploymentEngine::NailyFact < Astute::DeploymentEngine
def deploy_piece(nodes, retries=2, change_node_status=true)
return false unless validate_nodes(nodes)
if nodes.empty?
Astute.logger.info "#{@ctx.task_id}: Returning from deployment stage. No nodes to deploy"
return
end
Astute.logger.info "#{@ctx.task_id}: Calculation of required attributes to pass, include netw.settings"
@ctx.reporter.report(nodes_status(nodes, 'deploying', {'progress' => 0}))
begin
@ -33,14 +27,23 @@ class Astute::DeploymentEngine::NailyFact < Astute::DeploymentEngine
Astute.logger.warn "Some error occurred when prepare LogParser: #{e.message}, trace: #{e.format_backtrace}"
end
nodes.each do |node|
upload_mclient = MClient.new(@ctx, "uploadfile", [node['uid']])
upload_mclient.upload(:path => '/etc/naily.facts', :content => create_facts(node), :overwrite => true, :parents => true)
end
nodes.each { |node| upload_facts(node) }
Astute.logger.info "#{@ctx.task_id}: Required attrs/metadata passed via facts extension. Starting deployment."
Astute::PuppetdDeployer.deploy(@ctx, nodes, retries, change_node_status)
nodes_roles = nodes.map { |n| {n['uid'] => n['role']} }
Astute.logger.info "#{@ctx.task_id}: Finished deployment of nodes => roles: #{nodes_roles.inspect}"
end
private
def upload_facts(node)
Astute.logger.info "#{@ctx.task_id}: storing metadata for node uid=#{node['uid']}"
Astute.logger.debug "#{@ctx.task_id}: stores metadata: #{node.to_yaml}"
# This is synchronious RPC call, so we are sure that data were sent and processed remotely
upload_mclient = Astute::MClient.new(@ctx, "uploadfile", [node['uid']])
upload_mclient.upload(:path => '/etc/astute.yaml', :content => node.to_yaml, :overwrite => true, :parents => true)
end
end

View File

@ -1,30 +0,0 @@
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
require 'json'
require 'ipaddr'
module Astute
module Metadata
def self.publish_facts(ctx, uid, metadata)
# This is synchronious RPC call, so we are sure that data were sent and processed remotely
Astute.logger.info "#{ctx.task_id}: nailyfact - storing metadata for node uid=#{uid}"
Astute.logger.debug "#{ctx.task_id}: nailyfact stores metadata: #{metadata.inspect}"
nailyfact = MClient.new(ctx, "nailyfact", [uid])
# TODO(mihgen) check results!
stats = nailyfact.post(:value => metadata.to_json)
end
end
end

View File

@ -1,39 +0,0 @@
metadata :name => "Naily Fact Agent",
:description => "Key/values in a text file",
:author => "Puppet Master Guy",
:license => "GPL",
:version => "Version 1",
:url => "www.naily.com",
:timeout => 40
action "get", :description => "fetches a value from a file" do
display :failed
input :key,
:prompt => "Key",
:description => "Key you want from the file",
:type => :string,
:validation => '^[a-zA-Z0-9_]+$',
:optional => false,
:maxlength => 0
output :value,
:description => "Value",
:display_as => "Value"
end
action "post", :description => "Create new attributes file" do
display :failed
input :value,
:prompt => "Value",
:description => "Value you want to set in the file",
:type => :string,
:validation => '.*',
:optional => false,
:maxlength => 0
output :msg,
:description => "Status",
:display_as => "Status"
end

View File

@ -1,87 +0,0 @@
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
require 'json'
module MCollective
module Agent
class Nailyfact<RPC::Agent
nailyfile = "/etc/naily.facts"
def parse_facts(fname)
begin
if File.exist?(fname)
kv_map = {}
File.readlines(fname).each do |line|
if line =~ /^(.+)=(.+)$/
@key = $1.strip;
@val = $2.strip
kv_map.update({@key=>@val})
end
end
return kv_map
else
f = File.open(fname,'w')
f.close
File.open("/var/log/facter.log", "a") {|f| f.write("#{Time.now} EMPTY facts saved\n")}
return {}
end
rescue
logger.warn("Could not access naily facts file. There was an error in nailyfacts.rb:parse_facts")
return {}
end
end
def write_facts(fname, facts)
if not File.exists?(File.dirname(fname))
Dir.mkdir(File.dirname(fname))
end
begin
f = File.open(fname,"w+")
facts.each do |k,v|
f.puts("#{k} = #{v}")
end
f.close
File.open("/var/log/facter.log", "a") {|f| f.write("#{Time.now} facts saved\n")}
return true
rescue
File.open("/var/log/facter.log", "a") {|f| f.write("#{Time.now} facts NOT saved\n")}
return false
end
end
action "get" do
validate :key, String
kv_map = parse_facts(nailyfile)
if kv_map[request[:key]] != nil
reply[:value] = kv_map[request[:key]]
end
end
action "post" do
validate :value, String
kv_map = JSON.parse(request[:value])
if write_facts(nailyfile, kv_map)
reply[:msg] = "Settings Updated!"
else
reply.fail! "Could not write file!"
end
end
end
end
end

View File

@ -31,22 +31,6 @@ describe "MCollective" do
check_mcollective_result(stats)
stats[0].results[:data][:msg].should eql("Hello, it is my reply: #{data_to_send}")
end
it "it should update facts file with new key-value and could get it back" do
data_to_send = {"anykey" => rand(2**30).to_s, "other" => "static"}
mc = rpcclient("nailyfact")
mc.progress = false
mc.discover(:nodes => [NODE])
stats = mc.post(:value => data_to_send.to_json)
check_mcollective_result(stats)
stats = mc.get(:key => "anykey")
check_mcollective_result(stats)
stats[0].results[:data][:value].should eql(data_to_send['anykey'])
stats = mc.get(:key => "other")
check_mcollective_result(stats)
stats[0].results[:data][:value].should eql(data_to_send['other'])
end
end
end

View File

@ -53,7 +53,7 @@ describe "NailyFact DeploymentEngine" do
it "it should not raise an exception if deployment mode is unknown" do
deploy_engine.stubs(:generate_and_upload_ssh_keys).with([1], deploy_data.first['deployment_id'])
Astute::Metadata.stubs(:publish_facts).times(deploy_data.size)
deploy_engine.expects(:upload_facts).times(deploy_data.size)
Astute::PuppetdDeployer.stubs(:deploy).with(ctx, deploy_data, instance_of(Fixnum), true).once
expect {deploy_engine.deploy(deploy_data)}.to_not raise_exception
end
@ -65,15 +65,16 @@ describe "NailyFact DeploymentEngine" do
end
it "should not raise any exception" do
Astute::Metadata.expects(:publish_facts).times(deploy_data.size)
uniq_nodes_uid = deploy_data.map { |n| n['uid'] }.uniq
deploy_engine.expects(:upload_facts).times(deploy_data.size)
uniq_nodes_uid = deploy_data.map {|n| n['uid'] }.uniq
deploy_engine.expects(:generate_and_upload_ssh_keys).with(uniq_nodes_uid, deploy_data.first['deployment_id'])
# we got two calls, one for controller (high priority), and another for all computes (same low priority)
Astute::PuppetdDeployer.expects(:deploy).with(ctx, controller_nodes, instance_of(Fixnum), true).once
Astute::PuppetdDeployer.expects(:deploy).with(ctx, compute_nodes, instance_of(Fixnum), true).once
deploy_engine.deploy(deploy_data)
expect {deploy_engine.deploy(deploy_data)}.to_not raise_exception
end
end
@ -89,22 +90,22 @@ describe "NailyFact DeploymentEngine" do
let(:node_amount) { deploy_data.size }
it "should prepare log parsing for every deploy call because node may be deployed several times" do
Astute::Metadata.expects(:publish_facts).times(node_amount)
deploy_engine.expects(:upload_facts).times(node_amount)
ctx.deploy_log_parser.expects(:prepare).with(compute_nodes).once
ctx.deploy_log_parser.expects(:prepare).with(cinder_nodes).once
uniq_nodes_uid = deploy_data.map {|n| n['uid'] }.uniq
deploy_engine.expects(:generate_and_upload_ssh_keys).with(uniq_nodes_uid, deploy_data.first['deployment_id'])
Astute::PuppetdDeployer.expects(:deploy).times(2)
deploy_engine.deploy(deploy_data)
end
it "should generate and publish facts for every deploy call because node may be deployed several times" do
it "should generate and publish facts for every deploy call because node may be deployed several times" do
ctx.deploy_log_parser.expects(:prepare).with(compute_nodes).once
ctx.deploy_log_parser.expects(:prepare).with(cinder_nodes).once
Astute::Metadata.expects(:publish_facts).times(node_amount)
deploy_engine.expects(:upload_facts).times(node_amount)
uniq_nodes_uid = deploy_data.map {|n| n['uid'] }.uniq
deploy_engine.expects(:generate_and_upload_ssh_keys).with(uniq_nodes_uid, deploy_data.first['deployment_id'])
@ -120,8 +121,8 @@ describe "NailyFact DeploymentEngine" do
end
it "ha deploy should not raise any exception" do
Astute::Metadata.expects(:publish_facts).at_least_once
deploy_engine.expects(:upload_facts).at_least_once
uniq_nodes_uid = deploy_data.map {|n| n['uid'] }.uniq
deploy_engine.expects(:generate_and_upload_ssh_keys).with(uniq_nodes_uid, deploy_data.first['deployment_id'])
@ -137,7 +138,7 @@ describe "NailyFact DeploymentEngine" do
end
it "ha deploy should not raise any exception if there are only one controller" do
Astute::Metadata.expects(:publish_facts).at_least_once
deploy_engine.expects(:upload_facts).at_least_once
Astute::PuppetdDeployer.expects(:deploy).once
ctrl = deploy_data.find { |n| n['role'] == 'controller' }