morpheus-cli 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,261 @@
1
+ # require 'yaml'
2
+ require 'io/console'
3
+ require 'rest_client'
4
+ require 'term/ansicolor'
5
+ require 'optparse'
6
+
7
+
8
+ class Morpheus::Cli::Servers
9
+ include Term::ANSIColor
10
+ def initialize()
11
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
12
+ @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
13
+ @servers_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).servers
14
+ @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
15
+ @zones_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).zones
16
+ @zone_types = @zones_interface.zone_types['zoneTypes']
17
+ @active_groups = ::Morpheus::Cli::Groups.load_group_file
18
+ end
19
+
20
+ def handle(args)
21
+ if @access_token.empty?
22
+ print red,bold, "\nInvalid Credentials. Unable to acquire access token. Please verify your credentials and try again.\n\n",reset
23
+ return 1
24
+ end
25
+ if args.empty?
26
+ puts "\nUsage: morpheus servers [list,add,remove] [name]\n\n"
27
+ end
28
+
29
+ case args[0]
30
+ when 'list'
31
+ list(args[1..-1])
32
+ when 'add'
33
+ add(args[1..-1])
34
+ when 'remove'
35
+ remove(args[1..-1])
36
+ else
37
+ puts "\nUsage: morpheus servers [list,add,remove] [name]\n\n"
38
+ end
39
+ end
40
+
41
+ def add(args)
42
+ if args.count < 2
43
+ puts "\nUsage: morpheus servers add ZONE [name]\n\n"
44
+ return
45
+ end
46
+ options = {zone: args[0]}
47
+
48
+ zone=nil
49
+ if !options[:group].nil?
50
+ group = find_group_by_name(options[:group])
51
+ if !group.nil?
52
+ options['groupId'] = group['id']
53
+ end
54
+ else
55
+ options['groupId'] = @active_groups[@appliance_name.to_sym]
56
+ end
57
+
58
+ if !options['groupId'].nil?
59
+ if !options[:zone].nil?
60
+ zone = find_zone_by_name(options['groupId'], options[:zone])
61
+ if !zone.nil?
62
+ options['zoneId'] = zone['id']
63
+ end
64
+ end
65
+ end
66
+
67
+ if options['zoneId'].nil?
68
+ puts red,bold,"\nEither the zone was not specified or was not found. Please make sure a zone is specified with --zone\n\n", reset
69
+ return
70
+ end
71
+
72
+ zone_type = zone_type_for_id(zone['zoneTypeId'])
73
+ begin
74
+ case zone_type['code']
75
+ when 'standard'
76
+ add_standard(args[1],options[:description],zone, args[2..-1])
77
+ list([])
78
+ when 'openstack'
79
+ add_openstack(args[1],options[:description],zone, args[2..-1])
80
+ list([])
81
+ when 'amazon'
82
+ add_amazon(args[1],options[:description],zone, args[2..-1])
83
+ list([])
84
+ else
85
+ puts "Unsupported Zone Type: This version of the morpheus cli does not support the requested zone type"
86
+ end
87
+ rescue RestClient::Exception => e
88
+ if e.response.code == 400
89
+ error = JSON.parse(e.response.to_s)
90
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
91
+ else
92
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
93
+ end
94
+ return nil
95
+ end
96
+ end
97
+
98
+ def remove(args)
99
+ if args.count < 1
100
+ puts "\nUsage: morpheus servers remove [name]\n\n"
101
+ return
102
+ end
103
+ begin
104
+ server_results = @servers_interface.get({name: args[0]})
105
+ if server_results['servers'].empty?
106
+ puts "Server not found by name #{args[0]}"
107
+ return
108
+ end
109
+ @servers_interface.destroy(server_results['servers'][0]['id'])
110
+ list([])
111
+ rescue RestClient::Exception => e
112
+ if e.response.code == 400
113
+ error = JSON.parse(e.response.to_s)
114
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
115
+ else
116
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
117
+ end
118
+ return nil
119
+ end
120
+ end
121
+
122
+ def list(args)
123
+ options = {}
124
+ optparse = OptionParser.new do|opts|
125
+ opts.on( '-g', '--group GROUP', "Group Name" ) do |group|
126
+ options[:group] = group
127
+ end
128
+ end
129
+ optparse.parse(args)
130
+ begin
131
+ params = {}
132
+ if !options[:group].nil?
133
+ group = find_group_by_name(options[:group])
134
+ if !group.nil?
135
+ params['site'] = group['id']
136
+ end
137
+ end
138
+
139
+ json_response = @servers_interface.get(params)
140
+ servers = json_response['servers']
141
+ print "\n" ,red, bold, "Morpheus Servers\n","==================", reset, "\n\n"
142
+ if servers.empty?
143
+ puts yellow,"No servers currently configured.",reset
144
+ else
145
+ servers.each do |server|
146
+ print red, "= #{server['name']} - #{server['description']} (#{server['status']})\n"
147
+ end
148
+ end
149
+ print reset,"\n\n"
150
+
151
+ rescue => e
152
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
153
+ return nil
154
+ end
155
+ end
156
+
157
+ private
158
+
159
+
160
+ def add_openstack(name, description,zone, args)
161
+ options = {}
162
+ optparse = OptionParser.new do|opts|
163
+
164
+ opts.on( '-s', '--size SIZE', "Disk Size" ) do |size|
165
+ options[:diskSize] = size.to_l
166
+ end
167
+ opts.on('-i', '--image IMAGE', "Image Name") do |image|
168
+ options[:imageName] = image
169
+ end
170
+
171
+ opts.on('-f', '--flavor FLAVOR', "Flavor Name") do |flavor|
172
+ options[:flavorName] = flavor
173
+ end
174
+ end
175
+ optparse.parse(args)
176
+
177
+ server_payload = {server: {name: name, description: description}, zoneId: zone['id']}
178
+ response = @servers_interface.create(server_payload)
179
+ end
180
+
181
+ def add_standard(name,description,zone, args)
182
+ options = {}
183
+ networkOptions = {name: 'eth0'}
184
+ optparse = OptionParser.new do|opts|
185
+ opts.banner = "Usage: morpheus server add ZONE NAME [options]"
186
+ opts.on( '-u', '--ssh-user USER', "SSH Username" ) do |sshUser|
187
+ options['sshUsername'] = sshUser
188
+ end
189
+ opts.on('-p', '--password PASSWORD', "SSH Password (optional)") do |password|
190
+ options['sshPassword'] = password
191
+ end
192
+
193
+ opts.on('-h', '--host HOST', "HOST IP") do |host|
194
+ options['sshHost'] = host
195
+ end
196
+
197
+ options['dataDevice'] = '/dev/sdb'
198
+ opts.on('-m', '--data-device DATADEVICE', "Data device for LVM") do |device|
199
+ options['dataDevice'] = device
200
+ end
201
+
202
+
203
+ opts.on('-n', '--interface NETWORK', "Default Network Interface") do |net|
204
+ networkOptions[:name] = net
205
+ end
206
+
207
+ opts.on_tail(:NONE, "--help", "Show this message") do
208
+ puts opts
209
+ exit
210
+ end
211
+ end
212
+ optparse.parse(args)
213
+
214
+ server_payload = {server: {name: name, description: description, zone: {id: zone['id']}}.merge(options), network: networkOptions}
215
+ response = @servers_interface.create(server_payload)
216
+
217
+ end
218
+
219
+ def add_amazon(name,description,zone, args)
220
+ puts "NOT YET IMPLEMENTED"
221
+ end
222
+
223
+ def zone_type_for_id(id)
224
+ # puts "Zone Types #{@zone_types}"
225
+ if !@zone_types.empty?
226
+ zone_type = @zone_types.find { |z| z['id'].to_i == id.to_i}
227
+ if !zone_type.nil?
228
+ return zone_type
229
+ end
230
+ end
231
+ return nil
232
+ end
233
+
234
+
235
+ def find_group_by_name(name)
236
+ group_results = @groups_interface.get(name)
237
+ if group_results['groups'].empty?
238
+ puts "Group not found by name #{name}"
239
+ return nil
240
+ end
241
+ return group_results['groups'][0]
242
+ end
243
+
244
+ def find_zone_by_name(groupId, name)
245
+ zone_results = @zones_interface.get({groupId: groupId, name: name})
246
+ if zone_results['zones'].empty?
247
+ puts "Zone not found by name #{name}"
248
+ return nil
249
+ end
250
+ return zone_results['zones'][0]
251
+ end
252
+
253
+ def find_group_by_id(id)
254
+ group_results = @groups_interface.get(id)
255
+ if group_results['groups'].empty?
256
+ puts "Group not found by id #{id}"
257
+ return nil
258
+ end
259
+ return group_results['groups'][0]
260
+ end
261
+ end
@@ -0,0 +1,5 @@
1
+ module Morpheus
2
+ module Cli
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,204 @@
1
+ # require 'yaml'
2
+ require 'io/console'
3
+ require 'rest_client'
4
+ require 'term/ansicolor'
5
+ require 'optparse'
6
+
7
+
8
+ class Morpheus::Cli::Zones
9
+ include Term::ANSIColor
10
+ def initialize()
11
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
12
+ @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
13
+ @zones_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).zones
14
+ @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
15
+ @zone_types = @zones_interface.zone_types['zoneTypes']
16
+ end
17
+
18
+ def handle(args)
19
+ if @access_token.empty?
20
+ print red,bold, "\nInvalid Credentials. Unable to acquire access token. Please verify your credentials and try again.\n\n",reset
21
+ return 1
22
+ end
23
+ if args.empty?
24
+ puts "\nUsage: morpheus zones [list,add,remove] [name]\n\n"
25
+ end
26
+
27
+ case args[0]
28
+ when 'list'
29
+ list(args[1..-1])
30
+ when 'add'
31
+ add(args[1..-1])
32
+ when 'remove'
33
+ remove(args[1..-1])
34
+ else
35
+ puts "\nUsage: morpheus zones [list,add,remove] [name]\n\n"
36
+ end
37
+ end
38
+
39
+ def add(args)
40
+ if args.count < 1
41
+ puts "\nUsage: morpheus zones add [name] --group GROUP --type TYPE\n\n"
42
+ return
43
+ end
44
+ params = {zone_type: 'standard'}
45
+ optparse = OptionParser.new do|opts|
46
+ opts.on( '-g', '--group GROUP', "Group Name" ) do |group|
47
+ params[:group] = group
48
+ end
49
+ opts.on( '-t', '--type TYPE', "Zone Type" ) do |zone_type|
50
+ params[:zone_type] = zone_type
51
+ end
52
+ opts.on( '-d', '--description DESCRIPTION', "Description (optional)" ) do |desc|
53
+ params[:description] = desc
54
+ end
55
+ end
56
+ optparse.parse(args)
57
+ zone = {name: args[0], description: params[:description]}
58
+ if !params[:group].nil?
59
+ group = find_group_by_name(params[:group])
60
+ if !group.nil?
61
+ zone['groupId'] = group['id']
62
+ end
63
+ end
64
+
65
+ if !params[:zone_type].nil?
66
+ zone['zoneType'] = {code:zone_type_code_for_name(params[:zone_type])}
67
+ end
68
+
69
+ begin
70
+ @zones_interface.create(zone)
71
+ rescue => e
72
+ if e.response.code == 400
73
+ error = JSON.parse(e.response.to_s)
74
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
75
+ else
76
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
77
+ end
78
+ return nil
79
+ end
80
+ list([])
81
+ end
82
+
83
+ def remove(args)
84
+ if args.count < 2
85
+ puts "\nUsage: morpheus zones remove [name] --group GROUP\n\n"
86
+ return
87
+ end
88
+
89
+ params = {}
90
+ optparse = OptionParser.new do|opts|
91
+ opts.on( '-g', '--group GROUP', "Group Name" ) do |group|
92
+ params[:group] = group
93
+ end
94
+ end
95
+ optparse.parse(args)
96
+
97
+ if !params[:group].nil?
98
+ group = find_group_by_name(params[:group])
99
+ if !group.nil?
100
+ params[:groupId] = group['id']
101
+ else
102
+ puts "\nGroup #{params[:group]} not found!"
103
+ return
104
+ end
105
+ else params[:group].nil?
106
+ puts "\nUsage: morpheus zones remove [name] --group GROUP"
107
+ return
108
+ end
109
+
110
+
111
+ begin
112
+ zone_results = @zones_interface.get({name: args[0], groupId: params[:groupId]})
113
+ if zone_results['zones'].empty?
114
+ puts "Zone not found by name #{args[0]}"
115
+ return
116
+ end
117
+ @zones_interface.destroy(zone_results['zones'][0]['id'])
118
+ list([])
119
+ rescue RestClient::Exception => e
120
+ if e.response.code == 400
121
+ error = JSON.parse(e.response.to_s)
122
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
123
+ else
124
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
125
+ end
126
+ return nil
127
+ end
128
+ end
129
+
130
+ def list(args)
131
+ options = {}
132
+ optparse = OptionParser.new do|opts|
133
+ opts.on( '-g', '--group GROUP', "Group Name" ) do |group|
134
+ options[:group] = group
135
+ end
136
+ end
137
+ optparse.parse(args)
138
+ begin
139
+ params = {}
140
+ if !options[:group].nil?
141
+ group = find_group_by_name(options[:group])
142
+ if !group.nil?
143
+ params['groupId'] = group['id']
144
+ end
145
+ end
146
+
147
+ json_response = @zones_interface.get(params)
148
+ zones = json_response['zones']
149
+ print "\n" ,cyan, bold, "Morpheus Zones\n","==================", reset, "\n\n"
150
+ if zones.empty?
151
+ puts yellow,"No zones currently configured.",reset
152
+ else
153
+ zones.each do |zone|
154
+ print cyan, "= #{zone['name']} (#{zone_type_for_id(zone['zoneTypeId'])}) - #{zone['description']}\n"
155
+ end
156
+ end
157
+ print reset,"\n\n"
158
+
159
+ rescue => e
160
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
161
+ return nil
162
+ end
163
+ end
164
+
165
+ private
166
+
167
+ def zone_type_for_id(id)
168
+ if !@zone_types.empty?
169
+ zone_type = @zone_types.find { |z| z['id'].to_i == id.to_i}
170
+ if !zone_type.nil?
171
+ return zone_type['name']
172
+ end
173
+ end
174
+ return nil
175
+ end
176
+
177
+ def zone_type_code_for_name(name)
178
+ if !@zone_types.empty?
179
+ zone_type = @zone_types.find { |z| z['name'].downcase == name.downcase}
180
+ if !zone_type.nil?
181
+ return zone_type['code']
182
+ end
183
+ end
184
+ return nil
185
+ end
186
+
187
+ def find_group_by_name(name)
188
+ group_results = @groups_interface.get(name)
189
+ if group_results['groups'].empty?
190
+ puts "Group not found by name #{name}"
191
+ return nil
192
+ end
193
+ return group_results['groups'][0]
194
+ end
195
+
196
+ def find_group_by_id(id)
197
+ group_results = @groups_interface.get(id)
198
+ if group_results['groups'].empty?
199
+ puts "Group not found by id #{id}"
200
+ return nil
201
+ end
202
+ return group_results['groups'][0]
203
+ end
204
+ end
@@ -0,0 +1,21 @@
1
+ require "morpheus/cli/version"
2
+
3
+ module Morpheus
4
+ module Cli
5
+ require 'morpheus/api/api_client'
6
+ require 'morpheus/api/groups_interface'
7
+ require 'morpheus/api/zones_interface'
8
+ require 'morpheus/api/servers_interface'
9
+ require 'morpheus/api/instances_interface'
10
+ require 'morpheus/api/instance_types_interface'
11
+ require 'morpheus/cli/credentials'
12
+ require 'morpheus/cli/error_handler'
13
+ require 'morpheus/cli/remote'
14
+ require 'morpheus/cli/groups'
15
+ require 'morpheus/cli/zones'
16
+ require 'morpheus/cli/servers'
17
+ require 'morpheus/cli/instances'
18
+ require 'morpheus/cli/instance_types'
19
+ # Your code goes here...
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'morpheus/cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "morpheus-cli"
8
+ spec.version = Morpheus::Cli::VERSION
9
+ spec.authors = ["David Estes"]
10
+ spec.email = ["davydotcom@gmail.com"]
11
+ spec.summary = "Provides CLI Interface to the Morpheus Public/Private Cloud Appliance"
12
+ spec.description = "Morpheus allows one to manage docker containers and deploy applications on the CLI"
13
+ spec.homepage = "http://www.gomorpheus.com"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_dependency 'term-ansicolor', '~> 1.3.0'
25
+ spec.add_dependency "rest-client", "~> 1.7"
26
+ spec.add_dependency "filesize"
27
+ spec.add_dependency "table_print"
28
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morpheus-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Estes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: term-ansicolor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: filesize
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: table_print
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Morpheus allows one to manage docker containers and deploy applications
98
+ on the CLI
99
+ email:
100
+ - davydotcom@gmail.com
101
+ executables:
102
+ - morpheus
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/morpheus
112
+ - lib/morpheus/api/api_client.rb
113
+ - lib/morpheus/api/groups_interface.rb
114
+ - lib/morpheus/api/instance_types_interface.rb
115
+ - lib/morpheus/api/instances_interface.rb
116
+ - lib/morpheus/api/servers_interface.rb
117
+ - lib/morpheus/api/zones_interface.rb
118
+ - lib/morpheus/cli.rb
119
+ - lib/morpheus/cli/credentials.rb
120
+ - lib/morpheus/cli/error_handler.rb
121
+ - lib/morpheus/cli/groups.rb
122
+ - lib/morpheus/cli/instance_types.rb
123
+ - lib/morpheus/cli/instances.rb
124
+ - lib/morpheus/cli/remote.rb
125
+ - lib/morpheus/cli/servers.rb
126
+ - lib/morpheus/cli/version.rb
127
+ - lib/morpheus/cli/zones.rb
128
+ - morpheus-cli.gemspec
129
+ homepage: http://www.gomorpheus.com
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.2.2
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance
153
+ test_files: []