Exemple #1
0
    def do_setup(self, context):
        """Driver initialization"""
        if purity_fb is None:
            msg = _("Missing 'purity_fb' python module, ensure the library"
                    " is installed and available.")
            raise exception.ManilaException(message=msg)

        self.api = self._safe_get_from_config_or_fail("flashblade_api")
        self.management_address = self._safe_get_from_config_or_fail(
            "flashblade_mgmt_vip")
        self.data_address = self._safe_get_from_config_or_fail(
            "flashblade_data_vip")
        self._sys = purity_fb.PurityFb(self.management_address)
        self._sys.disable_verify_ssl()
        try:
            self._sys.login(self.api)
            self._sys._api_client.user_agent = self._user_agent
        except purity_fb.rest.ApiException as ex:
            msg = _("Exception when logging into the array: %s\n") % ex
            LOG.exception(msg)
            raise exception.ManilaException(message=msg)

        backend_name = self.configuration.safe_get("share_backend_name")
        self._backend_name = backend_name or self.__class__.__name__

        LOG.debug("setup complete")
Exemple #2
0
def collect_volumes():
    #========= Login to Kubernetes cluster ======================

    # Configs can be set in Configuration class directly or using helper utility
    kubernetes.config.load_incluster_config()

    v1 = kubernetes.client.CoreV1Api()

    # Collect state about each PVC found in the system.
    pvcs = {}
    ret = v1.list_persistent_volume_claim_for_all_namespaces(watch=False)
    for i in ret.items:
        pvcs[i.metadata.uid] = {
            "name": i.metadata.name,
            "namespace": i.metadata.namespace,
            "storageclass": i.spec.storage_class_name,
            "labels": i.metadata.labels
        }

    # To group PVCs by StatefulSet, create regexes that matches the naming
    # convention for the PVCs that belong to VolumeClaimTemplates.
    ss_regexes = {}
    ret = kubernetes.client.AppsV1Api().list_stateful_set_for_all_namespaces(
        watch=False)
    for i in ret.items:
        if i.spec.volume_claim_templates:
            for vct in i.spec.volume_claim_templates:
                ssname = i.metadata.name + "." + i.metadata.namespace
                ss_regexes[ssname] = re.compile(vct.metadata.name + "-" +
                                                i.metadata.name + "-[0-9]+")

    # Search for PURE_K8S_NAMESPACE
    pso_namespace = ""
    pso_prefix = ""
    ret = v1.list_pod_for_all_namespaces(watch=False)
    for i in ret.items:
        for c in i.spec.containers:
            if c.env:
                for e in c.env:
                    if e.name == "PURE_K8S_NAMESPACE":
                        pso_prefix = e.value
                        pso_namespace = i.metadata.namespace
                        break

    if not pso_namespace:
        print("Did not find PSO, exiting")
        exit(1)

    # Find the secret associated with the pure-provisioner in order to find the
    # login info for all FlashArrays and FlashBlades.
    flashblades = {}
    flasharrays = {}

    secrets = v1.read_namespaced_secret("pure-provisioner-secret",
                                        pso_namespace)
    rawbytes = base64.b64decode(secrets.data['pure.json'])
    purejson = json.loads(rawbytes.decode("utf-8"))
    pso_namespace = i.metadata.namespace
    flashblades = purejson["FlashBlades"] if "FlashBlades" in purejson else {}
    flasharrays = purejson["FlashArrays"] if "FlashArrays" in purejson else {}

    # Begin collecting and correlating volume information from the backends.
    vols = []

    # Disable warnings due to unsigned SSL certs.
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    #========= Login to FlashArrays ======================

    for fajson in flasharrays:
        fa = purestorage.FlashArray(fajson["MgmtEndPoint"],
                                    api_token=fajson["APIToken"])

        try:
            for vol in fa.list_volumes(names=[pso_prefix + "*"], space=True):
                assert vol["name"].startswith(pso_prefix + "-pvc-")
                uid = vol["name"].replace(pso_prefix + "-pvc-", "")

                if uid not in pvcs:
                    print("Found orphan PersistentVolume: " + uid +
                          " on FlashArray " + fajson["MgmtEndPoint"])
                    continue

                pvc = pvcs[uid]

                tags = {
                    "all": "all",
                    "storageclass": pvc["storageclass"],
                    "namespace": pvc["namespace"],
                    "name": pvc["name"],
                    "backend": "FA " + fajson["MgmtEndPoint"]
                }
                if pvc["labels"]:
                    for l in pvc["labels"]:
                        tags["label/" + l] = pvc["labels"][l]
                for ssname, rgx in ss_regexes.items():
                    if rgx.match(pvc["name"]):
                        tags["statefulset"] = ssname

                vol = {
                    "uid": uid,
                    "logical_bytes": vol["total"],
                    "physical_bytes": vol["volumes"] * vol["data_reduction"],
                    "data_reduction": vol["data_reduction"],
                    "provisioned_bytes": vol["size"],
                    "tags": tags
                }

                vols.append(vol)

        except:
            pass

    #========= Login to FlashBlades ======================

    for fbjson in flashblades:
        fb = purity_fb.PurityFb(fbjson["MgmtEndPoint"],
                                api_token=fbjson["APIToken"])

        res = fb.file_systems.list_file_systems(filter="name='" + pso_prefix +
                                                "*'")
        for fs in res.items:
            assert fs.name.startswith(pso_prefix + "-pvc-")
            uid = fs.name.replace(pso_prefix + "-pvc-", "")

            if uid not in pvcs:
                print("Found orphan PersistentVolume: " + uid +
                      " on FlashBlade " + fbjson["MgmtEndPoint"])
                continue

            pvc = pvcs[uid]

            tags = {
                "all": "all",
                "storageclass": pvc["storageclass"],
                "namespace": pvc["namespace"],
                "name": pvc["name"],
                "backend": "FB " + fbjson["MgmtEndPoint"]
            }
            if pvc["labels"]:
                for l in pvc["labels"]:
                    tags["label/" + l] = pvc["labels"][l]
            for ssname, rgx in ss_regexes.items():
                if rgx.match(pvc["name"]):
                    tags["statefulset"] = ssname

            vol = {
                "uid": uid,
                "logical_bytes": fs.space.virtual,
                "physical_bytes": fs.space.total_physical,
                "provisioned_bytes": fs.provisioned,
                "tags": tags
            }

            vols.append(vol)

    return vols
                "uid": uid,
                "logical_bytes": vol["total"],
                "physical_bytes": vol["total"] / vol["data_reduction"],
                "provisioned_bytes": vol["size"],
                "tags": tags
            }

            vols.append(vol)

    except:
        pass

#========= Login to FlashBlades ======================

for fbjson in flashblades:
    fb = purity_fb.PurityFb(fbjson["MgmtEndPoint"],
                            api_token=fbjson["APIToken"])

    res = fb.file_systems.list_file_systems(filter="name='" + pso_prefix +
                                            "*'")
    for fs in res.items:
        assert fs.name.startswith(pso_prefix + "-pvc-")
        uid = fs.name.replace(pso_prefix + "-pvc-", "")

        if uid not in pvcs:
            print("Found orphan PersistentVolume: " + uid + " on FlashBlade " +
                  fbjson["MgmtEndPoint"])
            continue

        pvc = pvcs[uid]

        tags = {