Skip to content

Commit

Permalink
Merge pull request #15990 from jameswnl/rep-server-settings
Browse files Browse the repository at this point in the history
Tool to replicate server settings to other servers
  • Loading branch information
carbonin authored Sep 20, 2017
2 parents 0bddb46 + 7af94f6 commit a215bb7
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
$LOAD_PATH << Rails.root.join("tools")

require "server_settings_replicator/server_settings_replicator"

describe ServerSettingsReplicator do
let(:miq_server) { EvmSpecHelper.local_miq_server }
let!(:miq_server_remote) { EvmSpecHelper.remote_miq_server }
let(:settings) { {:k1 => {:k2 => {:k3 => 'v3'}}} }

describe "#replicate" do
it "targets only other servers" do
miq_server.add_settings_for_resource(settings)
expect(described_class).to receive(:copy_to).with([miq_server_remote], settings)
described_class.replicate(miq_server, 'k1/k2')
end
end

describe "#construct_setting_tree" do
it "handle simple value" do
path = [:k1, :k2]
values = 'abc'
expect(described_class.construct_setting_tree(path, values)).to eq(:k1 => {:k2 => 'abc'})
end

it "handle hash value" do
path = [:k1, :k2]
values = {:k3 => 'v3', :k4 => 'v4'}
expect(described_class.construct_setting_tree(path, values)).to eq(:k1 => {:k2 => {:k3 => 'v3', :k4 => 'v4'}})
end
end
end
20 changes: 20 additions & 0 deletions tools/replicate_server_settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
require File.expand_path("../config/environment", __dir__)
$LOAD_PATH << Rails.root.join("tools")
require 'trollop'
require 'server_settings_replicator/server_settings_replicator'

opts = Trollop.options(ARGV) do
banner "USAGE: #{__FILE__} -s <server id> -p <path/to/the/settings> \n" \
"Example: #{__FILE__} -d -s 1 -p ems/ems_amazon/additional_instance_types"

opt :dry_run, "Dry Run", :short => "d"
opt :serverid, "Replicating source server Id (default: current server)", :short => "s"
opt :path, "Replicating source path within advanced settings hash", :short => "p", :default => ""
end

puts opts.inspect
Trollop.die :path, "is required" unless opts[:path_given]

server = opts[:serverid] ? MiqServer.find(opts[:serverid]) : MiqServer.my_server
ServerSettingsReplicator.replicate(server, opts[:path], opts[:dry_run])
31 changes: 31 additions & 0 deletions tools/server_settings_replicator/server_settings_replicator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class ServerSettingsReplicator
def self.replicate(server, path_string, dry_run = false)
path = path_string.split("/").map(&:to_sym)

# all servers except source
target_servers = MiqServer.where.not(:id => server.id)
settings = construct_setting_tree(path, server.settings_for_resource.fetch_path(path).to_h)

puts "Replicating from server id=#{server.id}, path=#{path_string} to #{target_servers.count} servers"
puts "Settings: #{settings}"

if dry_run
puts "Dry run, no updates have been made"
else
copy_to(target_servers, settings)
end
puts "Done"
end

def self.construct_setting_tree(path, values)
# construct the partial tree containing the target values
path.reverse.inject(values) { |merged, element| {element => merged} }
end

def self.copy_to(target_servers, target_settings)
target_servers.each do |target|
puts " - replicating to server id=#{target.id}..."
target.add_settings_for_resource(target_settings)
end
end
end

0 comments on commit a215bb7

Please sign in to comment.