morpheus-cli 4.1.5 → 4.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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