morpheus-cli 4.1.5 → 4.1.6

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.
@@ -10,15 +10,11 @@ class Morpheus::Cli::NetworksCommand
10
10
 
11
11
  set_command_name :networks
12
12
 
13
- register_subcommands :list, :get, :add, :update, :remove #, :generate_pool
13
+ register_subcommands :list, :get, :add, :update, :remove
14
14
  register_subcommands :'types' => :list_types
15
15
  register_subcommands :'get-type' => :get_type
16
16
 
17
- register_subcommands :list_subnets, :get_subnet, :add_subnet, :update_subnet, :remove_subnet
18
- register_subcommands :'subnet-types' => :list_subnet_types
19
- register_subcommands :'get-subnet-type' => :get_subnet_type
20
-
21
- # set_default_subcommand :list
17
+ register_subcommands :list_subnets, # :get_subnet, :add_subnet, :update_subnet, :remove_subnet
22
18
 
23
19
  def initialize()
24
20
  # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -28,8 +24,8 @@ class Morpheus::Cli::NetworksCommand
28
24
  @api_client = establish_remote_appliance_connection(opts)
29
25
  @networks_interface = @api_client.networks
30
26
  @network_types_interface = @api_client.network_types
31
- @network_subnets_interface = @api_client.network_subnets
32
- @network_subnet_types_interface = @api_client.network_subnet_types
27
+ @subnets_interface = @api_client.subnets
28
+ @subnet_types_interface = @api_client.subnet_types
33
29
  @clouds_interface = @api_client.clouds
34
30
  @options_interface = @api_client.options
35
31
  end
@@ -49,6 +45,12 @@ class Morpheus::Cli::NetworksCommand
49
45
  opts.on('--cidr VALUE', String, "Filter by cidr, matches beginning of value.") do |val|
50
46
  params['cidr'] = val
51
47
  end
48
+ opts.on('-a', '--all', "Display all data, including subnets.") do
49
+ options[:show_subnets] = true
50
+ end
51
+ opts.on('--subnets', '--subnets', "Display subnets as rows under each network found.") do
52
+ options[:show_subnets] = true
53
+ end
52
54
  build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
53
55
  opts.footer = "List networks."
54
56
  end
@@ -89,7 +91,8 @@ class Morpheus::Cli::NetworksCommand
89
91
  if networks.empty?
90
92
  print cyan,"No networks found.",reset,"\n"
91
93
  else
92
- rows = networks.collect {|network|
94
+ rows = []
95
+ networks.each do |network|
93
96
  row = {
94
97
  id: network['id'],
95
98
  name: network['name'],
@@ -98,12 +101,30 @@ class Morpheus::Cli::NetworksCommand
98
101
  cidr: network['cidr'],
99
102
  pool: network['pool'] ? network['pool']['name'] : '',
100
103
  dhcp: network['dhcpServer'] ? 'Yes' : 'No',
104
+ subnets: (network['subnets'].size rescue 'n/a'),
101
105
  visibility: network['visibility'].to_s.capitalize,
102
106
  tenants: network['tenants'] ? network['tenants'].collect {|it| it['name'] }.uniq.join(', ') : ''
103
107
  }
104
- row
105
- }
106
- columns = [:id, :name, :type, :cloud, :cidr, :pool, :dhcp, :visibility, :tenants]
108
+ rows << row
109
+ if network['subnets'] && network['subnets'].size() > 0 && options[:show_subnets]
110
+ network['subnets'].each do |subnet|
111
+ subnet_row = {
112
+ id: subnet['id'],
113
+ name: " #{subnet['name']}",
114
+ # type: subnet['type'] ? subnet['type']['name'] : '',
115
+ type: "Subnet",
116
+ cloud: network['zone'] ? network['zone']['name'] : '',
117
+ cidr: subnet['cidr'],
118
+ pool: subnet['pool'] ? subnet['pool']['name'] : '',
119
+ dhcp: subnet['dhcpServer'] ? 'Yes' : 'No',
120
+ visibility: subnet['visibility'].to_s.capitalize,
121
+ tenants: subnet['tenants'] ? subnet['tenants'].collect {|it| it['name'] }.uniq.join(', ') : ''
122
+ }
123
+ rows << subnet_row
124
+ end
125
+ end
126
+ end
127
+ columns = [:id, :name, :type, :cloud, :cidr, :pool, :dhcp, :subnets, :visibility, :tenants]
107
128
  if options[:include_fields]
108
129
  columns = options[:include_fields]
109
130
  end
@@ -205,6 +226,32 @@ class Morpheus::Cli::NetworksCommand
205
226
  print as_pretty_table(rows, columns)
206
227
  end
207
228
 
229
+ # if options[:show_subnets]
230
+ # subnets data is limited, use /networks/:id/subnets to fetch it all.
231
+ subnets = network['subnets']
232
+ if subnets and subnets.size > 0
233
+ print_h2 "Subnets", options
234
+ rows = []
235
+ subnet_rows = subnets.collect { |subnet|
236
+ {
237
+ id: subnet['id'],
238
+ name: " #{subnet['name']}",
239
+ # type: subnet['type'] ? subnet['type']['name'] : '',
240
+ type: "Subnet",
241
+ cloud: network['zone'] ? network['zone']['name'] : '',
242
+ cidr: subnet['cidr'],
243
+ pool: subnet['pool'] ? subnet['pool']['name'] : '',
244
+ dhcp: subnet['dhcpServer'] ? 'Yes' : 'No',
245
+ visibility: subnet['visibility'].to_s.capitalize,
246
+ tenants: subnet['tenants'] ? subnet['tenants'].collect {|it| it['name'] }.uniq.join(', ') : ''
247
+ }
248
+ }
249
+ columns = [:id, :name, :cidr, :dhcp, :visibility]
250
+ print cyan
251
+ print as_pretty_table(subnet_rows, columns, options)
252
+ print reset
253
+ print_results_pagination({'meta'=>{'total'=>subnet_rows.size,'size'=>subnet_rows.size}}, {:label => "subnet", :n_label => "subnets"})
254
+ end
208
255
  print reset,"\n"
209
256
  return 0
210
257
  rescue RestClient::Exception => e
@@ -1101,150 +1148,13 @@ class Morpheus::Cli::NetworksCommand
1101
1148
  end
1102
1149
  end
1103
1150
 
1104
- def list_subnet_types(args)
1105
- options = {}
1106
- optparse = Morpheus::Cli::OptionParser.new do |opts|
1107
- opts.banner = subcommand_usage()
1108
- opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
1109
- options[:cloud] = val
1110
- end
1111
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
1112
- opts.footer = "List subnet types."
1113
- end
1114
- optparse.parse!(args)
1115
- connect(options)
1116
- begin
1117
- params = {}
1118
- params.merge!(parse_list_options(options))
1119
- if options[:cloud]
1120
- #return network_types_for_cloud(options[:cloud], options)
1121
- zone = find_zone_by_name_or_id(nil, options[:cloud])
1122
- #params["zoneTypeId"] = zone['zoneTypeId']
1123
- params["zoneId"] = zone['id']
1124
- params["creatable"] = true
1125
- end
1126
- @network_subnet_types_interface.setopts(options)
1127
- if options[:dry_run]
1128
- print_dry_run @network_subnet_types_interface.dry.list(params)
1129
- return
1130
- end
1131
- json_response = @network_subnet_types_interface.list(params)
1132
-
1133
- render_result = render_with_format(json_response, options, 'subnetTypes')
1134
- return 0 if render_result
1135
-
1136
- subnet_types = json_response['subnetTypes']
1137
-
1138
- title = "Morpheus Subnet Types"
1139
- subtitles = []
1140
- subtitles += parse_list_subtitles(options)
1141
- if options[:cloud]
1142
- subtitles << "Cloud: #{options[:cloud]}"
1143
- end
1144
- print_h1 title, subtitles
1145
- if subnet_types.empty?
1146
- print cyan,"No subnet types found.",reset,"\n"
1147
- else
1148
- rows = subnet_types.collect do |subnet_type|
1149
- {
1150
- id: subnet_type['id'],
1151
- code: subnet_type['code'],
1152
- name: subnet_type['name']
1153
- }
1154
- end
1155
- columns = [:id, :name, :code]
1156
- print cyan
1157
- print as_pretty_table(rows, columns, options)
1158
- print reset
1159
- print_results_pagination(json_response)
1160
- end
1161
- print reset,"\n"
1162
- return 0
1163
-
1164
- rescue RestClient::Exception => e
1165
- print_rest_exception(e, options)
1166
- exit 1
1167
- end
1168
- end
1169
-
1170
- def get_subnet_type(args)
1171
- options = {}
1172
- optparse = Morpheus::Cli::OptionParser.new do |opts|
1173
- opts.banner = subcommand_usage("[type]")
1174
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
1175
- opts.footer = "Get details about a subnet type.\n" +
1176
- "[type] is required. This is the id or name of a subnet type."
1177
- end
1178
- optparse.parse!(args)
1179
- connect(options)
1180
- begin
1181
- params = {}
1182
- @network_subnet_types_interface.setopts(options)
1183
- if options[:dry_run]
1184
- if args[0].to_s =~ /\A\d{1,}\Z/
1185
- print_dry_run @network_subnet_types_interface.dry.get(args[0].to_i)
1186
- else
1187
- print_dry_run @network_subnet_types_interface.dry.list({name:args[0]})
1188
- end
1189
- return
1190
- end
1191
-
1192
- subnet_type = find_subnet_type_by_name_or_id(args[0])
1193
- return 1 if subnet_type.nil?
1194
- json_response = {'subnetType' => subnet_type} # skip redundant request
1195
- # json_response = @networks_interface.get(subnet_type['id'])
1196
-
1197
- render_result = render_with_format(json_response, options, 'subnetType')
1198
- return 0 if render_result
1199
-
1200
- subnet_type = json_response['subnetType']
1201
-
1202
- title = "Morpheus Subnet Type"
1203
-
1204
- print_h1 "Morpheus Subnet Type", [], options
1205
-
1206
- print cyan
1207
- description_cols = {
1208
- "ID" => 'id',
1209
- "Name" => 'name',
1210
- "Code" => 'name',
1211
- "Description" => 'description',
1212
- "Createable" => lambda {|it| format_boolean(it['creatable']) },
1213
- "Deletable" => lambda {|it| format_boolean(it['deleteable']) },
1214
- }
1215
- print_description_list(description_cols, subnet_type)
1216
-
1217
-
1218
-
1219
- option_types = subnet_type['optionTypes'] || []
1220
- option_types = option_types.sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
1221
- if !option_types.empty?
1222
- print_h2 "Config Option Types", [], options
1223
- option_type_cols = {
1224
- "Name" => lambda {|it| it['fieldContext'].to_s != '' ? "#{it['fieldContext']}.#{it['fieldName']}" : it['fieldName'] },
1225
- "Label" => lambda {|it| it['fieldLabel'] },
1226
- "Type" => lambda {|it| it['type'] },
1227
- }
1228
- print cyan
1229
- print as_pretty_table(option_types, option_type_cols)
1230
- end
1231
-
1232
- print reset,"\n"
1233
- return 0
1234
- rescue RestClient::Exception => e
1235
- print_rest_exception(e, options)
1236
- exit 1
1237
- end
1238
- end
1239
-
1240
-
1241
1151
  def list_subnets(args)
1242
1152
  options = {}
1243
1153
  params = {}
1244
1154
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1245
- opts.banner = subcommand_usage("[network] [subnet]")
1155
+ opts.banner = subcommand_usage("[network]")
1246
1156
  build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
1247
- opts.footer = "Get details about a network." + "\n" +
1157
+ opts.footer = "List subnets under a network." + "\n" +
1248
1158
  "[network] is required. This is the name or id of a network."
1249
1159
  end
1250
1160
  optparse.parse!(args)
@@ -1255,14 +1165,14 @@ class Morpheus::Cli::NetworksCommand
1255
1165
  begin
1256
1166
  network = find_network_by_name_or_id(args[0])
1257
1167
  return 1 if network.nil?
1258
-
1168
+ params['networkId'] = network['id']
1259
1169
  params.merge!(parse_list_options(options))
1260
- @network_subnets_interface.setopts(options)
1170
+ @subnets_interface.setopts(options)
1261
1171
  if options[:dry_run]
1262
- print_dry_run @network_subnets_interface.dry.list(network['id'], params)
1172
+ print_dry_run @subnets_interface.dry.list(params)
1263
1173
  return
1264
1174
  end
1265
- json_response = @network_subnets_interface.list(network['id'], params)
1175
+ json_response = @subnets_interface.list(params)
1266
1176
  subnets = json_response["subnets"]
1267
1177
  if options[:json]
1268
1178
  puts as_json(json_response, options, "subnets")
@@ -1304,618 +1214,6 @@ class Morpheus::Cli::NetworksCommand
1304
1214
  end
1305
1215
  end
1306
1216
 
1307
- def get_subnet(args)
1308
- options = {}
1309
- optparse = Morpheus::Cli::OptionParser.new do |opts|
1310
- opts.banner = subcommand_usage("[network] [subnet]")
1311
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
1312
- opts.footer = "Get details about a subnet." + "\n" +
1313
- "[network] is required. This is the name or id of a network." + "\n" +
1314
- "[subnet] is required. This is the name or id of a subnet."
1315
- end
1316
- optparse.parse!(args)
1317
- if args.count != 2
1318
- raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
1319
- end
1320
- connect(options)
1321
- begin
1322
- network = find_network_by_name_or_id(args[0])
1323
- return 1 if network.nil?
1324
-
1325
- @network_subnets_interface.setopts(options)
1326
- if options[:dry_run]
1327
- if args[1].to_s =~ /\A\d{1,}\Z/
1328
- print_dry_run @network_subnets_interface.dry.get(network['id'], args[1].to_i)
1329
- else
1330
- print_dry_run @network_subnets_interface.dry.list(network['id'], {name:args[1]})
1331
- end
1332
- return
1333
- end
1334
- subnet = find_subnet_by_name_or_id(network['id'], args[1])
1335
- return 1 if subnet.nil?
1336
- json_response = {'subnet' => subnet} # skip redundant request
1337
- # json_response = @network_subnets_interface.get(network['id'], subnet['id'])
1338
- subnet = json_response['subnet']
1339
- if options[:json]
1340
- puts as_json(json_response, options, "subnet")
1341
- return 0
1342
- elsif options[:yaml]
1343
- puts as_yaml(json_response, options, "subnet")
1344
- return 0
1345
- elsif options[:csv]
1346
- puts records_as_csv([subnet], options)
1347
- return 0
1348
- end
1349
- print_h1 "Subnet Details", [], options
1350
- print cyan
1351
- description_cols = {
1352
- "ID" => 'id',
1353
- "Name" => 'name',
1354
- "Description" => 'description',
1355
- "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
1356
- "Network" => lambda {|it| network['name'] },
1357
- "Cloud" => lambda {|it| network['zone'] ? network['zone']['name'] : '' },
1358
- "CIDR" => 'cidr',
1359
- "Gateway" => 'gateway',
1360
- "Netmask" => 'netmask',
1361
- "Subnet" => 'subnetAddress',
1362
- "Primary DNS" => 'dnsPrimary',
1363
- "Secondary DNS" => 'dnsSecondary',
1364
- "Pool" => lambda {|it| it['pool'] ? it['pool']['name'] : '' },
1365
- "DHCP" => lambda {|it| format_boolean it['dhcpServer'] },
1366
- #"Allow IP Override" => lambda {|it| it['allowStaticOverride'] ? 'Yes' : 'No' },
1367
- "Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
1368
- "Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' },
1369
- # "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
1370
- }
1371
- print_description_list(description_cols, subnet)
1372
-
1373
- if subnet['resourcePermission'].nil?
1374
- print "\n", "No group access found", "\n"
1375
- else
1376
- print_h2 "Group Access"
1377
- rows = []
1378
- if subnet['resourcePermission']['all']
1379
- rows.push({"name" => 'All'})
1380
- end
1381
- if subnet['resourcePermission']['sites']
1382
- subnet['resourcePermission']['sites'].each do |site|
1383
- rows.push(site)
1384
- end
1385
- end
1386
- rows = rows.collect do |site|
1387
- {group: site['name'], default: site['default'] ? 'Yes' : ''}
1388
- end
1389
- columns = [:group, :default]
1390
- print cyan
1391
- print as_pretty_table(rows, columns)
1392
- end
1393
-
1394
- print reset,"\n"
1395
- return 0
1396
- rescue RestClient::Exception => e
1397
- print_rest_exception(e, options)
1398
- return 1
1399
- end
1400
- end
1401
-
1402
- def add_subnet(args)
1403
- options = {}
1404
- subnet_type_id = nil
1405
- tenants = nil
1406
- group_access_all = nil
1407
- group_access_list = nil
1408
- group_defaults_list = nil
1409
- optparse = Morpheus::Cli::OptionParser.new do |opts|
1410
- opts.banner = subcommand_usage("[network]")
1411
- opts.on('-t', '--type ID', "Subnet Type Name or ID") do |val|
1412
- subnet_type_id = val
1413
- end
1414
- opts.on('--name VALUE', String, "Name for this subnet") do |val|
1415
- options[:options]['name'] = val
1416
- end
1417
- opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
1418
- group_access_all = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
1419
- end
1420
- opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
1421
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1422
- group_access_list = []
1423
- else
1424
- group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1425
- end
1426
- end
1427
- opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
1428
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1429
- group_defaults_list = []
1430
- else
1431
- group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1432
- end
1433
- end
1434
- opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
1435
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1436
- options['tenants'] = []
1437
- else
1438
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1439
- end
1440
- end
1441
- opts.on('--accounts LIST', Array, "alias for --tenants") do |list|
1442
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1443
- options['tenants'] = []
1444
- else
1445
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1446
- end
1447
- end
1448
- opts.on('--visibility [private|public]', String, "Visibility") do |val|
1449
- options['visibility'] = val
1450
- end
1451
- # opts.on('--active [on|off]', String, "Can be used to disable a subnet") do |val|
1452
- # options['active'] = val.to_s == 'on' || val.to_s == 'true'
1453
- # end
1454
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
1455
- opts.footer = "Create a new subnet." + "\n" +
1456
- "[network] is required. This is the name or id of a network." #+ "\n" +
1457
- #"[name] is required and can be passed as --name instead."
1458
- end
1459
- optparse.parse!(args)
1460
- # if args.count < 1 || args.count > 2
1461
- if args.count != 1
1462
- raise_command_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args}\n#{optparse}"
1463
- end
1464
- if args[1]
1465
- options[:options]['name'] = args[1]
1466
- end
1467
- connect(options)
1468
- begin
1469
- network = find_network_by_name_or_id(args[0])
1470
- return 1 if network.nil?
1471
-
1472
- passed_options = (options[:options] || {}).reject {|k,v| k.is_a?(Symbol) }
1473
- payload = nil
1474
- if options[:payload]
1475
- payload = options[:payload]
1476
- payload.deep_merge!({'subnet' => passed_options}) unless passed_options.empty?
1477
-
1478
- else
1479
- payload = {'subnet' => {}}
1480
- payload.deep_merge!({'subnet' => passed_options}) unless passed_options.empty?
1481
-
1482
- # Name
1483
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this subnet.'}], options[:options])
1484
- # payload['subnet']['name'] = v_prompt['name']
1485
-
1486
- # Subnet Type
1487
- if !subnet_type_id
1488
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Subnet Type', 'type' => 'select', 'optionSource' => 'subnetTypes', 'required' => true, 'description' => 'Choose a subnet type.'}], options[:options], @api_client, {networkId: network['id']})
1489
- subnet_type_id = v_prompt['type']
1490
- end
1491
- subnet_type = find_subnet_type_by_name_or_id(subnet_type_id)
1492
- return 1 if subnet_type.nil?
1493
- payload['subnet']['type'] = {'id' => subnet_type['id'] }
1494
- #payload['subnet']['type'] = {'code' => subnet_type['code'] }
1495
-
1496
- subnet_type_option_types = subnet_type['optionTypes']
1497
- if subnet_type_option_types && subnet_type_option_types.size > 0
1498
- # prompt for option types
1499
- subnet_type_params = Morpheus::Cli::OptionTypes.prompt(subnet_type_option_types,options[:options],@api_client, {networkId: network['id']})
1500
- payload['subnet'].deep_merge!(subnet_type_params)
1501
-
1502
- else
1503
- # DEFAULT INPUTS
1504
-
1505
- # CIDR
1506
- # if options['cidr']
1507
- # payload['subnet']['cidr'] = options['cidr']
1508
- # else
1509
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cidr', 'fieldLabel' => 'CIDR', 'type' => 'text', 'required' => false, 'description' => ''}], options)
1510
- # payload['subnet']['cidr'] = v_prompt['cidr']
1511
- # end
1512
-
1513
- end
1514
-
1515
- # Group Access
1516
- # Group Access (default is All)
1517
- if group_access_all.nil?
1518
- if payload['resourcePermissions'].nil?
1519
- payload['resourcePermissions'] ||= {}
1520
- payload['resourcePermissions']['all'] = true
1521
- end
1522
- else
1523
- payload['resourcePermissions'] ||= {}
1524
- payload['resourcePermissions']['all'] = group_access_all
1525
- end
1526
- if group_access_list != nil
1527
- payload['resourcePermissions'] ||= {}
1528
- payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
1529
- site = {"id" => site_id.to_i}
1530
- if group_defaults_list && group_defaults_list.include?(site_id)
1531
- site["default"] = true
1532
- end
1533
- site
1534
- end
1535
- end
1536
-
1537
- # Tenants
1538
- if options['tenants']
1539
- payload['tenantPermissions'] = {}
1540
- payload['tenantPermissions']['accounts'] = options['tenants']
1541
- end
1542
-
1543
- # Active
1544
- if options['active'] != nil
1545
- payload['subnet']['active'] = options['active']
1546
- end
1547
-
1548
- # Visibility
1549
- if options['visibility'] != nil
1550
- payload['subnet']['visibility'] = options['visibility']
1551
- end
1552
-
1553
- end
1554
-
1555
- @network_subnets_interface.setopts(options)
1556
- if options[:dry_run]
1557
- print_dry_run @network_subnets_interface.dry.create(network['id'], payload)
1558
- return
1559
- end
1560
- json_response = @network_subnets_interface.create(network['id'], payload)
1561
- if options[:json]
1562
- puts as_json(json_response, options)
1563
- elsif !options[:quiet]
1564
- subnet = json_response['subnet']
1565
- print_green_success "Added subnet #{subnet['name']}"
1566
- get_args = [network['id'], subnet['id']] + (options[:remote] ? ["-r",options[:remote]] : [])
1567
- get_subnet(get_args)
1568
- end
1569
- return 0
1570
- rescue RestClient::Exception => e
1571
- print_rest_exception(e, options)
1572
- return 1
1573
- end
1574
- end
1575
-
1576
-
1577
- def update_subnet(args)
1578
- options = {}
1579
- tenants = nil
1580
- group_access_all = nil
1581
- group_access_list = nil
1582
- group_defaults_list = nil
1583
- optparse = Morpheus::Cli::OptionParser.new do |opts|
1584
- opts.banner = subcommand_usage("[network] [subnet]")
1585
- opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
1586
- group_access_all = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
1587
- end
1588
- opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
1589
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1590
- group_access_list = []
1591
- else
1592
- group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1593
- end
1594
- end
1595
- opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
1596
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1597
- group_defaults_list = []
1598
- else
1599
- group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1600
- end
1601
- end
1602
- opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
1603
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1604
- options['tenants'] = []
1605
- else
1606
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1607
- end
1608
- end
1609
- opts.on('--accounts LIST', Array, "alias for --tenants") do |list|
1610
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
1611
- options['tenants'] = []
1612
- else
1613
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
1614
- end
1615
- end
1616
- opts.on('--visibility [private|public]', String, "Visibility") do |val|
1617
- options['visibility'] = val
1618
- end
1619
- # opts.on('--active [on|off]', String, "Can be used to disable a network") do |val|
1620
- # options['active'] = val.to_s == 'on' || val.to_s == 'true'
1621
- # end
1622
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
1623
- opts.footer = "Update a subnet." + "\n" +
1624
- "[network] is required. This is the name or id of a network." + "\n" +
1625
- "[subnet] is required. This is the name or id of a subnet."
1626
- end
1627
- optparse.parse!(args)
1628
- if args.count != 2
1629
- raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
1630
- end
1631
- connect(options)
1632
- begin
1633
- network = find_network_by_name_or_id(args[0])
1634
- return 1 if network.nil?
1635
-
1636
- subnet = find_subnet_by_name_or_id(network['id'], args[1])
1637
- return 1 if subnet.nil?
1638
-
1639
- # merge -O options into normally parsed options
1640
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
1641
-
1642
- # construct payload
1643
- payload = nil
1644
- if options[:payload]
1645
- payload = options[:payload]
1646
- else
1647
- # prompt for network options
1648
- payload = {
1649
- 'subnet' => {
1650
- }
1651
- }
1652
-
1653
- # allow arbitrary -O options
1654
- payload['subnet'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
1655
-
1656
- # Group Access
1657
- if group_access_all != nil
1658
- payload['resourcePermissions'] ||= {}
1659
- payload['resourcePermissions']['all'] = group_access_all
1660
- end
1661
- if group_access_list != nil
1662
- payload['resourcePermissions'] ||= {}
1663
- payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
1664
- site = {"id" => site_id.to_i}
1665
- if group_defaults_list && group_defaults_list.include?(site_id)
1666
- site["default"] = true
1667
- end
1668
- site
1669
- end
1670
- end
1671
-
1672
- # Tenants
1673
- if options['tenants']
1674
- payload['tenantPermissions'] = {}
1675
- payload['tenantPermissions']['accounts'] = options['tenants']
1676
- end
1677
-
1678
- # Active
1679
- if options['active'] != nil
1680
- payload['subnet']['active'] = options['active']
1681
- end
1682
-
1683
- # Visibility
1684
- if options['visibility'] != nil
1685
- payload['subnet']['visibility'] = options['visibility']
1686
- end
1687
-
1688
- end
1689
-
1690
- @network_subnets_interface.setopts(options)
1691
- if options[:dry_run]
1692
- print_dry_run @network_subnets_interface.dry.update(network['id'], subnet['id'], payload)
1693
- return
1694
- end
1695
- json_response = @network_subnets_interface.update(network['id'], subnet['id'], payload)
1696
- if options[:json]
1697
- puts as_json(json_response, options)
1698
- elsif !options[:quiet]
1699
- subnet = json_response['subnet']
1700
- print_green_success "Updated subnet #{subnet['name']}"
1701
- get_args = [network['id'], subnet['id']] + (options[:remote] ? ["-r",options[:remote]] : [])
1702
- get_subnet(get_args)
1703
- end
1704
- return 0
1705
- rescue RestClient::Exception => e
1706
- print_rest_exception(e, options)
1707
- return 1
1708
- end
1709
- end
1710
-
1711
- def remove_subnet(args)
1712
- options = {}
1713
- optparse = Morpheus::Cli::OptionParser.new do |opts|
1714
- opts.banner = subcommand_usage("[network] [subnet]")
1715
- build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
1716
- opts.footer = "Delete a subnet." + "\n" +
1717
- "[network] is required. This is the name or id of a network." + "\n" +
1718
- "[subnet] is required. This is the name or id of a subnet."
1719
- end
1720
- optparse.parse!(args)
1721
- if args.count != 2
1722
- raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
1723
- end
1724
- connect(options)
1725
- begin
1726
- network = find_network_by_name_or_id(args[0])
1727
- return 1 if network.nil?
1728
-
1729
- subnet = find_subnet_by_name_or_id(network['id'], args[1])
1730
- return 1 if subnet.nil?
1731
-
1732
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the subnet: #{subnet['name']}?")
1733
- return 9, "aborted command"
1734
- end
1735
- @network_subnets_interface.setopts(options)
1736
- if options[:dry_run]
1737
- print_dry_run @network_subnets_interface.dry.destroy(network['id'], subnet['id'])
1738
- return 0
1739
- end
1740
- json_response = @network_subnets_interface.destroy(network['id'], subnet['id'])
1741
- if options[:json]
1742
- puts as_json(json_response, options)
1743
- else
1744
- print_green_success "Removed subnet #{subnet['name']}"
1745
- end
1746
- return 0
1747
- rescue RestClient::Exception => e
1748
- print_rest_exception(e, options)
1749
- return 1
1750
- end
1751
- end
1752
-
1753
1217
  private
1754
1218
 
1755
-
1756
- def find_network_by_name_or_id(val)
1757
- if val.to_s =~ /\A\d{1,}\Z/
1758
- return find_network_by_id(val)
1759
- else
1760
- return find_network_by_name(val)
1761
- end
1762
- end
1763
-
1764
- def find_network_by_id(id)
1765
- begin
1766
- json_response = @networks_interface.get(id.to_i)
1767
- return json_response['network']
1768
- rescue RestClient::Exception => e
1769
- if e.response && e.response.code == 404
1770
- print_red_alert "Network not found by id #{id}"
1771
- return nil
1772
- else
1773
- raise e
1774
- end
1775
- end
1776
- end
1777
-
1778
- def find_network_by_name(name)
1779
- json_response = @networks_interface.list({name: name.to_s})
1780
- networks = json_response['networks']
1781
- if networks.empty?
1782
- print_red_alert "Network not found by name #{name}"
1783
- return nil
1784
- elsif networks.size > 1
1785
- print_red_alert "#{networks.size} networks found by name #{name}"
1786
- rows = networks.collect do |it|
1787
- {id: it['id'], name: it['name']}
1788
- end
1789
- puts as_pretty_table(rows, [:id, :name], {color:red})
1790
- return nil
1791
- else
1792
- network = networks[0]
1793
- # merge in tenants map
1794
- if json_response['tenants'] && json_response['tenants'][network['id']]
1795
- network['tenants'] = json_response['tenants'][network['id']]
1796
- end
1797
- return network
1798
- end
1799
- end
1800
-
1801
- def find_network_type_by_name_or_id(val)
1802
- if val.to_s =~ /\A\d{1,}\Z/
1803
- return find_network_type_by_id(val)
1804
- else
1805
- return find_network_type_by_name(val)
1806
- end
1807
- end
1808
-
1809
- def find_network_type_by_id(id)
1810
- begin
1811
- json_response = @network_types_interface.get(id.to_i)
1812
- return json_response['networkType']
1813
- rescue RestClient::Exception => e
1814
- if e.response && e.response.code == 404
1815
- print_red_alert "Network Type not found by id #{id}"
1816
- return nil
1817
- else
1818
- raise e
1819
- end
1820
- end
1821
- end
1822
-
1823
- def find_network_type_by_name(name)
1824
- json_response = @network_types_interface.list({name: name.to_s})
1825
- network_types = json_response['networkTypes']
1826
- if network_types.empty?
1827
- print_red_alert "Network Type not found by name #{name}"
1828
- return network_types
1829
- elsif network_types.size > 1
1830
- print_red_alert "#{network_types.size} network types found by name #{name}"
1831
- rows = network_types.collect do |it|
1832
- {id: it['id'], name: it['name']}
1833
- end
1834
- puts as_pretty_table(rows, [:id, :name], {color:red})
1835
- return nil
1836
- else
1837
- return network_types[0]
1838
- end
1839
- end
1840
-
1841
- def find_subnet_by_name_or_id(network_id, val)
1842
- if val.to_s =~ /\A\d{1,}\Z/
1843
- return find_subnet_by_id(network_id, val)
1844
- else
1845
- return find_subnet_by_name(network_id, val)
1846
- end
1847
- end
1848
-
1849
- def find_subnet_by_id(network_id, id)
1850
- begin
1851
- json_response = @network_subnets_interface.get(network_id, id.to_i)
1852
- return json_response['subnet']
1853
- rescue RestClient::Exception => e
1854
- if e.response && e.response.code == 404
1855
- print_red_alert "Subnet not found by id #{id}"
1856
- return nil
1857
- else
1858
- raise e
1859
- end
1860
- end
1861
- end
1862
-
1863
- def find_subnet_by_name(network_id, name)
1864
- json_response = @network_subnets_interface.list(network_id, {name: name.to_s})
1865
- subnets = json_response['subnets']
1866
- if subnets.empty?
1867
- print_red_alert "Subnet not found by name #{name}"
1868
- return nil
1869
- elsif subnets.size > 1
1870
- print_red_alert "#{subnets.size} subnets found by name #{name}"
1871
- rows = subnets.collect do |it|
1872
- {id: it['id'], name: it['name']}
1873
- end
1874
- puts as_pretty_table(rows, [:id, :name], {color:red})
1875
- return nil
1876
- else
1877
- return subnets[0]
1878
- end
1879
- end
1880
-
1881
- def find_subnet_type_by_name_or_id(val)
1882
- if val.to_s =~ /\A\d{1,}\Z/
1883
- return find_subnet_type_by_id(val)
1884
- else
1885
- return find_subnet_type_by_name(val)
1886
- end
1887
- end
1888
-
1889
- def find_subnet_type_by_id(id)
1890
- begin
1891
- json_response = @network_subnet_types_interface.get(id.to_i)
1892
- return json_response['subnetType']
1893
- rescue RestClient::Exception => e
1894
- if e.response && e.response.code == 404
1895
- print_red_alert "Subnet Type not found by id #{id}"
1896
- return nil
1897
- else
1898
- raise e
1899
- end
1900
- end
1901
- end
1902
-
1903
- def find_subnet_type_by_name(name)
1904
- json_response = @network_subnet_types_interface.list({name: name.to_s})
1905
- subnet_types = json_response['subnetTypes']
1906
- if subnet_types.empty?
1907
- print_red_alert "Subnet Type not found by name #{name}"
1908
- return subnet_types
1909
- elsif subnet_types.size > 1
1910
- print_red_alert "#{subnet_types.size} subnet types found by name #{name}"
1911
- rows = subnet_types.collect do |it|
1912
- {id: it['id'], name: it['name']}
1913
- end
1914
- puts as_pretty_table(rows, [:id, :name], {color:red})
1915
- return nil
1916
- else
1917
- return subnet_types[0]
1918
- end
1919
- end
1920
-
1921
1219
  end