Revision 306bed0e lib/query.py

b/lib/query.py
71 71
                              RS_NORMAL, RS_UNKNOWN, RS_NODATA,
72 72
                              RS_UNAVAIL, RS_OFFLINE)
73 73

  
74
(NETQ_CONFIG,
75
 NETQ_GROUP,
76
 NETQ_STATS,
77
 NETQ_INST) = range(300, 304)
74 78

  
75 79
# Constants for requesting data from the caller/data provider. Each property
76 80
# collected/computed separately by the data provider should have its own to
......
2422 2426
    ])
2423 2427

  
2424 2428

  
2429
class NetworkQueryData:
2430
  """Data container for network data queries.
2431

  
2432
  """
2433
  def __init__(self, networks, network_to_groups,
2434
               network_to_instances, stats):
2435
    """Initializes this class.
2436

  
2437
    @param networks: List of network objects
2438
    @type network_to_groups: dict; network UUID as key
2439
    @param network_to_groups: Per-network list of groups
2440
    @type network_to_instances: dict; network UUID as key
2441
    @param network_to_instances: Per-network list of instances
2442
    @type stats: dict; network UUID as key
2443
    @param stats: Per-network usage statistics
2444

  
2445
    """
2446
    self.networks = networks
2447
    self.network_to_groups = network_to_groups
2448
    self.network_to_instances = network_to_instances
2449
    self.stats = stats
2450

  
2451
  def __iter__(self):
2452
    """Iterate over all networks.
2453

  
2454
    """
2455
    for net in self.networks:
2456
      if self.stats:
2457
        self.curstats = self.stats.get(net.uuid, None)
2458
      else:
2459
        self.curstats = None
2460
      yield net
2461

  
2462

  
2463
_NETWORK_SIMPLE_FIELDS = {
2464
  "name": ("Network", QFT_TEXT, 0, "The network"),
2465
  "network": ("Subnet", QFT_TEXT, 0, "The subnet"),
2466
  "gateway": ("Gateway", QFT_OTHER, 0, "The gateway"),
2467
  "network6": ("IPv6Subnet", QFT_OTHER, 0, "The ipv6 subnet"),
2468
  "gateway6": ("IPv6Gateway", QFT_OTHER, 0, "The ipv6 gateway"),
2469
  "mac_prefix": ("MacPrefix", QFT_OTHER, 0, "The mac prefix"),
2470
  "network_type": ("NetworkType", QFT_OTHER, 0, "The network type"),
2471
  }
2472

  
2473

  
2474
_NETWORK_STATS_FIELDS = {
2475
  "free_count": ("FreeCount", QFT_NUMBER, 0, "How many addresses are free"),
2476
  "reserved_count": ("ReservedCount", QFT_NUMBER, 0, "How many addresses are reserved"),
2477
  "map": ("Map", QFT_TEXT, 0, "The actual mapping"),
2478
  "external_reservations": ("ExternalReservations", QFT_TEXT, 0, "The external reservations"),
2479
  }
2480

  
2481

  
2482
def _GetNetworkStatsField(field, kind, ctx, net):
2483
  """Gets the value of a "stats" field from L{NetworkQueryData}.
2484

  
2485
  @param field: Field name
2486
  @param kind: Data kind, one of L{constants.QFT_ALL}
2487
  @type ctx: L{NetworkQueryData}
2488

  
2489
  """
2490

  
2491
  try:
2492
    value = ctx.curstats[field]
2493
  except KeyError:
2494
    return _FS_UNAVAIL
2495

  
2496
  if kind == QFT_TEXT:
2497
    return value
2498

  
2499
  assert kind in (QFT_NUMBER, QFT_UNIT)
2500

  
2501
  # Try to convert into number
2502
  try:
2503
    return int(value)
2504
  except (ValueError, TypeError):
2505
    logging.exception("Failed to convert network field '%s' (value %r) to int",
2506
                      value, field)
2507
    return _FS_UNAVAIL
2508

  
2509

  
2510
def _BuildNetworkFields():
2511
  """Builds list of fields for network queries.
2512

  
2513
  """
2514
  # Add simple fields
2515
  fields = [
2516
    (_MakeField(name, title, kind, doc),
2517
     NETQ_CONFIG, 0, _GetItemAttr(name))
2518
    for (name, (title, kind, flags, doc)) in _NETWORK_SIMPLE_FIELDS.items()]
2519

  
2520
  def _GetLength(getter):
2521
    return lambda ctx, network: len(getter(ctx)[network.uuid])
2522

  
2523
  def _GetSortedList(getter):
2524
    return lambda ctx, network: utils.NiceSort(getter(ctx)[network.uuid])
2525

  
2526
  network_to_groups = operator.attrgetter("network_to_groups")
2527
  network_to_instances = operator.attrgetter("network_to_instances")
2528

  
2529
  # Add fields for node groups
2530
  fields.extend([
2531
    (_MakeField("group_cnt", "NodeGroups", QFT_NUMBER, "Number of nodegroups"),
2532
     NETQ_GROUP, 0, _GetLength(network_to_groups)),
2533
	(_MakeField("group_list", "GroupList", QFT_OTHER, "List of nodegroups"),
2534
     NETQ_GROUP, 0, _GetSortedList(network_to_groups)),
2535
    ])
2536

  
2537
  # Add fields for instances
2538
  fields.extend([
2539
    (_MakeField("inst_cnt", "Instances", QFT_NUMBER, "Number of instances"),
2540
     NETQ_INST, 0, _GetLength(network_to_instances)),
2541
    (_MakeField("inst_list", "InstanceList", QFT_OTHER, "List of instances"),
2542
     NETQ_INST, 0, _GetSortedList(network_to_instances)),
2543
    ])
2544

  
2545
  # Add fields for usage statistics
2546
  fields.extend([
2547
    (_MakeField(name, title, kind, doc), NETQ_STATS, 0,
2548
    compat.partial(_GetNetworkStatsField, name, kind))
2549
    for (name, (title, kind, flags, doc)) in _NETWORK_STATS_FIELDS.items()
2550
    ])
2551

  
2552
  return _PrepareFieldList(fields, [])
2553

  
2425 2554
#: Fields for cluster information
2426 2555
CLUSTER_FIELDS = _BuildClusterFields()
2427 2556

  
......
2446 2575
#: Fields available for exports
2447 2576
EXPORT_FIELDS = _BuildExportFields()
2448 2577

  
2578
#: Fields available for network queries
2579
NETWORK_FIELDS = _BuildNetworkFields()
2580

  
2449 2581
#: All available resources
2450 2582
ALL_FIELDS = {
2451 2583
  constants.QR_CLUSTER: CLUSTER_FIELDS,
......
2456 2588
  constants.QR_OS: OS_FIELDS,
2457 2589
  constants.QR_JOB: JOB_FIELDS,
2458 2590
  constants.QR_EXPORT: EXPORT_FIELDS,
2591
  constants.QR_NETWORK: NETWORK_FIELDS,
2459 2592
  }
2460 2593

  
2461 2594
#: All available field lists

Also available in: Unified diff