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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cheftacular/README.md +155 -63
  3. data/lib/cheftacular/actions/db_console.rb +3 -3
  4. data/lib/cheftacular/actions/deploy.rb +18 -12
  5. data/lib/cheftacular/actions/migrate.rb +1 -1
  6. data/lib/cheftacular/actions/tail.rb +1 -1
  7. data/lib/cheftacular/auditor.rb +14 -6
  8. data/lib/cheftacular/chef/data_bag.rb +1 -4
  9. data/lib/cheftacular/cheftacular.rb +19 -15
  10. data/lib/cheftacular/cloud_provider.rb +32 -0
  11. data/lib/cheftacular/dns.rb +1 -1
  12. data/lib/cheftacular/error.rb +13 -2
  13. data/lib/cheftacular/file_system.rb +122 -0
  14. data/lib/cheftacular/files/rvm.sh +55 -0
  15. data/lib/cheftacular/getter.rb +10 -3
  16. data/lib/cheftacular/helper.rb +31 -127
  17. data/lib/cheftacular/initialization_action.rb +8 -0
  18. data/lib/cheftacular/initializer.rb +104 -44
  19. data/lib/cheftacular/parser.rb +6 -0
  20. data/lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb +2 -2
  21. data/lib/cheftacular/stateless_actions/arguments.rb +9 -2
  22. data/lib/cheftacular/stateless_actions/backups.rb +1 -1
  23. data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +16 -5
  24. data/lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb +79 -0
  25. data/lib/cheftacular/stateless_actions/chef_bootstrap.rb +20 -4
  26. data/lib/cheftacular/stateless_actions/chef_server.rb +78 -0
  27. data/lib/cheftacular/stateless_actions/clean_cookbooks.rb +3 -3
  28. data/lib/cheftacular/stateless_actions/clean_server_passwords.rb +3 -1
  29. data/lib/cheftacular/stateless_actions/cleanup_log_files.rb +1 -0
  30. data/lib/cheftacular/stateless_actions/client_list.rb +2 -2
  31. data/lib/cheftacular/stateless_actions/cloud.rb +30 -2
  32. data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +7 -13
  33. data/lib/cheftacular/stateless_actions/compile_audit_log.rb +1 -1
  34. data/lib/cheftacular/stateless_actions/create_git_key.rb +3 -1
  35. data/lib/cheftacular/stateless_actions/environment.rb +2 -0
  36. data/lib/cheftacular/stateless_actions/file.rb +4 -2
  37. data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +2 -1
  38. data/lib/cheftacular/stateless_actions/full_bootstrap.rb +2 -0
  39. data/lib/cheftacular/stateless_actions/get_active_ssh_connections.rb +1 -1
  40. data/lib/cheftacular/stateless_actions/help.rb +9 -7
  41. data/lib/cheftacular/stateless_actions/initialize_cheftacular_yml.rb +29 -0
  42. data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +5 -36
  43. data/lib/cheftacular/stateless_actions/list_toggleable_roles.rb +45 -0
  44. data/lib/cheftacular/stateless_actions/location_aliases.rb +24 -0
  45. data/lib/cheftacular/stateless_actions/pass.rb +4 -4
  46. data/lib/cheftacular/stateless_actions/reinitialize.rb +0 -6
  47. data/lib/cheftacular/stateless_actions/remove_client.rb +12 -7
  48. data/lib/cheftacular/stateless_actions/role_toggle.rb +141 -0
  49. data/lib/cheftacular/stateless_actions/server_update.rb +2 -2
  50. data/lib/cheftacular/stateless_actions/update_chef_client.rb +18 -0
  51. data/lib/cheftacular/stateless_actions/upload_nodes.rb +5 -3
  52. data/lib/cheftacular/stateless_actions/upload_roles.rb +1 -1
  53. data/lib/cheftacular/version.rb +1 -1
  54. data/lib/cloud_interactor/authentication.rb +78 -40
  55. data/lib/cloud_interactor/cloud_interactor.rb +4 -1
  56. data/lib/cloud_interactor/cloud_provider.rb +19 -0
  57. data/lib/cloud_interactor/domain/create.rb +1 -1
  58. data/lib/cloud_interactor/domain/create_record.rb +1 -1
  59. data/lib/cloud_interactor/domain/destroy_record.rb +1 -1
  60. data/lib/cloud_interactor/domain/list_records.rb +1 -1
  61. data/lib/cloud_interactor/domain/update.rb +1 -1
  62. data/lib/cloud_interactor/domain/update_record.rb +6 -6
  63. data/lib/cloud_interactor/helpers.rb +1 -1
  64. data/lib/cloud_interactor/parser.rb +3 -2
  65. data/lib/cloud_interactor/region.rb +27 -0
  66. data/lib/cloud_interactor/server/create.rb +9 -0
  67. data/lib/cloud_interactor/sshkey.rb +59 -0
  68. data/lib/ridley/monkeypatches.rb +12 -0
  69. data/lib/sshkit/actions/start_task.rb +8 -2
  70. metadata +16 -2
@@ -25,6 +25,8 @@ class Cheftacular
25
25
 
26
26
  class StatelessAction
27
27
  def upload_nodes invalidate_file_node_cache=false
28
+ @config['filesystem'].cleanup_file_caches('current') if invalidate_file_node_cache
29
+
28
30
  raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling']
29
31
 
30
32
  @config['chef_environments'].each do |env|
@@ -38,10 +40,10 @@ class Cheftacular
38
40
  node_roles_hash, bag_hash, allowed_changes_hash = {},{},{}
39
41
 
40
42
  Dir.foreach(@config['locs']['nodes']) do |fr|
41
- next if @config['helper'].is_junk_filename?(fr)
43
+ next if @config['filesystem'].is_junk_filename?(fr)
42
44
 
43
45
  Dir.foreach("#{ @config['locs']['nodes'] }/#{ fr }") do |f|
44
- next if @config['helper'].is_junk_filename?(f)
46
+ next if @config['filesystem'].is_junk_filename?(f)
45
47
 
46
48
  node_roles_hash[f.split('.json').first] = JSON.parse(File.read("#{ @config['locs']['nodes'] }/#{ fr }/#{ f }"))
47
49
  end
@@ -126,7 +128,7 @@ class Cheftacular
126
128
  @config['ChefDataBag'].save_node_roles_bag env
127
129
  end if !@options['force_yes'] && @config['helper'].running_in_mode?('devops')
128
130
 
129
- @config['helper'].cleanup_file_caches('current') if invalidate_file_node_cache
131
+ @config['filesystem'].cleanup_file_caches('current') if invalidate_file_node_cache
130
132
  end
131
133
  end
132
134
  end
@@ -13,7 +13,7 @@ class Cheftacular
13
13
  raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling']
14
14
 
15
15
  Dir.foreach(@config['locs']['roles']) do |rd|
16
- next if @config['helper'].is_junk_filename?(rd)
16
+ next if @config['filesystem'].is_junk_filename?(rd)
17
17
 
18
18
  puts("Loading in role from file #{ rd }") if @options['verbose']
19
19
 
@@ -1,5 +1,5 @@
1
1
  class Cheftacular
2
2
  #major_version.minor_version.bugfixes
3
- VERSION = "2.5.0"
3
+ VERSION = "2.6.0"
4
4
  RUBY_VERSION = "2.2.2"
5
5
  end
@@ -7,50 +7,88 @@ class CloudInteractor
7
7
  end
8
8
 
9
9
  def auth_service interaction_class
10
- except_keys = []
11
-
12
- interaction_class = case interaction_class.downcase
13
- when 'volume'
14
- case @options['preferred_cloud']
15
- when 'rackspace'
16
- except_keys = [:provider, :version]
17
-
18
- 'Rackspace::BlockStorage'
19
- else
20
- raise "CloudInteractor Does not currently support this #{ options['preferred_cloud'] }'s' volume creation at this time"
21
- end
22
- when 'dns'
23
- case @options['preferred_cloud']
24
- when 'rackspace'
25
- except_keys = [:version, :rackspace_region]
26
-
27
- interaction_class
28
- else
29
- except_keys = [:version]
30
-
31
- interaction_class
32
- end
33
- else
34
- interaction_class
35
- end
10
+ interaction_class, except_keys = parse_interaction_class(interaction_class)
36
11
 
37
12
  classes_to_inject = interaction_class.split('::')
38
13
  classes_to_inject = classes_to_inject.map { |str| str.camelcase }
39
14
 
40
- cloud_hash = case @options['preferred_cloud']
41
- when 'rackspace'
42
- {
43
- provider: @options['preferred_cloud'].capitalize,
44
- rackspace_username: @auth_hash['cloud_auth'][@options['preferred_cloud']]['username'],
45
- rackspace_api_key: @auth_hash['cloud_auth'][@options['preferred_cloud']]['api_key'],
46
- version: :v2,
47
- rackspace_region: @options['preferred_cloud_region'].to_sym,
48
- connection_options: {}
49
- }.delete_if { |key, value| except_keys.flatten.include?(key) }
50
- else raise "CloudInteractor Does not currently support #{ @options['preferred_cloud'] } at this time"
51
- end
52
-
53
- Fog.class_eval(classes_to_inject.join('::')).new(cloud_hash)
15
+ cloud_hash = parse_cloud_hash
16
+
17
+ if interaction_class == 'DNS'
18
+ cloud_hash = parse_dns_cloud_hash cloud_hash
19
+ end
20
+
21
+ Fog.class_eval(classes_to_inject.join('::')).new(cloud_hash.delete_if { |key, value| except_keys.flatten.include?(key) })
22
+ end
23
+
24
+ def parse_interaction_class interaction_class, except_keys = []
25
+ return_class = case interaction_class.downcase
26
+ when 'volume'
27
+ case @options['preferred_cloud']
28
+ when 'rackspace'
29
+ except_keys << [:provider, :version]
30
+
31
+ 'Rackspace::BlockStorage'
32
+ else
33
+ raise "CloudInteractor Does not currently support this #{ @options['preferred_cloud'] }'s' volume creation at this time"
34
+ end
35
+ when 'dns'
36
+ case @options['route_dns_changes_via']
37
+ when 'rackspace'
38
+ except_keys << [:version, :rackspace_region]
39
+
40
+ interaction_class
41
+ else
42
+ except_keys << [:version]
43
+
44
+ interaction_class
45
+ end
46
+ else
47
+ interaction_class
48
+ end
49
+
50
+ [return_class, except_keys.flatten]
51
+ end
52
+
53
+ def parse_cloud_hash
54
+ case @options['preferred_cloud']
55
+ when 'rackspace'
56
+ {
57
+ provider: 'Rackspace',
58
+ rackspace_username: @auth_hash['cloud_authentication'][@options['preferred_cloud']]['username'],
59
+ rackspace_api_key: @auth_hash['cloud_authentication'][@options['preferred_cloud']]['api_key'],
60
+ version: :v2,
61
+ rackspace_region: @options['preferred_cloud_region'].to_sym,
62
+ connection_options: {}
63
+ }
64
+ when 'digitalocean'
65
+ {
66
+ provider: 'DigitalOcean',
67
+ digitalocean_api_key: @auth_hash['cloud_authentication'][@options['preferred_cloud']]['api_key'],
68
+ digitalocean_client_id: @auth_hash['cloud_authentication'][@options['preferred_cloud']]['client_id']
69
+ #version: :v1
70
+ }
71
+ else raise "CloudInteractor Does not currently support #{ @options['preferred_cloud'] } at this time"
72
+ end
73
+ end
74
+
75
+ def parse_dns_cloud_hash cloud_hash
76
+ if @options['route_dns_changes_via'] == @options['preferred_cloud']
77
+ cloud_hash
78
+ else
79
+ case @options['route_dns_changes_via']
80
+ when 'rackspace'
81
+ cloud_hash
82
+ when 'dnsimple'
83
+ {
84
+ provider: 'dnsimple',
85
+ dnsimple_email: @auth_hash['cloud_authentication'][@options['route_dns_changes_via']]['email'],
86
+ dnsimple_password: @auth_hash['cloud_authentication'][@options['route_dns_changes_via']]['password'],
87
+ dnsimple_token: @auth_hash['cloud_authentication'][@options['route_dns_changes_via']]['token']
88
+ }
89
+ else raise "CloudInteractor does not currently support #{ @options['route_dns_changes_via'] } as a DNS creation provider at this time"
90
+ end
91
+ end
54
92
  end
55
93
  end
56
94
  end
@@ -1,5 +1,5 @@
1
1
  class CloudInteractor
2
- ALLOWED_HLMS = ['domain', 'flavor', 'image', 'server', 'volume']
2
+ ALLOWED_HLMS = ['domain', 'flavor', 'image', 'region', 'server', 'sshkey', 'volume']
3
3
 
4
4
  def initialize auth_hash, options
5
5
  @main_obj, @classes = {},{}
@@ -7,10 +7,13 @@ class CloudInteractor
7
7
  @main_obj['output'] = {}
8
8
  @auth_hash = auth_hash
9
9
  @classes['helper'] = Helper.new(@main_obj, @classes, @options)
10
+ @classes['clouds'] = CloudProvider.new(@options)
10
11
  @classes['domain'] = Domain.new(@main_obj, @auth_hash, @classes, @options)
11
12
  @classes['flavor'] = Flavor.new(@main_obj, @classes, @options)
12
13
  @classes['image'] = Image.new(@main_obj, @classes, @options)
14
+ @classes['region'] = Region.new(@main_obj, @classes, @options)
13
15
  @classes['server'] = Server.new(@main_obj, @classes, @options)
16
+ @classes['sshkey'] = SSHKey.new(@main_obj, @classes, @options)
14
17
  @classes['volume'] = Volume.new(@main_obj, @classes, @options)
15
18
  @classes['auth'] = Authentication.new(@auth_hash, @options)
16
19
  end
@@ -0,0 +1,19 @@
1
+ class CloudInteractor
2
+ class CloudProvider
3
+ def initialize options={}
4
+ @options = options
5
+ end
6
+
7
+ #args will always be a hash
8
+ def parse_provider_domain_record_name args
9
+ case @options['route_dns_changes_via']
10
+ when 'rackspace'
11
+ "#{ args['subdomain'] }.#{ args['domain'] }"
12
+ when 'dnsimple'
13
+ args['subdomain']
14
+ else
15
+ "#{ args['subdomain'] }.#{ args['domain'] }"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -9,7 +9,7 @@ class CloudInteractor
9
9
  return false
10
10
  end
11
11
 
12
- @classes['auth'].auth_service(RESOURCE).instance_eval('zones').create(domain: args[IDENTITY.singularize], email: @auth_hash['cloud_auth'][@options['preferred_cloud']]['email'])
12
+ @classes['auth'].auth_service(RESOURCE).instance_eval('zones').create(domain: args[IDENTITY.singularize], email: @auth_hash['cloud_authentication'][@options['preferred_cloud']]['email'])
13
13
 
14
14
  puts "Created #{ IDENTITY } #{ args[IDENTITY.singularize] }..."
15
15
  end
@@ -3,7 +3,7 @@ class CloudInteractor
3
3
  def create_record args, already_created=false
4
4
  args['type'] ||= 'A'
5
5
  args['ttl'] ||= 300
6
- args['target_domain'] ||= "#{ args['subdomain'] }.#{ args[IDENTITY.singularize] }"
6
+ args['target_domain'] ||= @classes['clouds'].parse_provider_domain_record_name(args)
7
7
  args['target_domain'] = args[IDENTITY.singularize] if args['subdomain'].blank?
8
8
 
9
9
  read args, false
@@ -4,7 +4,7 @@ class CloudInteractor
4
4
  read args, false
5
5
 
6
6
  @main_obj['specific_records'][args[IDENTITY.singularize]].each do |record_hash|
7
- already_exists = true if record_hash['name'] == "#{ args['subdomain'] }.#{ args[IDENTITY.singularize] }"
7
+ already_exists = true if record_hash['name'] == @classes['clouds'].parse_provider_domain_record_name(args)
8
8
 
9
9
  args['id'] = record_hash['id']
10
10
 
@@ -1,7 +1,7 @@
1
1
  class CloudInteractor
2
2
  class Domain
3
3
  def list_records args, output=false
4
- puts "Querying #{ args["domain"] } for rackspace..."
4
+ puts "Querying #{ args["domain"] } for records..."
5
5
 
6
6
  specific_fog_object = @classes['auth'].auth_service(RESOURCE).instance_eval('zones').get @main_obj["specific_#{ IDENTITY }"].last['id']
7
7
 
@@ -10,7 +10,7 @@ class CloudInteractor
10
10
  return false
11
11
  end
12
12
 
13
- @classes['auth'].auth_service(resource).instance_eval('zones').get(@main_obj["specific_#{ IDENTITY }"].last['id']).update(ttl: 5, email: @auth_hash['cloud_auth'][@options['preferred_cloud']]['email'])
13
+ @classes['auth'].auth_service(resource).instance_eval('zones').get(@main_obj["specific_#{ IDENTITY }"].last['id']).update(ttl: 5, email: @auth_hash['cloud_authentication'][@options['preferred_cloud']]['email'])
14
14
 
15
15
  puts "Updated #{ IDENTITY } #{ args[IDENTITY.singularize] }..."
16
16
  end
@@ -1,9 +1,9 @@
1
1
  class CloudInteractor
2
2
  class Domain
3
3
  def update_record args, already_created=false
4
- args['type'] ||= 'A'
5
- args['ttl'] ||= 300
6
- args['target_domain'] ||= "#{ args['subdomain'] }.#{ args[IDENTITY.singularize] }"
4
+ args['type'] ||= 'A'
5
+ args['ttl'] ||= 300
6
+ args['target_domain'] ||= @classes['clouds'].parse_provider_domain_record_name(args)
7
7
  args['target_domain'] = args[IDENTITY.singularize] if args['subdomain'].blank?
8
8
 
9
9
  read args, false
@@ -24,8 +24,8 @@ class CloudInteractor
24
24
  #the fact that there is no public update method is silly
25
25
  specific_record = specific_fog_object.records.get(args['id'])
26
26
 
27
- case @options['preferred_cloud']
28
- when 'rackspace'
27
+ case @options['route_dns_changes_via']
28
+ when /rackspace|dnsimple/
29
29
  specific_record.type = args['type']
30
30
  specific_record.value = args['target_ip']
31
31
  specific_record.ttl = args['ttl']
@@ -41,4 +41,4 @@ class CloudInteractor
41
41
  end
42
42
  end
43
43
  end
44
- end
44
+ end
@@ -14,7 +14,7 @@ class CloudInteractor
14
14
  end
15
15
 
16
16
  def generic_list_call identity, resource, output=true
17
- puts "Returning list of #{ identity } for #{ @options['preferred_cloud'] }..."
17
+ puts "Returning list of #{ identity } for #{ resource == 'DNS' ? @options['route_dns_changes_via'] : @options['preferred_cloud'] }..."
18
18
 
19
19
  @main_obj[identity] = JSON.parse(@classes['auth'].auth_service(resource).instance_eval(identity).to_json)
20
20
 
@@ -1,5 +1,6 @@
1
1
  class CloudInteractor
2
2
  def parse_args args, final_args={}
3
+ args[0] = args[0].singularize
3
4
  #example args: domain "create:mydomain.us:23.253.44.192:my"
4
5
 
5
6
  raise "This class does not support #{ args[0] } at this time" unless ALLOWED_HLMS.include?(args[0])
@@ -27,8 +28,8 @@ class CloudInteractor
27
28
  when args[0] =~ /domain/ then { 1 => "domain", 2 => "subdomain", 3 => "target_ip", 4 => 'type' }
28
29
  when args[0] =~ /server/ then { 1 => "name", 2 => "flavor" }
29
30
  when args[0] =~ /volume/ then { 1 => "display_name", 2 => "size", 3 => 'volume_type' }
30
- when args[0] =~ /flavor/ then { 1 => "name" }
31
- when args[0] =~ /image/ then { 1 => "name" }
31
+ when args[0] =~ /sshkey/ then { 1 => "name", 2 => :ssh_pub_key }
32
+ when args[0] =~ /flavor|image|region/ then { 1 => "name" }
32
33
  else raise "FATAL! Unsupported High Level Class #{ args[0] } for CloudInteractor! Please raise an issue on github with this stacktrace! args:#{ args }"
33
34
  end
34
35
 
@@ -0,0 +1,27 @@
1
+
2
+ class CloudInteractor
3
+ class Region
4
+ IDENTITY = 'regions'
5
+ RESOURCE = 'compute'
6
+
7
+ def initialize main_obj, classes, options={}
8
+ @main_obj = main_obj
9
+ @options = options
10
+ @classes = classes
11
+ end
12
+
13
+ def run method, args
14
+ self.send(method, args)
15
+ end
16
+
17
+ def list args, output=true
18
+ @classes['helper'].generic_list_call IDENTITY, RESOURCE, output
19
+ end
20
+
21
+ def read args, output=true
22
+ list [], false
23
+
24
+ @classes['helper'].generic_read_parse args, IDENTITY, output
25
+ end
26
+ end
27
+ end
@@ -7,6 +7,9 @@ class CloudInteractor
7
7
  #Note, if no flavor is passed it defaults to a 512MB standard!
8
8
  @classes['flavor'].read args['flavor']
9
9
 
10
+ @classes['region'].read(@options['preferred_cloud_region'], false) if @options['preferred_cloud'] == 'digitalocean'
11
+ @classes['sshkey'].bootstrap if @options['preferred_cloud'] == 'digitalocean'
12
+
10
13
  read args, false
11
14
 
12
15
  unless @main_obj["specific_#{ IDENTITY }"].empty?
@@ -23,6 +26,12 @@ class CloudInteractor
23
26
  image_id: @main_obj['specific_images'].first['id']
24
27
  }
25
28
 
29
+ if @options['preferred_cloud'] == 'digitalocean'
30
+ final_create_args[:region_id] = @main_obj['specific_regions'].first['id']
31
+ final_create_args[:ssh_key_ids] = @main_obj['specific_ssh_keys'].first['id']
32
+ final_create_args[:private_networking] = true
33
+ end
34
+
26
35
  @main_obj["#{ IDENTITY }_create_request"] = JSON.parse(@classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).create(final_create_args).to_json)
27
36
 
28
37
  @main_obj["#{ IDENTITY }_created_passwords"] ||= {}
@@ -0,0 +1,59 @@
1
+
2
+ class CloudInteractor
3
+ class SSHKey
4
+ IDENTITY = 'ssh_keys'
5
+ RESOURCE = 'compute'
6
+
7
+ def initialize main_obj, classes, options={}
8
+ @main_obj = main_obj
9
+ @options = options
10
+ @classes = classes
11
+ end
12
+
13
+ def run method, args
14
+ self.send(method, args)
15
+ end
16
+
17
+ def list args={}, output=true
18
+ @classes['helper'].generic_list_call IDENTITY, RESOURCE, output
19
+ end
20
+
21
+ def read args, output=true
22
+ list [], false
23
+
24
+ @classes['helper'].generic_read_parse args, IDENTITY, output
25
+ end
26
+
27
+ def create args
28
+ puts "Creating #{ args['name'] } in #{ IDENTITY }..."
29
+
30
+ puts("Creating #{ IDENTITY.singularize } with args #{ ap(args) }") if @options['verbose']
31
+
32
+ @main_obj["#{ IDENTITY }_create_request"] = JSON.parse(@classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).create(args).to_json)
33
+ end
34
+
35
+ def destroy args
36
+ read args, false
37
+
38
+ @classes['helper'].generic_destroy_parse args, IDENTITY, RESOURCE
39
+ end
40
+
41
+ #special method for digitalocean api, will attempt to create the sshkeyid on DO if one matching the user's hostname is not found
42
+ def bootstrap output=true
43
+ read Socket.gethostname, false
44
+
45
+ if @main_obj["specific_#{ IDENTITY }"].empty?
46
+ puts "Did not detect an SSHKey on DigitalOcean for the system #{ Socket.gethostname }, creating..."
47
+ create_hash = {}
48
+ create_hash['name'] = Socket.gethostname
49
+ create_hash['ssh_pub_key'] = File.read(File.expand_path('~/.ssh/id_rsa.pub'))
50
+
51
+ create create_hash
52
+
53
+ sleep 5
54
+
55
+ read Socket.gethostname, false
56
+ end
57
+ end
58
+ end
59
+ end
@@ -9,3 +9,15 @@ module Ridley
9
9
  end
10
10
  end
11
11
  end
12
+
13
+ module Ridley
14
+ class NodeObject < Ridley::ChefObject
15
+ def public_ipv4
16
+ address = self.cloud? ? self.automatic[:cloud][:public_ipv4] || self.automatic[:ipaddress] : self.automatic[:ipaddress]
17
+
18
+ address.is_a?(Hash) ? address['ip_address'] : address
19
+ end
20
+
21
+ alias_method :public_ipaddress, :public_ipv4
22
+ end
23
+ end
@@ -7,12 +7,18 @@ module SSHKit
7
7
 
8
8
  puts "Running #{ command } for #{ name } (#{ ip_address }) (Run with with --debug to generate a log as well)"
9
9
 
10
- mig_loc = "/var/www/vhosts/#{ options['repository'] }/current"
10
+ target_loc = "/var/www/vhosts/#{ options['repository'] }/current"
11
+
12
+ if test( target_loc )
13
+ puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no directory at #{ target_loc }!"
14
+
15
+ return ['', timestamp]
16
+ end
11
17
 
12
18
  capture_args = ["RAILS_ENV=#{ true_env }"]
13
19
  capture_args << command.split(' ')
14
20
 
15
- within mig_loc do
21
+ within target_loc do
16
22
  out << capture( *capture_args.flatten )
17
23
  end
18
24
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cheftacular
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis Alridge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-19 00:00:00.000000000 Z
11
+ date: 2015-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -238,12 +238,16 @@ files:
238
238
  - lib/cheftacular/auditor.rb
239
239
  - lib/cheftacular/chef/data_bag.rb
240
240
  - lib/cheftacular/cheftacular.rb
241
+ - lib/cheftacular/cloud_provider.rb
241
242
  - lib/cheftacular/decryptor.rb
242
243
  - lib/cheftacular/dns.rb
243
244
  - lib/cheftacular/encryptor.rb
244
245
  - lib/cheftacular/error.rb
246
+ - lib/cheftacular/file_system.rb
247
+ - lib/cheftacular/files/rvm.sh
245
248
  - lib/cheftacular/getter.rb
246
249
  - lib/cheftacular/helper.rb
250
+ - lib/cheftacular/initialization_action.rb
247
251
  - lib/cheftacular/initializer.rb
248
252
  - lib/cheftacular/parser.rb
249
253
  - lib/cheftacular/stateless_action.rb
@@ -256,7 +260,9 @@ files:
256
260
  - lib/cheftacular/stateless_actions/bootstrappers/redhat_bootstrap.rb
257
261
  - lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb
258
262
  - lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb
263
+ - lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb
259
264
  - lib/cheftacular/stateless_actions/chef_bootstrap.rb
265
+ - lib/cheftacular/stateless_actions/chef_server.rb
260
266
  - lib/cheftacular/stateless_actions/clean_cookbooks.rb
261
267
  - lib/cheftacular/stateless_actions/clean_sensu_plugins.rb
262
268
  - lib/cheftacular/stateless_actions/clean_server_passwords.rb
@@ -278,18 +284,23 @@ files:
278
284
  - lib/cheftacular/stateless_actions/get_pg_pass.rb
279
285
  - lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb
280
286
  - lib/cheftacular/stateless_actions/help.rb
287
+ - lib/cheftacular/stateless_actions/initialize_cheftacular_yml.rb
281
288
  - lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb
282
289
  - lib/cheftacular/stateless_actions/knife_upload.rb
290
+ - lib/cheftacular/stateless_actions/list_toggleable_roles.rb
291
+ - lib/cheftacular/stateless_actions/location_aliases.rb
283
292
  - lib/cheftacular/stateless_actions/pass.rb
284
293
  - lib/cheftacular/stateless_actions/reinitialize.rb
285
294
  - lib/cheftacular/stateless_actions/remove_client.rb
286
295
  - lib/cheftacular/stateless_actions/replication_status.rb
287
296
  - lib/cheftacular/stateless_actions/restart_swap.rb
297
+ - lib/cheftacular/stateless_actions/role_toggle.rb
288
298
  - lib/cheftacular/stateless_actions/rvm.rb
289
299
  - lib/cheftacular/stateless_actions/server_update.rb
290
300
  - lib/cheftacular/stateless_actions/service.rb
291
301
  - lib/cheftacular/stateless_actions/slack.rb
292
302
  - lib/cheftacular/stateless_actions/test_env.rb
303
+ - lib/cheftacular/stateless_actions/update_chef_client.rb
293
304
  - lib/cheftacular/stateless_actions/update_cloudflare_dns_from_cloud.rb
294
305
  - lib/cheftacular/stateless_actions/update_split_branches.rb
295
306
  - lib/cheftacular/stateless_actions/update_tld.rb
@@ -298,6 +309,7 @@ files:
298
309
  - lib/cheftacular/version.rb
299
310
  - lib/cloud_interactor/authentication.rb
300
311
  - lib/cloud_interactor/cloud_interactor.rb
312
+ - lib/cloud_interactor/cloud_provider.rb
301
313
  - lib/cloud_interactor/domain.rb
302
314
  - lib/cloud_interactor/domain/create.rb
303
315
  - lib/cloud_interactor/domain/create_record.rb
@@ -313,6 +325,7 @@ files:
313
325
  - lib/cloud_interactor/helpers.rb
314
326
  - lib/cloud_interactor/image.rb
315
327
  - lib/cloud_interactor/parser.rb
328
+ - lib/cloud_interactor/region.rb
316
329
  - lib/cloud_interactor/server.rb
317
330
  - lib/cloud_interactor/server/attach_volume.rb
318
331
  - lib/cloud_interactor/server/create.rb
@@ -323,6 +336,7 @@ files:
323
336
  - lib/cloud_interactor/server/poll.rb
324
337
  - lib/cloud_interactor/server/read.rb
325
338
  - lib/cloud_interactor/server/read_volume.rb
339
+ - lib/cloud_interactor/sshkey.rb
326
340
  - lib/cloud_interactor/version.rb
327
341
  - lib/cloud_interactor/volume.rb
328
342
  - lib/cloud_interactor/volume/create.rb