cheftacular 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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