cheftacular 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/bin/cft +4 -0
  3. data/bin/cftclr +4 -0
  4. data/bin/cheftacular +4 -0
  5. data/bin/client-list +4 -0
  6. data/lib/cheftacular/README.md +416 -0
  7. data/lib/cheftacular/actions/check.rb +32 -0
  8. data/lib/cheftacular/actions/console.rb +62 -0
  9. data/lib/cheftacular/actions/database.rb +13 -0
  10. data/lib/cheftacular/actions/db_console.rb +67 -0
  11. data/lib/cheftacular/actions/deploy.rb +40 -0
  12. data/lib/cheftacular/actions/log.rb +47 -0
  13. data/lib/cheftacular/actions/migrate.rb +57 -0
  14. data/lib/cheftacular/actions/run.rb +64 -0
  15. data/lib/cheftacular/actions/scale.rb +94 -0
  16. data/lib/cheftacular/actions/tail.rb +55 -0
  17. data/lib/cheftacular/actions.rb +14 -0
  18. data/lib/cheftacular/auditor.rb +46 -0
  19. data/lib/cheftacular/chef/data_bag.rb +104 -0
  20. data/lib/cheftacular/cheftacular.rb +55 -0
  21. data/lib/cheftacular/decryptors.rb +45 -0
  22. data/lib/cheftacular/encryptors.rb +48 -0
  23. data/lib/cheftacular/getters.rb +153 -0
  24. data/lib/cheftacular/helpers.rb +296 -0
  25. data/lib/cheftacular/initializers.rb +451 -0
  26. data/lib/cheftacular/parsers.rb +199 -0
  27. data/lib/cheftacular/remote_helpers.rb +30 -0
  28. data/lib/cheftacular/stateless_action.rb +16 -0
  29. data/lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb +44 -0
  30. data/lib/cheftacular/stateless_actions/arguments.rb +68 -0
  31. data/lib/cheftacular/stateless_actions/backups.rb +116 -0
  32. data/lib/cheftacular/stateless_actions/bootstrappers/centos_bootstrap.rb +7 -0
  33. data/lib/cheftacular/stateless_actions/bootstrappers/coreos_bootstrap.rb +7 -0
  34. data/lib/cheftacular/stateless_actions/bootstrappers/fedora_bootstrap.rb +7 -0
  35. data/lib/cheftacular/stateless_actions/bootstrappers/redhat_bootstrap.rb +7 -0
  36. data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +102 -0
  37. data/lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb +7 -0
  38. data/lib/cheftacular/stateless_actions/chef_bootstrap.rb +40 -0
  39. data/lib/cheftacular/stateless_actions/chef_environment.rb +21 -0
  40. data/lib/cheftacular/stateless_actions/clean_cookbooks.rb +104 -0
  41. data/lib/cheftacular/stateless_actions/clean_sensu_plugins.rb +19 -0
  42. data/lib/cheftacular/stateless_actions/clean_server_passwords.rb +14 -0
  43. data/lib/cheftacular/stateless_actions/cleanup_log_files.rb +14 -0
  44. data/lib/cheftacular/stateless_actions/client_list.rb +89 -0
  45. data/lib/cheftacular/stateless_actions/cloud.rb +107 -0
  46. data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +109 -0
  47. data/lib/cheftacular/stateless_actions/compile_audit_log.rb +60 -0
  48. data/lib/cheftacular/stateless_actions/compile_readme.rb +41 -0
  49. data/lib/cheftacular/stateless_actions/create_git_key.rb +67 -0
  50. data/lib/cheftacular/stateless_actions/disk_report.rb +75 -0
  51. data/lib/cheftacular/stateless_actions/environment.rb +100 -0
  52. data/lib/cheftacular/stateless_actions/fetch_file.rb +24 -0
  53. data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +70 -0
  54. data/lib/cheftacular/stateless_actions/full_bootstrap.rb +30 -0
  55. data/lib/cheftacular/stateless_actions/get_active_ssh_connections.rb +18 -0
  56. data/lib/cheftacular/stateless_actions/get_haproxy_log.rb +55 -0
  57. data/lib/cheftacular/stateless_actions/get_log_from_bag.rb +38 -0
  58. data/lib/cheftacular/stateless_actions/get_pg_pass.rb +61 -0
  59. data/lib/cheftacular/stateless_actions/help.rb +71 -0
  60. data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +220 -0
  61. data/lib/cheftacular/stateless_actions/knife_upload.rb +23 -0
  62. data/lib/cheftacular/stateless_actions/pass.rb +49 -0
  63. data/lib/cheftacular/stateless_actions/reinitialize.rb +46 -0
  64. data/lib/cheftacular/stateless_actions/remove_client.rb +81 -0
  65. data/lib/cheftacular/stateless_actions/replication_status.rb +103 -0
  66. data/lib/cheftacular/stateless_actions/restart_swap.rb +55 -0
  67. data/lib/cheftacular/stateless_actions/rvm.rb +14 -0
  68. data/lib/cheftacular/stateless_actions/server_update.rb +99 -0
  69. data/lib/cheftacular/stateless_actions/service.rb +14 -0
  70. data/lib/cheftacular/stateless_actions/test_env.rb +82 -0
  71. data/lib/cheftacular/stateless_actions/update_split_branches.rb +64 -0
  72. data/lib/cheftacular/stateless_actions/update_tld.rb +62 -0
  73. data/lib/cheftacular/stateless_actions/upload_nodes.rb +120 -0
  74. data/lib/cheftacular/stateless_actions/upload_roles.rb +24 -0
  75. data/lib/cheftacular/version.rb +5 -0
  76. data/lib/cheftacular.rb +4 -0
  77. data/lib/cloud_interactor/authentication.rb +56 -0
  78. data/lib/cloud_interactor/cloud_interactor.rb +23 -0
  79. data/lib/cloud_interactor/domain/create.rb +17 -0
  80. data/lib/cloud_interactor/domain/create_record.rb +27 -0
  81. data/lib/cloud_interactor/domain/destroy.rb +17 -0
  82. data/lib/cloud_interactor/domain/destroy_record.rb +23 -0
  83. data/lib/cloud_interactor/domain/list.rb +9 -0
  84. data/lib/cloud_interactor/domain/list_records.rb +22 -0
  85. data/lib/cloud_interactor/domain/read.rb +23 -0
  86. data/lib/cloud_interactor/domain/read_record.rb +27 -0
  87. data/lib/cloud_interactor/domain/update.rb +18 -0
  88. data/lib/cloud_interactor/domain/update_record.rb +42 -0
  89. data/lib/cloud_interactor/domain.rb +18 -0
  90. data/lib/cloud_interactor/flavor.rb +27 -0
  91. data/lib/cloud_interactor/helpers.rb +70 -0
  92. data/lib/cloud_interactor/image.rb +27 -0
  93. data/lib/cloud_interactor/parser.rb +37 -0
  94. data/lib/cloud_interactor/server/attach_volume.rb +33 -0
  95. data/lib/cloud_interactor/server/create.rb +39 -0
  96. data/lib/cloud_interactor/server/destroy.rb +11 -0
  97. data/lib/cloud_interactor/server/detach_volume.rb +21 -0
  98. data/lib/cloud_interactor/server/list.rb +7 -0
  99. data/lib/cloud_interactor/server/list_volumes.rb +25 -0
  100. data/lib/cloud_interactor/server/poll.rb +22 -0
  101. data/lib/cloud_interactor/server/read.rb +9 -0
  102. data/lib/cloud_interactor/server/read_volume.rb +24 -0
  103. data/lib/cloud_interactor/server.rb +17 -0
  104. data/lib/cloud_interactor/version.rb +4 -0
  105. data/lib/cloud_interactor/volume/create.rb +13 -0
  106. data/lib/cloud_interactor/volume/destroy.rb +11 -0
  107. data/lib/cloud_interactor/volume/list.rb +7 -0
  108. data/lib/cloud_interactor/volume/read.rb +9 -0
  109. data/lib/cloud_interactor/volume.rb +20 -0
  110. data/lib/ridley/monkeypatches.rb +11 -0
  111. data/lib/sshkit/actions/start_commit_check.rb +19 -0
  112. data/lib/sshkit/actions/start_deploy.rb +25 -0
  113. data/lib/sshkit/actions/start_log_fetch.rb +91 -0
  114. data/lib/sshkit/actions/start_task.rb +29 -0
  115. data/lib/sshkit/getters.rb +67 -0
  116. data/lib/sshkit/helpers.rb +13 -0
  117. data/lib/sshkit/monkeypatches.rb +19 -0
  118. metadata +375 -0
@@ -0,0 +1,48 @@
1
+
2
+ class Cheftacular
3
+ class Encryptor
4
+ ALGORITHM = 'aes-256-cbc'
5
+
6
+ def initialize data_bag_secret
7
+ @data_bag_secret = data_bag_secret
8
+ end
9
+
10
+ def return_encrypted_hash hash
11
+ hash.each_pair do |key, value|
12
+ hash[key] = encrypt_data_for_databag(value) unless (key =~ /id/) == 0
13
+ end
14
+
15
+ hash
16
+ end
17
+
18
+ #https://github.com/opscode/chef/blob/master/lib/chef/encrypted_data_bag_item/encryptor.rb
19
+ def encrypt_data_for_databag string
20
+ encryptor = openssl_encryptor
21
+
22
+ {
23
+ "encrypted_data" => encrypt_string(string, encryptor),
24
+ "iv" => Base64.encode64(@iv),
25
+ "version" => 1,
26
+ "cipher" => ALGORITHM
27
+ }
28
+ end
29
+
30
+ def encrypt_string string, encryptor
31
+ enc_data = encryptor.update(FFI_Yajl::Encoder.encode(json_wrapper: string))
32
+ enc_data << encryptor.final
33
+
34
+ Base64.encode64(enc_data)
35
+ end
36
+
37
+ def openssl_encryptor
38
+ openssl_encryptor = begin
39
+ encryptor = OpenSSL::Cipher::Cipher.new(ALGORITHM)
40
+ encryptor.encrypt
41
+ @iv = encryptor.random_iv
42
+ encryptor.iv = @iv
43
+ encryptor.key = Digest::SHA256.digest(@data_bag_secret)
44
+ encryptor
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,153 @@
1
+
2
+ class Cheftacular
3
+ class Getter
4
+ def initialize options, config
5
+ @options, @config = options, config
6
+ end
7
+
8
+ def get_repository_from_role_name name, *args
9
+ @config['dummy_sshkit'].get_repository_from_role_name( name, @config['cheftacular']['repositories'], args )
10
+ end
11
+
12
+ #[TODO] if ridley changes its parsing strategy
13
+ def get_true_node_objects get_all_nodes=false, get_new_nodes=false
14
+ nodes, all_nodes, names, iter_arr, file_cache_nodes, h = [],[],[],[],[],{}
15
+
16
+ @config['chef_nodes'] = @config['ridley'].node.all
17
+
18
+ @config['helper'].completion_rate? 0, __method__
19
+
20
+ file_cache_nodes = @config['helper'].check_nodes_file_cache if @config['helper'].compare_file_node_cache_against_chef_nodes('equal')
21
+
22
+ @config['chef_nodes'].each do |n|
23
+ true_obj = if !file_cache_nodes.empty? && @config['parser'].array_of_nodes_contains_node_name?(file_cache_nodes, n.name)
24
+ file_cache_nodes[@config['parser'].index_of_node_name_in_array_of_nodes(file_cache_nodes, n.name)]
25
+ else
26
+ @config['helper'].cleanup_file_caches('current')
27
+
28
+ @config['ridley'].node.find(n.name)
29
+ end
30
+
31
+ iter_arr << n.name
32
+
33
+ progress_value = (( iter_arr.length.to_f/@config['chef_nodes'].length.to_f )*100 ).floor
34
+
35
+ @config['helper'].completion_rate? progress_value, __method__
36
+
37
+ all_nodes << true_obj
38
+
39
+ next if !get_all_nodes && true_obj.chef_environment != @options['env'] && true_obj.chef_environment != '_default'
40
+
41
+ if get_all_nodes
42
+ h[n.name] = true_obj
43
+ names << n.name
44
+
45
+ next
46
+ end
47
+
48
+ if @options['role'] == 'all'
49
+ next if true_obj.chef_environment == '_default'
50
+
51
+ h[n.name] = true_obj
52
+ names << n.name
53
+
54
+ next
55
+ end
56
+
57
+ if @options['node_name'] && true_obj.name == @options['node_name']
58
+ h[n.name] = true_obj
59
+ names << n.name
60
+
61
+ next
62
+ end
63
+
64
+ if @options['address'] && true_obj.public_ipaddress == @options['address']
65
+ h[n.name] = true_obj
66
+ names << n.name
67
+
68
+ next
69
+ end
70
+
71
+ unless ( @options['address'] || @options['node_name'] )
72
+ if true_obj.run_list.include?("role[#{ @options['role'] }]")
73
+ h[n.name] = true_obj
74
+ names << n.name
75
+
76
+ next #not needed here but good to keep in mind
77
+ end
78
+ end
79
+ end
80
+
81
+ names.sort.each { |name| nodes << h[name] }
82
+
83
+ @config['helper'].write_nodes_file_cache(all_nodes) unless @config['helper'].compare_file_node_cache_against_chef_nodes('equal')
84
+
85
+ puts("") unless @options['quiet']
86
+
87
+ nodes
88
+ end
89
+
90
+ def get_current_stack
91
+ get_current_repo_config['stack']
92
+ end
93
+
94
+ def get_current_database
95
+ get_current_repo_config['database']
96
+ end
97
+
98
+ def get_current_repo_config
99
+ if @config['cheftacular']['repositories'].has_key?(@options['role'])
100
+ @config['cheftacular']['repositories'][@options['role']]
101
+ else
102
+ @options['role']
103
+ end
104
+ end
105
+
106
+ def get_current_role_map ret=""
107
+ @config['cheftacular']['role_maps'].each_pair do |main_role, role_hash|
108
+ ret = role_hash if role_hash['role_name'] == @options['role']
109
+ end
110
+
111
+ ret
112
+ end
113
+
114
+ def get_addresses_hash env='staging', ret_hash={}
115
+ @config[env]['addresses_bag_hash']['addresses'].each do |serv_hash|
116
+ ret_hash[serv_hash['public']] = { "dn" => serv_hash['dn'], "priv" => serv_hash['address'], "pub" => serv_hash['public'] }
117
+
118
+ end if @config[env].has_key?('addresses_bag_hash')
119
+
120
+ ret_hash
121
+ end
122
+
123
+ def get_split_branch_hash ret={}
124
+ @config['cheftacular']['repositories'].each_pair do |name, repo_hash|
125
+ ret[repo_hash['name']] = repo_hash if repo_hash.has_key?('has_split_branches') && repo_hash['has_split_branches'] == 'true'
126
+ end
127
+
128
+ ret
129
+ end
130
+
131
+ def get_address_hash node_name, ret={}
132
+ @config['chef_environments'].each do |env|
133
+ next unless @config.has_key?(env) #in case the env hashes are not loaded
134
+
135
+ @config[env]['addresses_bag_hash']['addresses'].each do |serv_hash|
136
+ ret[serv_hash['name']] = { "dn" => serv_hash['dn'], "priv" => serv_hash['address'], "pub" => serv_hash['public'] } if serv_hash['name'] == node_name
137
+ end
138
+ end
139
+
140
+ ret
141
+ end
142
+
143
+ def get_repo_names_for_repositories ret={}
144
+ @config['cheftacular']['repositories'].each_pair do |name, repo_hash|
145
+ ret[repo_hash['repo_name']] = repo_hash
146
+
147
+ ret[repo_hash['repo_name']]['role'] = name
148
+ end
149
+
150
+ ret
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,296 @@
1
+
2
+ class Cheftacular
3
+ class Helper
4
+ def initialize options, config
5
+ @options, @config = options, config
6
+ end
7
+
8
+ def declassify
9
+ #(self.class::TRUENAME.constantize).to_s.underscore.dasherize
10
+ Cheftacular.to_s.underscore.dasherize
11
+ end
12
+
13
+ #[TODO] Refactor to more accurate solution
14
+ def running_in_gem?
15
+ File.expand_path('.', __FILE__).split('/').include?('.rvm') ||
16
+ (File.exist?(File.expand_path("#{ Dir.getwd }/.ruby-gemset")) &&
17
+ File.read(File.expand_path("#{ Dir.getwd }/.ruby-gemset")) != 'hiplogiq-deploy')
18
+ end
19
+
20
+ #TODO add command check
21
+ def is_command? command
22
+ @config['action'].public_methods(false).include?(command.to_sym)
23
+ end
24
+
25
+ def is_stateless_command? command
26
+ @config['stateless_action'].public_methods(false).include?(command.to_sym)
27
+ end
28
+
29
+ def is_not_command_or_stateless_command? command
30
+ !@config['action'].public_methods(false).include?(command.to_sym) && !@config['stateless_action'].public_methods(false).include?(command.to_sym)
31
+ end
32
+
33
+ #[TODO] Refactor to running_on_chef_node?
34
+ def running_on_chef_node?
35
+ Dir.entries('/etc').include?('chef')
36
+ rescue StandardError => e
37
+ exception_output "An error occurred while trying to see if this system is a chef node. Assuming the system is not a chef node.", e, false
38
+ end
39
+
40
+ def running_in_mode? mode
41
+ @config['cheftacular']['mode'] == mode
42
+ end
43
+
44
+ def fetch_remote_version
45
+ puts "Checking remote #{ declassify } version..."
46
+
47
+ `gem list #{ declassify } --remote`[/(\d+\.\d+\.\d+)/]
48
+ end
49
+
50
+ def is_junk_filename? filename
51
+ filename =~ /.DS_Store|.com.apple.timemachine.supported|README.*/ || filename == '.' || filename == '..' && File.directory?(filename)
52
+ end
53
+
54
+ def completion_rate? percent, mode
55
+ case mode.to_s
56
+ when 'initializer' then print("Fetching initialization chef data for #{ @options['env'] }....0%") if !@options['quiet'] && percent == 0
57
+ when 'get_true_node_objects' then print("Retrieving node data from chef server for #{ @config['chef_nodes'].count } nodes....0%") if !@options['quiet'] && percent == 0
58
+ end
59
+
60
+ case percent
61
+ when 1..9 then print("\b\b#{ percent.to_i }%") unless @options['quiet']
62
+ when 10..99 then print("\b\b\b#{ percent.to_i }%") unless @options['quiet']
63
+ when 100 then print("\b\b\b\b#{ percent.to_i }%\n") unless @options['quiet']
64
+ end
65
+ end
66
+
67
+ def display_readme option="", out=""
68
+ puts File.read(File.expand_path('../README.md', __FILE__))
69
+ end
70
+
71
+ def gen_pass length=20, mode="truepass"
72
+ lowercase = 'a'..'z'
73
+ uppercase = 'A'..'Z'
74
+ numbers = 0..9
75
+
76
+ length = @config['cheftacular']['server_pass_length'] if length.to_i <= @config['cheftacular']['server_pass_length']
77
+
78
+ sets = case mode
79
+ when "truepass" then [lowercase, uppercase, numbers]
80
+ when "numsonly" then [numbers]
81
+ when "lowernum" then [lowercase, numbers]
82
+ when "uppernum" then [uppercase, numbers]
83
+ when "lowercase" then [lowercase]
84
+ when "uppercase" then [uppercase]
85
+ end
86
+
87
+ o = sets.flatten.map { |i| i.to_a }.flatten
88
+
89
+ (0...length.to_i).map { o[rand(o.length)] }.join
90
+ end
91
+
92
+ def set_location_if_app ret=""
93
+ if get_codebase_from_role_name(Dir.getwd.split('/').last, "has_key?")
94
+ ret = Dir.getwd.split('/').last
95
+ end
96
+
97
+ ret
98
+ end
99
+
100
+ def sudo ip_address
101
+ "echo #{ @config['server_passwords'][ip_address] } | sudo -S"
102
+ end
103
+
104
+ def output_run_stats
105
+ puts("\nDone in #{ Time.now - @config['start_time'] } seconds at #{ Time.now.strftime('%Y-%m-%d %l:%M:%S %P') }.") unless @options['quiet']
106
+ end
107
+
108
+ def write_version_file version
109
+ File.open( current_version_file_path, "w") { |f| f.write(version) }
110
+ end
111
+
112
+ def set_local_instance_vars
113
+ [
114
+ @options,
115
+ @config['locs'],
116
+ @config['ridley'],
117
+ @config[@options['env']]['logs_bag_hash'],
118
+ @config[@options['env']]['chef_passwords_bag_hash'],
119
+ @config['bundle_command'],
120
+ @config['cheftacular'],
121
+ @config['server_passwords']
122
+ ]
123
+ end
124
+
125
+ def exception_output message, exception='', exit_on_call=true, suppress_error_output=false
126
+ puts "#{ message }\n"
127
+
128
+ puts("Error message: #{ exception }\n#{ exception.backtrace.join("\n") }") unless suppress_error_output
129
+
130
+ exit if exit_on_call
131
+ end
132
+
133
+ def write_nodes_file_cache nodes
134
+ nodes.each do |node|
135
+ File.open( File.join( current_nodes_file_cache_path, "#{ node.name }.json"), "w") { |f| f.write(node.to_json) }
136
+ end
137
+ end
138
+
139
+ def check_nodes_file_cache nodes=[]
140
+ Dir.entries(current_nodes_file_cache_path).each do |location|
141
+ next if is_junk_filename?(location)
142
+
143
+ nodes << @config['ridley'].node.from_file("#{ current_nodes_file_cache_path }/#{ location }" )
144
+ end
145
+
146
+ nodes
147
+ end
148
+
149
+ def current_version_file_path
150
+ current_file_path 'version-check.txt'
151
+ end
152
+
153
+ def current_audit_file_path
154
+ current_file_path 'audit-check.txt'
155
+ end
156
+
157
+ def compare_file_node_cache_against_chef_nodes mode='include?'
158
+ chef_server_names, nodes_file_cache_names = [],[]
159
+ included = true
160
+
161
+ @config['chef_nodes'].each { |node| chef_server_names << node.name }
162
+
163
+ check_nodes_file_cache.each { |node| nodes_file_cache_names << node.name }
164
+
165
+ nodes_file_cache_names.each do |node_name|
166
+ unless chef_server_names.include?(node_name)
167
+ included = false
168
+
169
+ break
170
+ end
171
+ end
172
+
173
+ case mode
174
+ when 'include?' then return included
175
+ when 'not_equal' then return check_nodes_file_cache.count != names.count
176
+ when 'equal' then return chef_server_names.sort == nodes_file_cache_names.sort
177
+ end
178
+ end
179
+
180
+ def is_higher_version? vstr1, vstr2
181
+ Gem::Version.new(vstr1) > Gem::Version.new(vstr2)
182
+ end
183
+
184
+ def set_log_loc_and_timestamp
185
+ @config['dummy_sshkit'].set_log_loc_and_timestamp @config['locs']
186
+ end
187
+
188
+ def knife_bootstrap_command
189
+ address = @options['address']
190
+ user = @config['cheftacular']['deploy_user']
191
+ password = @config['server_passwords'][@options['address']]
192
+ nodename = @options['node_name']
193
+ chef_ver = @config['cheftacular']['chef_client_version']
194
+
195
+ "knife bootstrap #{ address } -x #{ user } -P #{ password } -N #{ nodename } --sudo --use-sudo-password --bootstrap-version #{ chef_ver }"
196
+ end
197
+
198
+ #the documentation hashes must be populated *before* this method runs for it to return anything!
199
+ def compile_documentation_lines mode, out=[]
200
+ doc_arr = case mode
201
+ when 'action' then @config['documentation']['action']
202
+ when 'application' then @config['documentation']['action'] + @config['documentation']['application']
203
+ when 'stateless_action' then @config['documentation']['stateless_action']
204
+ when 'devops' then @config['documentation']['action'] + @config['documentation']['stateless_action']
205
+ end
206
+
207
+ count = 1
208
+
209
+ doc_arr.sort {|a, b| a[0] <=> b[0]}.flatten(1).each do |line|
210
+
211
+ out << "#{ count }. #{ line }" if line.class.to_s == 'String'
212
+
213
+ out << line if line.class.to_s == 'Array'
214
+
215
+ count += 1 if line.class.to_s == 'String'
216
+
217
+ #puts("#{ out[out.index("#{ count }. #{ line }")] }::#{ line.class }::#{ count }\n") unless line.class.to_s == 'Array'
218
+ end
219
+
220
+ out
221
+ end
222
+
223
+ #compares how close str1 is to str2
224
+ def compare_strings str1, str2
225
+ str1_chars = str1.split('').uniq
226
+ str2_chars = str2.split('').uniq
227
+
228
+ ((str1_chars + str2_chars).uniq.length * 1.0) / (str1_chars.length + str2_chars.length)
229
+ end
230
+
231
+ def set_cloud_options
232
+ @options['preferred_cloud'] = @options['preferred_cloud'].nil? ? @config['cheftacular']['preferred_cloud'] : @options['preferred_cloud']
233
+ @options['preferred_cloud_image'] = @options['preferred_cloud_image'].nil? ? @config['cheftacular']['preferred_cloud_image'] : @options['preferred_cloud_image']
234
+ @options['preferred_cloud_region'] = @options['preferred_cloud_region'].nil? ? @config['cheftacular']['preferred_cloud_region'] : @options['preferred_cloud_region']
235
+ @options['virtualization_mode'] = @options['virtualization_mode'].nil? ? @config['cheftacular']['virtualization_mode'] : @options['virtualization_mode']
236
+ end
237
+
238
+ def current_nodes_file_cache_path
239
+ current_file_path 'node_cache'
240
+ end
241
+
242
+ def cleanup_file_caches mode='old'
243
+ base_dir = File.join( @config['locs']['app-root'], 'tmp', declassify )
244
+
245
+ Dir.entries(base_dir).each do |entry|
246
+ next if is_junk_filename?(entry)
247
+
248
+ case mode
249
+ when 'old'
250
+ FileUtils.rm("#{ base_dir }/#{ entry }") if File.file?("#{ base_dir }/#{ entry }") && !entry.include?(Time.now.strftime("%Y%m%d"))
251
+
252
+ check_current_day_entry = false
253
+ when 'current'
254
+ check_current_day_entry = true
255
+ end
256
+
257
+
258
+ if File.exists?("#{ base_dir }/#{ entry }") && File.directory?("#{ base_dir }/#{ entry }")
259
+ FileUtils.rm_rf("#{ base_dir }/#{ entry }") if !check_current_day_entry && !entry.include?(Time.now.strftime("%Y%m%d"))
260
+
261
+ FileUtils.rm_rf("#{ base_dir }/#{ entry }") if check_current_day_entry && entry.include?(Time.now.strftime("%Y%m%d"))
262
+
263
+ FileUtils.mkdir_p @config['helper'].current_nodes_file_cache_path
264
+ end
265
+ end
266
+ end
267
+
268
+ def remove_current_file_node_cache
269
+ base_dir = File.join( @config['locs']['app-root'], 'tmp', declassify )
270
+
271
+ Dir.entries(base_dir).each do |entry|
272
+ next if is_junk_filename?(entry)
273
+
274
+ FileUtils.rm_rf("#{ base_dir }/#{ entry }") if File.directory?("#{ base_dir }/#{ entry }") && entry.include?(Time.now.strftime("%Y%m%d"))
275
+ end
276
+ end
277
+
278
+ private
279
+ def current_file_path file_name
280
+ File.join( @config['locs']['app-root'], 'tmp', declassify, "#{ Time.now.strftime("%Y%m%d") }-#{ file_name }")
281
+ end
282
+ end
283
+ end
284
+
285
+ class String
286
+ def scrub_pretty_text
287
+ self.gsub("",'').gsub(/\[0m|\[1m|\[32m|\[35m|\[36m/,'')
288
+ end
289
+ end
290
+
291
+ class Fixnum
292
+ def digits(base = 10)
293
+ quotient, remainder = divmod(base)
294
+ (quotient > 0 ? quotient.digits : []) + [remainder]
295
+ end
296
+ end