Exemplo n.º 1
0
def build_services(status=None, paths=None, create_instance=False, node=None):
    """
    Returns a list of all services of status matching the specified status.
    If no status is specified, returns all services.
    """
    if paths is None:
        paths = []

    errors = []
    services = {}

    if isinstance(paths, str):
        paths = [paths]

    if len(paths) == 0:
        paths = list_services()
        missing_paths = []
    else:
        local_paths = list_services()
        missing_paths = sorted(list(set(paths) - set(local_paths)))
        for m in missing_paths:
            name, namespace, kind = split_path(m)
            if create_instance:
                services[m] = factory(kind)(name, namespace, node=node)
            else:
                # foreign service
                services[m] = factory(kind)(name,
                                            namespace,
                                            node=node,
                                            volatile=True)
        paths = list(set(paths) & set(local_paths))

    for path in paths:
        name, namespace, kind = split_path(path)
        try:
            svc = factory(kind)(name, namespace, node=node)
        except (ex.Error, ex.InitError, ValueError,
                utilities.configparser.Error) as e:
            errors.append("%s: %s" % (path, str(e)))
            node.log.error(str(e))
            continue
        except ex.AbortAction:
            continue
        except:
            import traceback
            traceback.print_exc()
            continue
        services[svc.path] = svc
    return [s for _, s in sorted(services.items())], errors
Exemplo n.º 2
0
 def volsvc(self):
     volume = factory("vol")(name=self.volname,
                             namespace=self.svc.namespace,
                             node=self.svc.node)
     if not volume.exists():
         volume = factory("vol")(name=self.volname,
                                 namespace=self.svc.namespace,
                                 node=self.svc.node,
                                 volatile=True)
         try:
             volume = self._configure_volume(volume)
         except Exception as exc:
             import traceback
             traceback.print_exc()
     return volume
Exemplo n.º 3
0
 def _install_data(self, kind):
     for data in self.data_data(kind):
         name, _, kind = split_path(data["obj"])
         obj = factory(kind)(name,
                             namespace=self.svc.namespace,
                             volatile=True,
                             node=self.svc.node)
         if not obj.exists():
             self.log.warning(
                 "referenced %s %s does not exist: "
                 "expected data %s can not be installed in the volume",
                 kind, name, data["key"])
             continue
         keys = obj.resolve_key(data["key"])
         if not keys and not is_glob(data["key"]):
             self.log.warning(
                 "%s %s has no key %s. "
                 "expected data can not be installed in the volume", kind,
                 name, data["key"])
             continue
         self.log.debug("install ./%s/%s/%s in %s", kind, name, data["key"],
                        data["path"])
         for key in keys:
             obj.install_key(key,
                             data["path"],
                             uid=self.uid,
                             gid=self.gid,
                             mode=self.octal_mode,
                             dirmode=self.octal_dirmode)
Exemplo n.º 4
0
 def kind_environment_env(self, kind, mappings):
     env = {}
     if mappings is None:
         return env
     for mapping in mappings:
         try:
             var, val = mapping.split("=", 1)
         except Exception as exc:
             self.log.info("ignored %s environment mapping %s: %s", kind,
                           mapping, exc)
             continue
         try:
             name, key = val.split("/", 1)
         except Exception as exc:
             self.log.info("ignored %s environment mapping %s: %s", kind,
                           mapping, exc)
             continue
         var = var.upper()
         obj = factory(kind)(name,
                             namespace=self.svc.namespace,
                             volatile=True,
                             node=self.svc.node)
         if not obj.exists():
             self.log.info(
                 "ignored %s environment mapping %s: config %s does not exist",
                 kind, mapping, name)
             continue
         if key not in obj.data_keys():
             self.log.info(
                 "ignored %s environment mapping %s: key %s does not exist",
                 kind, mapping, key)
             continue
         val = obj.decode_key(key)
         env[var] = val
     return env
Exemplo n.º 5
0
 def delete_volume(self, name, namespace=None):
     volume = factory("vol")(name=name, namespace=namespace, node=self.node)
     if not volume.exists():
         self.log.info("volume does not exist")
         return
     self.log.info("delete volume %s", volume.path)
     volume.action("delete", options={"wait": True, "unprovision": True, "time": "5m"})
Exemplo n.º 6
0
 def create_volume(self,
                   name,
                   namespace=None,
                   size=None,
                   access="rwo",
                   fmt=True,
                   nodes=None,
                   shared=False):
     volume = factory("vol")(name=name, namespace=namespace, node=self.node)
     if volume.exists():
         self.log.info("volume %s already exists", name)
         return volume
     if nodes is None:
         nodes = ""
     self.log.info(
         "create volume %s (pool name: %s, pool type: %s, "
         "access: %s, size: %s, format: %s, nodes: %s, shared: %s)",
         volume.path, self.name, self.type, access, size, fmt, nodes,
         shared)
     self.configure_volume(volume,
                           fmt=fmt,
                           size=convert_size(size),
                           access=access,
                           nodes=nodes,
                           shared=shared)
     volume.action("provision", options={"wait": True, "time": "5m"})
Exemplo n.º 7
0
 def ca(self):
     capath = self.oget("DEFAULT", "ca")
     name, namespace, kind = split_path(capath)
     return factory("sec")(name,
                           namespace=namespace,
                           volatile=True,
                           node=self.node)
Exemplo n.º 8
0
 def on_create(self):
     changes = []
     has_ca = False
     if not self.oget("DEFAULT", "cn"):
         if self.namespace == "system":
             changes.append("cn=%s" % self.name)
         else:
             changes.append("cn=%s" % self.fullname)
     if self.namespace != "system":
         try:
             self.conf_get("DEFAULT", "validity")
         except ex.OptNotFound:
             changes.append("validity=%s" % DEFAULT_SACC_CERT_VALIDITY)
         grant = "guest:" + self.namespace
         changes.append("grant=%s" % grant)
     if not self.oget("DEFAULT", "ca"):
         capath = self.node.oget("cluster", "ca")
         if capath is None:
             capath = "system/sec/ca-" + self.node.cluster_name
         name, namespace, kind = split_path(capath)
         casec = factory("sec")(name,
                                namespace="system",
                                volatile=True,
                                log=self.log)
         if casec.exists():
             has_ca = True
             changes.append("ca=%s" % capath)
         else:
             print("no cluster CA defined. skip certificate generation.")
     if changes:
         self.set_multi(changes)
     if has_ca and "certificate" not in self.data_keys(
     ) and "private_key" in casec.data_keys():
         self.gen_cert()
Exemplo n.º 9
0
 def init(self):
     if self.username is not None and self.password is not None:
         return
     s = "array#" + self.head
     try:
         stype = self.node.oget(s, "type")
     except Exception:
         raise ex.Error("no array configuration for head %s"%self.head)
     if stype != "nexenta":
         raise ex.Error("array %s type is not nexanta" % self.head)
     try:
         self.username = self.node.oget(s, "username")
     except Exception:
         raise ex.Error("no username information for head %s"%self.head)
     try:
         self.password = self.node.oget(s, "password")
     except Exception:
         raise ex.Error("no password information for head %s"%self.head)
     self.port = self.node.oget(s, "port")
     try:
         secname, namespace, _ = split_path(self.password)
         self.password = factory("sec")(secname, namespace=namespace, volatile=True).decode_key("password")
     except Exception as exc:
         raise ex.Error("error decoding password: %s" % exc)
     self.url = 'https://%(head)s:%(port)d/rest/nms/ <https://%(head)s:%(port)d/rest/nms/>'%dict(head=self.head, port=self.port)
Exemplo n.º 10
0
 def action(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     if options.kind == "node":
         obj = shared.NODE
     elif options.kind:
         obj = factory(options.kind)(name="dummy", node=shared.NODE, volatile=True)
     else:
         raise ex.HTTP(400, "A kind must be specified.")
     return obj.full_kwstore.dump()
Exemplo n.º 11
0
 def action(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     name, namespace, kind = split_path(options.path)
     svc = factory(kind)(name=name, namespace=namespace, volatile=True)
     data = {
         "status": 0,
         "data": [res.rid for res in svc.get_resources("task") if res.confirmation],
     }
     return data
Exemplo n.º 12
0
    def __init__(self, objects=None, node=None):
        if objects is None:
            objects = []
        self.objects = objects
        self.filtering = len(objects) > 0
        if node:
            self.node = node
        else:
            self.node = Node()
        done = []
        for s in self.node.conf_sections(cat="array"):
            try:
                name = self.node.oget(s, "name")
            except Exception:
                name = None
            if not name:
                name = s.split("#", 1)[-1]
            if name in done:
                continue
            if self.filtering and name not in self.objects:
                continue
            try:
                stype = self.node.oget(s, "type")
            except:
                continue
            if stype != "hds":
                continue
            try:
                bin = self.node.oget(s, 'bin')
                jre_path = self.node.oget(s, 'jre_path')
                url = self.node.oget(s, 'url')
                username = self.node.oget(s, 'username')
                password = self.node.oget(s, 'password')
            except Exception as exc:
                print("error parsing section %s: %s" % (s, exc),
                      file=sys.stderr)
                continue

            try:
                secname, namespace, _ = split_path(password)
                password = factory("sec")(secname,
                                          namespace=namespace,
                                          volatile=True).decode_key("password")
            except Exception as exc:
                print("error decoding password: %s", exc, file=sys.stderr)
                continue

            self.arrays.append(
                Array(name,
                      url,
                      username,
                      password,
                      bin=bin,
                      jre_path=jre_path,
                      node=self.node))
            done.append(name)
Exemplo n.º 13
0
 def __init__(self, objects=None, node=None):
     if objects is None:
         objects = []
     self.objects = objects
     self.filtering = len(objects) > 0
     if node:
         self.node = node
     else:
         self.node = Node()
     done = []
     for s in self.node.conf_sections(cat="array"):
         name = s.split("#", 1)[-1]
         if name in done:
             continue
         try:
             stype = self.node.oget(s, "type")
         except:
             continue
         if stype != "eva":
             continue
         try:
             manager = self.node.oget(s, 'manager')
             username = self.node.oget(s, 'username')
             password = self.node.oget(s, 'password')
             sssubin = self.node.oget(s, 'bin')
         except Exception as exc:
             print("error parsing section %s: %s" % (s, exc),
                   file=sys.stderr)
             pass
         try:
             secname, namespace, _ = split_path(password)
             password = factory("sec")(secname,
                                       namespace=namespace,
                                       volatile=True).decode_key("password")
         except Exception as exc:
             print("error decoding password: %s", exc, file=sys.stderr)
             continue
         out, err = sssu('ls system',
                         manager,
                         username,
                         password,
                         sssubin=sssubin)
         _in = False
         for line in out.split('\n'):
             if 'Systems avail' in line:
                 _in = True
                 continue
             if not _in:
                 continue
             name = line.strip()
             if self.filtering and name not in self.objects:
                 continue
             self.arrays.append(
                 Eva(name, manager, username, password, sssubin=sssubin))
             done.append(name)
Exemplo n.º 14
0
    def __init__(self, objects=None, node=None):
        if objects is None:
            objects = []
        self.objects = objects
        if len(objects) > 0:
            self.filtering = True
        else:
            self.filtering = False
        self.arrays = []
        if node:
            self.node = node
        else:
            self.node = Node()
        done = []
        for s in self.node.conf_sections(cat="array"):
            name = s.split("#", 1)[-1]
            if name in done:
                continue
            if self.filtering and name not in self.objects:
                continue
            try:
                stype = self.node.oget(s, "type")
            except:
                continue
            if stype != "centera":
                continue

            try:
                server = self.node.oget(s, "server")
                username = self.node.oget(s, "username")
                password = self.node.oget(s, "password")
                jcass_dir = self.node.oget(s, "jcass_dir")
                java_bin = self.node.oget(s, "java_bin")
            except:
                print("error parsing section", s, file=sys.stderr)

            try:
                secname, namespace, _ = split_path(password)
                password = factory("sec")(secname,
                                          namespace=namespace,
                                          volatile=True).decode_key("password")
            except Exception as exc:
                print("error decoding password: %s", exc, file=sys.stderr)
                continue

            self.arrays.append(
                Centera(name,
                        server=server,
                        username=username,
                        password=password,
                        java_bin=java_bin,
                        jcass_dir=jcass_dir,
                        node=self.node))
            done.append(name)
Exemplo n.º 15
0
    def test_raises_on_dup_destinations(mocker, osvc_path_tests,
                                        volume_mounts):
        mocker.patch.object(Volume, 'status', return_value=core.status.UP)

        svc1 = Svc('svc1')
        pool = Pool(name="dir1", node=Node())
        for vol_name in ['vol1', 'vol2']:
            pool.configure_volume(factory("vol")(name=vol_name))
            svc1 += Volume(rid="#" + vol_name, name=vol_name)

        container = ContainerDocker(rid='#dck1', volume_mounts=volume_mounts)
        svc1 += container

        with pytest.raises(ex.Error, match=r'same destination mount point'):
            container.volume_options()
Exemplo n.º 16
0
 def postinstall(self, key=None):
     """
     Refresh installed keys
     """
     changed_volumes = set()
     for path in list_services(namespace=self.namespace, kinds=["svc"]):
         name, _, _ = split_path(path)
         svc = factory("svc")(name, namespace=self.namespace, volatile=True, node=self.node, log=self.log)
         for res in svc.get_resources("volume"):
             if res.has_data(self.kind, self.path, key) and res._status() == core.status.UP:
                 installed = res._install_data(self.kind)
                 if installed:
                     changed_volumes.add(res.volsvc.path)
                 if res.volsvc.path in changed_volumes:
                     res.send_signals()
Exemplo n.º 17
0
 def __init__(self, objects=None, node=None):
     if objects is None:
         objects = []
     self.objects = objects
     self.filtering = len(objects) > 0
     self.timeout = 10
     if node:
         self.node = node
     else:
         self.node = Node()
     done = []
     for s in self.node.conf_sections(cat="array"):
         try:
             name = self.node.oget(s, 'name')
         except Exception:
             name = None
         if not name:
             name = s.split("#", 1)[-1]
         if name in done:
             continue
         if self.filtering and name not in self.objects:
             continue
         try:
             stype = self.node.oget(s, "type")
         except:
             continue
         if stype != "dorado":
             continue
         timeout = self.node.oget(s, "timeout")
         try:
             username = self.node.oget(s, "username")
             password = self.node.oget(s, "password")
             api = self.node.oget(s, "api")
         except:
             print("error parsing section", s, file=sys.stderr)
             continue
         try:
             secname, namespace, _ = split_path(password)
             password = factory("sec")(secname,
                                       namespace=namespace,
                                       volatile=True).decode_key("password")
         except Exception as exc:
             print("error decoding password: %s", exc, file=sys.stderr)
             continue
         self.arrays.append(
             Dorado(name, api, username, password, timeout, node=self.node))
         done.append(name)
Exemplo n.º 18
0
 def postinstall(self, key=None):
     """
     Refresh installed keys
     """
     for path in self.node.svcs_selector("*/svc/*",
                                         namespace=self.namespace,
                                         local=True):
         name, _, _ = split_path(path)
         svc = factory("svc")(name,
                              namespace=self.namespace,
                              volatile=True,
                              node=self.node,
                              log=self.log)
         for vol in svc.get_resources("volume"):
             if vol.has_data(self.kind, self.path,
                             key) and vol._status() == core.status.UP:
                 vol._install_data(self.kind)
Exemplo n.º 19
0
 def create_volume_locked(self):
     volume = factory("vol")(name=self.volname,
                             namespace=self.svc.namespace,
                             node=self.svc.node)
     if volume.exists():
         self.log.info("volume %s already exists", self.volname)
         data = volume.print_status_data(mon_data=True)
         if not data or "cluster" not in data:
             return volume
         if not self.svc.node.get_pool(volume.pool):
             raise ex.Error("pool %s not found on this node" % volume.pool)
         if self.svc.options.leader and volume.topology == "failover" and \
            (self.owned() or not self.claimed(volume)) and \
            data["avail"] != "up":
             cluster_avail = data["cluster"].get("avail")
             if cluster_avail is None:
                 self.log.info(
                     "no take over decision, we are leader but unknown cluster avail for volume %s",
                     self.volname)
             elif cluster_avail == "up":
                 self.log.info(
                     "volume %s is up on, peer, we are leader: take it over",
                     self.volname)
                 volume.action("takeover",
                               options={
                                   "wait": True,
                                   "time": 60
                               })
         return volume
     elif not self.svc.options.leader:
         self.log.info(
             "volume %s does not exist, we are not leader: wait its propagation",
             self.volname)
         self.wait_for_fn(
             lambda: volume.exists(), 10, 1,
             "non leader instance waited for too long for the volume to appear"
         )
         return volume
     self.check_configure_requirements()
     self.log.info(
         "create new volume %s (pool name: %s, pool type: %s, "
         "access: %s, size: %s, format: %s, shared: %s)", self.volname,
         self.pool, self.pooltype, self.access,
         print_size(self.size, unit="B",
                    compact=True), self.format, self.shared)
     return self._configure_volume(volume)
Exemplo n.º 20
0
 def users(self, exclude=None):
     exclude = exclude or []
     users = []
     for child in self.children:
         if child in exclude:
             continue
         name, namespace, kind = split_path(child)
         obj = factory(kind)(name=name,
                             namespace=self.namespace,
                             volatile=True,
                             node=self.node)
         for res in obj.get_resources("volume"):
             if res.name != self.name:
                 continue
             if res.status() in (core.status.UP, core.status.STDBY_UP,
                                 core.status.WARN):
                 users.append(child)
     return users
Exemplo n.º 21
0
 def _data_status(self, kind):
     for data in self.data_data(kind):
         name, _, kind = split_path(data["obj"])
         obj = factory(kind)(name,
                             namespace=self.svc.namespace,
                             volatile=True,
                             node=self.svc.node)
         if not obj.exists():
             self.status_log(
                 "referenced %s %s does not exist: "
                 "expected data %s can not be installed in the volume" %
                 (kind, name, data["key"]), "warn")
             continue
         keys = obj.resolve_key(data["key"])
         if not keys and not is_glob(data["key"]):
             self.status_log(
                 "%s %s has no key %s. "
                 "expected data can not be installed in the volume" %
                 (kind, name, data["key"]), "warn")
Exemplo n.º 22
0
    def __init__(self, objects=None, node=None):
        if objects is None:
            objects = []
        self.objects = objects
        self.filtering = len(objects) > 0
        self.arrays = []
        if node:
            self.node = node
        else:
            self.node = Node()
        done = []
        for s in self.node.conf_sections(cat="array"):
            name = s.split("#", 1)[-1]
            if name in done:
                continue
            if self.filtering and name not in self.objects:
                continue
            try:
                stype = self.node.oget(s, "type")
            except:
                continue
            if stype != "netapp":
                continue

            kwargs = {"node": self.node}

            for key in ("server", "username", "key"):
                try:
                    kwargs[key] = self.node.oget(s, key)
                except:
                    print("missing parameter: %s", s)
            if "server" not in kwargs or "username" not in kwargs or "key" not in kwargs:
                continue
            try:
                secname, namespace, _ = split_path(kwargs["password"])
                kwargs["password"] = factory("sec")(
                    secname, namespace=namespace,
                    volatile=True).decode_key("password")
            except Exception as exc:
                print("error decoding password: %s", exc, file=sys.stderr)
                continue
            self.arrays.append(Netapp(s, **kwargs))
Exemplo n.º 23
0
    def test_mount_options_values_when_source_is_volume(
            mocker, vol_options, container_options, expected_options):
        mocker.patch.object(Volume, 'status', return_value=core.status.UP)

        vol_name = 'vol-' + vol_options + '-' + container_options
        Pool(name="dir1",
             node=Node()).configure_volume(factory("vol")(name=vol_name),
                                           access=vol_options)

        svc1 = Svc('svc1')
        vol = Volume(rid="#" + vol_name, name=vol_name, access=vol_options)
        container = ContainerDocker(
            rid='#dck1',
            volume_mounts=[vol_name + '/src:/dst:' + container_options])
        svc1 += vol
        svc1 += container

        assert container.volume_options() == [
            vol.mount_point + '/src:/dst:' + expected_options
        ]
Exemplo n.º 24
0
 def configure_volume(self,
                      volume,
                      size=None,
                      fmt=True,
                      access="rwo",
                      shared=False,
                      nodes=None,
                      env=None):
     if self.template is None:
         raise ex.Error("pool#%s.template is not set" % self.name)
     if not is_service(self.template):
         raise ex.Error("%s template volume not found" % self.template)
     name = self.default_disk_name(volume)
     tname, tnamespace, tkind = split_path(self.template)
     if tkind != "vol":
         raise ex.Error("%s template kind is not vol")
     svc = factory(tkind)(tname, tnamespace, volatile=True, node=self.node)
     config = svc.print_config_data()
     try:
         del config["DEFAULT"]["disable"]
     except KeyError:
         pass
     if "DEFAULT" not in config:
         config["DEFAULT"] = {}
     if "env" not in config:
         config["env"] = {}
     config["DEFAULT"]["pool"] = self.name
     config["DEFAULT"]["access"] = access
     if access in ("rox", "rwx"):
         config["DEFAULT"]["topology"] = "flex"
         config["DEFAULT"]["flex_min"] = 0
     if nodes:
         config["DEFAULT"]["nodes"] = nodes
     config["env"]["size"] = size
     if env:
         config["env"].update(env)
     self.node.install_svc_conf_from_data(volume.name, volume.namespace,
                                          volume.kind, config)
Exemplo n.º 25
0
 def configure_volume(self, volume, size=None, fmt=True, access="rwo", shared=False, nodes=None, env=None):
     name = self.default_disk_name(volume)
     data = self.translate(name=name, size=size, fmt=fmt, shared=shared)
     defaults = {
         "rtype": "DEFAULT",
         "pool": self.name,
         "size": size,
         "access": access,
     }
     if access in ("rox", "rwx"):
         defaults["topology"] = "flex"
         defaults["flex_min"] = 0
     if nodes:
         defaults["nodes"] = nodes
     if self.status_schedule is not None:
         defaults["status_schedule"] = self.status_schedule
     data.append(defaults)
     if env:
         data.append(env)
     volume._update(data)
     self.disable_sync_internal(volume)
     if volume.volatile:
         return volume
     return factory("vol")(name=volume.name, namespace=volume.namespace, node=self.node, volatile=volume.volatile)
Exemplo n.º 26
0
 def rbac_create_obj(self, path, cd, all_ns, thr=None, **kwargs):
     errors = []
     name, namespace, kind = split_path(path)
     grants = thr.user_grants(all_ns | set([namespace]))
     if namespace not in all_ns:
         if namespace == "system":
             errors.append(
                 "%s: create the new namespace system requires the root cluster role"
             )
             return errors
         elif "squatter" not in grants:
             errors.append(
                 "%s: create the new namespace %s requires the squatter cluster role"
                 % (path, namespace))
             return errors
         elif namespace not in grants["admin"]:
             thr.usr.set_multi(["grant+=admin:%s" % namespace])
             grants["admin"].add(namespace)
     thr.rbac_requires(roles=["admin"],
                       namespaces=[namespace],
                       grants=grants,
                       **kwargs)
     try:
         orig_obj = factory(kind)(name,
                                  namespace=namespace,
                                  volatile=True,
                                  node=shared.NODE)
     except:
         orig_obj = None
     try:
         obj = factory(kind)(name,
                             namespace=namespace,
                             volatile=True,
                             cd=cd,
                             node=shared.NODE)
     except Exception as exc:
         errors.append("%s: unbuildable config: %s" % (path, exc))
         return errors
     if kind == "vol":
         errors.append("%s: volume create requires the root privilege" %
                       path)
     elif kind == "ccfg":
         errors.append(
             "%s: cluster config create requires the root privilege" % path)
     elif kind == "svc":
         groups = ["disk", "fs", "app", "share", "sync"]
         for r in obj.get_resources(groups):
             if r.rid == "sync#i0":
                 continue
             errors.append("%s: resource %s requires the root privilege" %
                           (path, r.rid))
         for r in obj.get_resources("task"):
             if r.type not in ("task.podman", "task.docker"):
                 errors.append(
                     "%s: resource %s type %s requires the root privilege" %
                     (path, r.rid, r.type))
         for r in obj.get_resources("container"):
             if r.type not in ("container.podman", "container.docker"):
                 errors.append(
                     "%s: resource %s type %s requires the root privilege" %
                     (path, r.rid, r.type))
         for r in obj.get_resources("ip"):
             if r.type not in ("ip.cni"):
                 errors.append(
                     "%s: resource %s type %s requires the root privilege" %
                     (path, r.rid, r.type))
     for section, sdata in cd.items():
         rtype = cd[section].get("type")
         errors += thr.rbac_create_data_section(path,
                                                section,
                                                rtype,
                                                sdata,
                                                grants,
                                                obj,
                                                orig_obj,
                                                all_ns,
                                                thr=thr)
     return errors
Exemplo n.º 27
0
    def __init__(self, objects=None, node=None):
        if objects is None:
            objects = []
        self.objects = objects
        if len(objects) > 0:
            self.filtering = True
        else:
            self.filtering = False
        self.arrays = []
        if node:
            self.node = node
        else:
            self.node = Node()
        done = []
        for s in self.node.conf_sections(cat="array"):
            name = s.split("#", 1)[-1]
            if name in done:
                continue
            if self.filtering and name not in self.objects:
                continue
            try:
                stype = self.node.oget(s, "type")
            except:
                continue
            if stype != "emcvnx":
                continue

            try:
                method = self.node.oget(s, "method")
                scope = self.node.oget(s, "scope")
                spa = self.node.oget(s, "spa")
                spb = self.node.oget(s, "spb")
                username = self.node.oget(s, "username")
                password = self.node.oget(s, "password")
            except Exception as exc:
                print("error parsing section %s: %s" % (s, exc),
                      file=sys.stderr)
                continue

            if method == "credentials":
                if username is None or password is None:
                    print(
                        "error parsing section %s: username and password are mandatory"
                        % s,
                        file=sys.stderr)
                    continue
                try:
                    secname, namespace, _ = split_path(password)
                    password = factory("sec")(
                        secname, namespace=namespace,
                        volatile=True).decode_key("password")
                except Exception as exc:
                    print("error decoding password: %s", exc, file=sys.stderr)
                    continue

            self.arrays.append(
                EmcVnx(name,
                       method,
                       scope,
                       spa,
                       spb,
                       username=username,
                       password=password,
                       node=self.node))
            done.append(name)
Exemplo n.º 28
0
 def create_volume_locked(self):
     volume = factory("vol")(name=self.volname,
                             namespace=self.svc.namespace,
                             node=self.svc.node)
     if volume.exists():
         self.log.info("volume %s already exists", self.volname)
         data = volume.print_status_data(mon_data=True)
         if not data or "cluster" not in data:
             return volume
         if not self.svc.node.get_pool(volume.pool):
             raise ex.Error("pool %s not found on this node" % volume.pool)
         if self.svc.options.leader and volume.topology == "failover" and \
            (self.owned() or not self.claimed(volume)) and \
            data["avail"] != "up":
             cluster_avail = data["cluster"].get("avail")
             if cluster_avail is None:
                 self.log.info(
                     "no take over decision, we are leader but unknown cluster avail for volume %s",
                     self.volname)
             elif cluster_avail == "up":
                 self.log.info(
                     "volume %s is up on, peer, we are leader: take it over",
                     self.volname)
                 volume.action("takeover",
                               options={
                                   "wait": True,
                                   "time": 60
                               })
         return volume
     elif not self.svc.options.leader:
         self.log.info(
             "volume %s does not exist, we are not leader: wait its propagation",
             self.volname)
         self.wait_for_fn(
             lambda: volume.exists(), 10, 1,
             "non leader instance waited for too long for the "
             "volume to appear")
         return volume
     self.log.info(
         "create new volume %s (pool name: %s, pool type: %s, "
         "access: %s, size: %s, format: %s, shared: %s)", self.volname,
         self.pool, self.pooltype, self.access,
         print_size(self.size, unit="B",
                    compact=True), self.format, self.shared)
     pool = self.svc.node.find_pool(poolname=self.pool,
                                    pooltype=self.pooltype,
                                    access=self.access,
                                    size=self.size,
                                    fmt=self.format,
                                    shared=self.shared)
     if pool is None:
         raise ex.Error("could not find a pool matching criteria")
     pool.log = self.log
     try:
         nodes = self.svc._get("DEFAULT.nodes")
     except ex.OptNotFound:
         nodes = None
     env = {}
     for mapping in pool.volume_env:
         try:
             src, dst = mapping.split(":", 1)
         except Exception:
             continue
         args = src.split(".", 1)
         val = self.svc.oget(*args)
         if val is None:
             raise ex.Error("missing mapped key in %s: %s" %
                            (self.svc.path, mapping))
         if is_string(val) and ".." in val:
             raise ex.Error(
                 "the '..' substring is forbidden in volume env keys: %s=%s"
                 % (mapping, val))
         env[dst] = val
     pool.configure_volume(volume,
                           fmt=self.format,
                           size=self.size,
                           access=self.access,
                           nodes=nodes,
                           shared=self.shared,
                           env=env)
     volume = factory("vol")(name=self.volname,
                             namespace=self.svc.namespace,
                             node=self.svc.node)
     return volume
Exemplo n.º 29
0
    def gen_cert(self):
        data = {}
        for key in ("cn", "c", "st", "l", "o", "ou", "email", "alt_names",
                    "bits", "validity", "ca"):
            val = self.oget("DEFAULT", key)
            if val is not None:
                data[key] = val

        ca = data.get("ca")
        casec = None
        if ca is not None:
            casecname, canamespace, _ = split_path(ca)
            casec = factory("sec")(casecname,
                                   namespace=canamespace,
                                   log=self.log,
                                   volatile=True)
            if not casec.exists():
                raise ex.Error("ca secret %s does not exist" % ca)

        for key in ("crt", "key", "csr"):
            data[key] = self.tempfilename()

        if "alt_names" in data:
            data["cnf"] = self.tempfilename()

        try:
            add_data = []
            if casec:
                for key, kw in (("cacrt", "certificate"), ("cakey",
                                                           "private_key")):
                    if kw not in casec.data_keys():
                        continue
                    data[key] = self.tempfilename()
                    buff = bdecode(casec.decode_key(kw))
                    with open(data[key], "w") as ofile:
                        ofile.write(buff)
            gen_cert(log=self.log, **data)
            with open(data["key"], "r") as ofile:
                buff = ofile.read()
            fullpem = ""
            fullpem += buff
            add_data.append(("private_key", buff))
            if data.get("crt") is not None:
                with open(data["crt"], "r") as ofile:
                    buff = ofile.read()
                add_data.append(("certificate", buff))
            if data.get("csr") is not None:
                with open(data["csr"], "r") as ofile:
                    buff = ofile.read()
                add_data.append(("certificate_signing_request", buff))
            if data.get("cakey") is None:
                with open(data["crt"], "r") as ofile:
                    buff = ofile.read()
                fullpem += buff
                add_data.append(("certificate_chain", buff))
            else:
                # merge cacrt and crt
                with open(data["crt"], "r") as ofile:
                    buff = ofile.read()
                with open(data["cacrt"], "r") as ofile:
                    buff += ofile.read()
                fullpem += buff
                add_data.append(("certificate_chain", buff))
            add_data.append(("fullpem", fullpem))
            self._add_keys(add_data)
        finally:
            for key in ("crt", "key", "cacrt", "cakey", "csr", "cnf"):
                if key not in data:
                    continue
                try:
                    os.unlink(data[key])
                except Exception:
                    pass
Exemplo n.º 30
0
 def volsvc(self):
     return factory("vol")(name=self.volname,
                           namespace=self.svc.namespace,
                           node=self.svc.node)