danarchy_sys 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE +21 -0
  7. data/README.txt +86 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +6 -0
  10. data/bin/danarchy_sys +4 -0
  11. data/bin/setup +18 -0
  12. data/bin/setup.rb +86 -0
  13. data/danarchy_sys.gemspec +38 -0
  14. data/lib/danarchy_sys.rb +16 -0
  15. data/lib/danarchy_sys/aws.rb +9 -0
  16. data/lib/danarchy_sys/aws/compute.rb +13 -0
  17. data/lib/danarchy_sys/cli.rb +63 -0
  18. data/lib/danarchy_sys/cli/instance_manager.rb +130 -0
  19. data/lib/danarchy_sys/cli/instance_manager/instance_status.rb +50 -0
  20. data/lib/danarchy_sys/cli/instance_manager/prompts_create_instance.rb +182 -0
  21. data/lib/danarchy_sys/cli/menus.rb +60 -0
  22. data/lib/danarchy_sys/cli/providers.rb +33 -0
  23. data/lib/danarchy_sys/config.rb +66 -0
  24. data/lib/danarchy_sys/helpers.rb +61 -0
  25. data/lib/danarchy_sys/openstack.rb +9 -0
  26. data/lib/danarchy_sys/openstack/compute.rb +59 -0
  27. data/lib/danarchy_sys/openstack/compute/flavors.rb +47 -0
  28. data/lib/danarchy_sys/openstack/compute/images.rb +52 -0
  29. data/lib/danarchy_sys/openstack/compute/instances.rb +120 -0
  30. data/lib/danarchy_sys/openstack/compute/keypairs.rb +84 -0
  31. data/lib/danarchy_sys/openstack/compute/tests/answer_yes.rb +7 -0
  32. data/lib/danarchy_sys/openstack/compute/tests/flavors_test.rb +10 -0
  33. data/lib/danarchy_sys/openstack/compute/tests/images_test.rb +14 -0
  34. data/lib/danarchy_sys/openstack/compute/tests/instance_create_test.rb +14 -0
  35. data/lib/danarchy_sys/openstack/compute/tests/instance_manage_test.rb +24 -0
  36. data/lib/danarchy_sys/openstack/compute/tests/keypairs_prompt_test.rb +12 -0
  37. data/lib/danarchy_sys/openstack/compute/tests/keypairs_test.rb +38 -0
  38. data/lib/danarchy_sys/openstack/compute/tests/manage_test.rb +16 -0
  39. data/lib/danarchy_sys/printformats.rb +49 -0
  40. data/lib/danarchy_sys/version.rb +3 -0
  41. metadata +151 -0
@@ -0,0 +1,50 @@
1
+
2
+ class InstanceStatus
3
+ def self.all_instances(os_compute, instances)
4
+ istats = {}
5
+
6
+ id = 1
7
+ instances.each do |instance|
8
+ istats[id] = single_instance(os_compute, instance)
9
+ id += 1
10
+ end
11
+
12
+ fields = %w[name state image vcpus ram disk keypair]
13
+ format = PrintFormats.printf_numhash_values(istats, fields)
14
+ _header(format)
15
+
16
+ istats.each do |id, i|
17
+ printf("#{format}\n", "#{id}.",
18
+ i['name'],
19
+ i['state'],
20
+ i['image'],
21
+ i['vcpus'],
22
+ i['ram'],
23
+ i['disk'],
24
+ i['keypair'],
25
+ )
26
+ end
27
+ end
28
+
29
+ def self.single_instance(os_compute, instance)
30
+ comp_inst = os_compute.compute_instances
31
+ comp_imgs = os_compute.compute_images
32
+ comp_flvs = os_compute.compute_flavors
33
+
34
+ image = comp_imgs.get_image_by_id(instance.image['id'])
35
+ flavor = comp_flvs.get_flavor_by_id(instance.flavor['id'])
36
+
37
+ istats = { 'name' => instance.name,
38
+ 'state' => instance.state,
39
+ 'image' => image.name,
40
+ 'vcpus' => flavor.vcpus,
41
+ 'ram' => flavor.ram,
42
+ 'disk' => flavor.disk,
43
+ 'keypair' => instance.key_name,
44
+ }
45
+ end
46
+
47
+ def self._header(format)
48
+ printf("#{format}\n", 'Id', 'Name', 'State', 'Image', 'VCPUS', 'RAM', 'Disk', 'KeyPair')
49
+ end
50
+ end
@@ -0,0 +1,182 @@
1
+
2
+ # CLI Prompt to create a new instance
3
+ class PromptsCreateInstance
4
+ def self.create_instance(os_compute, instance_name)
5
+ comp_inst = os_compute.compute_instances
6
+ comp_imgs = os_compute.compute_images
7
+ comp_flvs = os_compute.compute_flavors
8
+ comp_keys = os_compute.compute_keypairs
9
+
10
+ # Prompt for and check that instance_name is unused
11
+ if instance_name == 'nil'
12
+ print "\nWhat should we name the instance?: "
13
+ instance_name = gets.chomp
14
+ end
15
+
16
+ # Make sure instance_name isn't already in use
17
+ until comp_inst.check_instance(instance_name) == false
18
+ print "\n#{instance_name} already exists! Try another name: "
19
+ instance_name = gets.chomp
20
+ end
21
+
22
+ puts "Creating instance: #{instance_name}"
23
+
24
+ # Prompt for image
25
+ puts "\nSelect an image (operating system) for #{instance_name}"
26
+ image = PromptsCreateInstance.image(comp_imgs)
27
+
28
+ # Prompt for flavor
29
+ puts "\nSelect a flavor (instance size) for #{instance_name}"
30
+ flavor = PromptsCreateInstance.flavor(comp_flvs)
31
+
32
+ # Prompt for keypair
33
+ puts "\nSelect a keypair (SSH key) for #{instance_name}"
34
+ keypair = PromptsCreateInstance.keypair(comp_keys)
35
+
36
+ # Print summary and prompt to continue
37
+ puts "\nInstance Name: #{instance_name}"
38
+ puts " Linux: #{image.name}"
39
+ puts "Instance Size: #{flavor.name}"
40
+ puts " Keypair: #{keypair.name}"
41
+
42
+ print 'Should we continue with creating the instance? (Y/N): '
43
+ instance = 'nil'
44
+ continue = gets.chomp
45
+
46
+ if continue =~ /^y(es)?$/i
47
+ puts "Creating instance: #{instance_name}"
48
+ instance = comp_inst.create_instance(instance_name, image.id, flavor.id, keypair.name)
49
+ else
50
+ puts "Abandoning creation of #{instance_name}"
51
+ return false
52
+ end
53
+
54
+ instance_check = comp_inst.check_instance(instance_name)
55
+
56
+ if instance_check == true
57
+ puts "Instance #{instance.name} is ready!"
58
+ return instance
59
+ else
60
+ raise "Error: Could not create instance: #{instance_name}" if instance_check == false
61
+ end
62
+ end
63
+
64
+ def self.image(comp_imgs)
65
+ images_numbered = Helpers.array_to_numhash(comp_imgs.list_images)
66
+ image_name = 'nil'
67
+
68
+ # List available images in a numbered hash.
69
+ puts "\nAvailable Images:"
70
+ i_name_length = Helpers.hash_largest_value(images_numbered).length
71
+ printf("%0s %-#{i_name_length}s\n", 'Id', 'Image')
72
+ images_numbered.each do |id, i_name|
73
+ printf("%0s %-#{i_name_length}s\n", "#{id}.", i_name)
74
+ end
75
+
76
+ # Loop input until existing image is selected
77
+ print 'Which image should we use for this instance?: '
78
+ until images_numbered.values.include?(image_name)
79
+ image_name = gets.chomp
80
+
81
+ if image_name =~ /^[0-9]*$/
82
+ until images_numbered.keys.include?(image_name)
83
+ print "#{image_name} is not a valid Id. Enter an Id from above: "
84
+ image_name = gets.chomp
85
+ end
86
+
87
+ image_name = images_numbered[image_name.to_s]
88
+ end
89
+
90
+ image_check = images_numbered.values.include?(image_name)
91
+ print "#{image_name} is not a valid image. Please enter an option from above: " if image_check == false
92
+ end
93
+
94
+ print "Image Name: #{image_name}\n"
95
+ comp_imgs.get_image_by_name(image_name)
96
+ end
97
+
98
+ def self.flavor(comp_flvs)
99
+ flavors = Helpers.objects_to_numhash(comp_flvs.all_flavors.sort_by(&:ram))
100
+ flavor_name = 'nil'
101
+
102
+ puts "\nAvailable Instance Flavors:"
103
+ puts sprintf("%0s %-15s %-10s %-10s %0s", 'Id', 'Name', 'RAM', 'VCPUs', 'Disk')
104
+ flavors.each do |id, flavor|
105
+ print sprintf("%0s %-15s %-10s %-10s %0s\n",
106
+ "#{id}.", flavor[:name].split('.')[1], flavor[:ram], flavor[:vcpus], flavor[:disk])
107
+ end
108
+
109
+ print 'Which flavor should we use for this instance?: '
110
+ flavor_check = false
111
+
112
+ until flavor_check == true
113
+ flavor_name = gets.chomp
114
+
115
+ if flavor_name =~ /^[0-9]*$/
116
+ until flavors.keys.include?(flavor_name.to_i)
117
+ print "#{flavor_name} is not a valid Id. Enter an Id from above: "
118
+ flavor_name = gets.chomp
119
+ end
120
+
121
+ flavor_name = flavors[flavor_name.to_i][:name].split('.')[1]
122
+ end
123
+
124
+ flavors.each_value do |flavor|
125
+ flavor_check = true if flavor[:name].end_with?(flavor_name)
126
+ end
127
+
128
+ print "#{flavor_name} is not a valid flavor. Please enter an option from above: " if flavor_check == false
129
+ end
130
+
131
+ print "Flavor Name: #{flavor_name}\n"
132
+ comp_flvs.get_flavor(flavor_name)
133
+ end
134
+
135
+ def self.keypair(comp_keys)
136
+ keypairs = Helpers.objects_to_numhash(comp_keys.all_keypairs)
137
+ keypair_name = 'nil'
138
+
139
+ # List available keypairs
140
+ puts "\nAvailable Keypairs:"
141
+ print sprintf("%0s %-15s\n", 'Id', 'KeyPair Name')
142
+ keypairs.each do |id, key|
143
+ print sprintf("%0s %-15s\n", "#{id}.", key[:name])
144
+ end
145
+
146
+ # Loop input until existing flavor is selected or create a new one
147
+ print 'Enter a keypair to use for this instance or enter a name for a new keypair : '
148
+ keypair_check = false
149
+
150
+ until keypair_check == true
151
+ keypair_name = gets.chomp
152
+
153
+ # Accept keypair Id as an entry
154
+ if keypair_name =~ /^[0-9]*$/
155
+ until keypairs.keys.include?(keypair_name.to_i)
156
+ print "#{keypair_name} is not a valid Id.
157
+ Enter an Id from above, or \'return\' to restart keypair selection. : "
158
+ keypair_name = gets.chomp
159
+ return keypair(settings, compute) if keypair_name == 'return'
160
+ end
161
+
162
+ keypair_name = keypairs[keypair_name.to_i][:name]
163
+ end
164
+
165
+ keypair_check = Helpers.check_nested_hash_value(keypairs, :name, keypair_name)
166
+
167
+ if keypair_check == false
168
+ print "#{keypair_name} is not an existing keypair.
169
+ Should we create a new keypair named #{keypair_name}? (Y/N): "
170
+
171
+ if gets.chomp =~ /^y(es)?$/i
172
+ puts "Creating keypair: #{keypair_name}!"
173
+ return comp_keys.create_keypair(keypair_name)
174
+ else
175
+ print 'Please enter an option from above: '
176
+ end
177
+ end
178
+ end
179
+
180
+ comp_keys.get_keypair(keypair_name)
181
+ end
182
+ end
@@ -0,0 +1,60 @@
1
+
2
+ class Menus
3
+ def self.get_menu(menu)
4
+ menus = { 'main' => { 'instance' => 'Instance Manager',
5
+ 'keypair' => 'Keypair Manager (Not yet implemented!)',
6
+ 'help' => 'Outputs commands for current the menu level',
7
+ 'exit' => 'Exit dAnarchy_sys'},
8
+ 'instance' => { 'status' => 'Current running status of instance',
9
+ 'connect' => 'Connect to instance through SSH',
10
+ 'start' => 'Start a currently stopped instance',
11
+ 'stop' => 'Stop a currently running instance',
12
+ 'pause' => 'Pause instance (to RAM)',
13
+ 'unpause' => 'Unpause instance from paused state',
14
+ 'suspend' => 'Suspend Instance (to disk)',
15
+ 'resume' => 'Resume instance from suspended state',
16
+ 'create' => 'Create a new instance',
17
+ 'delete' => 'Delete this instance'}
18
+ }
19
+
20
+ menus[menu]
21
+ end
22
+
23
+ def self.numbered_menu(menu)
24
+ numbered_menu = Helpers.hash_to_numhash(get_menu(menu))
25
+ end
26
+
27
+ def self.print_menu(menu)
28
+ if menu == 'main'
29
+ puts 'dAnarchy_sys main menu commands:'
30
+ puts 'Enter \'help\' to view available commands or \'exit\' to leave.'
31
+ # print_menu(menu)
32
+ elsif menu == 'instance'
33
+ puts 'Instance Manager commands: '
34
+ puts 'Enter \'help\' to view available commands or \'back\' for the main menu.'
35
+ # print_menu(menu)
36
+ elsif menu == 'keypair'
37
+ puts 'Keypair Manager commands: '
38
+ puts 'Not yet implemented!'
39
+ return
40
+ # print_menu(menu)
41
+ elsif menu == 'storage'
42
+ puts 'Storage Manager commands: '
43
+ puts 'Not yet implemented!'
44
+ return
45
+ # print_menu(menu)
46
+ end
47
+
48
+ # numbered_menu = Helpers.hash_to_numhash(menu)
49
+ numbered_menu = numbered_menu(menu)
50
+ menu = get_menu(menu)
51
+
52
+ fields = PrintFormats.printf_numhash(numbered_menu)
53
+
54
+ numbered_menu.each do |id, v|
55
+ v.each do |name, info|
56
+ printf("#{fields}\n", "#{id}.", "#{name}:", info)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+
2
+ class Providers
3
+ def self.chooser
4
+ config = ConfigMgr.new
5
+ danarchysys_config = config.load
6
+ providers = Helpers.array_to_numhash(danarchysys_config[:connections].keys)
7
+ provider = 'nil'
8
+
9
+ if providers.count == 1
10
+ provider = providers['1']
11
+ return provider
12
+ end
13
+
14
+ fields = PrintFormats.printf_hash(providers)
15
+ printf("#{fields}\n", 'Id', 'Provider')
16
+ providers.each do |id, provider|
17
+ printf("#{fields}\n", "#{id}.", provider)
18
+ end
19
+
20
+ until providers.values.include?(provider)
21
+ print 'Which provider should we use? (enter \'exit\' to leave): '
22
+ provider = gets.chomp
23
+
24
+ abort('Exiting') if provider == 'exit'
25
+
26
+ if provider =~ /^[0-9]*$/ # select by Id
27
+ provider = providers[provider.to_s]
28
+ end
29
+ end
30
+
31
+ provider
32
+ end
33
+ end
@@ -0,0 +1,66 @@
1
+
2
+ require 'yaml'
3
+
4
+ # dAnarchy_sys config management
5
+ class ConfigMgr
6
+ def initialize
7
+ @danarchysys_path = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
8
+ @config_file = File.join(@danarchysys_path, 'config', 'danarchysys.yml')
9
+ end
10
+
11
+ def config_template
12
+ config_template = {
13
+ :connections => {},
14
+ :settings => {}
15
+ }
16
+ end
17
+
18
+ def load
19
+ if File.exists?(@config_file)
20
+ return YAML.load_file(@config_file)
21
+ else
22
+ return config_template
23
+ end
24
+ end
25
+
26
+ def save(param_hash)
27
+ File.write(@config_file, param_hash.to_yaml)
28
+ end
29
+
30
+ def connection_add(provider, openstack_auth_url, openstack_username, openstack_api_key, openstack_tenant)
31
+ danarchysys_config = load
32
+
33
+ danarchysys_config[:connections][provider.to_sym] = {
34
+ openstack_auth_url: openstack_auth_url,
35
+ openstack_username: openstack_username,
36
+ openstack_api_key: openstack_api_key,
37
+ openstack_tenant: openstack_tenant
38
+ }
39
+
40
+ danarchysys_config
41
+ end
42
+
43
+ def connection_delete(provider)
44
+ danarchysys_config = load
45
+
46
+ danarchysys_config[:connections].delete(provider.to_sym)
47
+
48
+ danarchysys_config
49
+ end
50
+
51
+ def setting_add(name, value)
52
+ danarchysys_config = load
53
+
54
+ danarchysys_config[:settings][name.to_sym] = value
55
+
56
+ danarchysys_config
57
+ end
58
+
59
+ def setting_delete(name)
60
+ danarchysys_config = load
61
+
62
+ danarchysys_config[:settings].delete(name.to_sym)
63
+
64
+ danarchysys_config
65
+ end
66
+ end
@@ -0,0 +1,61 @@
1
+
2
+ # Routine methods for DanarchySys
3
+ class Helpers
4
+ def self.array_to_numhash(array)
5
+ numbered_hash = {}
6
+
7
+ count = 1
8
+ array.sort.each do |item|
9
+ numbered_hash[count.to_s] = item
10
+ count += 1
11
+ end
12
+
13
+ numbered_hash
14
+ end
15
+
16
+ def self.hash_to_numhash(hash)
17
+ numbered_hash = {}
18
+
19
+ hash.map.with_index(1) do | (k, v), index |
20
+ numbered_hash[index] = {k => v}
21
+ end
22
+
23
+ numbered_hash
24
+ end
25
+
26
+ def self.objects_to_numhash(objects)
27
+ numbered_object_hash = {}
28
+
29
+ objects.map.with_index(1) do | obj, index |
30
+ numbered_object_hash[index] = obj.all_attributes
31
+ end
32
+
33
+ numbered_object_hash
34
+ end
35
+
36
+ def self.hash_largest_key(hash)
37
+ hash.keys.map(&:to_s).max_by(&:size)
38
+ end
39
+
40
+ def self.hash_largest_value(hash)
41
+ hash.values.map(&:to_s).max_by(&:size)
42
+ end
43
+
44
+ def self.hash_largest_nested_key(hash)
45
+ hash.each_value.flat_map(&:keys).max_by(&:size)
46
+ end
47
+
48
+ def self.hash_largest_nested_value(hash)
49
+ hash.each_value.flat_map(&:values).max_by(&:size)
50
+ end
51
+
52
+ def self.check_nested_hash_value(hash, key, value)
53
+ check = false
54
+
55
+ hash.each_value do |val|
56
+ check = true if val[key].end_with?(value)
57
+ end
58
+
59
+ check
60
+ end
61
+ end