cheftacular 2.5.0 → 2.6.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.
- 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
|