morpheus-cli 0.1.0 → 0.1.1

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.
@@ -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