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")
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 = {