Пример #1
0
class SwiftUsageInput(IDataSource):
    def __init__(self, project, username, password, auth_url, ring_location="/etc/swift/account.ring.gz"):
        self.__project=project
        self.__username=username
        self.__password=password
        self.__auth_url=auth_url
        self.__ring_location=ring_location
        self.__ring=None
    def get_data(self, **kwargs):
        query_id=str(uuid.uuid4())
        data_list=[]
        from keystoneclient.v2_0 import client
        from swift.common.ring import Ring
        keystone=client.Client(username=self.__username, password=self.__password, tenant_name=self.__project, auth_url=self.__auth_url)
        self.__ring = Ring(self.__ring_location)
        tenants = [tenant.id for tenant in keystone.tenants.list()]
        random.shuffle(tenants)
        data=init_message()
        data["swift"] = {}
        for tenant, stats in zip(tenants, ThreadPool().map(self.fetch, tenants)):
            if stats is not None:
                data["swift"][tenant] = stats
        return data
        
    def fetch(self, tenant):
        account = "AUTH_%s" % tenant
        partition = self.__ring.get_part(account, None, None)
        nodes = self.__ring.get_part_nodes(partition)
        random.shuffle(nodes)
        for node in nodes:
            url = "http://%s:%s/%s/%s/%s" % (node["ip"], node["port"], node["device"], partition, account)
            try:
                response = requests.head(url, timeout=5)
                if response.status_code == 204:
                    return {
                        "containers" : int(response.headers["x-account-container-count"]),
                        "objects" : int(response.headers["x-account-object-count"]),
                        "bytes" : int(response.headers["x-account-bytes-used"]),
                        "quota" : int(response.headers["x-account-meta-quota-bytes"]) if "x-account-meta-quota-bytes" in response.headers else None
                    }
                elif response.status_code == 404:
                    return None
                else:
                    log.warning("error fetching %s [HTTP %s]", url, response.status_code)
            except:
                log.warning("error fetching %s", url, exc_info=True)
        log.error("failed to fetch info for tenant %s", tenant)
        return None