"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/geo-replication/src/peer_mountbroker.in" (16 Sep 2020, 6361 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/usr/bin/python3
    2 
    3 from __future__ import print_function
    4 
    5 import os
    6 from argparse import ArgumentParser, RawDescriptionHelpFormatter
    7 import json
    8 import sys
    9 
   10 PROG_DESCRIPTION = """
   11 GlusterFS Mountbroker user management
   12 """
   13 
   14 args = None
   15 
   16 
   17 def ok(message=""):
   18     if (not args and "-j" in sys.argv) or (args and args.json):
   19         print(json.dumps({"ok": True, "message": message}))
   20     else:
   21         if message:
   22             print(message)
   23 
   24     sys.exit(0)
   25 
   26 
   27 def notok(message=""):
   28     if (not args and "-j" in sys.argv) or (args and args.json):
   29         print(json.dumps({"ok": False, "message": message}))
   30     else:
   31         print("error: %s" % message)
   32 
   33     # Always return zero due to limitation while executing
   34     # as `gluster system:: execute`
   35     sys.exit(0)
   36 
   37 
   38 class NoStdErrParser(ArgumentParser):
   39     """
   40     with gluster system:: execute, stderr gives
   41     "Unable to end. Error : Bad file descriptor" error,
   42     so deriving new class, prints error message and
   43     exits with zero.
   44     """
   45     def error(self, message):
   46         notok(message)
   47 
   48 
   49 class MountbrokerUserMgmt(object):
   50     def __init__(self, volfile):
   51         self.volfile = volfile
   52         self._options = {}
   53         self.commented_lines = []
   54         self._parse()
   55 
   56     def _parse(self):
   57         with open(self.volfile, "r") as f:
   58             for line in f:
   59                 line = line.strip()
   60                 if line.startswith("option "):
   61                     key, value = line.split(" ")[1:]
   62                     self._options[key] = value
   63                 if line.startswith("#"):
   64                     self.commented_lines.append(line)
   65 
   66     def _get_write_data(self):
   67         op = "volume management\n"
   68         op += "    type mgmt/glusterd\n"
   69         for k, v in self._options.items():
   70             op += "    option %s %s\n" % (k, v)
   71         for line in self.commented_lines:
   72             op += "    %s\n" % line
   73         op += "end-volume"
   74         return op
   75 
   76     def save(self):
   77         with open(self.volfile + "_tmp", "w") as f:
   78             f.write(self._get_write_data())
   79             f.flush()
   80             os.fsync(f.fileno())
   81         os.rename(self.volfile + "_tmp", self.volfile)
   82 
   83     def set_opt(self, key, value):
   84         self._options[key] = value.strip()
   85 
   86     def remove_opt(self, key):
   87         if key in self._options:
   88             del(self._options[key])
   89 
   90     def add_user(self, user, volumes):
   91         vols = set()
   92         for k, v in self._options.items():
   93             if k.startswith("mountbroker-geo-replication.") \
   94                and user == k.split(".")[-1]:
   95                 vols.update(v.split(","))
   96 
   97         vols.update(volumes)
   98         self.set_opt("mountbroker-geo-replication.%s" % user,
   99                      ",".join(vols))
  100 
  101     def remove_volume(self, user, volumes):
  102         vols = set()
  103         for k, v in self._options.items():
  104             if k.startswith("mountbroker-geo-replication.") \
  105                and user == k.split(".")[-1]:
  106                 vols.update(v.split(","))
  107 
  108         for v1 in volumes:
  109             vols.discard(v1)
  110 
  111         if vols:
  112             self.set_opt("mountbroker-geo-replication.%s" % user,
  113                          ",".join(vols))
  114         else:
  115             self.remove_opt("mountbroker-geo-replication.%s" % user)
  116 
  117     def remove_user(self, user):
  118         self.remove_opt("mountbroker-geo-replication.%s" % user)
  119 
  120     def info(self):
  121         data = {"users": []}
  122 
  123         for k, v in self._options.items():
  124             if k.startswith("mountbroker-geo-replication."):
  125                 data["users"].append(
  126                     {"name": k.split(".")[-1], "volumes": v.split(",")}
  127                 )
  128             else:
  129                 data[k] = v
  130 
  131         return data
  132 
  133 
  134 def format_info(data):
  135     op = "%s %s\n" % ("Option".ljust(50), "Value".ljust(50))
  136     op += ("-" * 101) + "\n"
  137     for key, value in data.items():
  138         if key != "users":
  139             op += "%s %s\n" % (key.ljust(50), value)
  140 
  141     op += "\nUsers: %s\n" % ("None" if not data["users"] else "")
  142     for user in data["users"]:
  143         op += "%s: %s\n" % (user["name"], ", ".join(user["volumes"]))
  144     op += "\n\n"
  145     return op
  146 
  147 
  148 def _get_args():
  149     parser = NoStdErrParser(formatter_class=RawDescriptionHelpFormatter,
  150                             description=PROG_DESCRIPTION)
  151 
  152     parser.add_argument('-j', dest="json", help="JSON output",
  153                         action="store_true")
  154     subparsers = parser.add_subparsers(title='subcommands', dest='cmd')
  155     parser_useradd = subparsers.add_parser('user')
  156     parser_userdel = subparsers.add_parser('userdel')
  157     parser_volumedel = subparsers.add_parser('volumedel')
  158     subparsers.add_parser('info')
  159     parser_opt = subparsers.add_parser('opt')
  160     parser_optdel = subparsers.add_parser('optdel')
  161 
  162     parser_useradd.add_argument('username', help="Username", type=str)
  163     parser_useradd.add_argument('volumes', type=str, default='',
  164                                 help="Volumes list. ',' separated")
  165 
  166     parser_volumedel.add_argument('username', help="Username", type=str)
  167     parser_volumedel.add_argument('volumes', type=str, default='',
  168                                 help="Volumes list. ',' separated")
  169 
  170     parser_userdel.add_argument('username', help="Username", type=str)
  171 
  172     parser_opt.add_argument('opt_name', help="Name", type=str)
  173     parser_opt.add_argument('opt_value', help="Value", type=str)
  174 
  175     parser_optdel.add_argument('opt_name', help="Name", type=str)
  176 
  177     return parser.parse_args()
  178 
  179 
  180 def main():
  181     global args
  182     args = _get_args()
  183 
  184     m = MountbrokerUserMgmt("@GLUSTERD_VOLFILE@")
  185 
  186     if args.cmd == "opt":
  187         m.set_opt(args.opt_name, args.opt_value)
  188     elif args.cmd == "optdel":
  189         m.remove_opt(args.opt_name)
  190     elif args.cmd == "userdel":
  191         m.remove_user(args.username)
  192     elif args.cmd == "user":
  193         volumes = [v.strip() for v in args.volumes.split(",")
  194                    if v.strip() != ""]
  195         m.add_user(args.username, volumes)
  196     elif args.cmd == "volumedel":
  197         volumes = [v.strip() for v in args.volumes.split(",")
  198                    if v.strip() != ""]
  199         m.remove_volume(args.username, volumes)
  200     elif args.cmd == "info":
  201         info = m.info()
  202         if not args.json:
  203             info = format_info(info)
  204         ok(info)
  205 
  206     if args.cmd != "info":
  207         m.save()
  208         ok()
  209 
  210 if __name__ == "__main__":
  211     main()