danarchy_sys 0.3.2 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59baad97d006ee7aff82b4b2967e07234be91984
4
- data.tar.gz: c5a05a4144cd523a29ba0fb7f98dede535fd0b4f
3
+ metadata.gz: 4aa6e032fcc91f01d05a9e4e5a766c631aaccb8e
4
+ data.tar.gz: 209fdf53de2e687c9860582e3da9a457c749cb01
5
5
  SHA512:
6
- metadata.gz: 4edbb2c640b2762d56ceda9cb996f0aa8420441b6eacf377a3a3672fb2c80069565f3a6deaa96c74bfc628123872efe334ee4df7be6401694851903ecdce712a
7
- data.tar.gz: 662041f3b1cf5ad712cb3455461529f2f3181af54ff68f76bc05eac091bceb03df5ef36356732dc58c084e157a99f8729755053e04ff87a968a46faaf30c01e0
6
+ metadata.gz: 71707b82e521b6f6e8e0777b36822f58227edbb812b504a539d68d9c33ae271d6ddbc57ae9bc64fd538935a3ca5e509b407c69ae7c91f0e1c9cecc1a71be2c4b
7
+ data.tar.gz: 6a94054147211b6fa3f7c0f3aa03201f3eea2e1691ac85a6cefcf7b58285f0740e4614e290c9ca64db278b5358f6495485e3641fcd8524beff8fb43655d1b135
@@ -14,7 +14,7 @@ class InstanceManager
14
14
  return Menus.print_menu('main') if instance == 'main'
15
15
  end
16
16
 
17
- print "#{instance.name} ~: "
17
+ print "#{instance.name} ~: " if instance
18
18
  cmd = gets.chomp
19
19
 
20
20
  next if cmd.empty?
@@ -67,29 +67,18 @@ class InstanceManager
67
67
 
68
68
  printf("\n%#{instance.name.size}s %0s %0s\n", instance.name, ' => ', instance.state)
69
69
  elsif cmd == 'rebuild'
70
- print "Should we rebuild #{instance.name}? (Y/N): "
70
+ image = PromptsCreateInstance.image(os_compute.images)
71
+ print "Should we rebuild #{instance.name} with image: #{image.name}? (Y/N): "
71
72
  if gets.chomp =~ /^y(es)?$/i
72
- image = PromptsCreateInstance.image(os_compute.images)
73
- instance.rebuild(image.id, instance.name)
74
-
75
- print "Rebuilding #{instance.name} with #{image.name}"
76
- instance = os_compute.instances.get_instance(instance.name)
77
- until instance.state == 'ACTIVE'
78
- instance = os_compute.instances.get_instance(instance.name)
79
- sleep(3)
80
- print ' .'
81
- end
82
-
83
- addrs = os_compute.instances.get_public_addresses(instance.name)
84
- addrs.each { |ip| `ssh-keygen -R #{ip} &>/dev/null` }
73
+ puts "Rebuilding #{instance.name} with #{image.name}"
74
+ instance = os_compute.instances.rebuild_instance(instance, image)
85
75
  puts "\nRebuild successful!"
86
76
  else
87
77
  puts "Not rebuilding #{instance.name} at this time."
88
78
  end
89
79
  elsif cmd == 'connect'
90
80
  if instance.state == 'ACTIVE'
91
- connect = os_compute.ssh(instance.name)
92
- puts connect if connect != true
81
+ os_compute.ssh(instance.name)
93
82
  else
94
83
  puts "Unable to connect: #{instance.name} is not running!"
95
84
  end
@@ -103,14 +92,12 @@ class InstanceManager
103
92
  end
104
93
 
105
94
  def self.chooser(os_compute)
106
- comp_inst = os_compute.instances
107
- instances = comp_inst.all_instances
108
- instances_numhash = Helpers.objects_to_numhash(comp_inst.all_instances)
95
+ instances_numhash = Helpers.objects_to_numhash(os_compute.instances.all_instances)
109
96
  instance_name = nil
110
97
  instance = nil
111
98
 
112
99
  # Create a new instances if none exist
113
- if instances.empty?
100
+ if instances_numhash.empty?
114
101
  print 'No existing instances were found. Should we create a new one? (Y/N): '
115
102
  abort('Exiting!') unless gets.chomp =~ /^y(es)?$/i
116
103
  instance = PromptsCreateInstance.create_instance(os_compute, 'nil')
@@ -120,12 +107,12 @@ class InstanceManager
120
107
 
121
108
  puts 'Available instances:'
122
109
  istatus = InstanceStatus.new(os_compute)
123
- istatus.all_instances(instances)
110
+ istatus.all_instances(instances_numhash)
124
111
 
125
112
  # Loop input until an existing instance is selected
126
113
  print 'Enter an instance to manage or enter a name for a new instance: '
127
114
 
128
- until comp_inst.check_instance(instance_name) == true
115
+ until instances_numhash.values.collect{|i| i[:name]}.include?(instance_name) # os_compute.instances.check_instance(instance_name) == true
129
116
  instance_name = gets.chomp
130
117
 
131
118
  until instance_name.empty? == false
@@ -146,20 +133,21 @@ class InstanceManager
146
133
  instance_name = instances_numhash[instance_name.to_i][:name].to_s
147
134
  end
148
135
 
149
- unless comp_inst.check_instance(instance_name) == true
136
+ unless instances_numhash.values.collect{|i| i[:name]}.include?(instance_name) # os_compute.instances.check_instance(instance_name) == true
150
137
  print "#{instance_name} is not a valid instance.
151
138
  Should we create a new instance named #{instance_name}? (Y/N): "
152
139
 
153
140
  if gets.chomp =~ /^y(es)?$/i
154
- PromptsCreateInstance.create_instance(os_compute, instance_name)
141
+ instance = PromptsCreateInstance.create_instance(os_compute, instance_name)
142
+ return instance
155
143
  else
156
144
  puts "Not creating new instance: #{instance_name}."
157
- return false
145
+ return
158
146
  end
159
147
  end
160
148
  end
161
149
 
162
- instance = comp_inst.get_instance(instance_name)
150
+ instance = os_compute.instances.get_instance(instance_name)
163
151
  Menus.print_menu('instance')
164
152
  puts "Managing instance: #{instance_name}\tStatus: #{instance.state}"
165
153
  instance
@@ -8,7 +8,7 @@ class InstanceStatus
8
8
  def all_instances(instances)
9
9
  istats = {}
10
10
 
11
- instances.map.with_index(1) do |instance, id|
11
+ instances.each do |id, instance|
12
12
  istats[id] = single_instance(instance)
13
13
  end
14
14
 
@@ -32,29 +32,22 @@ class InstanceStatus
32
32
  end
33
33
 
34
34
  def single_instance(instance)
35
- image = @images.get_image_by_id(instance.image['id'])
36
- flavor = @flavors.get_flavor_by_id(instance.flavor['id'])
37
-
38
- image = NilImage.new if image == nil
39
-
40
- istats = { 'name' => instance.name,
41
- 'status' => instance.state,
42
- 'image' => image.name,
43
- 'vcpus' => flavor.vcpus,
44
- 'ram' => flavor.ram,
45
- 'disk' => flavor.disk,
46
- 'keypair' => instance.key_name,
35
+ image = Helpers.object_to_hash(@images.get_image_by_id(instance[:image]['id']))
36
+ flavor = Helpers.object_to_hash(@flavors.get_flavor_by_id(instance[:flavor]['id']))
37
+
38
+ image = {:name => 'Not Found'} if image == nil
39
+
40
+ istats = { 'name' => instance[:name],
41
+ 'status' => instance[:state],
42
+ 'image' => image[:name],
43
+ 'vcpus' => flavor[:vcpus],
44
+ 'ram' => flavor[:ram],
45
+ 'disk' => flavor[:disk],
46
+ 'keypair' => instance[:key_name],
47
47
  }
48
48
  end
49
49
 
50
50
  def _header(format)
51
51
  printf("#{format}\n", 'Id', 'Name', 'Status', 'Image', 'VCPUS', 'RAM', 'Disk', 'KeyPair')
52
52
  end
53
-
54
- class NilImage
55
- def name
56
- 'Not Found'
57
- end
58
- end
59
53
  end
60
-
@@ -4,10 +4,8 @@ class Helpers
4
4
  def self.array_to_numhash(array)
5
5
  numbered_hash = {}
6
6
 
7
- count = 1
8
- array.sort.each do |item|
9
- numbered_hash[count] = item
10
- count += 1
7
+ array.each.with_index(1) do |item, id|
8
+ numbered_hash[id] = item
11
9
  end
12
10
 
13
11
  numbered_hash
@@ -23,7 +21,13 @@ class Helpers
23
21
  numbered_hash
24
22
  end
25
23
 
24
+ def self.object_to_hash(object)
25
+ return nil if !object
26
+ object.all_attributes
27
+ end
28
+
26
29
  def self.objects_to_numhash(objects)
30
+ return nil if !objects
27
31
  numbered_object_hash = {}
28
32
 
29
33
  objects.map.with_index(1) do | obj, index |
@@ -11,10 +11,13 @@ module DanarchySys
11
11
  connection = danarchysys_config[:connections][provider.to_sym]
12
12
  @settings = danarchysys_config[:global_settings]
13
13
  @compute = Fog::Compute::OpenStack.new(connection)
14
+ @instances = @compute.servers
15
+ @images = @compute.images(filters: {'status' => ['ACTIVE']})
16
+ @flavors = @compute.flavors
14
17
  end
15
18
 
16
19
  def instances
17
- ComputeInstances.new(@compute, @settings)
20
+ ComputeInstances.new(@compute, @instances, @settings)
18
21
  end
19
22
 
20
23
  def keypairs
@@ -22,11 +25,11 @@ module DanarchySys
22
25
  end
23
26
 
24
27
  def images
25
- ComputeImages.new(@compute)
28
+ ComputeImages.new(@compute, @images)
26
29
  end
27
30
 
28
31
  def flavors
29
- ComputeFlavors.new(@compute)
32
+ ComputeFlavors.new(@compute, @flavors)
30
33
  end
31
34
 
32
35
  def secgroups
@@ -47,11 +50,14 @@ module DanarchySys
47
50
  image_id = instance.image['id']
48
51
  image = comp_img.get_image_by_id(image_id)
49
52
 
53
+ ssh = nil
50
54
  if image == nil
51
55
  puts "Image not found for #{instance.name}! This instance needs to be rebuild with a current image."
52
- return fallback_ssh(ipv4, pemfile)
56
+ ssh = fallback_ssh(ipv4, pemfile)
53
57
  end
54
58
 
59
+ return ssh if ssh == true
60
+
55
61
  # CoreOS is an exception with user as simply 'core' and not 'coreos'
56
62
  user = 'ubuntu' if image.name =~ /ubuntu/i
57
63
  user = 'debian' if image.name =~ /debian/i
@@ -69,24 +75,25 @@ module DanarchySys
69
75
  sleep(5)
70
76
  fallback_ssh(ipv4, pemfile)
71
77
  attempts += 1
78
+ puts 'Giving up after 3 tries.' if attempts > 3
72
79
  end
80
+
81
+ ssh
73
82
  end
74
83
 
75
84
  def fallback_ssh(ipv4, pemfile)
76
85
  users = ['ubuntu','debian','centos','fedora','core']
77
- ssh = false
86
+ ssh = nil
78
87
 
79
88
  users.each do |user|
80
89
  puts "Attempting connection as user: #{user} => #{ipv4}"
81
90
  connect = "ssh #{user}@#{ipv4} -i '#{pemfile}'"
82
91
  ssh = system(connect)
83
- return true if ssh == true
92
+ break if ssh == true
84
93
  end
85
94
 
86
- if ssh == false
87
- puts 'Unable to connect after 3 tries!'
88
- return false
89
- end
95
+ puts 'Unable to connect! User unknown or SSHd is not running on the instance.' if ssh == false
96
+ ssh
90
97
  end
91
98
  end
92
99
  end
@@ -1,47 +1,25 @@
1
1
 
2
2
  # OpenStack Flavor Management
3
3
  class ComputeFlavors
4
- def initialize(compute)
4
+ def initialize(compute, flavors)
5
5
  @compute = compute
6
+ @flavors = flavors
6
7
  end
7
8
 
8
- def all_flavors
9
- @compute.flavors
9
+ def all_flavors(*filter)
10
+ filter = filter.shift || {'status' => ['ACTIVE']}
11
+ @flavors = @compute.flavors(filters: filter)
10
12
  end
11
13
 
12
- def list_flavors
13
- flavors = all_flavors
14
- flavor_list = []
15
-
16
- # Get flavor names into array
17
- flavors.each do |i|
18
- flavor_list.push(i.name.split('.')[1])
19
- end
20
-
21
- flavor_list
22
- end
23
-
24
- def get_flavor(flavor_name)
25
- flavors = all_flavors
26
-
27
- # Get flavor object based on input flavor_name.
28
- flavor = 'nil'
29
- flavors.each do |f|
30
- flavor = f if f.name.end_with?(flavor_name)
31
- end
32
-
33
- flavor
14
+ def get_flavor_by_name(flavor_name)
15
+ @flavors.collect do |f|
16
+ f if f.name.end_with?(flavor_name)
17
+ end.compact!.first
34
18
  end
35
19
 
36
20
  def get_flavor_by_id(flavor_id)
37
- flavors = all_flavors
38
-
39
- # Get flavor based on input flavor_id.
40
- flavor = 'nil'
41
- flavors.each do |i|
42
- flavor = i if i.id == flavor_id
43
- end
44
-
45
- flavor
21
+ @flavors.collect do |i|
22
+ i if i.id == flavor_id
23
+ end.compact!.first
46
24
  end
47
25
  end
@@ -1,39 +1,27 @@
1
1
 
2
2
  # OpenStack Image Management
3
3
  class ComputeImages
4
- def initialize(compute)
4
+ def initialize(compute, images)
5
5
  @compute = compute
6
+ @images = images
6
7
  end
7
8
 
8
9
  def all_images(*filter)
9
- filter = filter.shift || {}
10
- @compute.images(filters: filter)
11
- end
12
-
13
- def list_all_images
14
- all_images.collect { |i| i.name }
15
- end
16
-
17
- def list_active_images
18
- all_images({'status' => 'ACTIVE'})
10
+ filter = filter.shift || {'status' => ['ACTIVE']}
11
+ @images = @compute.images(filters: filter)
19
12
  end
20
13
 
21
14
  def get_image_by_name(image_name)
22
- all_images({
23
- 'status' => 'ACTIVE',
24
- 'name' => image_name
25
- }).first
26
- # .first may become a problem here
27
- # if names are duplicates
15
+ @images.collect do |i|
16
+ next unless i.status == 'ACTIVE'
17
+ next unless i.name == image_name
18
+ i
19
+ end.compact!.first
28
20
  end
29
21
 
30
22
  def get_image_by_id(image_id)
31
- image = nil
32
-
33
- all_images.each do |i|
34
- image = i if i.id == image_id
35
- end
36
-
37
- image
23
+ @images.collect do |i|
24
+ i if i.id == image_id
25
+ end.compact!.first
38
26
  end
39
27
  end
@@ -1,22 +1,25 @@
1
1
 
2
2
  # OpenStack Instance Management
3
3
  class ComputeInstances
4
- def initialize(compute, settings)
4
+ def initialize(compute, instances, settings)
5
5
  @compute = compute
6
+ @instances = instances
6
7
  @settings = settings
7
8
  end
8
9
 
9
10
  def all_instances(*filter)
10
11
  filter = filter.shift || {}
11
- @compute.servers(filters: filter)
12
+ @instances = @compute.servers(filters: filter)
12
13
  end
13
14
 
14
15
  def list_all_instances
15
- all_instances.collect { |i| i.name }
16
+ @instances.collect { |i| i.name }
16
17
  end
17
18
 
18
19
  def list_active_instances
19
- all_instances({ 'status' => ['ACTIVE'] }).collect { |i| i.name }
20
+ @instances.collect do |i|
21
+ i.name if i.status == 'ACTIVE'
22
+ end.compact!
20
23
  end
21
24
 
22
25
  def check_instance(instance_name)
@@ -33,74 +36,56 @@ class ComputeInstances
33
36
  end
34
37
 
35
38
  def get_public_addresses(instance)
36
- if instance.class == String
37
- instance = get_instance(instance)
38
- end
39
-
39
+ instance = get_instance(instance) if instance.class == String
40
40
  addrs = instance.addresses
41
- return false if !addrs['public']
41
+ return nil if !addrs['public']
42
42
  addrs['public'].map{|a| a['addr']}
43
43
  end
44
44
 
45
45
  def get_private_addresses(instance)
46
- if instance.class == String
47
- instance = get_instance(instance)
48
- end
49
-
46
+ instance = get_instance(instance) if instance.class == String
50
47
  addrs = instance.addresses
51
- return false if !addrs['private']
48
+ return nil if !addrs['private']
52
49
  addrs['public'].map{|a| a['addr']}
53
50
  end
54
51
 
55
52
  def pause(instance)
56
- if instance.class == String
57
- instance = get_instance(instance)
58
- end
53
+ instance = get_instance(instance) if instance.class == String
59
54
 
60
55
  return false unless instance.state == 'ACTIVE'
61
56
  instance.pause
62
57
  end
63
58
 
64
59
  def unpause(instance)
65
- if instance.class == String
66
- instance = get_instance(instance)
67
- end
60
+ instance = get_instance(instance) if instance.class == String
68
61
 
69
62
  return false unless instance.state == 'PAUSED'
70
63
  instance.start
71
64
  end
72
65
 
73
66
  def suspend(instance)
74
- if instance.class == String
75
- instance = get_instance(instance)
76
- end
67
+ instance = get_instance(instance) if instance.class == String
77
68
 
78
69
  return false unless instance.state == 'ACTIVE'
79
70
  instance.suspend
80
71
  end
81
72
 
82
73
  def resume(instance)
83
- if instance.class == String
84
- instance = get_instance(instance)
85
- end
74
+ instance = get_instance(instance) if instance.class == String
86
75
 
87
76
  return false unless instance.state == 'SUSPENDED'
88
77
  instance.start
89
78
  end
90
79
 
91
80
  def start(instance)
92
- if instance.class == String
93
- instance = get_instance(instance)
94
- end
81
+ instance = get_instance(instance) if instance.class == String
95
82
 
96
83
  return false unless instance.state == 'SHUTOFF'
97
84
  instance.start
98
85
  end
99
86
 
100
87
  def stop(instance)
101
- if instance.class == String
102
- instance = get_instance(instance)
103
- end
88
+ instance = get_instance(instance) if instance.class == String
104
89
 
105
90
  return false unless instance.state == 'ACTIVE'
106
91
  instance.stop
@@ -116,6 +101,8 @@ class ComputeInstances
116
101
  user_data: user_data)
117
102
 
118
103
  # add security_group
104
+ # add volumes
105
+ # handle user_data with base64 encoding
119
106
 
120
107
  # Put error handling from instance_prompts here
121
108
 
@@ -123,10 +110,23 @@ class ComputeInstances
123
110
  instance
124
111
  end
125
112
 
126
- def delete_instance(instance_name)
127
- # check for and delete instance
128
- instance = get_instance(instance_name)
113
+ def rebuild_instance(instance, image)
114
+ instance = get_instance(instance) if instance.class == String
115
+
116
+ instance.rebuild(image.id, instance.name)
117
+ addrs = [get_public_addresses(instance),
118
+ get_private_addresses(instance)].flatten.compact!
119
+ addrs.each { |addr| system("ssh-keygen -R #{addr}") }
120
+
121
+ instance.wait_for { ready? }
122
+ instance
123
+ end
124
+
125
+ def delete_instance(instance)
126
+ instance = get_instance(instance) if instance.class == String
129
127
  return 1 if instance == false
128
+
129
+ instance_name = instance.name
130
130
  @compute.delete_server(instance.id)
131
131
 
132
132
  attempt = 1
@@ -136,6 +136,10 @@ class ComputeInstances
136
136
  attempt += 1
137
137
  end
138
138
 
139
+ addrs = [get_public_addresses(instance),
140
+ get_private_addresses(instance)].flatten.compact!
141
+ addrs.each { |addr| system("ssh-keygen -R #{addr}") }
142
+
139
143
  return true
140
144
  end
141
145
  end
@@ -1,3 +1,3 @@
1
1
  module DanarchySys
2
- VERSION = "0.3.2"
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danarchy_sys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan James
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-31 00:00:00.000000000 Z
11
+ date: 2017-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog-openstack
@@ -93,8 +93,6 @@ files:
93
93
  - bin/danarchy_sys
94
94
  - danarchy_sys.gemspec
95
95
  - lib/danarchy_sys.rb
96
- - lib/danarchy_sys/aws.rb
97
- - lib/danarchy_sys/aws/compute.rb
98
96
  - lib/danarchy_sys/cli.rb
99
97
  - lib/danarchy_sys/cli/instance_manager.rb
100
98
  - lib/danarchy_sys/cli/instance_manager/instance_status.rb
@@ -1,9 +0,0 @@
1
-
2
- require 'fog/aws'
3
-
4
- module DanarchySys
5
- module AWS
6
- # Load AWS compute requirements
7
- require_relative 'aws/compute'
8
- end
9
- end
@@ -1,13 +0,0 @@
1
- module DanarchySys
2
- module AWS
3
- class Compute
4
- def initialize(provider)
5
- config = ConfigManager.new
6
- danarchysys_config = config.load
7
- connection = danarchysys_config[:connections][provider]
8
- @settings = danarchysys_config[:settings]
9
- @compute = Fog::Compute::AWS.new(connection)
10
- end
11
- end
12
- end
13
- end