Class: Cheftacular::StatelessAction
- Inherits:
-
Object
- Object
- Cheftacular::StatelessAction
- Includes:
- RbConfig, SSHKit::DSL
- Defined in:
- lib/cheftacular/stateless_action.rb,
lib/cheftacular/stateless_actions/rvm.rb,
lib/cheftacular/stateless_actions/ssh.rb,
lib/cheftacular/stateless_actions/file.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/service.rb,
lib/cheftacular/stateless_actions/version.rb,
lib/cheftacular/stateless_actions/test_env.rb,
lib/cheftacular/stateless_actions/arguments.rb,
lib/cheftacular/stateless_actions/reset_bag.rb,
lib/cheftacular/stateless_actions/update_tld.rb,
lib/cheftacular/stateless_actions/chef_server.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/role_toggle.rb,
lib/cheftacular/stateless_actions/cleanup_logs.rb,
lib/cheftacular/stateless_actions/clear_caches.rb,
lib/cheftacular/stateless_actions/env_ssh_exec.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/compile_readme.rb,
lib/cheftacular/stateless_actions/create_git_key.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/update_cookbook.rb,
lib/cheftacular/stateless_actions/get_log_from_bag.rb,
lib/cheftacular/stateless_actions/location_aliases.rb,
lib/cheftacular/stateless_actions/compile_audit_log.rb,
lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb,
lib/cheftacular/stateless_actions/cheftacular_config.rb,
lib/cheftacular/stateless_actions/replication_status.rb,
lib/cheftacular/stateless_actions/update_chef_client.rb,
lib/cheftacular/stateless_actions/update_cheftacular.rb,
lib/cheftacular/stateless_actions/cheftacular_yml_help.rb,
lib/cheftacular/stateless_actions/list_toggleable_roles.rb,
lib/cheftacular/stateless_actions/update_split_branches.rb,
lib/cheftacular/stateless_actions/clean_server_passwords.rb,
lib/cheftacular/stateless_actions/chef_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/full_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb,
lib/cheftacular/stateless_actions/cloud_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/get_active_ssh_connections.rb,
lib/cheftacular/stateless_actions/initialize_cheftacular_yml.rb,
lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb,
lib/cheftacular/stateless_actions/update_cloudflare_dns_from_cloud.rb,
lib/cheftacular/stateless_actions/bootstrappers/centos_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/bootstrappers/coreos_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/bootstrappers/fedora_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/bootstrappers/redhat_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap_from_queue.rb,
lib/cheftacular/stateless_actions/update_the_cheftacular_cookbook_and_knife_upload.rb
Instance Method Summary collapse
-
#add_ssh_key_to_bag(specific_repository = "") ⇒ Object
TODO key for environment specific deploys?.
- #arguments ⇒ Object (also: #flags)
- #check_cheftacular_yml_keys(out = [], exit_on_missing = false, warn_on_missing = false) ⇒ Object
- #chef_bootstrap_from_queue(threads = []) ⇒ Object
- #chef_server ⇒ Object
- #cheftacular_config(command = '') ⇒ Object (also: #cc)
- #cheftacular_yml_help(command = '', key_nesting_array = []) ⇒ Object (also: #yml_help)
- #clean_cookbooks(local_options = {'interactive' => true}) ⇒ Object
- #clean_server_passwords ⇒ Object
- #cleanup_logs(directories_to_not_delete = '') ⇒ Object
- #clear_caches ⇒ Object
- #client_list ⇒ Object (also: #clients, #cl)
- #cloud(*args) ⇒ Object (also: #aws, #rax)
- #cloud_bootstrap(server_hash = {}, options_to_sync = ['node_name', 'flavor_name', 'descriptor', 'dns_config', 'address', 'private_address', 'client_pass']) ⇒ Object (also: #cb)
- #cloud_bootstrap_from_queue ⇒ Object
- #compile_audit_log(out = []) ⇒ Object
- #compile_readme(out = []) ⇒ Object
- #coreos_bootstrap_from_queue(out = []) ⇒ Object
- #create_git_key(oauth_key = "") ⇒ Object
- #disk_report(disk_hash = {}, out = []) ⇒ Object
- #env_ssh_exec(command = '', nodes = []) ⇒ Object
- #environment(type = "boot", treat_as_stateful = false, servers_to_interact_with = [], ask_on_destroy = false, remove = true, threads = []) ⇒ Object (also: #e, #env)
- #fedora_bootstrap_from_queue(out = []) ⇒ Object
- #file(location = '', file_name = '', mode = '') ⇒ Object
- #fix_known_hosts ⇒ Object (also: #fkh)
- #full_bootstrap_from_queue(options_to_sync = ['node_name', 'address', 'client_pass']) ⇒ Object
- #get_active_ssh_connections(connections_hash = {}, out = []) ⇒ Object
- #get_haproxy_log ⇒ Object
- #get_log_from_bag ⇒ Object
- #get_pg_pass(clip = false, target_repos = []) ⇒ Object
- #help(inference_modes = []) ⇒ Object
-
#initialize(options, config) ⇒ StatelessAction
constructor
A new instance of StatelessAction.
- #initialize_cheftacular_yml(example_file_to_load = 'cheftacular.yml') ⇒ Object
- #initialize_data_bag_contents(env = "") ⇒ Object
- #knife_upload ⇒ Object (also: #ku)
- #list_toggleable_roles(possible_toggles = []) ⇒ Object
- #location_aliases ⇒ Object (also: #la)
- #pass(node_name = '', mode = 'normal') ⇒ Object
- #redhat_bootstrap_from_queue(out = []) ⇒ Object
- #reinitialize(out = []) ⇒ Object
- #remove_client(delete_server = false, remove = true) ⇒ Object (also: #remove_node, #rc)
- #replication_status(rep_status_hash = {}, out = []) ⇒ Object
- #reset_bag(bag_name = '', bag_env = '') ⇒ Object
- #restart_swap ⇒ Object
- #role_toggle(state_toggle = '', target_run_list = [], skip_confirm = false) ⇒ Object (also: #rt)
- #rvm(command = '') ⇒ Object
-
#server_update ⇒ Object
TODO refactor to handling multiple server types.
- #service ⇒ Object
- #slack(message = '', channel = '') ⇒ Object
- #ssh(node_name = '', command = '') ⇒ Object
- #test_env(split_env = "splitstaging", type = "boot") ⇒ Object
- #ubuntu_bootstrap_from_queue(threads = [], execution_hash_array = []) ⇒ Object
- #update_chef_client ⇒ Object
- #update_cheftacular(status_hash = {}) ⇒ Object
- #update_cloudflare_dns_from_cloud ⇒ Object
- #update_cookbook(cookbook = 'TheCheftacularCookbook', version = 'latest') ⇒ Object (also: #uc)
- #update_split_branches ⇒ Object
- #update_the_cheftacular_cookbook_and_knife_upload ⇒ Object (also: #utccaku, #utcc)
- #update_tld(target_tld = "") ⇒ Object
- #upload_nodes(invalidate_file_node_cache = true) ⇒ Object (also: #un)
- #upload_roles ⇒ Object (also: #ur)
- #version ⇒ Object (also: #v)
- #vyatta_bootstrap_from_queue(out = []) ⇒ Object
Constructor Details
#initialize(options, config) ⇒ StatelessAction
Returns a new instance of StatelessAction.
13 14 15 |
# File 'lib/cheftacular/stateless_action.rb', line 13 def initialize , config @options, @config = , config end |
Instance Method Details
#add_ssh_key_to_bag(specific_repository = "") ⇒ Object
TODO key for environment specific deploys?
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb', line 23 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.gsub("'",'') else @config['default']['authentication_bag_hash']["specific_authorized_keys"] << public_ssh_key.gsub("'",'') end @config['ChefDataBag'].save_authentication_bag end |
#arguments ⇒ Object Also known as: flags
84 85 86 87 88 |
# File 'lib/cheftacular/stateless_actions/arguments.rb', line 84 def arguments @config['stateless_action_documentation'].arguments puts @config['documentation']['arguments'] end |
#check_cheftacular_yml_keys(out = [], exit_on_missing = false, warn_on_missing = 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 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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb', line 16 def check_cheftacular_yml_keys out=[], exit_on_missing=false, warn_on_missing=false = "Your cheftacular.yml is missing the key KEY, its default value is being set to DEFAULT for this run." #############################2.13.0################################################ unless @config['cheftacular'].has_key?('pleasantries') @config['cheftacular']['pleasantries'] = true end #############################2.11.0################################################ unless @config['cheftacular'].has_key?('server_creation_tries') @config['cheftacular']['server_creation_tries'] = 2 end unless @config['cheftacular']['backup_config'].has_key?('db_primary_role') puts .gsub('KEY', 'backup_config:db_primary_role').gsub('DEFAULT', 'db_primary') @config['cheftacular']['backup_config']['db_primary_role'] = 'db_primary' warn_on_missing = true end unless @config['cheftacular'].has_key?('git') puts(.gsub('KEY', 'git').split(',').first + ', Please add the git high level key to your cheftacular.yml.') @config['cheftacular']['git'] ||= {} warn_on_missing = true end unless @config['cheftacular']['git'].has_key?('check_remote_for_branch_existence') puts .gsub('KEY', 'git:check_remote_for_branch_existence').gsub('DEFAULT', 'false') @config['cheftacular']['git']['check_remote_for_branch_existence'] = false warn_on_missing = true end #############################2.10.0################################################ unless @config['cheftacular'].has_key?('self_update_repository') puts .gsub('KEY', 'self_update_repository').gsub('DEFAULT', 'blank') @config['cheftacular']['self_update_repository'] = '' warn_on_missing = true end #############################2.9.2################################################ unless @config['cheftacular']['slack'].has_key?('notify_on_command_execute') puts .gsub('KEY', 'slack:notify_on_command_execute').gsub('DEFAULT', 'blank') @config['cheftacular']['slack']['notify_command_execute'] = '' warn_on_missing = true end #############################2.9.0################################################ unless @config['cheftacular']['slack'].has_key?('notify_on_deployment_args') puts .gsub('KEY', 'slack:notify_on_deployment_args').gsub('DEFAULT', 'blank') @config['cheftacular']['slack']['notify_on_deployment_args'] = '' warn_on_missing = true end #############################2.7.0################################################ unless @config['cheftacular'].has_key?('backup_config') puts .gsub('KEY', 'backup_config').gsub('DEFAULT', 'nil') warn_on_missing = true end #############################2.6.0################################################ unless @config['cheftacular'].has_key?('route_dns_changes_via') puts .gsub('KEY', 'route_dns_changes_via').gsub('DEFAULT', @options['preferred_cloud']) @config['cheftacular']['route_dns_changes_via'] = @options['preferred_cloud'] warn_on_missing = true end unless @config['cheftacular'].has_key?('node_name_separator') puts .gsub('KEY', 'node_name_separator').gsub('DEFAULT', '-') @config['cheftacular']['node_name_separator'] = '-' warn_on_missing = true end unless @config['cheftacular'].has_key?('cloud_authentication') puts (.gsub('KEY', 'cloud_authentication').split(',').first + ', this is a critical issue and must be fixed.') exit_on_missing = true end if !@config['cheftacular'].has_key?('chef_server') && @options['command'] == 'chef_server' puts (.gsub('KEY', 'chef_server').split(',').first + ', this is a critical issue and must be fixed to run the chef_server command.') exit_on_missing = true end unless @config['cheftacular'].has_key?('chef_version') puts (.gsub('KEY', 'chef_version').split(',').first + ', this is a critical issue and must be fixed.') exit_on_missing = true end unless @config['cheftacular'].has_key?('pre_install_packages') puts .gsub('KEY', 'pre_install_packages').gsub('DEFAULT', '') @config['cheftacular']['pre_install_packages'] = '' warn_on_missing = true end unless @config['cheftacular'].has_key?('role_toggling') puts .gsub('KEY', 'role_toggling').gsub('DEFAULT', "it's default nested keys") @config['cheftacular']['role_toggling'] = {} @config['cheftacular']['role_toggling']['deactivated_role_suffix'] = '_deactivated' @config['cheftacular']['role_toggling']['strict_roles'] = true @config['cheftacular']['role_toggling']['skip_confirm'] = false @config['cheftacular']['role_toggling']['do_not_allow_toggling'] = true warn_on_missing = true end if warn_on_missing || exit_on_missing puts "Please enter your missing keys into your cheftacular.yml based off of the cheftacular.yml at" puts "\n https://github.com/SocialCentivPublic/cheftacular/blob/master/examples/cheftacular.yml" end exit if exit_on_missing || @options['command'] == __method__ end |
#chef_bootstrap_from_queue(threads = []) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/cheftacular/stateless_actions/chef_bootstrap_from_queue.rb', line 20 def chef_bootstrap_from_queue threads=[] raise "This action is not meant to be called directly!" if !@options['in_scaling'] && !@options['in_single_server_creation'] #@config['stateless_action'].remove_client #just in case execution_hash_array = compile_chef_bootstrap_commands @config['bootstrap_timestamp'] ||= Time.now.strftime("%Y%m%d%H%M%S") @config['server_creation_queue'].each do |server_hash| puts("#{ server_name_output(server_hash) } Starting chef-client installation...") unless @options['quiet'] threads << Thread.new { execute_execution_hash_array(server_hash, execution_hash_array) } end threads.each { |thread| thread.join } @options['force_yes'] = true # have the upload_nodes grab the new nodes @config['stateless_action'].upload_nodes(true) end |
#chef_server ⇒ Object
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 |
# File 'lib/cheftacular/stateless_actions/chef_server.rb', line 37 def chef_server raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') if @config['cheftacular']['chef_server'].nil? || !@config['cheftacular']['chef_server']['interactable'] raise "Chef server is not currently set to be interactable with the chef-server command" end command = ARGV[1] raise "Unsupported command (#{ command }) for cft chef_server" unless command =~ /restart|processes|memory/ command_prefix = case @config['cheftacular']['chef_server']['ssh_user'] when 'root' then '' else "echo #{ @config['cheftacular']['chef_server']['sudo_pass'] } | sudo -S " end command = case command when 'restart' then command_prefix + 'chef-server-ctl restart' when 'processes' then 'ps aux' when 'memory' then 'free -m' end = @options on ( @config['cheftacular']['chef_server']['ssh_user'] + "@" + @config['parser'].parse_base_chef_server_url ) do |host| puts "Beginning chef-server #{ command } run" start_chef_server_interactor(command, ) end end |
#cheftacular_config(command = '') ⇒ Object Also known as: cc
29 30 31 32 33 34 35 |
# File 'lib/cheftacular/stateless_actions/cheftacular_config.rb', line 29 def cheftacular_config command='' command = ARGV[1] if command.blank? raise "Unsupported command (#{ command }) for cft cheftacular_config" unless command =~ /diff|display|sync|overwrite/ self.send("cheftacular_config_#{ command }") end |
#cheftacular_yml_help(command = '', key_nesting_array = []) ⇒ Object Also known as: yml_help
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/cheftacular/stateless_actions/cheftacular_yml_help.rb', line 34 def cheftacular_yml_help command='', key_nesting_array=[] key_to_check = ARGV[1] raise "This command requires a key to check the documentation, please enter one as the first argument" if key_to_check.nil? key_to_check.split(':').each { |key| key_nesting_array << key } doc_hash = YAML::load(ERB.new(IO.read(File.open(File.("#{ @config['locs']['doc'] }/cheftacular_yml_help.yml")))).result) traverse_documentation_hash(doc_hash, key_nesting_array) end |
#clean_cookbooks(local_options = {'interactive' => true}) ⇒ 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/cheftacular/stateless_actions/clean_cookbooks.rb', line 22 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 = @config['filesystem'].parse_berkshelf_cookbook_versions chef_repo_cookbooks = @config['filesystem'].parse_chef_repo_cookbook_versions berkshelf_cookbooks.each_pair do |berkshelf_cookbook, cookbook_hash| if chef_repo_cookbooks.has_key?(berkshelf_cookbook) || chef_repo_cookbooks.has_key?(cookbook_hash['location']) #don't overwrite cookbooks without user input if ['interactive'] puts "COOKBOOK::~~~~#{ berkshelf_cookbook }~~~~::VERSION::~~~~~~~~#{ cookbook_hash['version'] } VS #{ chef_repo_cookbooks[berkshelf_cookbook] }" puts "\nEnter O | o | overwrite to overwrite ~~~~#{ berkshelf_cookbook }~~~~ 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[berkshelf_cookbook], cookbook_hash['version']) end cmnd = "#{ @config['locs']['berks'] }/#{ cookbook_hash['location'] } #{ @config['locs']['cookbooks'] }/#{ berkshelf_cookbook }" puts "Moving #{ cmnd } (#{ cookbook_hash['version'] }:#{ chef_repo_cookbooks[berkshelf_cookbook] })" if @options['verbose'] `rm -Rf #{ @config['locs']['cookbooks'] }/#{ berkshelf_cookbook }` `cp -Rf #{ cmnd }` end end end |
#clean_server_passwords ⇒ Object
10 11 12 13 14 |
# 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 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') end |
#cleanup_logs(directories_to_not_delete = '') ⇒ Object
29 30 31 32 33 34 35 36 |
# File 'lib/cheftacular/stateless_actions/cleanup_logs.rb', line 29 def cleanup_logs directories_to_not_delete='' directories_to_not_delete = ARGV[1] if directories_to_not_delete.blank? directories_to_not_delete ||= '' @config['filesystem'].remove_log_directories(directories_to_not_delete.split(',')) @config['filesystem'].initialize_log_directories(false) end |
#clear_caches ⇒ Object
27 28 29 |
# File 'lib/cheftacular/stateless_actions/clear_caches.rb', line 27 def clear_caches @config['filesystem'].cleanup_file_caches('all') end |
#client_list ⇒ Object Also known as: clients, cl
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/client_list.rb', line 34 def client_list @config['filesystem'].cleanup_file_caches('current-nodes') 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' next if @options['env'] != @config['cheftacular']['default_environment'] && env != @options['env'] next if @options['search_env_name'] && env != @options['search_env_name'] env_nodes = @config['parser'].exclude_nodes(nodes, [{ if: { not_env: env } }]) puts "\nFound #{ env_nodes.count } #{ env } total nodes: (If you input search arguments the number returned will be smaller)" out = " #{ 'name'.ljust(22) } #{ 'ip_address'.ljust(21) }" 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| next if @options['search_node_name'] && !node.name.include?(@options['search_node_name']) next if @options['search_role_name'] && !node.run_list.join(', ').gsub('role[','').gsub(']','').include?(@options['search_role_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(', ').gsub('role[','').gsub(']','') }" puts out end end end |
#cloud(*args) ⇒ Object Also known as: aws, rax
124 125 126 127 128 129 130 131 132 |
# File 'lib/cheftacular/stateless_actions/cloud.rb', line 124 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['cheftacular'], @options) @config['cloud_interactor'].run args end |
#cloud_bootstrap(server_hash = {}, options_to_sync = ['node_name', 'flavor_name', 'descriptor', 'dns_config', 'address', 'private_address', 'client_pass']) ⇒ Object Also known as: cb
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 |
# File 'lib/cheftacular/stateless_actions/cloud_bootstrap.rb', line 33 def cloud_bootstrap server_hash={}, =['node_name', 'flavor_name', 'descriptor', 'dns_config', 'address', 'private_address', 'client_pass'] 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'] = server_hash['node_name'] if server_hash.has_key?('node_name') @options['flavor_name'] = server_hash['flavor_name'] if server_hash.has_key?('flavor_name') @options['descriptor'] = server_hash['descriptor'] if server_hash.has_key?('descriptor') @options['with_dn'] = server_hash['dns_config'] if server_hash.has_key?('dns_config') @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'] @options['in_single_server_creation'] = true puts "Preparing to boot #{ @options['node_name'] }(#{ @options['flavor_name'] })..." real_node_name = @config['getter'].get_current_real_node_name #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:#{ real_node_name }:#{ @options['flavor_name'] }" status_hash = @config['stateless_action'].cloud "server", "poll:#{ real_node_name }" status_hash['created_servers'].each do |cloud_server_hash| next unless cloud_server_hash['name'] == "#{ real_node_name }" @options['address'], @options['private_address'] = @config['cloud_provider'].parse_addresses_from_server_create_hash cloud_server_hash end @options['client_pass'] = @config['cloud_provider'].parse_server_root_password_from_server_create_hash status_hash, real_node_name 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 server_hash = @config['queue_master'].sync_server_hash_into_queue(server_hash.merge(@config['helper'].())) puts("Created server #{ server_hash['node_name'] } and attached additional flags:") unless @options['quiet'] ap(@config['queue_master'].return_hash_from_queue('server_creation_queue', server_hash, 'node_name').except(*[0..3])) unless @options['quiet'] @config['stateless_action'].full_bootstrap_from_queue unless @config['in_server_creation_queue'] #bootstrap server with ruby and attach it to the chef server end |
#cloud_bootstrap_from_queue ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/cheftacular/stateless_actions/cloud_bootstrap_from_queue.rb', line 20 def cloud_bootstrap_from_queue raise "This action is not meant to be called directly!" unless @options['in_scaling'] @config['in_server_creation_queue'] = true @config['server_creation_queue'].each do |server_hash| puts("Preparing to boot server #{ server_hash['node_name'] } for #{ @options['env'] }!") unless @options['quiet'] puts("Creating server #{ server_hash['node_name'] } with arguments:") unless @options['quiet'] ap(server_hash.except('node_name')) unless @options['quiet'] @config['stateless_action'].cloud_bootstrap(server_hash) end @config['stateless_action'].full_bootstrap_from_queue end |
#compile_audit_log(out = []) ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/compile_audit_log.rb', line 16 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.sort.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 << @config['auditor'].compile_audit_hash_entry_as_array(log_hash, log_array_entry_count) 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.flatten.join("\n")) } end |
#compile_readme(out = []) ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/compile_readme.rb', line 20 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_from_queue(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/coreos_bootstrap_from_queue.rb', line 3 def coreos_bootstrap_from_queue out=[] raise "Not yet implemented!" end |
#create_git_key(oauth_key = "") ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/create_git_key.rb', line 24 def create_git_key oauth_key="" raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') 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
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/cheftacular/stateless_actions/disk_report.rb', line 16 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| @config['cheftacular']['deploy_user'] + "@" + 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 @config['filesystem'].generate_report_from_node_hash('disk report', disk_hash) end |
#env_ssh_exec(command = '', nodes = []) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/cheftacular/stateless_actions/env_ssh_exec.rb', line 23 def env_ssh_exec command='', nodes=[] raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') command = ARGV[1] if command.blank? nodes = @config['parser'].exclude_nodes( @config['getter'].get_true_node_objects(true), [{ unless: { env: @options['env'] }}] ) if nodes.empty? #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| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 5 do |host| n = get_node_from_address(nodes, host.hostname) log_data, = start_env_exec( n.name, n.public_ipaddress, command, , locs, passwords) end end |
#environment(type = "boot", treat_as_stateful = false, servers_to_interact_with = [], ask_on_destroy = false, remove = true, threads = []) ⇒ Object Also known as: e, env
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/cheftacular/stateless_actions/environment.rb', line 37 def environment type="boot", treat_as_stateful=false, servers_to_interact_with=[], ask_on_destroy=false, remove=true, threads=[] ask_on_destroy = case @options['env'] when 'staging' then true when 'production' then true else false end type = ARGV[1] if ARGV[1] servers_to_interact_with = ARGV[2].split(',') if ARGV[2] unless (type =~ /boot|destroy|destroy_raw_servers|boot_without_deploy/) == 0 raise "Unknown type: #{ type }, can only be 'boot'/'boot_without_deploy'/'destroy'/'destroy_raw_servers'" end nodes = @config['getter'].get_true_node_objects(!treat_as_stateful) 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"] unless servers_to_interact_with.empty? initial_servers = initial_servers.delete_if {|name, config_hash| !servers_to_interact_with.include?(name)} end if treat_as_stateful initial_servers = initial_servers.delete_if { |name, config_hash| config_hash.nil? || !config_hash.has_key?('descriptor') } initial_servers = initial_servers.delete_if { |name, config_hash| !config_hash['descriptor'].include?(@options['repository']) if !config_hash.nil? && config_hash.has_key?('descriptor') } end 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|boot_without_deploy/ begin initial_servers.each_pair do |name, config_hash| next if nodes.map { |n| n.name }.include?(name) config_hash ||= {} node_hash = {} node_hash['node_name'] = name node_hash['flavor_name'] = config_hash.has_key?('flavor') ? config_hash['flavor'] : @config['cheftacular']['default_flavor_name'] node_hash['descriptor'] = config_hash.has_key?('descriptor') ? config_hash['descriptor'] : name node_hash['dns_config'] = if config_hash.has_key?('dns_config') @config['parser'].parse_to_dns(config_hash['dns_config'], node_hash['node_name']) else @config['parser'].parse_to_dns('NODE_NAME.ENV_TLD', node_hash['node_name']) end @config['server_creation_queue'] << node_hash end @config['stateless_action'].cloud_bootstrap_from_queue end @config['ChefDataBag'].save_server_passwords_bag if type == 'boot' @options = @options.delete_if { |k,v| ['node_name','address', 'descriptor', 'with_dn', 'private_address', 'client_pass'].include?(k) } @options['role'] = @config['cheftacular']['backup_config']['db_primary_role'] @options['unset_address_and_node_name'] = true database_host = @config['parser'].exclude_nodes( @config['getter'].get_true_node_objects(true), [{ unless: "role[#{ @options['role'] }]"}, { if: { not_env: @options['env'] } }], true).first unless database_host.nil? @config['action'].deploy backup_pid = Process.spawn("cft backups load --env=#{ @options['env'] }") end puts("NOTE! This command is not finished until your terminal returns to an input state!") unless database_host.nil? @options['role'] = 'all' @config['action'].deploy Process.wait(backup_pid) unless database_host.nil? puts "Done loading data and setting up #{ @options['env'] }!" end when 'destroy' return false if ask_on_destroy && !environment_is_destroyable? @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 when 'destroy_raw_servers' return false if ask_on_destroy && !environment_is_destroyable? @options['delete_server_on_remove'] = true initial_servers.each_pair do |name, config_hash| next if nodes.map { |n| n.name }.include?(name) @options['node_name'] = name real_node_name = @config['getter'].get_current_real_node_name @config['stateless_action'].cloud('servers', "destroy:#{ real_node_name }") sleep 15 end end @config['auditor'].notify_slack_on_completion("environment #{ type } command completed for env: #{ @options['env'] } (#{ initial_servers.keys.join(' ,') })\n") if @config['cheftacular']['auditing'] end |
#fedora_bootstrap_from_queue(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/fedora_bootstrap_from_queue.rb', line 3 def fedora_bootstrap_from_queue out=[] raise "Not yet implemented!" end |
#file(location = '', file_name = '', mode = '') ⇒ Object
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 |
# File 'lib/cheftacular/stateless_actions/file.rb', line 52 def file location='', file_name='',mode='' @options['node_name'] = ARGV[1] unless @options['node_name'] location = ARGV[2] if location.blank? mode = ARGV[3] if mode.blank? file_name = ARGV[4] if file_name.blank? nodes = @config['error'].is_valid_node_name_option? mode = 'display' if mode.nil? mode = 'list' if file_name.nil? || file_name.blank? interaction_mode = case mode.split(':').first when 'cat' then 'sshkit' when 'display' then 'sshkit' when 'edit' then 'ssh' when /fetch|scp/ then 'scp' when 'list' then 'sshkit' when 'tail' then 'sshkit' when 'tail-f' then 'ssh' else raise "Unsupported Mode for cft file: #{ mode }, " end location = @config['parser'].parse_location_alias(location) command = @config['parser'].parse_mode_into_command(mode) nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}], true ) case interaction_mode when 'sshkit' then file_sshkit_execute(nodes, command, location, file_name) when 'ssh' then file_ssh_execute(nodes, mode, command, location, file_name) when 'scp' then file_scp_execute(nodes, command, location, file_name) end end |
#fix_known_hosts ⇒ Object Also known as: fkh
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 |
# File 'lib/cheftacular/stateless_actions/fix_known_hosts.rb', line 24 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'] arr << serv_hash['public'] end end targets = arr.uniq end targets.each do |target| @config['filesystem'].scrub_from_known_hosts target end end |
#full_bootstrap_from_queue(options_to_sync = ['node_name', 'address', 'client_pass']) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/cheftacular/stateless_actions/full_bootstrap_from_queue.rb', line 20 def full_bootstrap_from_queue =['node_name', 'address', 'client_pass'] raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling'] case @config['cheftacular']['preferred_cloud_os'] when 'ubuntu' || 'debian' then @config['stateless_action'].ubuntu_bootstrap_from_queue else @config['stateless_action'].instance_eval("#{ @config['cheftacular']['preferred_cloud_os'] }_bootstrap_from_queue") 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_from_queue end |
#get_active_ssh_connections(connections_hash = {}, out = []) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/cheftacular/stateless_actions/get_active_ssh_connections.rb', line 21 def get_active_ssh_connections connections_hash={}, out=[] nodes = @config['getter'].get_true_node_objects(true) nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] ) , locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning ssh connection check run for #{ n.name } (#{ n.public_ipaddress })" connections_hash[n.name] = start_connection_report( n.name, n.public_ipaddress, , locs, passwords) end @config['filesystem'].generate_report_from_node_hash('connections report', connections_hash) end |
#get_haproxy_log ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/cheftacular/stateless_actions/get_haproxy_log.rb', line 22 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| @config['cheftacular']['deploy_user'] + "@" + 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
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/cheftacular/stateless_actions/get_log_from_bag.rb', line 18 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
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 |
# File 'lib/cheftacular/stateless_actions/get_pg_pass.rb', line 18 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 |
#help(inference_modes = []) ⇒ 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 82 |
# File 'lib/cheftacular/stateless_actions/help.rb', line 24 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 << 'short_context_descriptions' end if @config['helper'].is_command? target_command @config['action_documentation'].send(target_command) puts @config['documentation']['action'][target_command.to_sym]['long_description'].flatten.join("\n\n") elsif @config['helper'].is_stateless_command? target_command @config['stateless_action_documentation'].send(target_command) puts @config['documentation']['stateless_action'][target_command.to_sym]['long_description'].flatten.join("\n\n") end if inference_modes.include?('action') || inference_modes.include?('both') || inference_modes.include?('short_context_descriptions') @config['action_documentation'].public_methods(false).each do |method| @config['action_documentation'].send(method) end end if inference_modes.include?('action') || inference_modes.include?('both') || inference_modes.include?('short_context_descriptions') @config['stateless_action_documentation'].public_methods(false).each do |method| @config['stateless_action_documentation'].send(method) end end puts @config['documentation']['arguments'].flatten.join("\n\n") if target_command == 'arguments' if inference_modes.include?('short_context_descriptions') if @config['helper'].running_in_mode?('devops') puts @config['helper'].compile_short_context_descriptions(@config['documentation']['action'].merge(@config['documentation']['stateless_action']), 35) else puts @config['helper'].compile_short_context_descriptions(@config['documentation']['action'].merge(@config['documentation']['application'])) end end puts @config['helper'].compile_documentation_lines(target_command).flatten.join("\n\n") if target_command =~ /action|stateless_action|application|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 'cft help #{ @config['cheftacular']['mode'] }' to see a list of commands" end end |
#initialize_cheftacular_yml(example_file_to_load = 'cheftacular.yml') ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/cheftacular/stateless_actions/initialize_cheftacular_yml.rb', line 29 def initialize_cheftacular_yml example_file_to_load='cheftacular.yml' example_file_to_load = 'thecheftacularcookbook.cheftacular.yml' if ARGV[1] == 'TheCheftacularCookbook' example_file_to_load = 'application.cheftacular.yml' if ARGV[1] == 'application' FileUtils.mkdir_p(File.join(@config['locs']['chef-repo'], "config")) if File.exist?(File.join(@config['locs']['chef-repo'], "config", "cheftacular.yml")) @config['helper'].write_config_cheftacular_yml_file('cheftacular.example.yml', example_file_to_load ) else @config['helper'].write_config_cheftacular_yml_file('cheftacular.yml', example_file_to_load) end end |
#initialize_data_bag_contents(env = "") ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb', line 15 def initialize_data_bag_contents env="" raise "Environment #{ env } does not exist on chef server!" if !env.blank? && !@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 @config['initializer'].initialize_environment_config_bag_contents if @config['helper'].running_in_mode?('devops') exit if @options['command'] == __method__ end |
#knife_upload ⇒ Object Also known as: ku
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/cheftacular/stateless_actions/knife_upload.rb', line 24 def knife_upload raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') arg = ARGV[1] option = case arg when 'force' then ' --force' else '' end puts("Starting upload...") unless @options['quiet'] out = `knife upload / --chef-repo-path #{ @config['locs']['chef-repo'] }#{ option }` puts out end |
#list_toggleable_roles(possible_toggles = []) ⇒ Object
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 |
# File 'lib/cheftacular/stateless_actions/list_toggleable_roles.rb', line 17 def list_toggleable_roles possible_toggles=[] @options['node_name'] = ARGV[1] unless @options['node_name'] raise "You have yet to fully configure your role toggling settings! Exiting..." if @config['cheftacular']['role_toggling'].has_key?('do_not_allow_toggling') nodes = @config['error'].is_valid_node_name_option? suffix = @config['cheftacular']['role_toggling']['deactivated_role_suffix'] nodes.first.run_list.each do |role| role = role.gsub('role[','').gsub(']','') if !role.include?(suffix) && @config['parser'].parse_role("#{ role }#{ suffix }", 'boolean') possible_toggles << role possible_toggles << "#{ role }#{ suffix }" elsif role.include?(suffix) && @config['parser'].parse_role("#{ role.gsub(suffix,'') }", 'boolean') possible_toggles << role possible_toggles << role.gsub(suffix,'') end end puts "The current run_list for #{ @options['node_name'] } is:" ap nodes.first.run_list puts "\nThe possible toggles for #{ @options['node_name'] } are:" ap possible_toggles end |
#location_aliases ⇒ Object Also known as: la
27 28 29 |
# File 'lib/cheftacular/stateless_actions/location_aliases.rb', line 27 def location_aliases ap @config['cheftacular']['location_aliases'] end |
#pass(node_name = '', mode = 'normal') ⇒ Object
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 18 def pass node_name='', mode='normal' @options['node_name'] = ARGV[1] if !@options['node_name'] && node_name.blank? @options['node_name'] = node_name if !@options['node_name'] && !node_name.blank? nodes = @config['error'].is_valid_node_name_option? if nodes.first.chef_environment != @options['env'] @config['initializer'].initialize_data_bags_for_environment nodes.first.chef_environment, false, ['server_passwords'] end if mode =~ /normal/ 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"] }" end 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 if mode =~ /normal/ end |
#redhat_bootstrap_from_queue(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/centos_bootstrap_from_queue.rb', line 3 def redhat_bootstrap_from_queue out=[] raise "Not yet implemented!" end |
#reinitialize(out = []) ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/reinitialize.rb', line 16 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"` puts("Starting reinitialization...") unless @options['quiet'] out << `#{ knife_bootstrap_command }` puts(out.last) unless @options['quiet'] end |
#remove_client(delete_server = false, remove = true) ⇒ Object Also known as: remove_node, rc
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 |
# File 'lib/cheftacular/stateless_actions/remove_client.rb', line 24 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 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:#{ @config['getter'].get_current_real_node_name(n.name) }" 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 end puts("Done. Please verify that the output of the next line(s) match your expectations (running cft client_list)") if @options['verbose'] @config['stateless_actions'].client_list if @options['verbose'] end |
#replication_status(rep_status_hash = {}, out = []) ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/replication_status.rb', line 16 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| @config['cheftacular']['deploy_user'] + "@" + 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| @config['cheftacular']['deploy_user'] + "@" + 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 |
#reset_bag(bag_name = '', bag_env = '') ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/cheftacular/stateless_actions/reset_bag.rb', line 16 def reset_bag bag_name='', bag_env='' raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') bag_name = ARGV[1] if bag_name.blank? bag_env = @options['env'] if bag_env.blank? begin @config['ChefDataBag'].send("reset_#{ bag_name }_bag") puts "Successfully reset bag #{ bag_name }." rescue NoMethodError => e puts "You are not able to reset the bag \"#{ bag_name }\" via reset_bag, please use knife to edit the contents.\n #{ e }" end @config['stateless_action'].clear_caches end |
#restart_swap ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/cheftacular/stateless_actions/restart_swap.rb', line 20 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| @config['cheftacular']['deploy_user'] + "@" + 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 |
#role_toggle(state_toggle = '', target_run_list = [], skip_confirm = false) ⇒ Object Also known as: rt
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/cheftacular/stateless_actions/role_toggle.rb', line 41 def role_toggle state_toggle='', target_run_list=[], skip_confirm=false @options['node_name'] = ARGV[1] unless @options['node_name'] @config['parser'].parse_role(ARGV[2]) state_toggle = ARGV[3] if state_toggle.blank? raise "You have yet to fully configure your role toggling settings! Exiting..." if @config['cheftacular']['role_toggling'].has_key?('do_not_allow_toggling') raise "You may only enter activate or deactivate for the state toggle argument for the #{ __method__ } command." unless (state_toggle =~ /activate|deactivate/) == 0 @config['initializer'].initialize_data_bags_for_environment @options['env'], false, ['node_roles'] @config['initializer'].initialize_node_roles_bag_contents @options['env'] @config['filesystem'].cleanup_file_caches('current-nodes') nodes = @config['error'].is_valid_node_name_option? suffix = @config['cheftacular']['role_toggling']['deactivated_role_suffix'] if @options['role'].include?(suffix) unless @config['parser'].parse_role("#{ @options['role'].gsub(suffix,'') }", 'boolean') puts "Role #{ @options['role'] } does not have an activated role! There is no #{ @options['role'].gsub(suffix,'') } role!" return false end else unless @config['parser'].parse_role("#{ @options['role'] }#{ suffix }", 'boolean') puts "Role #{ @options['role'] } does not have a deactivated role! There is no #{ @options['role'] }#{ suffix } role!" return false end end current_node_roles = nodes.first.run_list if current_node_roles.include?("role[#{ @options['role'] }]") && !@options['role'].include?(suffix) if state_toggle == 'activate' puts "The role #{ @options['role'] } is already activated for #{ nodes.first.name }!" else puts "The role #{ @options['role'] } is currently activated, setting it to #{ @options['role'] }#{ suffix }" target_run_list = current_node_roles.map {|r| r.gsub(@options['role'], "#{ @options['role'] }#{ suffix }") if current_node_roles.include?("role[#{ @options['role'] }]") } end elsif current_node_roles.include?("role[#{ @options['role'] }]") && @options['role'].include?(suffix) if state_toggle == 'activate' puts "The role #{ @options['role'] } is currently deactivated, setting it to #{ @options['role'].gsub(suffix, '') }" target_run_list = current_node_roles.map {|r| r.gsub(@options['role'], "#{ @options['role'].gsub(suffix, '') }") if current_node_roles.include?("role[#{ @options['role'] }]") } else puts "The role #{ @options['role'] } is already deactivated for #{ nodes.first.name }!" end elsif current_node_roles.include?("role[#{ @options['role'] }#{ suffix }]") #they passed in the reverse of a role that was already deactivated if state_toggle == 'activate' puts "The role #{ @options['role'] } is currently deactivated, setting it to it's activated state" target_run_list = current_node_roles.map {|r| r.gsub("#{ @options['role'] }#{ suffix }", "#{ @options['role'] }") if current_node_roles.include?("role[#{ @options['role'] }#{ suffix }]") } else puts "The role #{ @options['role'] } is already deactivated for #{ nodes.first.name }!" end elsif current_node_roles.include?("role[#{ @options['role'].gsub(suffix, '') }]") #they passed in the reverse of a role that was already activated if state_toggle == 'activate' puts "The role #{ @options['role'] } is already activated for #{ nodes.first.name }!" else puts "The role #{ @options['role'] } is currently activated, setting it to it's deactivated state" target_run_list = current_node_roles.map {|r| r.gsub("#{ @options['role'].gsub('suffix','') }", "#{ @options['role'] }") if current_node_roles.include?("role[#{ @options['role'].gsub('suffix','') }]") } end elsif !current_node_roles.include?("role[#{ @options['role'] }]") && @config['cheftacular']['role_toggling']['strict_roles'] puts "The node does not have #{ @options['role'] } and strict roles is set to true, exiting..." return false elsif !current_node_roles.include?("role[#{ @options['role'] }]") && !@config['cheftacular']['role_toggling']['strict_roles'] puts "The node does not have #{ @options['role'] } and strict roles is set to false, setting this new role..." target_run_list = current_node_roles + "role[#{ @options['role'] }" end unless target_run_list.empty? puts "Updating node run list for #{ nodes.first.name } from" ap current_node_roles puts "to:" ap target_run_list if skip_confirm || !@config['cheftacular']['role_toggling']['skip_confirm'] puts "Enter Y/y to confirm." input = STDIN.gets.chomp return false unless ( input =~ /y|Y|yes|Yes/ ) == 0 end @config[@options['env']]['node_roles_bag_hash']['node_roles'][nodes.first.name.gsub(/\d/,'')]['run_list'] = target_run_list nodes.first.send("run_list=", target_run_list) nodes.first.save @config['ChefDataBag'].save_node_roles_bag @options['env'] @config['filesystem'].cleanup_file_caches('current-nodes') puts "Triggering deploy to set the new role..." @config['action'].deploy end end |
#rvm(command = '') ⇒ Object
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 |
# File 'lib/cheftacular/stateless_actions/rvm.rb', line 41 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| @config['cheftacular']['deploy_user'] + "@" + 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
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/server_update.rb', line 22 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| @config['cheftacular']['deploy_user'] + "@" + 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: timestamp } end on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + 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
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/service.rb', line 27 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 'ls /etc/init' when /list/ then 'ls /etc/init' when 'restart' then "service #{ ARGV[2] } restart" when 'stop' then "service #{ ARGV[2] } stop" when 'start' then "service #{ ARGV[2] } start" else 'ls /etc/init' end command = case ARGV[1] when nil then 'ls /etc/init.d' when /list/ then 'ls /etc/init.d' when 'restart' then "sv restart #{ ARGV[2] }" when 'stop' then "sv stop #{ ARGV[2] }" when 'start' then "sv start #{ ARGV[2] }" else 'ls /etc/init.d' end if @options['runsv'] raise "You did not pass a service to #{ ARGV[1] }" if ARGV[1] =~ /restart|stop|start/ && ARGV[2].nil? #initctl list | awk '{ print $1 }' | xargs -n1 initctl show-config 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| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host| n = get_node_from_address(nodes, host.hostname) puts "Beginning run of \"#{ command }\" for #{ n.name } (#{ n.public_ipaddress })" start_service_run( n.name, n.public_ipaddress, , locs, passwords, command, cheftacular) end end |
#slack(message = '', channel = '') ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/cheftacular/stateless_actions/slack.rb', line 22 def slack ='', channel='' return false if @config['cheftacular']['slack']['webhook'].nil? @slack_notifier ||= Slack::Notifier.new @config['cheftacular']['slack']['webhook'], username: 'Cheftacular' = ARGV[1] if !.nil? && .blank? channel = ARGV[2] if !channel.nil? && channel.blank? @slack_notifier.channel = channel.nil? ? @config['cheftacular']['slack']['default_channel'] : channel @slack_notifier.ping end |
#ssh(node_name = '', command = '') ⇒ Object
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/ssh.rb', line 22 def ssh node_name='', command='' @options['node_name'] = ARGV[1] unless @options['node_name'] command = ARGV[3] if command.blank? && ARGV[2] == 'exec' @config['stateless_action'].pass(@options['node_name']) if command.blank? nodes = @config['error'].is_valid_node_name_option? if !command.blank? && nodes.first.chef_environment != @options['env'] @config['initializer'].initialize_data_bags_for_environment nodes.first.chef_environment, false, ['addresses', 'server_passwords'] @config['initializer'].initialize_passwords nodes.first.chef_environment end nodes.each do |n| puts("Beginning ssh run for #{ n.name } (#{ n.public_ipaddress })") unless @options['quiet'] start_ssh_session(n.public_ipaddress, command) end @config['auditor'].notify_slack_on_completion("ssh run completed on #{ @options['node_name'] } (#{ nodes.first.public_ipaddress })\n") if @config['cheftacular']['auditing'] && command.blank? end |
#test_env(split_env = "splitstaging", type = "boot") ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/test_env.rb', line 27 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' begin @config['cheftacular']['split_env_nodes'].each_pair do |name, config_hash| next if nodes.map { |n| n.name }.include?(@options['node_name']) config_hash ||= {} node_hash = {} true_name = name.gsub('SPLITENV', split_env) @options['sub_env'] = split_env node_hash['node_name'] = name node_hash['flavor_name'] = config_hash.has_key?('flavor') ? config_hash['flavor'] : @config['cheftacular']['default_flavor_name'] node_hash['descriptor'] = config_hash.has_key?('descriptor') ? "#{ config_hash['descriptor'] }-#{ split_env }" : name node_hash['dns_config'] = if config_hash.has_key?('dns_config') @config['parser'].parse_to_dns(config_hash['dns_config'], node_hash['node_name']) else @config['parser'].parse_to_dns('NODE_NAME.ENV_TLD', node_hash['node_name']) end puts("Preparing to boot server #{ @options['node_name'] } for #{ @options['env'] }'s #{ split_env } environment!") unless @options['quiet'] @config['stateless_action'].cloud_bootstrap_from_queue sleep 15 end ensure @config['ChefDataBag'].save_server_passwords_bag end 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_from_queue(threads = [], execution_hash_array = []) ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap_from_queue.rb', line 16 def ubuntu_bootstrap_from_queue threads=[], execution_hash_array=[] raise "This action is not meant to be called directly!" if !@options['in_scaling'] && !@options['in_single_server_creation'] @config['bootstrap_timestamp'] ||= Time.now.strftime("%Y%m%d%H%M%S") @config['queue_master'].generate_passwords_for_each_server_hash_in_queue execution_hash_array << compile_root_execute_hash execution_hash_array << compile_deploy_execute_hash execution_hash_array << compile_rvm_execute_hash if @config['cheftacular']['install_rvm_on_boot'] execution_hash_array << compile_install_rvm_sh_file_hashes if @config['cheftacular']['install_rvm_on_boot'] execution_hash_array = execution_hash_array.flatten(1) @config['server_creation_queue'].each do |server_hash| puts("#{ server_name_output(server_hash) }_Starting initial setup for server...") threads << Thread.new { execute_execution_hash_array(server_hash, execution_hash_array) } end threads.each { |thread| thread.join } @config['server_creation_queue'].each do |server_hash| @config[@options['env']]['server_passwords_bag_hash']["#{ server_hash['address'] }-root-pass"] = server_hash['client_pass'] @config[@options['env']]['server_passwords_bag_hash']["#{ server_hash['address'] }-deploy-pass"] = server_hash['deploy_password'] @config[@options['env']]['server_passwords_bag_hash']["#{ server_hash['address'] }-name"] = server_hash['node_name'] end @config['ChefDataBag'].save_server_passwords_bag unless @config['in_server_creation_queue'] end |
#update_chef_client ⇒ Object
14 15 16 17 |
# File 'lib/cheftacular/stateless_actions/update_chef_client.rb', line 14 def update_chef_client raise "Not Yet Implemented" raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') end |
#update_cheftacular(status_hash = {}) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/cheftacular/stateless_actions/update_cheftacular.rb', line 17 def update_cheftacular status_hash={} update_cheftacular_not_configured_to_update if @config['cheftacular']['self_update_repository'] != @config['locs']['root'].split('/').last @config['helper'].set_detected_cheftacular_version puts "Attempting to update cheftacular from #{ Cheftacular::VERSION } to #{ @config['detected_cheftacular_version'] }..." status_hash['gemfile_is_latest_version'] = update_cheftacular_from_git status_hash['gemfile_is_latest_version'] = update_cheftacular_gemfile unless status_hash['gemfile_is_latest_version'] #status_hash['bundled_latest_version'] = update_cheftacular_bundle if status_hash['gemfile_is_latest_version'] puts "Please run bundle install to update to the latest version." #if !status_hash['gemfile_is_latest_version'] || !status_hash['bundled_latest_version'] # puts( # "Issues occured in automatically updating your cheftacular " + # "to #{ @config['detected_cheftacular_version'] }, please send " + # "the output of this command to your DevOps administrator or add " + # "it as an issue at this gem's github page." # ) #else # puts "Successfully installed version #{ @config['detected_cheftacular_version'] }, please re-run your command." #end end |
#update_cloudflare_dns_from_cloud ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cheftacular/stateless_actions/update_cloudflare_dns_from_cloud.rb', line 26 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_cookbook(cookbook = 'TheCheftacularCookbook', version = 'latest') ⇒ Object Also known as: uc
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_cookbook.rb', line 29 def update_cookbook cookbook='TheCheftacularCookbook', version='latest' raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') cookbook = ARGV[1] if ARGV[1] version = ARGV[2] if ARGV[2] if version == 'local' if File.exists?(File.("#{ @config['locs']['true-root'] }/#{ cookbook }")) `rm -Rf #{ @config['locs']['cookbooks'] }/#{ cookbook }` if File.exists?(File.("#{ @config['locs']['cookbooks'] }/#{ cookbook }")) `cp -Rf #{ @config['locs']['true-root'] }/#{ cookbook } #{ @config['locs']['cookbooks'] }/#{ cookbook }` `rm -Rf #{ @config['locs']['cookbooks'] }/#{ cookbook }/.git` else puts "You do not have #{ cookbook } under the #{ @config['locs']['true-root'] } directory!" end else @config['cheftacular']['wrapper_cookbooks'].split(',').each do |wrapper_cookbook| wrapper_cookbook_loc = "#{ @config['locs']['cookbooks'] }/#{ wrapper_cookbook }" 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 fetching cookbooks, moving #{ cookbook } into local chef repo" specific_cookbook = @config['filesystem'].parse_berkshelf_cookbook_versions(version).select {|key| key.include?(cookbook)}[cookbook] puts "Moving #{ cookbook } (#{ specific_cookbook['version'] })[#{ specific_cookbook['mtime'] }] to your chef-repo!" `rm -Rf #{ @config['locs']['cookbooks'] }/#{ cookbook }` if File.exists?(File.("#{ @config['locs']['cookbooks'] }/#{ cookbook }")) `cp -Rf #{ @config['locs']['berks'] }/#{ specific_cookbook['location'] } #{ @config['locs']['cookbooks'] }/#{ cookbook }` break end end end |
#update_split_branches ⇒ 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 |
# File 'lib/cheftacular/stateless_actions/update_split_branches.rb', line 28 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_the_cheftacular_cookbook_and_knife_upload ⇒ Object Also known as: utccaku, utcc
20 21 22 23 24 25 26 |
# File 'lib/cheftacular/stateless_actions/update_the_cheftacular_cookbook_and_knife_upload.rb', line 20 def update_the_cheftacular_cookbook_and_knife_upload raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops') @config['stateless_action'].update_cookbook('TheCheftacularCookbook', 'local') @config['stateless_action'].knife_upload end |
#update_tld(target_tld = "") ⇒ Object
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 |
# File 'lib/cheftacular/stateless_actions/update_tld.rb', line 17 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'] target_tld = old_tld if target_tld == 'self' 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 @config['ChefDataBag'].save_config_bag @config['ChefDataBag'].save_addresses_bag end |
#upload_nodes(invalidate_file_node_cache = true) ⇒ Object Also known as: un
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 131 132 133 134 135 136 137 |
# File 'lib/cheftacular/stateless_actions/upload_nodes.rb', line 32 def upload_nodes invalidate_file_node_cache=true @config['filesystem'].cleanup_file_caches('current-nodes') if invalidate_file_node_cache 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) : @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['filesystem'].is_junk_filename?(fr) Dir.foreach("#{ @config['locs']['nodes'] }/#{ fr }") do |f| next if @config['filesystem'].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['filesystem'].cleanup_file_caches('current-nodes') if invalidate_file_node_cache end |
#upload_roles ⇒ Object Also known as: ur
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/cheftacular/stateless_actions/upload_roles.rb', line 19 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['filesystem'].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 |
#version ⇒ Object Also known as: v
27 28 29 |
# File 'lib/cheftacular/stateless_actions/version.rb', line 27 def version @config['helper'].display_currently_installed_version end |
#vyatta_bootstrap_from_queue(out = []) ⇒ Object
3 4 5 |
# File 'lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap_from_queue.rb', line 3 def vyatta_bootstrap_from_queue out=[] raise "Not yet implemented!" end |