diff --git a/swift/cli/recon.py b/swift/cli/recon.py index 694a27731c..030d8d424b 100755 --- a/swift/cli/recon.py +++ b/swift/cli/recon.py @@ -175,22 +175,23 @@ class SwiftRecon(object): block = f.read(4096) return md5sum.hexdigest() - def get_devices(self, zone_filter, swift_dir, ring_name): + def get_devices(self, region_filter, zone_filter, swift_dir, ring_name): """ Get a list of hosts in the ring + :param region_filter: Only list regions matching given filter :param zone_filter: Only list zones matching given filter :param swift_dir: Directory of swift config, usually /etc/swift :param ring_name: Name of the ring, such as 'object' :returns: a set of tuples containing the ip and port of hosts """ ring_data = Ring(swift_dir, ring_name=ring_name) + devs = [d for d in ring_data.devs if d] + if region_filter is not None: + devs = [d for d in devs if d['region'] == region_filter] if zone_filter is not None: - ips = set((n['ip'], n['port']) for n in ring_data.devs - if n and n['zone'] == zone_filter) - else: - ips = set((n['ip'], n['port']) for n in ring_data.devs if n) - return ips + devs = [d for d in devs if d['zone'] == zone_filter] + return set((d['ip'], d['port']) for d in devs) def get_ringmd5(self, hosts, swift_dir): """ @@ -875,6 +876,8 @@ class SwiftRecon(object): args.add_option('--all', action="store_true", help="Perform all checks. Equal to -arudlq --md5 " "--sockstat") + args.add_option('--region', type="int", + help="Only query servers in specified region") args.add_option('--zone', '-z', type="int", help="Only query servers in specified zone") args.add_option('--timeout', '-t', type="int", metavar="SECONDS", @@ -903,10 +906,8 @@ class SwiftRecon(object): self.suppress_errors = options.suppress self.timeout = options.timeout - if options.zone is not None: - hosts = self.get_devices(options.zone, swift_dir, self.server_type) - else: - hosts = self.get_devices(None, swift_dir, self.server_type) + hosts = self.get_devices(options.region, options.zone, + swift_dir, self.server_type) print("--> Starting reconnaissance on %s hosts" % len(hosts)) print("=" * 79) diff --git a/test/unit/cli/test_recon.py b/test/unit/cli/test_recon.py index 2b4738c0c8..81866e0d0b 100644 --- a/test/unit/cli/test_recon.py +++ b/test/unit/cli/test_recon.py @@ -134,21 +134,38 @@ class TestRecon(unittest.TestCase): ringbuilder.add_dev({'id': 1, 'zone': 1, 'weight': 1, 'ip': '127.0.0.1', 'port': 10001, 'device': 'sda1', 'region': 0}) + ringbuilder.add_dev({'id': 2, 'zone': 0, 'weight': 1, + 'ip': '127.0.0.1', 'port': 10002, + 'device': 'sda1', 'region': 1}) + ringbuilder.add_dev({'id': 3, 'zone': 1, 'weight': 1, + 'ip': '127.0.0.1', 'port': 10003, + 'device': 'sda1', 'region': 1}) ringbuilder.rebalance() ringbuilder.get_ring().save(self.tmpfile_name) ips = self.recon_instance.get_devices( - None, self.swift_dir, self.ring_name) + None, None, self.swift_dir, self.ring_name) + self.assertEqual( + set([('127.0.0.1', 10000), ('127.0.0.1', 10001), + ('127.0.0.1', 10002), ('127.0.0.1', 10003)]), ips) + + ips = self.recon_instance.get_devices( + 0, None, self.swift_dir, self.ring_name) self.assertEqual( set([('127.0.0.1', 10000), ('127.0.0.1', 10001)]), ips) ips = self.recon_instance.get_devices( - 0, self.swift_dir, self.ring_name) + 1, None, self.swift_dir, self.ring_name) + self.assertEqual( + set([('127.0.0.1', 10002), ('127.0.0.1', 10003)]), ips) + + ips = self.recon_instance.get_devices( + 0, 0, self.swift_dir, self.ring_name) self.assertEqual(set([('127.0.0.1', 10000)]), ips) ips = self.recon_instance.get_devices( - 1, self.swift_dir, self.ring_name) - self.assertEqual(set([('127.0.0.1', 10001)]), ips) + 1, 1, self.swift_dir, self.ring_name) + self.assertEqual(set([('127.0.0.1', 10003)]), ips) def test_get_ringmd5(self): for server_type in ('account', 'container', 'object', 'object-1'):