morpheus-cli 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,75 @@
1
+
2
+ module Morpheus
3
+ module Cli
4
+ class CliRegistry
5
+
6
+ def initialize
7
+ @commands = {}
8
+ end
9
+
10
+ class << self
11
+
12
+ def instance
13
+ @instance ||= CliRegistry.new
14
+ end
15
+
16
+ def exec(command_name, args)
17
+ instance.get(command_name).new.handle(args)
18
+ end
19
+
20
+ def add(klass, command_name=nil)
21
+ klass_command_name = cli_ize(klass.name.split('::')[-1])
22
+
23
+ if has_command?(klass_command_name) && !command_name.nil?
24
+ instance.remove(klass_command_name)
25
+ instance.add(command_name, klass)
26
+ else
27
+ instance.add(klass_command_name, klass)
28
+ end
29
+ end
30
+
31
+ def has_command?(command_name)
32
+ if command_name.nil? || command_name == ''
33
+ false
34
+ else
35
+ !instance.get(command_name).nil?
36
+ end
37
+ end
38
+
39
+ def all
40
+ instance.all
41
+ end
42
+
43
+ private
44
+
45
+ def cli_ize(klass_name)
46
+ # borrowed from ActiveSupport
47
+ return klass_name unless klass_name =~ /[A-Z-]|::/
48
+ word = klass_name.to_s.gsub(/::/, '/')
49
+ word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(?=\b|[^a-z])/) { "#{$1 && '_'}" }
50
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
51
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
52
+ word.tr!("-", "_")
53
+ word.downcase!
54
+ word.chop.tr('_', '-')
55
+ end
56
+ end
57
+
58
+ def all
59
+ @commands
60
+ end
61
+
62
+ def get(cmd_name)
63
+ @commands[cmd_name.to_sym]
64
+ end
65
+
66
+ def add(cmd_name, klass)
67
+ @commands[cmd_name.to_sym] = klass
68
+ end
69
+
70
+ def remove(cmd_name)
71
+ @commands.delete(cmd_name.to_sym)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'io/console'
3
- require 'rest_client'
3
+ require 'optparse'
4
+
4
5
  module Morpheus
5
6
  module Cli
6
7
  class Credentials
@@ -21,7 +22,7 @@ module Morpheus
21
22
 
22
23
  oauth_url = File.join(@appliance_url, "/oauth/token")
23
24
  begin
24
- authorize_response = RestClient.post oauth_url, {grant_type: 'password', scope:'write', client_id: 'morph-cli', username: username, password: password}
25
+ authorize_response = Morpheus::RestClient.post oauth_url, {grant_type: 'password', scope:'write', client_id: 'morph-cli', username: username, password: password}
25
26
 
26
27
  json_response = JSON.parse(authorize_response.to_s)
27
28
  access_token = json_response['access_token']
@@ -96,4 +97,4 @@ module Morpheus
96
97
  end
97
98
  end
98
99
  end
99
- end
100
+ end
@@ -5,9 +5,14 @@ require 'term/ansicolor'
5
5
  require 'optparse'
6
6
  require 'filesize'
7
7
  require 'table_print'
8
+ require 'morpheus/cli/cli_command'
8
9
 
9
10
  class Morpheus::Cli::Deploys
11
+ include Morpheus::Cli::CliCommand
10
12
  include Term::ANSIColor
13
+
14
+ cli_command_name :deploy
15
+
11
16
  def initialize()
12
17
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
13
18
  @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
@@ -133,7 +138,7 @@ class Morpheus::Cli::Deploys
133
138
  #
134
139
  def load_deploy_file
135
140
  if !File.exist? "morpheus.yml"
136
- puts "No morheus.yml file detected in the current directory. Nothing to do."
141
+ puts "No morpheus.yml file detected in the current directory. Nothing to do."
137
142
  return nil
138
143
  end
139
144
 
@@ -150,4 +155,4 @@ class Morpheus::Cli::Deploys
150
155
  end
151
156
  return deploy_args
152
157
  end
153
- end
158
+ end
@@ -3,10 +3,12 @@ require 'io/console'
3
3
  require 'rest_client'
4
4
  require 'term/ansicolor'
5
5
  require 'optparse'
6
-
6
+ require 'morpheus/cli/cli_command'
7
7
 
8
8
  class Morpheus::Cli::Groups
9
+ include Morpheus::Cli::CliCommand
9
10
  include Term::ANSIColor
11
+
10
12
  def initialize()
11
13
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
12
14
  @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
@@ -168,4 +170,4 @@ class Morpheus::Cli::Groups
168
170
  def self.save_groups(group_map)
169
171
  File.open(groups_file_path, 'w') {|f| f.write group_map.to_yaml } #Store
170
172
  end
171
- end
173
+ end
@@ -4,8 +4,10 @@ require 'rest_client'
4
4
  require 'term/ansicolor'
5
5
  require 'optparse'
6
6
  require 'filesize'
7
+ require 'morpheus/cli/cli_command'
7
8
 
8
9
  class Morpheus::Cli::InstanceTypes
10
+ include Morpheus::Cli::CliCommand
9
11
  include Term::ANSIColor
10
12
  def initialize()
11
13
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -98,4 +100,4 @@ class Morpheus::Cli::InstanceTypes
98
100
  return nil
99
101
  end
100
102
  end
101
- end
103
+ end
@@ -5,8 +5,10 @@ require 'term/ansicolor'
5
5
  require 'optparse'
6
6
  require 'filesize'
7
7
  require 'table_print'
8
+ require 'morpheus/cli/cli_command'
8
9
 
9
10
  class Morpheus::Cli::Instances
11
+ include Morpheus::Cli::CliCommand
10
12
  include Term::ANSIColor
11
13
  def initialize()
12
14
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -24,7 +26,7 @@ class Morpheus::Cli::Instances
24
26
  return 1
25
27
  end
26
28
  if args.empty?
27
- puts "\nUsage: morpheus instances [list,add,remove,stop,start,restart,resize,upgrade,clone,envs,setenv,delenv] [name]\n\n"
29
+ puts "\nUsage: morpheus instances [list,add,remove,stop,start,restart,resize,upgrade,clone,envs,setenv,delenv,firewall_disable,firewall_enable,security_groups,apply_security_groups] [name]\n\n"
28
30
  return
29
31
  end
30
32
 
@@ -51,6 +53,14 @@ class Morpheus::Cli::Instances
51
53
  setenv(args[1..-1])
52
54
  when 'delenv'
53
55
  delenv(args[1..-1])
56
+ when 'firewall_disable'
57
+ firewall_disable(args[1..-1])
58
+ when 'firewall_enable'
59
+ firewall_enable(args[1..-1])
60
+ when 'security_groups'
61
+ security_groups(args[1..-1])
62
+ when 'apply_security_groups'
63
+ apply_security_groups(args[1..-1])
54
64
  else
55
65
  puts "\nUsage: morpheus instances [list,add,remove,stop,start,restart,resize,upgrade,clone,envs,setenv,delenv] [name]\n\n"
56
66
  end
@@ -439,6 +449,145 @@ class Morpheus::Cli::Instances
439
449
  end
440
450
  end
441
451
 
452
+ def firewall_disable(args)
453
+ if args.count < 1
454
+ puts "\nUsage: morpheus instances firewall_disable [name]\n\n"
455
+ return
456
+ end
457
+ begin
458
+ instance_results = @instances_interface.get({name: args[0]})
459
+ if instance_results['instances'].empty?
460
+ puts "Instance not found by name #{args[0]}"
461
+ return
462
+ end
463
+ @instances_interface.firewall_disable(instance_results['instances'][0]['id'])
464
+ security_groups([args[0]])
465
+ rescue RestClient::Exception => e
466
+ if e.response.code == 400
467
+ error = JSON.parse(e.response.to_s)
468
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
469
+ else
470
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
471
+ end
472
+ return nil
473
+ end
474
+ end
475
+
476
+ def firewall_enable(args)
477
+ if args.count < 1
478
+ puts "\nUsage: morpheus instances firewall_enable [name]\n\n"
479
+ return
480
+ end
481
+ begin
482
+ instance_results = @instances_interface.get({name: args[0]})
483
+ if instance_results['instances'].empty?
484
+ puts "Instance not found by name #{args[0]}"
485
+ return
486
+ end
487
+ @instances_interface.firewall_enable(instance_results['instances'][0]['id'])
488
+ security_groups([args[0]])
489
+ rescue RestClient::Exception => e
490
+ if e.response.code == 400
491
+ error = JSON.parse(e.response.to_s)
492
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
493
+ else
494
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
495
+ end
496
+ return nil
497
+ end
498
+ end
499
+
500
+ def security_groups(args)
501
+ if args.count < 1
502
+ puts "\nUsage: morpheus instances security_groups [name]\n\n"
503
+ return
504
+ end
505
+ begin
506
+ instance_results = @instances_interface.get({name: args[0]})
507
+ if instance_results['instances'].empty?
508
+ puts "Instance not found by name #{args[0]}"
509
+ return
510
+ end
511
+
512
+ instance_id = instance_results['instances'][0]['id']
513
+ json_response = @instances_interface.security_groups(instance_id)
514
+
515
+ securityGroups = json_response['securityGroups']
516
+ print "\n" ,cyan, bold, "Morpheus Security Groups for Instance:#{instance_id}\n","==================", reset, "\n\n"
517
+ print cyan, "Firewall Enabled=#{json_response['firewallEnabled']}\n\n"
518
+ if securityGroups.empty?
519
+ puts yellow,"No security groups currently applied.",reset
520
+ else
521
+ securityGroups.each do |securityGroup|
522
+ print cyan, "= #{securityGroup['id']} (#{securityGroup['name']}) - (#{securityGroup['description']})\n"
523
+ end
524
+ end
525
+ print reset,"\n\n"
526
+
527
+ rescue RestClient::Exception => e
528
+ if e.response.code == 400
529
+ error = JSON.parse(e.response.to_s)
530
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
531
+ else
532
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
533
+ end
534
+ return nil
535
+ end
536
+ end
537
+
538
+ def apply_security_groups(args)
539
+ usage = <<-EOF
540
+ Usage: morpheus instances apply_security_groups [name] [options]
541
+ EOF
542
+ if args.count < 1
543
+ puts usage
544
+ return
545
+ end
546
+
547
+ options = {}
548
+ clear_or_secgroups_specified = false
549
+ optparse = OptionParser.new do|opts|
550
+ opts.banner = usage
551
+ opts.on( '-c', '--clear', "Clear all security groups" ) do
552
+ options[:securityGroupIds] = []
553
+ clear_or_secgroups_specified = true
554
+ end
555
+ opts.on( '-s', '--secgroups SECGROUPS', "Apply the specified comma separated security group ids" ) do |secgroups|
556
+ options[:securityGroupIds] = secgroups.split(",")
557
+ clear_or_secgroups_specified = true
558
+ end
559
+ opts.on( '-h', '--help', "Prints this help" ) do
560
+ puts opts
561
+ exit
562
+ end
563
+ end
564
+ optparse.parse(args)
565
+
566
+ if !clear_or_secgroups_specified
567
+ puts usage
568
+ exit
569
+ end
570
+
571
+ begin
572
+ instance_results = @instances_interface.get({name: args[0]})
573
+ if instance_results['instances'].empty?
574
+ puts "Instance not found by name #{args[0]}"
575
+ return
576
+ end
577
+
578
+ @instances_interface.apply_security_groups(instance_results['instances'][0]['id'], options)
579
+ security_groups([args[0]])
580
+ rescue RestClient::Exception => e
581
+ if e.response.code == 400
582
+ error = JSON.parse(e.response.to_s)
583
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
584
+ else
585
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
586
+ end
587
+ return nil
588
+ end
589
+ end
590
+
442
591
  private
443
592
  def find_group_by_name(name)
444
593
  group_results = @groups_interface.get(name)
@@ -457,4 +606,4 @@ private
457
606
  end
458
607
  return instance_type_results['instanceTypes'][0]
459
608
  end
460
- end
609
+ end
@@ -14,6 +14,7 @@ class Morpheus::Cli::Remote
14
14
  def handle(args)
15
15
  if args.empty?
16
16
  puts "\nUsage: morpheus remote [list,add,remove,use] [name] [host]\n\n"
17
+ return
17
18
  end
18
19
 
19
20
  case args[0]
@@ -160,4 +161,4 @@ class Morpheus::Cli::Remote
160
161
  def self.save_appliances(appliance_map)
161
162
  File.open(appliances_file_path, 'w') {|f| f.write appliance_map.to_yaml } #Store
162
163
  end
163
- end
164
+ end
@@ -0,0 +1,243 @@
1
+ # require 'yaml'
2
+ require 'io/console'
3
+ require 'rest_client'
4
+ require 'term/ansicolor'
5
+ require 'optparse'
6
+ require 'filesize'
7
+ require 'table_print'
8
+ require 'morpheus/cli/cli_command'
9
+
10
+ class Morpheus::Cli::SecurityGroupRules
11
+ include Morpheus::Cli::CliCommand
12
+ include Term::ANSIColor
13
+ def initialize()
14
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
15
+ @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
16
+ @security_group_rules_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).security_group_rules
17
+ @active_security_group = ::Morpheus::Cli::SecurityGroups.load_security_group_file
18
+ end
19
+
20
+
21
+ def handle(args)
22
+ if @access_token.empty?
23
+ print red,bold, "\nInvalid Credentials. Unable to acquire access token. Please verify your credentials and try again.\n\n",reset
24
+ return 1
25
+ end
26
+ if args.empty?
27
+ puts "\nUsage: morpheus security-group-rules [list, add_custom_rule, remove]\n\n"
28
+ return
29
+ end
30
+
31
+ case args[0]
32
+ when 'list'
33
+ list(args[1..-1])
34
+ when 'add_custom_rule'
35
+ add_custom_rule(args[1..-1])
36
+ when 'add_instance_rule'
37
+ add_instance_rule(args[1..-1])
38
+ when 'remove'
39
+ remove(args[1..-1])
40
+ else
41
+ puts "\nUsage: morpheus security-group-rules [list,add_custom_rule,remove]\n\n"
42
+ end
43
+ end
44
+
45
+ def add_custom_rule(args)
46
+ usage = <<-EOT
47
+ Usage: morpheus security-group-rules add_custom_rule SOURCE_CIDR PORT_RANGE PROTOCOL [options]
48
+ SOURCE_CIDR: CIDR to white-list
49
+ PORT_RANGE: Port value (i.e. 123) or port range (i.e. 1-65535)
50
+ PROTOCOL: tcp, udp, icmp\n\n'
51
+ EOT
52
+
53
+ if args.count < 3
54
+ puts usage
55
+ return
56
+ end
57
+
58
+ security_group_id = nil
59
+ optparse = OptionParser.new do|opts|
60
+ opts.banner = "\nUsage: morpheus security-group-rules add_custom_rule SOURCE_CIDR PORT_RANGE PROTOCOL [options]"
61
+ opts.on( '-s', '--secgroup secgroup', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
62
+ security_group_id = id
63
+ end
64
+ opts.on( '-h', '--help', "Prints this help" ) do
65
+ puts opts
66
+ exit
67
+ end
68
+ end
69
+ optparse.parse(args)
70
+
71
+ if security_group_id.nil?
72
+ security_group_id = @active_security_group[@appliance_name.to_sym]
73
+ end
74
+
75
+ if security_group_id.nil?
76
+ puts "Security Group ID must be specified with options or set using 'security-groups use id'"
77
+ exit
78
+ end
79
+
80
+ options = {
81
+ :rule => {
82
+ :source => args[0],
83
+ :portRange => args[1],
84
+ :protocol => args[2],
85
+ :customRule => true
86
+ }
87
+ }
88
+
89
+ begin
90
+ @security_group_rules_interface.create(security_group_id, options)
91
+ rescue => e
92
+ if e.response.code == 400
93
+ error = JSON.parse(e.response.to_s)
94
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
95
+ else
96
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
97
+ end
98
+ return nil
99
+ end
100
+ list([])
101
+ end
102
+
103
+ def add_instance_rule(args)
104
+ usage = <<-EOT
105
+ Usage: morpheus security-group-rules add_instance_rule SOURCE_CIDR INSTANCE_TYPE_ID [options]
106
+ SOURCE_CIDR: CIDR to white-list
107
+ INSTANCE_TYPE_ID: ID of the Instance Type to access
108
+ EOT
109
+ if args.count < 2
110
+ puts usage
111
+ return
112
+ end
113
+
114
+ security_group_id = nil
115
+ optparse = OptionParser.new do|opts|
116
+ opts.banner = "\nmorpheus security-group-rules add_instance_rule SOURCE_CIDR INSTANCE_TYPE_ID [options]"
117
+ opts.on( '-s', '--secgroup secgroup', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
118
+ security_group_id = id
119
+ end
120
+ opts.on( '-h', '--help', "Prints this help" ) do
121
+ puts opts
122
+ exit
123
+ end
124
+ end
125
+ optparse.parse(args)
126
+
127
+ if security_group_id.nil?
128
+ security_group_id = @active_security_group[@appliance_name.to_sym]
129
+ end
130
+
131
+ if security_group_id.nil?
132
+ puts "Security Group ID must be specified with options or set using 'security-groups use id'"
133
+ exit
134
+ end
135
+
136
+ options = {
137
+ :rule => {
138
+ :source => args[0],
139
+ :instanceTypeId => args[1]
140
+ }
141
+ }
142
+
143
+ begin
144
+ @security_group_rules_interface.create(security_group_id, options)
145
+ rescue => e
146
+ if e.response.code == 400
147
+ error = JSON.parse(e.response.to_s)
148
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
149
+ else
150
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
151
+ end
152
+ return nil
153
+ end
154
+ list([])
155
+ end
156
+
157
+ def list(args)
158
+ options = {}
159
+ security_group_id = nil
160
+ optparse = OptionParser.new do|opts|
161
+ opts.banner = "\nUsage: morpheus security-group-rules list [options]"
162
+ opts.on( '-s', '--secgroup secgroup', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
163
+ security_group_id = id
164
+ end
165
+ opts.on( '-h', '--help', "Prints this help" ) do
166
+ puts opts
167
+ exit
168
+ end
169
+ end
170
+ optparse.parse(args)
171
+
172
+ if security_group_id.nil?
173
+ security_group_id = @active_security_group[@appliance_name.to_sym]
174
+ end
175
+
176
+ if security_group_id.nil?
177
+ puts "Security Group ID must be specified with options or set using 'security-groups use id'"
178
+ exit
179
+ end
180
+
181
+ begin
182
+ params = {}
183
+ json_response = @security_group_rules_interface.get(security_group_id, options)
184
+ rules = json_response['rules']
185
+ print "\n" ,cyan, bold, "Morpheus Security Group Rules for Security Group ID:#{security_group_id}\n","==================", reset, "\n\n"
186
+ if rules.empty?
187
+ puts yellow,"No Security Group Rules currently configured.",reset
188
+ else
189
+ rules.each do |rule|
190
+ print cyan, "= #{rule['id']} - (CIDR:#{rule['source']}, Port Range:#{rule['portRange']}, Protocol:#{rule['protocol']}, Custom Rule:#{rule['customRule']}, Instance Type:#{rule['instanceTypeId']})\n"
191
+ end
192
+ end
193
+ print reset,"\n\n"
194
+
195
+ rescue => e
196
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
197
+ return nil
198
+ end
199
+ end
200
+
201
+ def remove(args)
202
+ if args.count < 1
203
+ puts "\nUsage: morpheus security-group-rules remove ID [options]\n\n"
204
+ return
205
+ end
206
+
207
+ security_group_id = nil
208
+ optparse = OptionParser.new do|opts|
209
+ opts.banner = "\nUsage: morpheus security-group-rules remove ID [options]"
210
+ opts.on( '-s', '--secgroup secgroup', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
211
+ security_group_id = id
212
+ end
213
+ opts.on( '-h', '--help', "Prints this help" ) do
214
+ puts opts
215
+ exit
216
+ end
217
+ end
218
+ optparse.parse(args)
219
+
220
+ if security_group_id.nil?
221
+ security_group_id = @active_security_group[@appliance_name.to_sym]
222
+ end
223
+
224
+ if security_group_id.nil?
225
+ puts "Security Group ID must be specified with options or set using 'security-groups use id'"
226
+ exit
227
+ end
228
+
229
+ begin
230
+ @security_group_rules_interface.delete(security_group_id, args[0])
231
+ list([])
232
+ rescue RestClient::Exception => e
233
+ if e.response.code == 400
234
+ error = JSON.parse(e.response.to_s)
235
+ ::Morpheus::Cli::ErrorHandler.new.print_errors(error)
236
+ else
237
+ puts "Error Communicating with the Appliance. Please try again later. #{e}"
238
+ end
239
+ return nil
240
+ end
241
+ end
242
+
243
+ end