diff --git a/Rakefile.rb b/Rakefile.rb index a48a0e2..b1fd492 100644 --- a/Rakefile.rb +++ b/Rakefile.rb @@ -27,6 +27,27 @@ File.join(STATEDIR, 'config.yml'), ] +KNOWN_ISPS = { + hetzner: { + name: "Hetzner (hetzner.com)", + keys: %i{user password}, + }, + ovh: { + name: "OVH (ovh.com)", + keys: %i{app_key app_secret consumer_key}, + }, + serverscom: { + name: "Servers.com", + keys: %i{mail token password}, + }, + leaseweb: { + multiple: true, + name: "Leaseweb (leaseweb.com)", + keys: %i{apikey}, + }, +} + + $conf = {} CONFIG_FILES.each do |config_yml| $conf.deep_merge!(YAML.load_file(config_yml).deep_symbolize_keys) if File.exist?(config_yml) @@ -58,9 +79,90 @@ puts "STATEDIR=#{STATEDIR}: #{File.directory?(STATEDIR)}" puts "PRIVATE_SSH_KEY=#{PRIVATE_SSH_KEY}: #{File.exist?(PRIVATE_SSH_KEY)}" puts - puts "Hetzner account configured: #{!!$conf[:hetzner]}" - puts "OVH account configured: #{!!$conf[:ovh]}" - puts "Soyoustart account configured: #{!!$conf[:soyoustart]}" - puts "Servers.com account configured: #{!!$conf[:serverscom]}" - puts "Leaseweb accounts configured: #{($conf[:leaseweb] && $conf[:leaseweb].keys.join(', ')) || "none"}" + KNOWN_ISPS.each do |isp,isp_setup| + if isp_setup[:multiple] + puts "#{isp_setup[:name]} accounts configured: #{($conf[isp] && $conf[isp].keys.join(', ')) || "none"}" + else + puts "#{isp_setup[:name]}: #{!!$conf[isp]}" + end + end +end + +def prompt(*args) + print *args, ": " + STDIN.gets.chomp +end + +def yesno(*args) + response = nil + loop do + response = prompt(*args," (Y/N)").upcase + break if ['Y', 'N'].include? response + end + response == 'Y' +end + +def prompt_config(isp_setup, isp_conf, isp_name) + puts isp_name + isp_setup[:keys].each do |isp_key| + new_value = prompt("#{isp_key} (current '#{isp_conf[isp_key]}', blank to not touch, '.' to remove)") + if new_value == '.' + isp_conf.delete(isp_key) + elsif new_value != "" + isp_conf[isp_key] = new_value + end + end +end + +desc "interactively setup a minimal config" +task :configure do + local_conf = {} + local_conf.deep_merge!(YAML.load_file(CONFIG_FILES[-1]).deep_symbolize_keys) if File.exist?(CONFIG_FILES[-1]) + + KNOWN_ISPS.each do |isp, isp_setup| + isp_conf = local_conf[isp] || ($conf[isp] || {}) + + next unless yesno("Configure #{isp_setup[:name]}") + + if isp_setup[:multiple] + loop do + puts "#{isp_setup[:name]} - known accounts: #{isp_conf.keys.join(', ')}" + subaccount = prompt "ID for subaccount (blank for done)" + if subaccount != "" + prompt_config(isp_setup, isp_conf[subaccount.to_sym] ||= {}, "#{isp_setup[:name]}[#{subaccount}]") + else + break + end + end + else + prompt_config(isp_setup, isp_conf, isp_setup[:name]) + end + if isp_conf.values.all?{|r| r == ''} + local_conf.delete(isp) + else + puts YAML.dump(isp_conf) + if yesno("Keep this config for #{isp}") + local_conf[isp] = isp_conf + end + end + end + + %x{mkdir -p #{File.dirname(CONFIG_FILES[-1])}} + File.write(CONFIG_FILES[-1],YAML.dump(local_conf)) + + if File.exist?(PRIVATE_SSH_KEY) + puts "SSH keys exists, keeping" + else + puts "No ssh key, generating now." + puts "For OVH, please uploaded it in the web ui" if local_conf[:ovh] + puts "Generating a private key. For OVH please upload it in the web ui" + %x{mkdir -p #{File.dirname(PRIVATE_SSH_KEY)}} + %x{ssh-keygen -t rsa -f #{PRIVATE_SSH_KEY} -N ''} + end + + pem_file = "#{PRIVATE_SSH_KEY}.pub.pem" + if !File.exist?(pem_file) + puts "Also creating a PEM file for the SSH key" + %x{ssh-keygen -f #{PRIVATE_SSH_KEY} -e -m pem > #{pem_file}} + end end diff --git a/setup/bootstrap b/setup/bootstrap index b84968c..e9cf16c 100755 --- a/setup/bootstrap +++ b/setup/bootstrap @@ -10,3 +10,5 @@ rvm install `cat .ruby-version` cd $ROOT_DIR gem install bundler bundle install +rake configure +rake diff --git a/tasks/support/baremetal.rb b/tasks/support/baremetal.rb index 467e24c..efe2da3 100644 --- a/tasks/support/baremetal.rb +++ b/tasks/support/baremetal.rb @@ -20,7 +20,6 @@ def baremetal_isps # TODO: generic bootstrap hetzner_init leaseweb_init - soyoustart_init ovh_init serverscom_init end diff --git a/tasks/support/leaseweb.rb b/tasks/support/leaseweb.rb index 3f06497..f7b9f1b 100644 --- a/tasks/support/leaseweb.rb +++ b/tasks/support/leaseweb.rb @@ -59,9 +59,9 @@ def leaseweb_init host[:isp][:rack] = info['location']['rack'] host[:isp][:costs] = details['contract']['pricePerFrequency'] host[:isp][:currency] = details['contract']['currency'] || 'USD' - hardware_details['result']['network'].each_with_index.map { |interface, index| + hardware_details['result']['network'].each_with_index.map { |interface, index| #puts interface['settings']['speed'].class - unless interface['settings']['speed'].nil? + unless interface['settings']['speed'].nil? host[:isp]["network_#{index}".to_sym] = {} host[:isp]["network_#{index}".to_sym][:mac] = interface['mac_address'] host[:isp]["network_#{index}".to_sym][:speed] = interface['settings']['speed'] diff --git a/tasks/support/soyoustart.rb b/tasks/support/soyoustart.rb deleted file mode 100644 index 2dc2187..0000000 --- a/tasks/support/soyoustart.rb +++ /dev/null @@ -1,54 +0,0 @@ -def soyoustart_init - if $conf[:soyoustart] - soyoustart = Soyoustart::REST.new($conf[:soyoustart][:app_key], $conf[:soyoustart][:app_secret], $conf[:soyoustart][:consumer_key]) - - @isps["soyoustart"] = Class.new do - define_singleton_method :scan do |state| - target_state = {} - - soyoustart_servers = soyoustart.get('/dedicated/server') - puts "#{soyoustart_servers.length} servers at soyoustart" - soyoustart_servers.each do |id| - status = soyoustart.get("/dedicated/server/#{id}/serviceInfos")['status'] - if status != 'ok' - print "_" - next - end - metal = soyoustart.get("/dedicated/server/#{id}") - details = soyoustart.get("/dedicated/server/#{id}/specifications/hardware") - host = baremetal_by_id('soyoustart', metal['name'], state) - host[:isp][:info] = "#{details['description']} #{details['diskGroups'].map{|d| d['description']}.join(';')}" - host[:isp][:dc] = metal['datacenter'] - host[:isp][:rack] = metal['rack'] - - host[:ipv4] = metal['ip'] - - dc, dc_id = metal['datacenter'].scan(/^(.+?)(\d*)$/).first - - details['description'].split(' ')[0].gsub(/\-/,'') - - naming_convention = "#{metal['commercialRange']}-#{dc_id}-#{metal['rack']}-.#{dc}".downcase - baremetal_id = baremetal_unique_id(naming_convention, host, target_state.merge(state)) - target_state[baremetal_id] = host - end - puts '' - - target_state - end - - define_singleton_method :rescue do |hostparam| - host = baremetal_by_human_input(hostparam) - name = host[:isp][:id] - - puts "putting #{name} into rescue" - - soyoustart.put("/dedicated/server/#{name}", 'bootId' => 1122, 'monitoring' => false) - #soyoustart.put("/dedicated/server/#{name}/serviceInfos", 'renew' => {'automatic' => true, 'forced' => false, 'period' => 1, 'deleteAtExpiration' => false}) - soyoustart.post("/dedicated/server/#{name}/reboot") - wait_for_ssh(name) - soyoustart.put("/dedicated/server/#{name}", 'bootId' => 1) - end - - end - end -end