Created
July 31, 2014 17:00
-
-
Save tfitch/778c9557f39bb5958a36 to your computer and use it in GitHub Desktop.
converge nodes via API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# ASSUMES YOU'VE ALREADY USED single_org_setup.rb to create your nodes | |
# which will have saved the nodes key files to your machine and make API auth go | |
require 'fauxhai' | |
require 'mixlib/cli' | |
require 'mixlib/config' | |
require 'chef/rest' | |
require 'chef/node' | |
module ConvergeNodesSetup | |
attr_accessor :config | |
# This makes config functions available to be called directly | |
module_function :config=, :config | |
def self.determine_base_dir | |
current_dir = Dir.pwd | |
# Split current dir around the bin directory | |
# If we're in the bin directory, it will be the 1 index of the array | |
# and the base dir above it will be in the 0 index of the array | |
# Even if we're not, the entire dir path will be in the 0 index of the array | |
# and the rest of the array will be empty, based on how partition works | |
# Also make sure the dir string ends with a / to make life later easier | |
partition = current_dir.partition("bin") | |
if partition[0].end_with?("/") | |
partition[0] | |
else | |
partition[0] + "/" | |
end | |
end | |
def self.extract_org | |
# split on /, org will be last part of url | |
config[:chef_server_url].split('/')[-1] | |
end | |
class TermFile | |
TERM_FILE_KEYS = [:node_name, :client_key, :validation_client_name, | |
:validation_key, :chef_server_url] | |
def config | |
ConvergeNodesSetup.config | |
end | |
def create_erlang_term_file | |
puts "Creating chef.config" unless !config[:verbose] | |
config_dir = config[:base_dir] + "config" | |
Dir.mkdir(config_dir) unless Dir.exists?(config_dir) | |
# Assumes we're on a unix system, b/c of mode + perm bits | |
terms = term_file_hash | |
File.open("#{config_dir}/chef.config", "w", 0644) do |file| | |
terms.each do |key, value| | |
file.write("{#{key}, \"#{value}\"}.\n") | |
end | |
file.write("{org_name, \"#{ConvergeNodesSetup.extract_org}\"}.\n") | |
end | |
end | |
def term_file_hash | |
term_hash = {} | |
TERM_FILE_KEYS.each do |key| | |
term_hash[key] = ConvergeNodesSetup.config[key] | |
end | |
term_hash | |
end | |
end # End TermFile class | |
class ServerSetup | |
def config | |
ConvergeNodesSetup.config | |
end | |
def org | |
@org ||= ConvergeNodesSetup.extract_org | |
end | |
def node_json(name) | |
{ | |
:name => name, | |
:admin => false | |
} | |
end | |
def clients_endpoint | |
"clients" | |
end | |
def nodes_endpoint | |
"nodes" | |
end | |
def request_body1 | |
'{ | |
"overrides": {}, | |
"name": "latte", | |
"chef_type": "node", | |
"json_class": "Chef::Node", | |
"attributes": { | |
"hardware_type": "laptop" | |
} | |
}' | |
end | |
def request_body2 | |
'{ | |
"overrides": {}, | |
"name": "latte", | |
"chef_type": "node", | |
"json_class": "Chef::Node", | |
"attributes": { | |
"hardware_type": "laptop" | |
}, | |
"run_list": [], | |
"defaults": {} | |
}' | |
end | |
def keys_dir | |
config[:base_dir] + "keys" | |
end | |
def config_dir | |
config[:base_dir] + "config" | |
end | |
def rest_client | |
Chef::REST.new(config[:chef_server_url], config[:node_name], | |
config[:client_key]) | |
end | |
def converge_node(node_number) | |
# org is in the name to namespace keys and configs that all go into same dir | |
node_name = "testing_node_#{org}_#{node_number}" | |
puts "Converging node #{nodes_endpoint}/#{node_name}" unless !config[:verbose] | |
begin | |
# creating a node consists of creating the client for that node, then the node | |
node_info = node_json(node_name) | |
node = Chef::Node.new | |
node.name(node_name) | |
# TODO TFITCH: attach Fauxhai attributes here. Then post/save the node | |
# 400 rest_client.put("#{nodes_endpoint}/#{node_name}", node_info) | |
# rest_client.put_rest("#{nodes_endpoint}/#{node_name}", request_body1) | |
# 500 rest_client.put("#{nodes_endpoint}/#{node_name}", Fauxhai.mock(platform: 'ubuntu', version: '12.04')) | |
# rest_client.put("#{nodes_endpoint}/#{node_name}", request_body2) | |
rest_client.put("nodes/testing_node_loadtest_0", '{"name": "testing_node_loadtest_0"}') | |
rescue Net::HTTPServerException => e | |
if e.message == '409 "Conflict"' | |
puts "Received 409 Conflict creating node #{node_name}" unless !config[:verbose] | |
puts "Assuming node already exists and key/config are in place" unless !config[:verbose] | |
else | |
# Don't know the cause of the error, so bail | |
raise | |
end | |
end | |
end | |
def converge_nodes | |
node_count = config[:nodes].to_i | |
node_count.times do |count| | |
converge_node(count) | |
end | |
end | |
end # End ServerSetup class | |
end # End ConvergeNodesSetup Module | |
class ConvergeNodesCli | |
include Mixlib::CLI | |
option :help, | |
:short => "-h", | |
:long => "--help", | |
:boolean => true, | |
:description => "Print usage, which is this message.", | |
:show_options => true, | |
:exit => 0 | |
option :verbose, | |
:short => "-v", | |
:long => "--verbose", | |
:boolean => true, | |
:description => "Verbose mode, give output when the script performs actions." | |
option :knife_rb, | |
:short => "-k knife.rb", | |
:long => "--knife knife.rb", | |
:required => true, | |
:description => "The location of knife.rb config to use." | |
option :nodes, | |
:short => "-n integer", | |
:long => "--nodes integer", | |
:default => 100, | |
:description => "The number of nodes to create for the test run. Default is 100." | |
end | |
class ConvergeNodesConfig | |
extend Mixlib::Config | |
end | |
args = ConvergeNodesCli.new | |
args.parse_options(ARGV) | |
ConvergeNodesConfig.from_file(args.config[:knife_rb]) | |
config = args.config.merge!(ConvergeNodesConfig.configuration) | |
config[:base_dir] = ConvergeNodesSetup.determine_base_dir | |
puts "Using a base dir of #{config[:base_dir]}" unless !config[:verbose] | |
ConvergeNodesSetup.config = config | |
termfile = ConvergeNodesSetup::TermFile.new | |
termfile.create_erlang_term_file | |
setup = ConvergeNodesSetup::ServerSetup.new | |
setup.converge_nodes | |
puts "Finished" unless !config[:verbose] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment