Class: Cheftacular::StatelessAction
- Inherits:
-
Object
- Object
- Cheftacular::StatelessAction
- Includes:
- RbConfig
- Defined in:
- lib/cheftacular/stateless_action.rb,
lib/cheftacular/stateless_actions/rvm.rb,
lib/cheftacular/stateless_actions/help.rb,
lib/cheftacular/stateless_actions/pass.rb,
lib/cheftacular/stateless_actions/cloud.rb,
lib/cheftacular/stateless_actions/slack.rb,
lib/cheftacular/stateless_actions/backups.rb,
lib/cheftacular/stateless_actions/service.rb,
lib/cheftacular/stateless_actions/test_env.rb,
lib/cheftacular/stateless_actions/arguments.rb,
lib/cheftacular/stateless_actions/fetch_file.rb,
lib/cheftacular/stateless_actions/update_tld.rb,
lib/cheftacular/stateless_actions/client_list.rb,
lib/cheftacular/stateless_actions/disk_report.rb,
lib/cheftacular/stateless_actions/environment.rb,
lib/cheftacular/stateless_actions/get_pg_pass.rb,
lib/cheftacular/stateless_actions/knife_upload.rb,
lib/cheftacular/stateless_actions/reinitialize.rb,
lib/cheftacular/stateless_actions/restart_swap.rb,
lib/cheftacular/stateless_actions/upload_nodes.rb,
lib/cheftacular/stateless_actions/upload_roles.rb,
lib/cheftacular/stateless_actions/remove_client.rb,
lib/cheftacular/stateless_actions/server_update.rb,
lib/cheftacular/stateless_actions/chef_bootstrap.rb,
lib/cheftacular/stateless_actions/compile_readme.rb,
lib/cheftacular/stateless_actions/create_git_key.rb,
lib/cheftacular/stateless_actions/full_bootstrap.rb,
lib/cheftacular/stateless_actions/clean_cookbooks.rb,
lib/cheftacular/stateless_actions/cloud_bootstrap.rb,
lib/cheftacular/stateless_actions/fix_known_hosts.rb,
lib/cheftacular/stateless_actions/get_haproxy_log.rb,
lib/cheftacular/stateless_actions/chef_environment.rb,
lib/cheftacular/stateless_actions/get_log_from_bag.rb,
lib/cheftacular/stateless_actions/cleanup_log_files.rb,
lib/cheftacular/stateless_actions/compile_audit_log.rb,
lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb,
lib/cheftacular/stateless_actions/replication_status.rb,
lib/cheftacular/stateless_actions/clean_sensu_plugins.rb,
lib/cheftacular/stateless_actions/update_split_branches.rb,
lib/cheftacular/stateless_actions/clean_server_passwords.rb,
lib/cheftacular/stateless_actions/check_cheftacular_settings.rb,
lib/cheftacular/stateless_actions/get_active_ssh_connections.rb,
lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb,
lib/cheftacular/stateless_actions/bootstrappers/centos_bootstrap.rb,
lib/cheftacular/stateless_actions/bootstrappers/coreos_bootstrap.rb,
lib/cheftacular/stateless_actions/bootstrappers/fedora_bootstrap.rb,
lib/cheftacular/stateless_actions/bootstrappers/redhat_bootstrap.rb,
lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb,
lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb,
lib/cheftacular/stateless_actions/update_cloudflare_dns_from_cloud.rb,
lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb
Instance Method Summary collapse
-
#add_ssh_key_to_bag(specific_repository = "") ⇒ Object
TODO key for environment specific deploys?.
- #arguments ⇒ Object
- #backups(force_fetch_and_restore = false) ⇒ Object
- #check_cheftacular_settings ⇒ Object
- #chef_bootstrap(out = []) ⇒ Object
- #chef_environment ⇒ Object
- #clean_cookbooks(local_options = {'interactive' => true}) ⇒ Object
- #clean_sensu_plugins ⇒ Object
- #clean_server_passwords ⇒ Object
- #cleanup_log_files ⇒ Object
- #client_list ⇒ Object
- #cloud(*args) ⇒ Object (also: #aws, #rax)
- #cloud_bootstrap ⇒ Object
- #compile_audit_log(out = []) ⇒ Object
- #compile_readme(out = []) ⇒ Object
- #coreos_bootstrap(out = []) ⇒ Object
- #create_git_key(oauth_key = "") ⇒ Object
- #disk_report(disk_hash = {}, out = []) ⇒ Object
- #environment(type = "boot", ask_on_destroy = false, remove = true) ⇒ Object
- #fedora_bootstrap(out = []) ⇒ Object
- #fetch_file(out = []) ⇒ Object
- #fix_known_hosts ⇒ Object
- #full_bootstrap ⇒ Object
- #get_active_ssh_connections ⇒ Object
- #get_haproxy_log ⇒ Object
- #get_log_from_bag ⇒ Object
- #get_pg_pass(clip = false, target_repos = []) ⇒ Object
- #get_shorewall_allowed_connections(master_log_data = '') ⇒ Object
- #help(inference_modes = []) ⇒ Object
-
#initialize(options, config) ⇒ StatelessAction
constructor
A new instance of StatelessAction.
- #initialize_data_bag_contents(env = "") ⇒ Object
- #knife_upload ⇒ Object
- #pass ⇒ Object
- #redhat_bootstrap(out = []) ⇒ Object
- #reinitialize(out = []) ⇒ Object
- #remove_client(delete_server = false, remove = true) ⇒ Object
- #replication_status(rep_status_hash = {}, out = []) ⇒ Object
- #restart_swap ⇒ Object
- #rvm(command = '') ⇒ Object
-
#server_update ⇒ Object
TODO refactor to handling multiple server types.
- #service ⇒ Object
- #slack(message = '', channel = '') ⇒ Object
- #test_env(split_env = "splitstaging", type = "boot") ⇒ Object
- #ubuntu_bootstrap(out = []) ⇒ Object
- #update_cloudflare_dns_from_cloud ⇒ Object
- #update_split_branches ⇒ Object
- #update_tld(target_tld = "") ⇒ Object
- #upload_nodes(invalidate_file_node_cache = false) ⇒ Object
- #upload_roles ⇒ Object
- #vyatta_bootstrap(out = []) ⇒ Object
Constructor Details
#initialize(options, config) ⇒ StatelessAction
Returns a new instance of StatelessAction.
12 13 14 |
# File 'lib/cheftacular/stateless_action.rb', line 12 def initialize , config @options, @config = , config end |
Instance Method Details
#add_ssh_key_to_bag(specific_repository = "") ⇒ Object
TODO key for environment specific deploys?
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb', line 20 def add_ssh_key_to_bag specific_repository="" raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') raise "Please put quotes around your SSH public key!" if ARGV[1].length < 25 #TODO REFACTOR to accurate length of shortest key specific_repository = ARGV[2] if ARGV[2] && specific_repository.empty? if !specific_repository.empty? && @config['getter'].get_repo_names_for_repositories.include?(specific_repository) puts "The repository passed (#{ specific_repository }) is not listed in the cheftacular.yml repositories hash! Please update the hash or check your spelling!" return false end public_ssh_key = ARGV[1] if specific_repository.blank? @config['default']['authentication_bag_hash']["authorized_keys"] << public_ssh_key else @config['default']['authentication_bag_hash']["specific_authorized_keys"] << public_ssh_key end @config['ChefDataBag'].save_authentication_bag end |
#arguments ⇒ Object
59 60 61 62 |
# File 'lib/cheftacular/stateless_actions/arguments.rb', line 59 def arguments #TODO point this command to it's help and display? raise "This command currently does nothing, do not try to run it." end |
#backups(force_fetch_and_restore = false) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/cheftacular/stateless_actions/backups.rb', line 16 def backups force_fetch_and_restore=false fetch_backup = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['fetch_backups'] restore_backup = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['restore_backups'] puts "For #{ @options['env'] } (sub-env: #{ @options['sub_env'] }) fetch backups was set to #{ fetch_backup ? 'on' : 'off' } and restoring backups was set to #{ restore_backup ? 'on' : 'off' }" case ARGV[1] when 'activate' then restore_backup, fetch_backup = true, true when 'deactivate' then restore_backup, fetch_backup = false, false end puts "For #{ @options['env'] } (sub-env: #{ @options['sub_env'] }) fetch backups is now set to #{ fetch_backup ? 'on' : 'off' } and restoring backups is now set to #{ restore_backup ? 'on' : 'off' }" @config[@options['env']]['config_bag_hash'][@options['sub_env']]['fetch_backups'] = fetch_backup @config[@options['env']]['config_bag_hash'][@options['sub_env']]['restore_backups'] = restore_backup @config['ChefDataBag'].save_config_bag if force_fetch_and_restore nodes = @config['getter'].get_true_node_objects true db_primary_nodes = @config['parser'].exclude_nodes( nodes, [{ unless: 'role[db_primary]' }, { if: { not_env: 'production' } }]) backup_slave_local_ip = @config['cheftacular']['backup_server'] if backup_slave_local_ip == 'first_production_slave' backup_slave = @config['parser'].exclude_nodes( nodes, [{ unless: 'role[db_slave]' }, { if: { not_env: 'production' } }], true) backup_slave_local_ip = @config['getter'].get_address_hash(backup_slave.first.hostname)['priv'] end , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = set_local_instance_vars on ( db_primary_nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts("Beginning db fetch_and_restore for #{ n.name } (#{ n.public_ipaddress }) for env #{ ['env'] }") unless ['quiet'] start_db_fetch_and_restore( n.name, n.public_ipaddress, , locs, cheftacular, passwords, backup_slave_local_ip) end @config['action'].migrate else puts "Triggering deploy on databases to refresh backup setting..." @options['role'] = 'db_primary' @config['action'].deploy end end |
#check_cheftacular_settings ⇒ Object
10 11 12 |
# File 'lib/cheftacular/stateless_actions/check_cheftacular_settings.rb', line 10 def check_cheftacular_settings raise "Not Yet Implemented" end |
#chef_bootstrap(out = []) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/cheftacular/stateless_actions/chef_bootstrap.rb', line 13 def chef_bootstrap out=[] raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] @options['address'] = ARGV[1] unless @options['address'] @options['node_name'] = ARGV[2] unless @options['node_name'] @config['stateless_action'].remove_client #just in case puts("Starting chef-client initialization...") unless @options['quiet'] out << `#{ @config['helper'].knife_bootstrap_command }` puts(out.last) unless @options['quiet'] || @options['in_scaling'] puts("Sending up data_bag_key file...") unless @options['quiet'] out << `scp -oStrictHostKeyChecking=no #{ @config['locs']['chef'] }/#{ @config['cheftacular']['data_bag_key_file'] } #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] }:/home/#{ @config['cheftacular']['deploy_user'] }` puts("Moving key file to chef directory on server...") unless @options['quiet'] out << `ssh -t -oStrictHostKeyChecking=no #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] } "#{ @config['helper'].sudo(@options['address']) } mv -f /home/#{ @config['cheftacular']['deploy_user'] }/#{ @config['cheftacular']['data_bag_key_file'] } /etc/chef"` @options['force_yes'] = true # have the upload_nodes grab the new nodes @config['stateless_action'].upload_nodes end |
#chef_environment ⇒ Object
17 18 19 |
# File 'lib/cheftacular/stateless_actions/chef_environment.rb', line 17 def chef_environment raise "Not yet Implemented" end |
#clean_cookbooks(local_options = {'interactive' => true}) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/cheftacular/stateless_actions/clean_cookbooks.rb', line 19 def clean_cookbooks ={'interactive' => true} raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') ARGV.each do |arg| case arg when "force" then ['interactive'] = false end end @config['cheftacular']['wrapper_cookbooks'].split(',').each do |wrapper_cookbook| wrapper_cookbook_loc = "#{ @config['locs']['cookbooks'] }/#{ wrapper_cookbook }" FileUtils.rm(File.("#{ wrapper_cookbook_loc }/Berksfile.lock")) if File.exists?(File.("#{ wrapper_cookbook_loc }/Berksfile.lock")) FileUtils.rm_rf(File.("#{ @config['locs']['berks'] }/cookbooks")) if File.exists?(File.("#{ @config['locs']['berks'] }/cookbooks")) Dir.chdir wrapper_cookbook_loc puts "Installing new cookbooks..." out = `berks install` puts "#{out}\nFinished... Beginning directory scanning and conflict resolution..." berkshelf_cookbooks = {} Dir.foreach(@config['locs']['berks']) do |berkshelf_cookbook| next if @config['helper'].is_junk_filename?(berkshelf_cookbook) skip = false berkshelf_cookbooks.keys.each do |processed_berkshelf_cookbook| if processed_berkshelf_cookbook.rpartition('-').first == berkshelf_cookbook.rpartition('-').first cookbook_mtime = File.mtime(File.("#{ @config['locs']['berks'] }/#{ berkshelf_cookbook }")) pcookbook_mtime = File.mtime(File.("#{ @config['locs']['berks'] }/#{ processed_berkshelf_cookbook }")) skip = true if cookbook_mtime < pcookbook_mtime #get only the latest version, berkshelf pulls in multiple commits from git repos for SOME REASON end end next if skip berkshelf_cookbooks[berkshelf_cookbook] = if File.exists?(File.("#{ @config['locs']['berks'] }/#{ berkshelf_cookbook }/metadata.rb")) File.read(File.("#{ @config['locs']['berks'] }/#{ berkshelf_cookbook }/metadata.rb")).gsub('"',"'").gsub(/^version[\s]*('\d[.\d]+')/).peek[/('\d[.\d]+')/].gsub("'",'') else berkshelf_cookbook.split('-').last end end chef_repo_cookbooks = {} Dir.foreach(@config['locs']['cookbooks']) do |chef_repo_cookbook| next if @config['helper'].is_junk_filename?(chef_repo_cookbook) new_name = chef_repo_cookbook.rpartition('-').first chef_repo_cookbooks[chef_repo_cookbook] = if File.exists?(File.("#{ @config['locs']['cookbooks'] }/#{ chef_repo_cookbook }/metadata.rb")) File.read(File.("#{ @config['locs']['cookbooks'] }/#{ chef_repo_cookbook }/metadata.rb")).gsub('"',"'").gsub(/^version[\s]*('\d[.\d]+')/).peek[/('\d[.\d]+')/].gsub("'",'') else JSON.parse(File.read(File.("#{ @config['locs']['cookbooks'] }/#{ chef_repo_cookbook }/metadata.json"))).to_hash['version'] end end berkshelf_cookbooks.each_pair do |berkshelf_cookbook, version| new_name = berkshelf_cookbook.rpartition('-').first if chef_repo_cookbooks.has_key?(new_name) || chef_repo_cookbooks.has_key?(berkshelf_cookbook) #don't overwrite cookbooks without user input if ['interactive'] puts "COOKBOOK::~~~~#{ new_name }~~~~::VERSION::~~~~~~~~#{ version } VS #{ chef_repo_cookbooks[new_name] }" puts "\nEnter O | o | overwrite to overwrite ~~~~#{ new_name }~~~~ in the chef-repo (THIS SHOULD NOT BE DONE LIGHTLY)" puts "Enter N | n | no to skip to the next conflict" puts "If you pass force to this script, it will always overwrite." #puts "If you pass a STRING of comma delimited cookbooks, it will skip these cookbooks automatically and overwrite others" #puts "Example: ruby ./executables/clean-cookbooks 'application_ruby,wordpress'" puts "Input:" input = STDIN.gets.chomp next if (input =~ /N|n|no/) == 0 end next if @config['helper'].is_higher_version?(chef_repo_cookbooks[new_name], version) end cmnd = "#{ @config['locs']['berks'] }/#{ berkshelf_cookbook } #{ @config['locs']['cookbooks'] }/#{ new_name }" puts "Moving #{ cmnd } (#{ version }:#{ chef_repo_cookbooks[new_name] })" if @options['verbose'] `rm -Rf #{ @config['locs']['cookbooks'] }/#{ new_name }` `cp -Rf #{ cmnd }` end end end |
#clean_sensu_plugins ⇒ Object
12 13 14 15 16 17 |
# File 'lib/cheftacular/stateless_actions/clean_sensu_plugins.rb', line 12 def clean_sensu_plugins raise "This method is not yet implemented" raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') #TODO use this to keep the cookbook files directory up to date with the sensu community plugins repo end |
#clean_server_passwords ⇒ Object
10 11 12 |
# File 'lib/cheftacular/stateless_actions/clean_server_passwords.rb', line 10 def clean_server_passwords #TODO clean up non-existent entries in all envs server_password bags end |
#cleanup_log_files ⇒ Object
10 11 12 |
# File 'lib/cheftacular/stateless_actions/cleanup_log_files.rb', line 10 def cleanup_log_files #TODO end |
#client_list ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/cheftacular/stateless_actions/client_list.rb', line 25 def client_list @config['helper'].cleanup_file_caches('current') nodes = @config['getter'].get_true_node_objects(true) @config['chef_environments'].each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['addresses', 'server_passwords'] end environments = nodes.map { |n| n.chef_environment } environments.uniq.each do |env| next if env == '_default' env_nodes = @config['parser'].exclude_nodes(nodes, [{ if: { not_env: env } }]) puts "\nFound #{ env_nodes.count } #{ env } nodes:" out = " #{ 'name'.ljust(22) } #{ 'ip_address'.ljust(20) }" out << "#{ 'private_address'.ljust(21) }" if @options['with_private'] out << "#{ 'pass?'.ljust(5) } #{ 'domain'.ljust(41) }" if @options['verbose'] out << "#{ 'deploy_password'.ljust(21) }" if @options['verbose'] out << "run_list" puts out auth_hash = @config[env]['server_passwords_bag_hash'] addresses_hash = @config['getter'].get_addresses_hash env env_nodes.each do |node| #client = @ridley.client.find(options['node_name']) out = " #{ node.chef_id.ljust(22,'_') }_#{ node.public_ipaddress.ljust(20,'_') }" if @options['with_private'] if addresses_hash.has_key?(node.public_ipaddress) out << addresses_hash[node.public_ipaddress]['address'].ljust(20,'_') else out << ''.ljust(20,'_') end end if @options['verbose'] out << "_" + auth_hash.has_key?("#{ node.public_ipaddress }-deploy-pass").to_s.ljust(5,'_') + "_" if addresses_hash.has_key?(node.public_ipaddress) out << addresses_hash[node.public_ipaddress]['dn'].ljust(40,'_') else out << ''.ljust(40,'_') end if auth_hash.has_key?("#{ node.public_ipaddress }-deploy-pass") out << "_" + auth_hash["#{ node.public_ipaddress }-deploy-pass"] else out << "_" + ''.ljust(@config['cheftacular']['server_password_length'],'_') end end out << "_#{ node.run_list.join(', ') }" puts out end end end |
#cloud(*args) ⇒ Object Also known as: aws, rax
93 94 95 96 97 98 99 100 101 |
# File 'lib/cheftacular/stateless_actions/cloud.rb', line 93 def cloud *args raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] args = ARGV[1..ARGV.length] if args.empty? @config['cloud_interactor'] ||= CloudInteractor.new(@config['default']['authentication_bag_hash'], @options) @config['cloud_interactor'].run args end |
#cloud_bootstrap ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/cheftacular/stateless_actions/cloud_bootstrap.rb', line 28 def cloud_bootstrap raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] @options['node_name'] = ARGV[1] unless @options['node_name'] @options['flavor_name'] = ARGV[2] unless @options['flavor_name'] @options['descriptor'] = ARGV[3] if ARGV[3] && !@options['descriptor'] if `which sshpass`.empty? raise "sshpass not installed! Please run brew install https://raw.github.com/eugeneoden/homebrew/eca9de1/Library/Formula/sshpass.rb (or get it from your repo for linux)" end #the output of the cloud command is a hash, this hash is UPDATED every time a rax command is run so you only need to grab it when you need it @config['stateless_action'].cloud "server", "create:#{ @options['env'] }_#{ @options['node_name'] }:#{ @options['flavor_name'] }" status_hash = @config['stateless_action'].cloud "server", "poll:#{ @options['env'] }_#{ @options['node_name'] }" status_hash['created_servers'].each do |server_hash| next unless server_hash['name'] == "#{ @options['env'] }_#{ @options['node_name'] }" @options['address'] = server_hash['ipv4_address'] @options['private_address'] = server_hash['addresses']['private'][0]['addr'] end begin @options['client_pass'] = status_hash['admin_passwords']["#{ @options['env'] }_#{ @options['node_name'] }"] rescue NoMethodError => e puts "Unable to locate an admin pass for server #{ @options['node_name'] }, does the server already exist? Exiting #{ __method__ }..." return false end tld = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].count compile_args = ['set_all_attributes'] compile_args << "set_specific_domain:#{ @options['with_dn'] }" if @options['with_dn'] address_hash = @config['DNS'].(*compile_args) @config['DNS'].create_dns_record_for_domain_from_address_hash(@options['with_dn'], address_hash, "specific_domain_mode") if @options['with_dn'] @config['DNS'].create_dns_record_for_domain_from_address_hash(tld, address_hash) @config['ChefDataBag'].save_addresses_bag @options['dont_remove_address_or_server'] = true #flag to make sure our entry isnt removed in addresses bag @config['stateless_action'].full_bootstrap #bootstrap server with ruby and attach it to the chef server end |
#compile_audit_log(out = []) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/cheftacular/stateless_actions/compile_audit_log.rb', line 13 def compile_audit_log out=[] compiled_audit_hash = {} @config['chef_environments'].each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['audit'] @config['initializer'].initialize_audit_bag_contents env @config[env]['audit_bag_hash']['audit_log'].each_pair do |day, time_log_hash| compiled_audit_hash[day] ||= {} time_log_hash.each_pair do |time, log_array| compiled_audit_hash[day][time] ||= [] compiled_audit_hash[day][time] << log_array end end end compiled_audit_hash.keys.sort.each do |day| out << "# Audit Log Entries for #{ Date.parse(day) }" entry_count, int_times = 1, [] compiled_audit_hash[day].keys.each do |time| out << "#{ entry_count }. #{ time }" log_array_entry_count = 1 compiled_audit_hash[day][time].each do |log_arr| log_arr.each do |log_hash| out << " #{ log_array_entry_count }. #{ log_hash['command'] }" out << " 1. Hostname: #{ log_hash['hostname'] }" out << " 3. Arguments: #{ log_hash['arguments'] }" out << " 4. Options: #{ log_hash['options'].to_hash }" out << "" log_array_entry_count += 1 end end if compiled_audit_hash[day].has_key?(time) entry_count += 1 end end File.open("#{ @config['locs']['chef-log'] }/audit-log-#{ Time.now.strftime("%Y%m%d%H%M%S") }.md", "w") { |f| f.write(out.join("\n")) } end |
#compile_readme(out = []) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/cheftacular/stateless_actions/compile_readme.rb', line 11 def compile_readme out=[] @config['action_documentation'].public_methods(false).each do |method| @config['action_documentation'].send(method) end @config['stateless_action_documentation'].public_methods(false).each do |method| @config['stateless_action_documentation'].send(method) end out << '# Table of Contents for Cheftacular Commands' out << '1. [Cheftacular Arguments and Flags](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#arguments-and-flags-for-cheftacular)' out << '2. [Application Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-be-run-in-the-application-context)' out << '3. [DevOps Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-only-be-run-in-the-devops-context)' + "\n" out << @config['documentation']['arguments'] out << "\n## Commands that can be run in the application context" out << @config['helper'].compile_documentation_lines('application') out << "\n## Commands that can ONLY be run in the devops context" out << @config['helper'].compile_documentation_lines('stateless_action') FileUtils.rm("#{ @config['locs']['chef-log'] }/README.md") if File.exist?("#{ @config['locs']['chef-log'] }/README.md") File.open("#{ @config['locs']['chef-log'] }/README.md", "w") { |f| f.write(out.flatten.join("\n\n")) } end |
#coreos_bootstrap(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/coreos_bootstrap.rb', line 3 def coreos_bootstrap out=[] raise "Not yet implemented!" end |
#create_git_key(oauth_key = "") ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/cheftacular/stateless_actions/create_git_key.rb', line 19 def create_git_key oauth_key="" case ARGV[1] when nil then raise "Too few arguments, please enter the filename of the id_rsa file you want to use" when 'id_rsa' then raise "Sorry, you can't use your default id_rsa" else key_file = ARGV[1] end case ARGV[2] when nil then display_oauth_notice = true else oauth_key = ARGV[2] end data = File.read("#{ @config['locs']['chef'] }/#{ key_file }") data_pub = File.read("#{ @config['locs']['chef'] }/#{ key_file }.pub") hash = @config['default']['authentication_bag_hash'] if hash.has_key?('private_key') puts "Overwrite current git key in default data bag? (Y/y/N/n)" input = STDIN.gets.chomp overwrite = (input =~ /Y|y|yes/) == 0 else overwrite = true end if overwrite hash['git_private_key'] = data hash['git_public_key'] = data_pub hash['git_OAuth'] = oauth_key @config['ChefDataBag'].save_authentication_bag if oauth_key.blank? puts "REMEMBER! You need to put a OAuth token into this data bag item!" puts "You need to go to github and get the auth_token for the hiplogiq deploy user!" puts "Copy the key and paste it inbetween the quotes.\n" puts "\"Oauth\": \"<PASTE YOUR OAUTH KEY HERE>\"\n\n" puts "Please run \nknife data bag edit default authentication --secret-file #{ @config['locs']['chef'] }/#{ @config['cheftacular']['data_bag_key_file'] }\n" end end end |
#disk_report(disk_hash = {}, out = []) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/cheftacular/stateless_actions/disk_report.rb', line 13 def disk_report disk_hash={}, out=[] nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ if: { env: '_default' }}] ) @config['chef_environments'].each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['addresses', 'server_passwords'] @config['initializer'].initialize_passwords env end , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning disk report run for #{ n.name } (#{ n.public_ipaddress })" disk_hash[n.name] = start_disk_report( n.name, n.public_ipaddress, , locs, passwords) end disk_hash.each_pair do |serv_name, output| out << "#{ serv_name }:" line_count = 1 output.join("\n").split("\n").each do |line| out << line_count == 1 ? " #{ line }" : " #{ line }" line_count += 1 end out << "\n" end puts(out) if @options['no_logs'] || @options['verbose'] log_loc, = @config['helper']. puts("Generating log file for disk report at #{ log_loc }/disk-report-#{ }.txt") unless @options['quiet'] File.open("#{ log_loc }/disk-report-#{ }.txt", "w") { |f| f.write(out.join("\n").scrub_pretty_text) } unless @options['no_logs'] end |
#environment(type = "boot", ask_on_destroy = false, remove = true) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/cheftacular/stateless_actions/environment.rb', line 23 def environment type="boot", ask_on_destroy=false, remove=true ask_on_destroy = case @options['env'] when 'staging' then true when 'production' then true else false end type = ARGV[1] if ARGV[1] raise "Unknown type: #{ type }, can only be 'boot' or 'destroy'" unless (type =~ /boot|destroy/) == 0 nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}]) @options['force_yes'] = true @options['in_scaling'] = true initial_servers = @config['cheftacular']['env_boot_nodes']["#{ @options['env'] }_nodes"] if initial_servers.empty? puts "There are no servers defined for #{ @options['env'] } in the env_boot_nodes hash in your cheftacular.yml... Exiting" exit end case type when 'boot' initial_servers.each_pair do |name, config_hash| next if nodes.map { |n| n.name }.include?(name) @options['node_name'] = name @options['flavor_name'] = config_hash.has_key?('flavor') ? config_hash['flavor'] : @config['cheftacular']['default_flavor_name'] @options['descriptor'] = config_hash.has_key?('descriptor') ? config_hash['descriptor'] : name @options['with_dn'] = config_hash.has_key?('dns_config') ? @config['parser'].parse_to_dns(config_hash['dns_config']) : @config['parser'].parse_to_dns('NODE_NAME.ENV_TLD') puts("Preparing to boot server #{ @options['node_name'] } for #{ @options['env'] }!") unless @options['quiet'] @config['stateless_action'].cloud_bootstrap sleep 15 end @config['ChefDataBag'].save_server_passwords_bag @options['node_name'] = nil @options['role'] = 'all' @config['action'].deploy #TODO INTEGRATE backups TO LOAD DATA INTO THE NEWLY BOOTED ENV when 'destroy' if ask_on_destroy puts "Preparing to delete nodes in #{ @options['env'] }.\nEnter Y/y to confirm." input = STDIN.gets.chomp remove = false unless ( input =~ /y|Y|yes|Yes/ ) == 0 end return false unless remove @options['delete_server_on_remove'] = true nodes.each do |node| @options['node_name'] = node.name puts("Preparing to destroy server #{ @options['node_name'] } for #{ @options['env'] }!") unless @options['quiet'] @config['stateless_action'].remove_client sleep 15 end end end |
#fedora_bootstrap(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/fedora_bootstrap.rb', line 3 def fedora_bootstrap out=[] raise "Not yet implemented!" end |
#fetch_file(out = []) ⇒ Object
19 20 21 22 |
# File 'lib/cheftacular/stateless_actions/fetch_file.rb', line 19 def fetch_file out=[] #TODO raise "Not yet implemented" end |
#fix_known_hosts ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/cheftacular/stateless_actions/fix_known_hosts.rb', line 19 def fix_known_hosts targets = ["all"] if ARGV[1].class == String targets = [ARGV[1]] end if targets.first == 'all' nodes = @config['getter'].get_true_node_objects(true) arr = [] @config['chef_environments'].each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['addresses'] @config['initializer'].initialize_addresses_bag_contents env @config[env]['addresses_bag_hash']['addresses'].each do |serv_hash| arr << serv_hash['dn'].split('.').first arr << serv_hash['public'] end end targets = arr.uniq end targets.each do |target| case CONFIG['host_os'] when /mswin|windows/i raise "#{ __method__ } does not support this operating system at this time" when /linux|arch/i cleanup_known_hosts_for_BSD_linux_architecture target when /sunos|solaris/i raise "#{ __method__ } does not support this operating system at this time" when /darwin/i cleanup_known_hosts_for_BSD_linux_architecture target else raise "#{ __method__ } does not support this operating system at this time" end end end |
#full_bootstrap ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/cheftacular/stateless_actions/full_bootstrap.rb', line 13 def full_bootstrap raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] @options['address'] = ARGV[1] unless @options['address'] @options['client_pass'] = ARGV[2] unless @options['client_pass'] @options['node_name'] = ARGV[3] unless @options['node_name'] case @config['cheftacular']['preferred_cloud_os'] when 'ubuntu' || 'debian' then @config['stateless_action'].ubuntu_bootstrap else @config['stateless_action'].instance_eval("#{ @config['cheftacular']['preferred_cloud_os'] }_bootstrap") end @config['initializer'].initialize_passwords @options['env'] #reset the passwords var to contain the new deploy pass set in ubuntu_bootstrap @config['stateless_action'].chef_bootstrap end |
#get_active_ssh_connections ⇒ Object
13 14 15 16 |
# File 'lib/cheftacular/stateless_actions/get_active_ssh_connections.rb', line 13 def get_active_ssh_connections # netstat -atn | grep ':22' raise "Not yet implemented" end |
#get_haproxy_log ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/cheftacular/stateless_actions/get_haproxy_log.rb', line 19 def get_haproxy_log nodes = @config['getter'].get_true_node_objects true nodes = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ @config['cheftacular']['haproxy_config']['role_name'] }]" }, { if: { not_env: @options['env'] } }]) #this must always precede on () calls so they have the instance variables they need , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars #on is namespaced to SSHKit::Backend::Netssh.on on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts("Beginning haproxy log generation run for #{ n.name } (#{ n.public_ipaddress })") unless ['quiet'] start_haproxy_log_generator( n.name, n.public_ipaddress, , locs, cheftacular, passwords) end end |
#get_log_from_bag ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cheftacular/stateless_actions/get_log_from_bag.rb', line 15 def get_log_from_bag #TODO https://stackoverflow.com/questions/17882463/compressing-large-string-in-ruby log_loc, = @config['helper']. @options['role'] = 'all' unless @options['role'] nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}]) nodes.each do |node| if @config[@options['env']]['logs_bag_hash'].has_key?("#{ node.name }-run") puts("Found log data in logs bag. Outputting to #{ log_loc }/stashedlog/#{ node.name }-deploystash-#{ @config[@options['env']]['logs_bag_hash']["#{ node.name }-run"][:timestamp] }.txt") unless @options['quiet'] File.open("#{ log_loc }/stashedlog/#{ node.name }-deploystash-#{@config[@options['env']]['logs_bag_hash']["#{ node.name }-run"][:timestamp] }.txt", "w") do |f| f.write(@config[@options['env']]['logs_bag_hash']["#{ node.name }-run"][:text]) end puts(@config[@options['env']]['logs_bag_hash']["#{ node.name }-run"][:text]) if @options['verbose'] end end end |
#get_pg_pass(clip = false, target_repos = []) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/cheftacular/stateless_actions/get_pg_pass.rb', line 15 def get_pg_pass clip=false, target_repos=[] @config['parser'].parse_role(@options['role']) clip = ARGV[1] == 'clip' if @options['role'] target_repos << @config['cheftacular']['repositories'][@options['role']] else @config['cheftacular']['repositories'].each_pair do |short_repo_name, repo_hash| target_repos << repo_hash if repo_hash['database'] == 'postgresql' end end target_repos.each do |repo_hash| db_user = repo_hash['application_database_user'] database = repo_hash.has_key?('custom_database_name') ? repo_hash['custom_database_name'] : repo_hash['repo_name'] password = @config[@options['env']]['chef_passwords_bag_hash']['pg_pass'] if @config[@options['env']]['chef_passwords_bag_hash'].has_key?(repo_hash['repo_name']) && @config[@options['env']]['chef_passwords_bag_hash'][repo_hash['repo_name']].has_key?('pg_pass') password = @config[@options['env']]['chef_passwords_bag_hash'][repo_hash['repo_name']]['pg_pass'] unless @config[@options['env']]['chef_passwords_bag_hash'][repo_hash['repo_name']]['pg_pass'].empty? end puts "postgres password for user #{ db_user } in database #{ database }_#{ @options['env'] } is #{ password }" end if clip && target_repos.count == 1 case CONFIG['host_os'] when /mswin|windows/i raise "#{ __method__ } does not support this operating system at this time" when /linux|arch/i raise "#{ __method__ } does not support this operating system at this time" when /sunos|solaris/i raise "#{ __method__ } does not support this operating system at this time" when /darwin/i `echo '#{ password }' | pbcopy` else raise "#{ __method__ } does not support this operating system at this time" end elsif clip && target_repos.count > 1 puts "Unable to insert database string into clipboard, please copy paste as normal" end end |
#get_shorewall_allowed_connections(master_log_data = '') ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb', line 20 def get_shorewall_allowed_connections master_log_data='' if ARGV[1].nil? raise "Please pass a NODE_NAME with -n NODE_NAME" if @options['node_name'].nil? || @options['node_name'].empty? nodes = @config['getter'].get_true_node_objects true nodes = @config['parser'].exclude_nodes(nodes, [{ unless: { env: @options['env'] }}, { unless: { node: @options['node_name'] }}], true) #this must always precede on () calls so they have the instance variables they need , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars #on is namespaced to SSHKit::Backend::Netssh.on on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts("Beginning shorewall log capture run for #{ n.name } (#{ n.public_ipaddress })") unless ['quiet'] master_log_data = start_shorewall_log_capture( n.name, n.public_ipaddress, , locs, cheftacular, passwords) end else master_log_file = ARGV[1] raise "File not found! Did you enter the path correctly?" unless File.exist?(master_log_file) master_log_data = File.read(File.(master_log_file)) end puts("Parsing addresses from log data...") unless @options['quiet'] addresses = {} master_log_data.scan(/^.*Shorewall:net2fw:ACCEPT.*SRC=([\d]+\.[\d]+\.[\d]+\.[\d]+) DST.*DPT=80.*$/).each do |ip_address| addresses[ip_address] ||= 0 addresses[ip_address] += 1 end final_addresses = {} check_count = 0 addresses.each_pair do |address, count| next if count < 100 domain = `dig +short -x #{ address[0] }`.chomp.split("\n").join('|') domain = domain[0..(domain.length-2)] domain = address[0] if domain.blank? final_addresses[domain] ||= {} final_addresses[domain]['addresses'] ||= [] final_addresses[domain]['addresses'] << address[0] unless final_addresses[domain]['addresses'].include?(address[0]) final_addresses[domain]['count'] = count unless final_addresses[domain].has_key?('count') final_addresses[domain]['count'] += count if final_addresses[domain].has_key?('count') check_count += 1 puts("Processed #{ check_count } addresses (#{ address[0] }):#{ domain }:#{ count }") unless @options['quiet'] end final_addresses = final_addresses.sort_by {|key, value_hash| value_hash['count']}.to_h final_addresses = Hash[final_addresses.to_a.reverse] ap(final_addresses) if @options['verbose'] log_loc, = @config['helper']. CSV.open(File.("#{ @config['locs']['chef-log'] }/shorewall-parse-#{ }.csv"), "wb") do |csv| final_addresses.each_pair do |dns, info_hash| csv << [dns, info_hash['addresses'].join('|'), info_hash['count']] end end end |
#help(inference_modes = []) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/cheftacular/stateless_actions/help.rb', line 15 def help inference_modes=[] target_command = @options['command'] == 'help' ? ARGV[1] : ARGV[0] target_command = @config['cheftacular']['mode'] if target_command == 'current' target_command ||= '' case target_command when 'action' then inference_modes << 'action' when 'application' || 'devops' then inference_modes << 'both' when 'stateless_action' then inference_modes << 'stateless_action' when '' then inference_modes << 'both' end if @config['helper'].is_command? target_command @config['action_documentation'].send(target_command) puts @config['documentation']['action'].flatten.join("\n\n") elsif @config['helper'].is_stateless_command? target_command @config['stateless_action_documentation'].send(target_command) puts @config['documentation']['stateless_action'].flatten.join("\n\n") end @config['action_documentation'].public_methods(false).each do |method| @config['action_documentation'].send(method) end if inference_modes.include?('action') || inference_modes.include?('both') @config['stateless_action_documentation'].public_methods(false).each do |method| @config['stateless_action_documentation'].send(method) end if inference_modes.include?('stateless_action') || inference_modes.include?('both') puts @config['helper'].compile_documentation_lines('action').flatten.join("\n\n") if target_command == 'action' puts @config['documentation']['arguments'].flatten.join("\n\n") if target_command == 'arguments' puts @config['helper'].compile_documentation_lines('stateless_action').flatten.join("\n\n") if target_command == 'stateless_action' puts @config['helper'].compile_documentation_lines('application').flatten.join("\n\n") if target_command == 'application' || target_command.empty? puts @config['helper'].compile_documentation_lines('devops').flatten.join("\n\n") if target_command == 'devops' if inference_modes.empty? && @config['helper'].is_not_command_or_stateless_command?(target_command) methods = @config['action_documentation'].public_methods(false) + @config['stateless_action_documentation'].public_methods(false) sorted_methods = methods.uniq.sort_by { |method| @config['helper'].compare_strings(target_command, method.to_s)} puts "Unable to find documentation for #{ target_command }, did you mean:" puts " #{ sorted_methods.at(0) }" puts " #{ sorted_methods.at(1) }" puts " #{ sorted_methods.at(2) }\n" puts "If so, please run 'cft help COMMAND' with one of the above commands or run 'hip help application' to see a list of commands" end end |
#initialize_data_bag_contents(env = "") ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb', line 12 def initialize_data_bag_contents env="" raise "Environment does not exist on chef server!" unless @config['chef_environments'].include?(env) env = ARGV[1] if env.blank? @config['initializer'].initialize_audit_bag_contents env @config['initializer'].initialize_authentication_bag_contents @config['initializer'].initialize_chef_passwords_bag_contents env @config['initializer'].initialize_config_bag_contents env #@config['initializer'].initialize_server_passwords_bag_contents env @config['initializer'].initialize_addresses_bag_contents env #@config['initializer'].initialize_logs_bag_contents env #@config['ChefDataBag'].initialize_node_roles_bag_contents env end |
#knife_upload ⇒ Object
13 14 15 16 17 18 19 20 21 |
# File 'lib/cheftacular/stateless_actions/knife_upload.rb', line 13 def knife_upload raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') puts("Starting upload...") unless @options['quiet'] out = `knife upload / --chef-repo-path #{ @config['locs']['chef-repo'] }` puts out end |
#pass ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/cheftacular/stateless_actions/pass.rb', line 15 def pass @options['node_name'] = ARGV[1] unless @options['node_name'] raise "Too few arguments, please supply a node name" if ARGV.length < 2 nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ if: { not_node: @options["node_name"] } }], true ) raise "Node not found for #{ @options['node_name'] }" if nodes.empty? if nodes.first.chef_environment != @options['env'] @config['initializer'].initialize_data_bags_for_environment nodes.first.chef_environment, false, ['server_passwords'] end puts "The password for #{ nodes.first.name }(#{ nodes.first.public_ipaddress }) for env #{ nodes.first.chef_environment }" + " is #{ @config[nodes.first.chef_environment]['server_passwords_bag_hash']["#{ nodes.first.public_ipaddress }-deploy-pass"] }" case CONFIG['host_os'] when /mswin|windows/i raise "#{ __method__ } does not support this operating system at this time" when /linux|arch/i raise "#{ __method__ } does not support this operating system at this time" when /sunos|solaris/i raise "#{ __method__ } does not support this operating system at this time" when /darwin/i puts "Copying #{ nodes.first.name } (#{ nodes.first.public_ipaddress }) sudo password into your clipboard" `echo '#{ @config[nodes.first.chef_environment]['server_passwords_bag_hash']["#{ nodes.first.public_ipaddress }-deploy-pass"] }' | pbcopy` else raise "#{ __method__ } does not support this operating system at this time" end end |
#redhat_bootstrap(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/centos_bootstrap.rb', line 3 def redhat_bootstrap out=[] raise "Not yet implemented!" end |
#reinitialize(out = []) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/cheftacular/stateless_actions/reinitialize.rb', line 13 def reinitialize out=[] raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') @options['address'] = ARGV[1] unless @options['address'] @options['node_name'] = ARGV[2] unless @options['node_name'] puts("Sending up validator file...") unless @options['quiet'] chef_user = @config['cheftacular']['deploy_user'] out << `scp -oStrictHostKeyChecking=no #{ @config['locs']['chef'] }/chef-validator.pem #{ chef_user }@#{ @options['address'] }:/home/#{ chef_user }` puts("Moving validator file to chef directory on server...") unless @options['quiet'] out << `ssh -t -oStrictHostKeyChecking=no #{ chef_user }@#{ @options['address'] } "#{ sudo(@options['address']) } mv -f /home/#{ chef_user }/chef-validator.pem /etc/chef/validator.pem"` puts("Removing original client.pem file from server...") unless @options['quiet'] out << `ssh -t -oStrictHostKeyChecking=no #{ chef_user }@#{ @options['address'] } "#{ sudo(@options['address']) } rm /etc/chef/client.pem"` #remove_client #just in case puts("Starting reinitialization...") unless @options['quiet'] out << `#{ @config['helper'].knife_bootstrap_command }` puts(out.last) unless @options['quiet'] #@options['multi-step'] = true # have the upload_nodes grab the new nodes #upload_nodes end |
#remove_client(delete_server = false, remove = true) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/cheftacular/stateless_actions/remove_client.rb', line 14 def remove_client delete_server=false, remove=true @options['node_name'] = ARGV[1] unless @options['node_name'] @options['delete_server_on_remove'] = ARGV[2] if !@options['delete_server_on_remove'] && !@options['dont_remove_address_or_server'] && ARGV[2] @options['delete_server_on_remove'] = 'destroy' if delete_server || @options['delete_server_on_remove'] raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] raise "The only valid argument for the 2nd argument of this command is 'destroy', please enter this or leave it blank." if ARGV[2] && ARGV[2] != 'destroy' && !@options['dont_remove_address_or_server'] raise "Invalid arguments! Node name is blank. Please call this script as cft remove_client <node_name>" unless @options['node_name'] nodes = @config['getter'].get_true_node_objects(false, true) nodes.each do |n| begin client = @config['ridley'].client.find(@options['node_name']) rescue StandardError => e puts "Client #{ @options['node_name'] } not found." return false end if @options['env'] == 'production' && !@options['force_yes'] puts "Preparing to delete #{ @options['node_name'] } (#{ n.public_ipaddress }).\nEnter Y/y to confirm." input = STDIN.gets.chomp remove = false unless ( input =~ /y|Y|yes|Yes/ ) == 0 end if remove puts "Removing #{ n.name } (#{ n.public_ipaddress }) from node and client list" @config['ridley'].node.delete(n) @config['ridley'].client.delete(client) if @options['delete_server_on_remove'] == 'destroy' @config['stateless_action'].cloud "server", "destroy:#{ @options['env'] }_#{ n.name }" end end @config[@options['env']]['addresses_bag_hash'] = @config[@options['env']]['addresses_bag'].reload.to_hash @config['DNS'].('set_hash_to_nil') @config['ChefDataBag'].save_addresses_bag end puts("Done. Please verify that the output of the next line(s) match your expectations (running client-list)") if @options['verbose'] puts(`client-list`) if @options['verbose'] end |
#replication_status(rep_status_hash = {}, out = []) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/cheftacular/stateless_actions/replication_status.rb', line 13 def replication_status rep_status_hash={}, out=[] nodes = @config['getter'].get_true_node_objects(true) primary_nodes = @config['parser'].exclude_nodes( nodes, [{ if: { env: '_default' }}, { unless: "role[db_primary]"}] ) slave_nodes = @config['parser'].exclude_nodes( nodes, [{ if: { env: '_default' }}, { unless: "role[db_slave]"}] ) (primary_nodes + slave_nodes).map {|n| n.chef_environment}.uniq.each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['server_passwords'] @config['initializer'].initialize_passwords env end #this must always precede on () calls so they have the instance variables they need , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( primary_nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning replication status report run for #{ n.name } (#{ n.public_ipaddress })" env = n.name.split('_').first rep_status_hash[n.name] = start_replication_report( n.name, n.public_ipaddress, , locs, passwords) end on ( slave_nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning slave replication status report run for #{ n.name } (#{ n.public_ipaddress })" env = n.name.split('_').first rep_status_hash[n.name] = start_slave_replication_report( n.name, n.public_ipaddress, , locs, passwords) end rep_status_hash.each_pair do |serv_name, output| out << "#{ serv_name }:" output.join("\n").split("\n").each do |line| out << " #{ line }\n" end out << "\n" end puts(out) end |
#restart_swap ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/cheftacular/stateless_actions/restart_swap.rb', line 17 def restart_swap nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ if: { env: '_default' }}] ) #this must always precede on () calls so they have the instance variables they need , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning swap restart run for #{ n.name } (#{ n.public_ipaddress })" start_swap_restart( n.name, n.public_ipaddress, , locs, cheftacular, passwords) end end |
#rvm(command = '') ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/cheftacular/stateless_actions/rvm.rb', line 38 def rvm command='' raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') command = case ARGV[1] when nil then 'list' when /list|list_rubies/ then 'list rubies' when 'install' then "install #{ ARGV[2] }" when 'run' then ARGV[2..(ARGV.length-1)].join(' ') when 'all_environments' then ARGV[2..(ARGV.length-1)].join(' ') when 'test' then ARGV[2..(ARGV.length-1)].join(' ') when 'upgrade_rvm' then 'get stable --auto-dotfiles' else 'list' end if @config['cheftacular']['rvm_gpg_key'].nil? || @config['cheftacular']['rvm_gpg_key'].blank? raise "GPG Key not found in cheftacular.yml! Please update your rvm_gpg_key in the file!" end nodes = ARGV[1] == 'test' ? @config['getter'].get_true_node_objects : @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] ) unless ARGV[1] == 'all_servers' @config['chef_environments'].each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['addresses', 'server_passwords'] @config['initializer'].initialize_passwords env end if ARGV[1] == 'all_servers' , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning run of \"rvm #{ command }\" for #{ n.name } (#{ n.public_ipaddress })" start_rvm( n.name, n.public_ipaddress, , locs, passwords, command, cheftacular ) end end |
#server_update ⇒ Object
TODO refactor to handling multiple server types
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/cheftacular/stateless_actions/server_update.rb', line 19 def server_update raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') @options['rolling_restart'] = true if ARGV[1] && ARGV[1] == 'restart' if @options['rolling_restart'] puts "Preparing to do a rolling restart for all servers in env: #{ @options['env'] } (potential data loss).\nEnter Y/y to confirm, Q/q to exit completely." input = STDIN.gets.chomp @options['rolling_restart'] = false unless ( input =~ /y|Y|yes|Yes/ ) == 0 exit if ( input =~ /y|Y|quit|Quit/ ) == 0 end nodes = @config['getter'].get_true_node_objects true nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] ) #this must always precede on () calls so they have the instance variables they need , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 5 do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning apt-get run for #{ n.name } (#{ n.public_ipaddress })" log_data, = start_apt_updater( n.name, n.public_ipaddress, , locs, passwords) logs_bag_hash["#{ n.name }-upgrade"] = { text: log_data.scrub_pretty_text, timestamp: } end on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 120 do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning restart run for #{ n.name } (#{ n.public_ipaddress })" start_sys_restarter( n.name, n.public_ipaddress, , locs, passwords) end if @options['rolling_restart'] @config['ChefDataBag'].save_logs_bag end |
#service ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/cheftacular/stateless_actions/service.rb', line 22 def service raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') command = case ARGV[1] when nil then 'list' when /list/ then 'list' when 'restart' then "#{ ARGV[2] } restart" when 'stop' then "#{ ARGV[2] } stop" when 'start' then "#{ ARGV[2] } start" else 'list' end raise "You did not pass a service to #{ ARGV[1] }" if ARGV[1] =~ /restart|stop|start/ && ARGV[2].nil? service_location = "#{ ARGV[2] }.conf" nodes = @config['getter'].get_true_node_objects nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}], true ) , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning run of \"service #{ command }\" for #{ n.name } (#{ n.public_ipaddress })" start_service_run( n.name, n.public_ipaddress, , locs, passwords, command, cheftacular, service_location ) end end |
#slack(message = '', channel = '') ⇒ Object
19 20 21 22 23 24 25 26 27 |
# File 'lib/cheftacular/stateless_actions/slack.rb', line 19 def slack ='', channel='' @slack_notifier ||= Slack::Notifier.new @config['cheftacular']['slack']['webhook'], username: 'Cheftacular' = ARGV[1] if .blank? channel = ARGV[2] if channel.blank? @slack_notifier.channel = channel.nil? ? @config['cheftacular']['slack']['default_channel'] : channel @slack_notifier.ping end |
#test_env(split_env = "splitstaging", type = "boot") ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/cheftacular/stateless_actions/test_env.rb', line 24 def test_env split_env="splitstaging", type="boot" raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') env_index = @options['env'] == 'staging' ? 1 : 2 split_env = ARGV[1] unless @options['env'] == 'staging' type = ARGV[env_index] if ARGV[env_index] split_envs = @config['cheftacular']['run_list_environments'][@options['env']] raise "Unknown split_env: #{ split_env }, can only be #{ split_envs.values.join(', ') }" unless (split_env =~ /#{ split_envs.values.join('|') }/) == 0 raise "Unknown type: #{ type }, can only be 'boot' or 'destroy'" unless (type =~ /boot|destroy/) == 0 nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ unless: "role[#{ split_env.split('split').join('split_') }]" }, { unless: { env: @options['env'] }}]) @options['force_yes'] = true @options['in_scaling'] = true case type when 'boot' @config['cheftacular']['split_env_nodes'].each_pair do |name, config_hash| config_hash ||= {} true_name = name.gsub('SPLITENV', split_env) @options['sub_env'] = split_env @options['node_name'] = "#{ true_name }#{ 'p' if @options['env'] == 'production' }" @options['flavor_name'] = config_hash.has_key?('flavor') ? config_hash['flavor'] : @config['cheftacular']['default_flavor_name'] @options['descriptor'] = config_hash.has_key?('descriptor') ? "#{ config_hash['descriptor'] }-#{ split_env }" : name @options['with_dn'] = config_hash.has_key?('dns_config') ? @config['parser'].parse_to_dns(config_hash['dns_config']) : @config['parser'].parse_to_dns('NODE_NAME.ENV_TLD') next if nodes.map { |n| n.name }.include?(@options['node_name']) puts("Preparing to boot server #{ @options['node_name'] } for #{ @options['env'] }'s #{ split_env } environment!") unless @options['quiet'] @config['stateless_action'].cloud_bootstrap sleep 15 end @config['ChefDataBag'].save_server_passwords_bag when 'destroy' @options['delete_server_on_remove'] = true nodes.each do |node| @options['node_name'] = node.name puts("Preparing to destroy server #{ @options['node_name'] } for #{ @options['env'] }'s #{ split_env } environment!") unless @options['quiet'] @config['stateless_action'].remove_client sleep 15 end end end |
#ubuntu_bootstrap(out = []) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb', line 13 def ubuntu_bootstrap out=[] raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] @options['address'] = ARGV[1] unless @options['address'] @options['client_pass'] = ARGV[2] unless @options['address'] if `which sshpass`.empty? raise "sshpass not installed! Please run brew install https://raw.github.com/eugeneoden/homebrew/eca9de1/Library/Formula/sshpass.rb (or get it from your repo for linux)" end new_deploy_pass = @config['helper'].gen_pass(@config['cheftacular']['server_pass_length']) deploy_user = @config['cheftacular']['deploy_user'] root_commands = [ "cd /home", "adduser #{ deploy_user } --gecos \",,,,\" --disabled-password", "echo #{ deploy_user }:#{ new_deploy_pass } | chpasswd", "adduser #{ deploy_user } www-data", "adduser #{ deploy_user } sudo", "mkdir -p /home/#{ deploy_user }/.ssh", "touch /home/#{ deploy_user }/.ssh/authorized_keys && touch /home/#{ deploy_user }/.ssh/known_hosts", "chown -R #{ deploy_user }:www-data /home/#{ deploy_user }/.ssh", 'sed -i "s/StrictModes yes/StrictModes yes\nPasswordAuthentication no\nUseDNS no\nAllowUsers deploy postgres\n/" /etc/ssh/sshd_config'.gsub('deploy', deploy_user), 'sed -i "s/PermitRootLogin yes/PermitRootLogin no/" /etc/ssh/sshd_config' ] @config['default']['authentication_bag_hash']['authorized_keys'].each do |line| root_commands << "echo \"#{ line }\" >> /home/#{ deploy_user }/.ssh/authorized_keys" end sudo = "echo #{ new_deploy_pass } | sudo -S" deploy_commands = [ "#{ sudo } apt-get update", "#{ sudo } apt-get install curl git-core shorewall -y", "#{ sudo } apt-get upgrade -y" ] final_commands = [] if @config['cheftacular']['install_rvm_on_boot'] deploy_commands << "gpg --keyserver hkp://keys.gnupg.net --recv-keys #{ @config['cheftacular']['rvm_gpg_key'] }" deploy_commands << "curl -L https://get.rvm.io | bash -s stable" final_commands rvm_source = "source /home/deploy/.rvm/bin/rvm &&" final_commands = [ "#{ rvm_source } echo '#{ new_deploy_pass }' | rvmsudo -S rvm requirements", "#{ rvm_source } rvm install #{ @config['cheftacular']['ruby_version'] }", "#{ rvm_source } rvm install 1.9.3-p327" #chef's default ruby, we'll need it in a place rvm can find it until the symlink is made ] end out << `sshpass -p "#{ @options['client_pass'] }" ssh -t -oStrictHostKeyChecking=no root@#{ @options['address'] } '#{ root_commands.join(' && ') } && service ssh restart'` puts("Finished initial setup...stage 1 of 3 for server #{ @options['address'] }") if @options['in_scaling'] puts(out.last) unless @options['quiet'] || @options['in_scaling'] deploy_commands.each do |cmnd| puts("(#{ @options['address'] }) Running #{ cmnd.gsub("#{ new_deploy_pass }", "sudo password") }") unless @options['quiet'] || @options['in_scaling'] out << `ssh -t -oStrictHostKeyChecking=no #{ deploy_user }@#{ @options['address'] } "#{ cmnd }"` puts(out.last) unless @options['quiet'] || @options['in_scaling'] end puts("Finished deploy setup....stage 2 of 3 for server #{ @options['address'] }") if @options['in_scaling'] final_commands.each do |cmnd| puts "(#{ @options['address'] }) Running #{ cmnd.gsub("#{ new_deploy_pass }", "sudo password") }" out << `ssh -t -oStrictHostKeyChecking=no #{ deploy_user }@#{ @options['address'] } "#{ cmnd }"` puts(out.last) unless @options['quiet'] || @options['in_scaling'] end puts("Finished ruby setup......stage 3 of 3 for server #{ @options['address'] }") if @options['in_scaling'] @config[@options['env']]['server_passwords_bag_hash']["#{ @options['address'] }-root-pass"] = @options['client_pass'] @config[@options['env']]['server_passwords_bag_hash']["#{ @options['address'] }-deploy-pass"] = new_deploy_pass @config[@options['env']]['server_passwords_bag_hash']["#{ @options['address'] }-name"] = @options['node_name'] if @options['node_name'] @config['ChefDataBag'].save_server_passwords_bag unless @options['in_scaling'] end |
#update_cloudflare_dns_from_cloud ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/cheftacular/stateless_actions/update_cloudflare_dns_from_cloud.rb', line 23 def update_cloudflare_dns_from_cloud raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') target_domain = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] @config['stateless_action'].update_tld 'self' unless ARGV[1] == 'skip_update_tld' target_domain_records = @config['stateless_action'].cloud('domain', "read:#{ target_domain }")["records_for_#{ target_domain }"] @config['DNS'].update_cloudflare_from_array_of_domain_hashes target_domain, target_domain_records end |
#update_split_branches ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/cheftacular/stateless_actions/update_split_branches.rb', line 25 def update_split_branches target_loc = @config['helper'].running_in_mode?('application') ? @config['locs']['app-root'] : "#{ @config['locs']['root'] }/#{ @options['repository'] }" current_revision = `cd #{ target_loc } && git rev-parse --abbrev-ref HEAD` puts "Preparing to run merges..." split_branch_repos = @config['getter'].get_split_branch_hash raise "unsupported codebase, please run in #{ split_branch_repos.keys.join(', ') } only!" if ( @options['repository'] =~ /#{ split_branch_repos.keys.join('|') }/ ) == 0 test_for_changes = `cd #{ target_loc } && git diff --exit-code` unless test_for_changes.empty? puts "You have changes in your current working tree for #{ target_loc }. Please commit these changes before running this command." exit end commands = [ "cd #{ target_loc }", "git checkout master", "git pull origin master", "git fetch origin", ] @config['run_list_environments'].each_pair do |env, branch_hash| branch_hash.keys.each do |branch_name| true_branch_name = branch_name.gsub('_','-') commands << ["git checkout #{ true_branch_name }", "git pull origin #{ true_branch_name }", 'git merge master --no-edit', "git push origin #{ true_branch_name }"] end end commands << "git checkout #{ current_revision }" puts `#{ commands.flatten.join(' && ') }` unless @options['quiet'] puts "Update split branches complete. You have been returned to the branch you were on before which was \"#{ current_revision.chomp }\"." end |
#update_tld(target_tld = "") ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/cheftacular/stateless_actions/update_tld.rb', line 14 def update_tld target_tld="" raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') raise "Undefined new tld to migrate to" if ARGV.length <= 1 && target_tld.blank? nodes = @config['getter'].get_true_node_objects(true) #We need to manually update beta nodes as they share the same env space as their non-beta counterparts TODO Refactor? nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] ) address_hash = @config['getter'].get_addresses_hash @options['env'] target_tld = ARGV[1] if target_tld.blank? old_tld = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] if target_tld == 'self' target_tld = old_tld end nodes.each do |n| @options['node_name'] = n.name domain_obj = PublicSuffix.parse address_hash[n.public_ipaddress]['dn'] next unless domain_obj.domain == old_tld #we can't create records for domains not managed under the environment's tld #TODO CHECK CLOUD IF TLD EXISTS specific_domain = "#{ domain_obj.trd }.#{ target_tld }" if specific_domain != "#{ @options['node_name'] }.#{ target_tld }" @config['DNS'].create_dns_record_for_domain_from_address_hash(specific_domain, address_hash[n.public_ipaddress], "specific_domain_mode") end @config['DNS'].create_dns_record_for_domain_from_address_hash(target_tld, address_hash[n.public_ipaddress]) @config['DNS'].("set_specific_domain_name:#{ specific_domain }") sleep 1 #prepare for next domain end @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] = target_tld puts "BAG TLD::#{ @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] }" @config['ChefDataBag'].save_config_bag @config['ChefDataBag'].save_addresses_bag end |
#upload_nodes(invalidate_file_node_cache = false) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/cheftacular/stateless_actions/upload_nodes.rb', line 27 def upload_nodes invalidate_file_node_cache=false raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] @config['chef_environments'].each do |env| @config['initializer'].initialize_data_bags_for_environment env, false, ['node_roles'] @config['initializer'].initialize_node_roles_bag_contents env end nodes = @options['multi-step'] ? @config['getter'].get_true_node_objects(true,true) : @config['getter'].get_true_node_objects(true) node_roles_hash, bag_hash, allowed_changes_hash = {},{},{} Dir.foreach(@config['locs']['nodes']) do |fr| next if @config['helper'].is_junk_filename?(fr) Dir.foreach("#{ @config['locs']['nodes'] }/#{ fr }") do |f| next if @config['helper'].is_junk_filename?(f) node_roles_hash[f.split('.json').first] = JSON.parse(File.read("#{ @config['locs']['nodes'] }/#{ fr }/#{ f }")) end end if @config['helper'].running_in_mode?('devops') #only devops modes should have a nodes_dir @config['chef_environments'].each do |env| @config[env]['node_roles_bag_hash']['node_roles'].each_pair do |role_name, role_hash| bag_hash[role_hash['name']] = role_hash.to_hash #hashes from chef server are stored as hashie objects until forced into hashes end end if !@options['force_yes'] && @config['helper'].running_in_mode?('devops') node_roles_hash.each_pair do |role_name, role_hash| overwrite = false if bag_hash[role_name] != role_hash puts "Detected difference between saved roles hash and updated node_roles json hash for #{ role_name }." puts "Saved roles hash:" ap(bag_hash[role_name]) puts "New roles hash:" ap(role_hash) puts "Preparing to overwrite the saved roles hash with the node_roles hash, enter Y/y to confirm." input = STDIN.gets.chomp overwrite = true if ( input =~ /y|Y|yes|Yes/ ) == 0 allowed_changes_hash[role_name] = role_hash if overwrite else #bag_hash does not have a key for that role, populate it. allowed_changes_hash[role_name] = role_hash end @config[role_hash['chef_environment']]['node_roles_bag_hash']['node_roles'][role_name] = role_hash end else allowed_changes_hash = bag_hash end #force add any roles that are not in the bag in the event force yes is turned on (node_roles_hash.keys - bag_hash.keys).each do |role_not_in_node_roles_bag| new_role = node_roles_hash[role_not_in_node_roles_bag] allowed_changes_hash[role_not_in_node_roles_bag] = bag_hash[role_not_in_node_roles_bag] @config[new_role['chef_environment']]['node_roles_bag_hash']['node_roles'][new_role['name']] = new_role end if @options['force_yes'] && @config['helper'].running_in_mode?('devops') nodes.each do |node| # if there is a node_roles file that completely matches the name of the file, use it changes_for_current_node = false if allowed_changes_hash[node.name] allowed_changes_hash[node.name].each_pair do |node_key, node_val| if (node_key =~ /name/) != 0 && node.send(node_key) != node_val puts("Updating #{ node.name } with attribute #{ node_key } = #{ node_val } from #{ node.name }.json") unless @options['quiet'] node.send("#{ node_key }=", node_val) changes_for_current_node, invalidate_file_node_cache = true, true end end elsif allowed_changes_hash.keys.include?(node.name.gsub(/\d/,'')) #if there is a template file that matches the stripped down name, use it allowed_changes_hash[node.name.gsub(/\d/,'')].each_pair do |node_key, node_val| if (node_key =~ /name/) != 0 && node.send(node_key) != node_val puts("Updating #{ node.name } with attribute #{ node_key } = #{ node_val } from template json file") unless @options['quiet'] node.send("#{ node_key }=", node_val) changes_for_current_node, invalidate_file_node_cache = true, true end end end node.save if changes_for_current_node end @config['chef_environments'].each do |env| @config['ChefDataBag'].save_node_roles_bag env end if !@options['force_yes'] && @config['helper'].running_in_mode?('devops') @config['helper'].cleanup_file_caches('current') if invalidate_file_node_cache end |
#upload_roles ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/cheftacular/stateless_actions/upload_roles.rb', line 12 def upload_roles raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] Dir.foreach(@config['locs']['roles']) do |rd| next if @config['helper'].is_junk_filename?(rd) puts("Loading in role from file #{ rd }") if @options['verbose'] puts `knife role from file "#{ @config['locs']['roles'] }/#{ rd }"` end end |
#vyatta_bootstrap(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb', line 3 def vyatta_bootstrap out=[] raise "Not yet implemented!" end |