cheftacular 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cheftacular/README.md +155 -63
- data/lib/cheftacular/actions/db_console.rb +3 -3
- data/lib/cheftacular/actions/deploy.rb +18 -12
- data/lib/cheftacular/actions/migrate.rb +1 -1
- data/lib/cheftacular/actions/tail.rb +1 -1
- data/lib/cheftacular/auditor.rb +14 -6
- data/lib/cheftacular/chef/data_bag.rb +1 -4
- data/lib/cheftacular/cheftacular.rb +19 -15
- data/lib/cheftacular/cloud_provider.rb +32 -0
- data/lib/cheftacular/dns.rb +1 -1
- data/lib/cheftacular/error.rb +13 -2
- data/lib/cheftacular/file_system.rb +122 -0
- data/lib/cheftacular/files/rvm.sh +55 -0
- data/lib/cheftacular/getter.rb +10 -3
- data/lib/cheftacular/helper.rb +31 -127
- data/lib/cheftacular/initialization_action.rb +8 -0
- data/lib/cheftacular/initializer.rb +104 -44
- data/lib/cheftacular/parser.rb +6 -0
- data/lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb +2 -2
- data/lib/cheftacular/stateless_actions/arguments.rb +9 -2
- data/lib/cheftacular/stateless_actions/backups.rb +1 -1
- data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +16 -5
- data/lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb +79 -0
- data/lib/cheftacular/stateless_actions/chef_bootstrap.rb +20 -4
- data/lib/cheftacular/stateless_actions/chef_server.rb +78 -0
- data/lib/cheftacular/stateless_actions/clean_cookbooks.rb +3 -3
- data/lib/cheftacular/stateless_actions/clean_server_passwords.rb +3 -1
- data/lib/cheftacular/stateless_actions/cleanup_log_files.rb +1 -0
- data/lib/cheftacular/stateless_actions/client_list.rb +2 -2
- data/lib/cheftacular/stateless_actions/cloud.rb +30 -2
- data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +7 -13
- data/lib/cheftacular/stateless_actions/compile_audit_log.rb +1 -1
- data/lib/cheftacular/stateless_actions/create_git_key.rb +3 -1
- data/lib/cheftacular/stateless_actions/environment.rb +2 -0
- data/lib/cheftacular/stateless_actions/file.rb +4 -2
- data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +2 -1
- data/lib/cheftacular/stateless_actions/full_bootstrap.rb +2 -0
- data/lib/cheftacular/stateless_actions/get_active_ssh_connections.rb +1 -1
- data/lib/cheftacular/stateless_actions/help.rb +9 -7
- data/lib/cheftacular/stateless_actions/initialize_cheftacular_yml.rb +29 -0
- data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +5 -36
- data/lib/cheftacular/stateless_actions/list_toggleable_roles.rb +45 -0
- data/lib/cheftacular/stateless_actions/location_aliases.rb +24 -0
- data/lib/cheftacular/stateless_actions/pass.rb +4 -4
- data/lib/cheftacular/stateless_actions/reinitialize.rb +0 -6
- data/lib/cheftacular/stateless_actions/remove_client.rb +12 -7
- data/lib/cheftacular/stateless_actions/role_toggle.rb +141 -0
- data/lib/cheftacular/stateless_actions/server_update.rb +2 -2
- data/lib/cheftacular/stateless_actions/update_chef_client.rb +18 -0
- data/lib/cheftacular/stateless_actions/upload_nodes.rb +5 -3
- data/lib/cheftacular/stateless_actions/upload_roles.rb +1 -1
- data/lib/cheftacular/version.rb +1 -1
- data/lib/cloud_interactor/authentication.rb +78 -40
- data/lib/cloud_interactor/cloud_interactor.rb +4 -1
- data/lib/cloud_interactor/cloud_provider.rb +19 -0
- data/lib/cloud_interactor/domain/create.rb +1 -1
- data/lib/cloud_interactor/domain/create_record.rb +1 -1
- data/lib/cloud_interactor/domain/destroy_record.rb +1 -1
- data/lib/cloud_interactor/domain/list_records.rb +1 -1
- data/lib/cloud_interactor/domain/update.rb +1 -1
- data/lib/cloud_interactor/domain/update_record.rb +6 -6
- data/lib/cloud_interactor/helpers.rb +1 -1
- data/lib/cloud_interactor/parser.rb +3 -2
- data/lib/cloud_interactor/region.rb +27 -0
- data/lib/cloud_interactor/server/create.rb +9 -0
- data/lib/cloud_interactor/sshkey.rb +59 -0
- data/lib/ridley/monkeypatches.rb +12 -0
- data/lib/sshkit/actions/start_task.rb +8 -2
- metadata +16 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'ridley'
|
1
|
+
require 'ridley'
|
2
2
|
require 'highline/import'
|
3
3
|
require 'optparse'
|
4
4
|
require 'base64'
|
@@ -21,32 +21,36 @@ require 'net/http'
|
|
21
21
|
require 'timeout'
|
22
22
|
require 'slack-notifier'
|
23
23
|
require 'cloudflare'
|
24
|
-
require 'zlib'
|
25
24
|
require 'csv'
|
26
25
|
|
27
26
|
Dir["#{File.dirname(__FILE__)}/../**/*.rb"].each { |f| require f }
|
28
27
|
|
29
28
|
class Cheftacular
|
30
29
|
def initialize options={'env'=>'staging'}, config={}
|
31
|
-
@options, @config
|
30
|
+
@options, @config = options, config
|
31
|
+
SSHKit.config.format = :blackhole
|
32
|
+
#Fog::Logger[:warning] = nil
|
33
|
+
@config['start_time'] = Time.now
|
34
|
+
@config['helper'] = Helper.new(@options, @config)
|
35
|
+
@config['initialization_action'] = InitializationAction.new(@options, @config)
|
36
|
+
@config['filesystem'] = Cheftacular::FileSystem.new(@options, @config)
|
37
|
+
@config['initializer'] = Initializer.new(@options, @config)
|
32
38
|
|
33
|
-
|
39
|
+
if @config['helper'].is_initialization_command?(ARGV[0])
|
40
|
+
@options['command'] = ARGV[0] #this is normally set by parse_context but that is not run for initialization commands
|
41
|
+
else
|
42
|
+
@config['stateless_action'].initialize_data_bag_contents(@options['env']) #ensure basic structure are always maintained before each run
|
34
43
|
|
35
|
-
|
44
|
+
@config['parser'].parse_application_context if @config['cheftacular']['mode'] == 'application'
|
36
45
|
|
37
|
-
|
46
|
+
@config['parser'].parse_context
|
38
47
|
|
39
|
-
|
48
|
+
puts("Preparing to run command \"#{ @options['command'] }\"...") if @options['verbose']
|
40
49
|
|
41
|
-
|
50
|
+
@config['auditor'].audit_run if @config['cheftacular']['auditing']
|
51
|
+
end
|
42
52
|
|
43
|
-
@config['
|
44
|
-
|
45
|
-
@config['parser'].parse_context
|
46
|
-
|
47
|
-
puts("Preparing to run command \"#{ @options['command'] }\"...") if @options['verbose']
|
48
|
-
|
49
|
-
@config['auditor'].audit_run if @config['cheftacular']['auditing']
|
53
|
+
@config['stateless_action'].send('check_cheftacular_yml_keys')
|
50
54
|
|
51
55
|
@config['action'].send(@options['command']) if @config['helper'].is_command?(@options['command'])
|
52
56
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#This class will store any specific differences cheftacular will run into for different providers, usually via the cloud_bootstrap command
|
2
|
+
class Cheftacular
|
3
|
+
class CloudProvider
|
4
|
+
def initialize options, config
|
5
|
+
@options, @config = options, config
|
6
|
+
end
|
7
|
+
|
8
|
+
#public address, private address
|
9
|
+
def parse_addresses_from_server_create_hash server_hash
|
10
|
+
case @options['preferred_cloud']
|
11
|
+
when 'rackspace'
|
12
|
+
[server_hash['ipv4_address'], server_hash['addresses']['private'][0]['addr']]
|
13
|
+
when 'digitalocean'
|
14
|
+
[server_hash['public_ip_address'], server_hash['private_ip_address']]
|
15
|
+
else raise "CRITICAL! Encountered unsupported preferred cloud #{ @options['preferred_cloud'] }"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse_server_root_password_from_server_create_hash server_hash, real_node_name
|
20
|
+
case @options['preferred_cloud']
|
21
|
+
when 'rackspace'
|
22
|
+
begin
|
23
|
+
server_hash['admin_passwords']["#{ real_node_name }"]
|
24
|
+
rescue NoMethodError => e
|
25
|
+
raise "Unable to locate an admin pass for server #{ @options['node_name'] }, does the server already exist?"
|
26
|
+
end
|
27
|
+
when 'digitalocean' #we use sshkey authentication for initial server create for digitalocean
|
28
|
+
else raise "CRITICAL! Encountered unsupported preferred cloud #{ @options['preferred_cloud'] }"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/cheftacular/dns.rb
CHANGED
@@ -255,7 +255,7 @@ class Cheftacular
|
|
255
255
|
|
256
256
|
next
|
257
257
|
else
|
258
|
-
@config['
|
258
|
+
@config['error'].exception_output "There was an issue updating Cloudflare! Please create an issue on the cheftacular repository with this stacktrace!", e
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
data/lib/cheftacular/error.rb
CHANGED
@@ -5,16 +5,27 @@ class Cheftacular
|
|
5
5
|
@options, @config = options, config
|
6
6
|
end
|
7
7
|
|
8
|
-
def is_valid_node_name_option?
|
8
|
+
def is_valid_node_name_option? strict_env=false
|
9
9
|
raise "Too few arguments, please supply a node name" if @options['node_name'].nil?
|
10
10
|
|
11
11
|
nodes = @config['getter'].get_true_node_objects(true)
|
12
12
|
|
13
|
-
|
13
|
+
exclusion_args = [{ if: { not_node: @options["node_name"] } }]
|
14
|
+
exclusion_args << { if: { not_env: @options['env'] } } if strict_env
|
15
|
+
|
16
|
+
nodes = @config['parser'].exclude_nodes( nodes, exclusion_args, true )
|
14
17
|
|
15
18
|
raise "Node not found for #{ @options['node_name'] }" if nodes.empty?
|
16
19
|
|
17
20
|
nodes
|
18
21
|
end
|
22
|
+
|
23
|
+
def exception_output message, exception='', exit_on_call=true, suppress_error_output=false
|
24
|
+
puts "#{ message }\n"
|
25
|
+
|
26
|
+
puts("Error message: #{ exception }\n#{ exception.backtrace.join("\n") }") unless suppress_error_output
|
27
|
+
|
28
|
+
exit if exit_on_call
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
class Cheftacular
|
2
|
+
class FileSystem
|
3
|
+
def initialize options, config
|
4
|
+
@options, @config = options, config
|
5
|
+
end
|
6
|
+
|
7
|
+
def write_version_file version
|
8
|
+
File.open( current_version_file_path, "w") { |f| f.write(version) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def write_nodes_file_cache nodes
|
12
|
+
nodes.each do |node|
|
13
|
+
File.open( File.join( current_nodes_file_cache_path, "#{ node.name }.json"), "w") { |f| f.write(node.to_json) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_nodes_file_cache nodes=[]
|
18
|
+
Dir.entries(current_nodes_file_cache_path).each do |location|
|
19
|
+
next if is_junk_filename?(location)
|
20
|
+
|
21
|
+
nodes << @config['ridley'].node.from_file("#{ current_nodes_file_cache_path }/#{ location }" )
|
22
|
+
end
|
23
|
+
|
24
|
+
nodes
|
25
|
+
end
|
26
|
+
|
27
|
+
def current_version_file_path
|
28
|
+
current_file_path 'version-check.txt'
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_audit_file_path
|
32
|
+
current_file_path 'audit-check.txt'
|
33
|
+
end
|
34
|
+
|
35
|
+
def is_junk_filename? filename
|
36
|
+
filename =~ /.DS_Store|.com.apple.timemachine.supported|README.*/ || filename == '.' || filename == '..' && File.directory?(filename)
|
37
|
+
end
|
38
|
+
|
39
|
+
def compare_file_node_cache_against_chef_nodes mode='include?'
|
40
|
+
chef_server_names, nodes_file_cache_names = [],[]
|
41
|
+
included = true
|
42
|
+
|
43
|
+
@config['chef_nodes'].each { |node| chef_server_names << node.name }
|
44
|
+
|
45
|
+
check_nodes_file_cache.each { |node| nodes_file_cache_names << node.name }
|
46
|
+
|
47
|
+
nodes_file_cache_names.each do |node_name|
|
48
|
+
unless chef_server_names.include?(node_name)
|
49
|
+
included = false
|
50
|
+
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
case mode
|
56
|
+
when 'include?' then return included
|
57
|
+
when 'not_equal' then return check_nodes_file_cache.count != names.count
|
58
|
+
when 'equal' then return chef_server_names.sort == nodes_file_cache_names.sort
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def current_nodes_file_cache_path
|
63
|
+
current_file_path 'node_cache'
|
64
|
+
end
|
65
|
+
|
66
|
+
def cleanup_file_caches mode='old', check_current_day_entry=false
|
67
|
+
base_dir = File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify )
|
68
|
+
|
69
|
+
Dir.entries(base_dir).each do |entry|
|
70
|
+
next if is_junk_filename?(entry)
|
71
|
+
|
72
|
+
case mode
|
73
|
+
when 'old'
|
74
|
+
FileUtils.rm("#{ base_dir }/#{ entry }") if File.file?("#{ base_dir }/#{ entry }") && !entry.include?(Time.now.strftime("%Y%m%d"))
|
75
|
+
when 'current'
|
76
|
+
check_current_day_entry = true
|
77
|
+
when 'current-audit-only'
|
78
|
+
FileUtils.rm("#{ base_dir }/#{ entry }") if File.file?("#{ base_dir }/#{ entry }") && entry.include?(Time.now.strftime("%Y%m%d"))
|
79
|
+
end
|
80
|
+
|
81
|
+
if File.exists?("#{ base_dir }/#{ entry }") && File.directory?("#{ base_dir }/#{ entry }")
|
82
|
+
FileUtils.rm_rf("#{ base_dir }/#{ entry }") if !check_current_day_entry && !entry.include?(Time.now.strftime("%Y%m%d"))
|
83
|
+
|
84
|
+
FileUtils.rm_rf("#{ base_dir }/#{ entry }") if check_current_day_entry && entry.include?(Time.now.strftime("%Y%m%d"))
|
85
|
+
|
86
|
+
FileUtils.mkdir_p current_nodes_file_cache_path
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def remove_current_file_node_cache
|
92
|
+
base_dir = File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify )
|
93
|
+
|
94
|
+
Dir.entries(base_dir).each do |entry|
|
95
|
+
next if is_junk_filename?(entry)
|
96
|
+
|
97
|
+
FileUtils.rm_rf("#{ base_dir }/#{ entry }") if File.directory?("#{ base_dir }/#{ entry }") && entry.include?(Time.now.strftime("%Y%m%d"))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def current_chef_repo_cheftacular_file_cache_path
|
102
|
+
current_file_path "chef_repo_cheftacular_cache"
|
103
|
+
end
|
104
|
+
|
105
|
+
def write_chef_repo_cheftacular_cache_file hash
|
106
|
+
File.open( current_chef_repo_cheftacular_file_cache_path, "w") { |f| f.write(hash) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def write_chef_repo_cheftacular_yml_file file_location
|
110
|
+
File.open( file_location, "w") { |f| f.write(@config['helper'].compile_chef_repo_cheftacular_yml_as_hash.to_yaml) }
|
111
|
+
end
|
112
|
+
|
113
|
+
def write_config_cheftacular_yml_file filename='cheftacular.yml'
|
114
|
+
File.open( File.join(@config['locs']['chef-repo'], "config", filename), "w") { |f| f.write(File.read(File.join(@config['locs']['examples'], "cheftacular.yml"))) }
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def current_file_path file_name
|
119
|
+
File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify, "#{ Time.now.strftime("%Y%m%d") }-#{ file_name }")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
#
|
4
|
+
# RVM profile
|
5
|
+
#
|
6
|
+
# /etc/profile.d/rvm.sh # sh extension required for loading.
|
7
|
+
#
|
8
|
+
if [ -n "${BASH_VERSION:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
9
|
+
|
10
|
+
# Load user rvmrc configurations, if exist
|
11
|
+
for file in /etc/rvmrc "$HOME/.rvmrc" ; do
|
12
|
+
[[ -s "$file" ]] && source $file
|
13
|
+
done
|
14
|
+
|
15
|
+
# Load RVM if it is installed, try user then root install.
|
16
|
+
if [[ -s "$rvm_path/scripts/rvm" ]] ; then
|
17
|
+
source "$rvm_path/scripts/rvm"
|
18
|
+
|
19
|
+
elif [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
|
20
|
+
true ${rvm_path:="$HOME/.rvm"}
|
21
|
+
source "$HOME/.rvm/scripts/rvm"
|
22
|
+
|
23
|
+
elif [[ -s "/home/deploy/.rvm/scripts/rvm" ]] ; then
|
24
|
+
true ${rvm_path:="/usr/local/rvm/scripts/rvm"}
|
25
|
+
source "/usr/local/rvm/scripts/rvm"
|
26
|
+
fi
|
27
|
+
|
28
|
+
#
|
29
|
+
# Opt-in for custom prompt through by setting:
|
30
|
+
#
|
31
|
+
# rvm_ps1=1
|
32
|
+
#
|
33
|
+
# in either /etc/rvmrc or $HOME/.rvmrc
|
34
|
+
#
|
35
|
+
if [[ ${rvm_ps1:-0} -eq 1 ]] ; then
|
36
|
+
# Source RVM ps1 functions for a great prompt.
|
37
|
+
if [[ -s "$rvm_path/contrib/ps1_functions" ]] ; then
|
38
|
+
source "$rvm_path/contrib/ps1_functions"
|
39
|
+
elif [[ -s "/usr/local/rvm/contrib/ps1_functions" ]] ; then
|
40
|
+
source "/usr/local/rvm/contrib/ps1_functions"
|
41
|
+
fi
|
42
|
+
|
43
|
+
if command -v ps1_set >/dev/null 2>&1 ; then
|
44
|
+
ps1_set
|
45
|
+
fi
|
46
|
+
fi
|
47
|
+
|
48
|
+
# Add /usr/local/rvm/bin to /bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/opt/java/bin:/opt/java/jre/bin:/usr/lib/perl5/core_perl/bin:/usr/local/rvm/bin:/usr/local/rvm/bin in necessary
|
49
|
+
if [[ "${rvm_bin_path}" != "${rvm_path}/bin" ]] ; then
|
50
|
+
regex="^([^:]*:)*${rvm_bin_path}(:[^:]*)*$"
|
51
|
+
if [[ ! "${PATH}" =~ $regex ]] ; then
|
52
|
+
export PATH="${rvm_bin_path}:${PATH}"
|
53
|
+
fi
|
54
|
+
fi
|
55
|
+
fi
|
data/lib/cheftacular/getter.rb
CHANGED
@@ -17,13 +17,13 @@ class Cheftacular
|
|
17
17
|
|
18
18
|
@config['helper'].completion_rate? 0, __method__
|
19
19
|
|
20
|
-
file_cache_nodes = @config['
|
20
|
+
file_cache_nodes = @config['filesystem'].check_nodes_file_cache if @config['filesystem'].compare_file_node_cache_against_chef_nodes('equal')
|
21
21
|
|
22
22
|
@config['chef_nodes'].each do |n|
|
23
23
|
true_obj = if !file_cache_nodes.empty? && @config['parser'].array_of_nodes_contains_node_name?(file_cache_nodes, n.name)
|
24
24
|
file_cache_nodes[@config['parser'].index_of_node_name_in_array_of_nodes(file_cache_nodes, n.name)]
|
25
25
|
else
|
26
|
-
@config['
|
26
|
+
@config['filesystem'].cleanup_file_caches('current')
|
27
27
|
|
28
28
|
@config['ridley'].node.find(n.name)
|
29
29
|
end
|
@@ -80,7 +80,7 @@ class Cheftacular
|
|
80
80
|
|
81
81
|
names.sort.each { |name| nodes << h[name] }
|
82
82
|
|
83
|
-
@config['
|
83
|
+
@config['filesystem'].write_nodes_file_cache(all_nodes) unless @config['filesystem'].compare_file_node_cache_against_chef_nodes('equal')
|
84
84
|
|
85
85
|
puts("") unless @options['quiet']
|
86
86
|
|
@@ -149,5 +149,12 @@ class Cheftacular
|
|
149
149
|
|
150
150
|
ret
|
151
151
|
end
|
152
|
+
|
153
|
+
def get_current_real_node_name other_node_name='', ret=''
|
154
|
+
ret << @options['env'] + @config['cheftacular']['node_name_separator']
|
155
|
+
ret << ( other_node_name.blank? ? @options['node_name'] : other_node_name )
|
156
|
+
|
157
|
+
ret
|
158
|
+
end
|
152
159
|
end
|
153
160
|
end
|
data/lib/cheftacular/helper.rb
CHANGED
@@ -28,26 +28,29 @@ class Cheftacular
|
|
28
28
|
!@config['action'].public_methods(false).include?(command.to_sym) && !@config['stateless_action'].public_methods(false).include?(command.to_sym)
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
|
31
|
+
def is_initialization_command? command=''
|
32
|
+
command ||= ''
|
33
|
+
|
34
|
+
@config['initialization_action'].public_methods(false).include?(command.to_sym)
|
35
|
+
end
|
36
|
+
|
37
|
+
def running_on_chef_node? ret = false
|
38
|
+
Dir.entries('/etc').include?('chef') && File.exist?('/etc/chef/client.rb') && !File.size?('/etc/chef/client.rb').nil?
|
33
39
|
rescue StandardError => e
|
34
|
-
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
|
40
|
+
@config['error'].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
|
35
41
|
end
|
36
42
|
|
37
43
|
def running_in_mode? mode
|
38
44
|
@config['cheftacular']['mode'] == mode
|
39
45
|
end
|
40
46
|
|
47
|
+
#TODO, fix for clients that block amazon hosted rubygems?
|
41
48
|
def fetch_remote_version
|
42
49
|
puts "Checking remote #{ declassify } version..."
|
43
50
|
|
44
51
|
`gem list #{ declassify } --remote`[/(\d+\.\d+\.\d+)/]
|
45
52
|
end
|
46
53
|
|
47
|
-
def is_junk_filename? filename
|
48
|
-
filename =~ /.DS_Store|.com.apple.timemachine.supported|README.*/ || filename == '.' || filename == '..' && File.directory?(filename)
|
49
|
-
end
|
50
|
-
|
51
54
|
def completion_rate? percent, mode
|
52
55
|
case mode.to_s
|
53
56
|
when 'initializer' then print("Fetching initialization chef data for #{ @options['env'] }....0%") if !@options['quiet'] && percent == 0
|
@@ -102,10 +105,6 @@ class Cheftacular
|
|
102
105
|
puts("\nDone in #{ Time.now - @config['start_time'] } seconds at #{ Time.now.strftime('%Y-%m-%d %l:%M:%S %P') }.") unless @options['quiet']
|
103
106
|
end
|
104
107
|
|
105
|
-
def write_version_file version
|
106
|
-
File.open( current_version_file_path, "w") { |f| f.write(version) }
|
107
|
-
end
|
108
|
-
|
109
108
|
def set_local_instance_vars
|
110
109
|
[
|
111
110
|
@options,
|
@@ -119,61 +118,6 @@ class Cheftacular
|
|
119
118
|
]
|
120
119
|
end
|
121
120
|
|
122
|
-
def exception_output message, exception='', exit_on_call=true, suppress_error_output=false
|
123
|
-
puts "#{ message }\n"
|
124
|
-
|
125
|
-
puts("Error message: #{ exception }\n#{ exception.backtrace.join("\n") }") unless suppress_error_output
|
126
|
-
|
127
|
-
exit if exit_on_call
|
128
|
-
end
|
129
|
-
|
130
|
-
def write_nodes_file_cache nodes
|
131
|
-
nodes.each do |node|
|
132
|
-
File.open( File.join( current_nodes_file_cache_path, "#{ node.name }.json"), "w") { |f| f.write(node.to_json) }
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def check_nodes_file_cache nodes=[]
|
137
|
-
Dir.entries(current_nodes_file_cache_path).each do |location|
|
138
|
-
next if is_junk_filename?(location)
|
139
|
-
|
140
|
-
nodes << @config['ridley'].node.from_file("#{ current_nodes_file_cache_path }/#{ location }" )
|
141
|
-
end
|
142
|
-
|
143
|
-
nodes
|
144
|
-
end
|
145
|
-
|
146
|
-
def current_version_file_path
|
147
|
-
current_file_path 'version-check.txt'
|
148
|
-
end
|
149
|
-
|
150
|
-
def current_audit_file_path
|
151
|
-
current_file_path 'audit-check.txt'
|
152
|
-
end
|
153
|
-
|
154
|
-
def compare_file_node_cache_against_chef_nodes mode='include?'
|
155
|
-
chef_server_names, nodes_file_cache_names = [],[]
|
156
|
-
included = true
|
157
|
-
|
158
|
-
@config['chef_nodes'].each { |node| chef_server_names << node.name }
|
159
|
-
|
160
|
-
check_nodes_file_cache.each { |node| nodes_file_cache_names << node.name }
|
161
|
-
|
162
|
-
nodes_file_cache_names.each do |node_name|
|
163
|
-
unless chef_server_names.include?(node_name)
|
164
|
-
included = false
|
165
|
-
|
166
|
-
break
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
case mode
|
171
|
-
when 'include?' then return included
|
172
|
-
when 'not_equal' then return check_nodes_file_cache.count != names.count
|
173
|
-
when 'equal' then return chef_server_names.sort == nodes_file_cache_names.sort
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
121
|
def is_higher_version? vstr1, vstr2
|
178
122
|
Gem::Version.new(vstr1) > Gem::Version.new(vstr2)
|
179
123
|
end
|
@@ -187,7 +131,7 @@ class Cheftacular
|
|
187
131
|
user = @config['cheftacular']['deploy_user']
|
188
132
|
password = @config['server_passwords'][@options['address']]
|
189
133
|
nodename = @options['node_name']
|
190
|
-
chef_ver = @config['cheftacular']['
|
134
|
+
chef_ver = @config['cheftacular']['chef_version'].to_i >= 12 ? '12.4.0' : '11.16.4'
|
191
135
|
|
192
136
|
"knife bootstrap #{ address } -x #{ user } -P #{ password } -N #{ nodename } --sudo --use-sudo-password --bootstrap-version #{ chef_ver }"
|
193
137
|
end
|
@@ -204,14 +148,11 @@ class Cheftacular
|
|
204
148
|
count = 1
|
205
149
|
|
206
150
|
doc_arr.sort {|a, b| a[0] <=> b[0]}.flatten(1).each do |line|
|
207
|
-
|
208
151
|
out << "#{ count }. #{ line }" if line.class.to_s == 'String'
|
209
152
|
|
210
153
|
out << line if line.class.to_s == 'Array'
|
211
154
|
|
212
155
|
count += 1 if line.class.to_s == 'String'
|
213
|
-
|
214
|
-
#puts("#{ out[out.index("#{ count }. #{ line }")] }::#{ line.class }::#{ count }\n") unless line.class.to_s == 'Array'
|
215
156
|
end
|
216
157
|
|
217
158
|
out
|
@@ -226,49 +167,11 @@ class Cheftacular
|
|
226
167
|
end
|
227
168
|
|
228
169
|
def set_cloud_options
|
229
|
-
@options['preferred_cloud'] = @options['preferred_cloud'].nil? ? @config['cheftacular']['preferred_cloud']
|
230
|
-
@options['preferred_cloud_image'] = @options['preferred_cloud_image'].nil? ? @config['cheftacular']['preferred_cloud_image']
|
231
|
-
@options['preferred_cloud_region'] = @options['preferred_cloud_region'].nil? ? @config['cheftacular']['preferred_cloud_region']
|
232
|
-
@options['virtualization_mode'] = @options['virtualization_mode'].nil? ? @config['cheftacular']['virtualization_mode']
|
233
|
-
|
234
|
-
|
235
|
-
def current_nodes_file_cache_path
|
236
|
-
current_file_path 'node_cache'
|
237
|
-
end
|
238
|
-
|
239
|
-
def cleanup_file_caches mode='old', check_current_day_entry=false
|
240
|
-
base_dir = File.join( @config['locs']['app-root'], 'tmp', declassify )
|
241
|
-
|
242
|
-
Dir.entries(base_dir).each do |entry|
|
243
|
-
next if is_junk_filename?(entry)
|
244
|
-
|
245
|
-
case mode
|
246
|
-
when 'old'
|
247
|
-
FileUtils.rm("#{ base_dir }/#{ entry }") if File.file?("#{ base_dir }/#{ entry }") && !entry.include?(Time.now.strftime("%Y%m%d"))
|
248
|
-
when 'current'
|
249
|
-
check_current_day_entry = true
|
250
|
-
when 'current-audit-only'
|
251
|
-
FileUtils.rm("#{ base_dir }/#{ entry }") if File.file?("#{ base_dir }/#{ entry }") && entry.include?(Time.now.strftime("%Y%m%d"))
|
252
|
-
end
|
253
|
-
|
254
|
-
if File.exists?("#{ base_dir }/#{ entry }") && File.directory?("#{ base_dir }/#{ entry }")
|
255
|
-
FileUtils.rm_rf("#{ base_dir }/#{ entry }") if !check_current_day_entry && !entry.include?(Time.now.strftime("%Y%m%d"))
|
256
|
-
|
257
|
-
FileUtils.rm_rf("#{ base_dir }/#{ entry }") if check_current_day_entry && entry.include?(Time.now.strftime("%Y%m%d"))
|
258
|
-
|
259
|
-
FileUtils.mkdir_p @config['helper'].current_nodes_file_cache_path
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
def remove_current_file_node_cache
|
265
|
-
base_dir = File.join( @config['locs']['app-root'], 'tmp', declassify )
|
266
|
-
|
267
|
-
Dir.entries(base_dir).each do |entry|
|
268
|
-
next if is_junk_filename?(entry)
|
269
|
-
|
270
|
-
FileUtils.rm_rf("#{ base_dir }/#{ entry }") if File.directory?("#{ base_dir }/#{ entry }") && entry.include?(Time.now.strftime("%Y%m%d"))
|
271
|
-
end
|
170
|
+
@options['preferred_cloud'] = @options['preferred_cloud'].nil? ? @config['cheftacular']['preferred_cloud'].downcase : @options['preferred_cloud'].downcase
|
171
|
+
@options['preferred_cloud_image'] = @options['preferred_cloud_image'].nil? ? @config['cheftacular']['preferred_cloud_image'] : @options['preferred_cloud_image']
|
172
|
+
@options['preferred_cloud_region'] = @options['preferred_cloud_region'].nil? ? @config['cheftacular']['preferred_cloud_region'] : @options['preferred_cloud_region']
|
173
|
+
@options['virtualization_mode'] = @options['virtualization_mode'].nil? ? @config['cheftacular']['virtualization_mode'] : @options['virtualization_mode']
|
174
|
+
@options['route_dns_changes_via'] = @options['route_dns_changes_via'].nil? ? @config['cheftacular']['route_dns_changes_via'].downcase : @options['route_dns_changes_via'].downcase
|
272
175
|
end
|
273
176
|
|
274
177
|
def does_cheftacular_config_have? key_array
|
@@ -331,14 +234,6 @@ class Cheftacular
|
|
331
234
|
exit
|
332
235
|
end
|
333
236
|
|
334
|
-
def current_chef_repo_cheftacular_file_cache_path
|
335
|
-
current_file_path "chef_repo_cheftacular_cache"
|
336
|
-
end
|
337
|
-
|
338
|
-
def write_chef_repo_cheftacular_cache_file hash
|
339
|
-
File.open( current_chef_repo_cheftacular_file_cache_path, "w") { |f| f.write(hash) }
|
340
|
-
end
|
341
|
-
|
342
237
|
def compile_chef_repo_cheftacular_yml_as_hash
|
343
238
|
master_hash = get_cheftacular_yml_as_hash
|
344
239
|
master_hash['replace_keys_in_chef_repo'].each_pair do |key, val|
|
@@ -348,13 +243,22 @@ class Cheftacular
|
|
348
243
|
master_hash
|
349
244
|
end
|
350
245
|
|
351
|
-
def
|
352
|
-
|
353
|
-
|
246
|
+
def install_rvm_sh_file out=[]
|
247
|
+
puts("Starting rvm.sh installation...") unless @options['quiet']
|
248
|
+
|
249
|
+
commands = [
|
250
|
+
"#{ @config['helper'].sudo(@options['address']) } mv /home/deploy/rvm.sh /etc/profile.d",
|
251
|
+
"#{ @config['helper'].sudo(@options['address']) } chmod 755 /etc/profile.d/rvm.sh",
|
252
|
+
"#{ @config['helper'].sudo(@options['address']) } chown root:root /etc/profile.d/rvm.sh"
|
253
|
+
]
|
254
|
+
|
255
|
+
out << `scp -oStrictHostKeyChecking=no #{ @config['locs']['cheftacular-lib-files'] }/rvm.sh #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] }:/home/#{ @config['cheftacular']['deploy_user'] }`
|
256
|
+
|
257
|
+
commands.each do |command|
|
258
|
+
out << `ssh -t -oStrictHostKeyChecking=no #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] } "#{ command }"`
|
259
|
+
end
|
354
260
|
|
355
|
-
|
356
|
-
def current_file_path file_name
|
357
|
-
File.join( @config['locs']['app-root'], 'tmp', declassify, "#{ Time.now.strftime("%Y%m%d") }-#{ file_name }")
|
261
|
+
puts("Completed rvm.sh installation into /etc/profile.d/rvm.sh") unless @options['quiet']
|
358
262
|
end
|
359
263
|
end
|
360
264
|
end
|