def list_conf(args): e, ep, n, ns = _process_namespace(args) c = ACMClient(endpoint=e, namespace=(None if n == "[default]" else n), ak=ns["ak"], sk=ns["sk"]) if ep["tls"]: c.set_options(tls_enabled=True) try: configs = c.list_all(args.group, args.prefix) except: print("List failed.") sys.exit(1) for i in sorted(configs, key=lambda x: x["group"] + x["dataId"]): print("%(group)s/%(dataId)s" % i)
def _get_client(e, ep, n, ns): c = ACMClient(endpoint=e, namespace=(None if n == "[default]" else n), ak=ns["ak"], sk=ns["sk"]) if ep.get("kms_enabled"): c.set_options(kms_enabled=True, kms_ak=ns.get("kms_ak"), kms_secret=ns.get("kms_secret"), region_id=ep.get("region_id"), key_id=ns.get("key_id")) if ep["tls"]: c.set_options(tls_enabled=True) return c
def push(args): if args.file: if not sys.stdin.isatty(): print( _colored( "Warning: content from stdin will be ignored since file is specified.", "grey")) if not os.path.exists(args.file): print("File %s does not exist." % _colored(args.file, "red")) sys.exit(1) content = _read_file(args.file) elif not sys.stdin.isatty(): content = sys.stdin.read() else: print("Use file or stdin as input.") sys.exit(1) e, ep, n, ns = _process_namespace(args) c = ACMClient(endpoint=e, namespace=(None if n == "[default]" else n), ak=ns["ak"], sk=ns["sk"]) if ep["tls"]: c.set_options(tls_enabled=True) if args.data_id.count("/") > 1: print("Invalid dataId or filename, more than one / is given.") sys.exit(1) group, data_id = args.data_id.split("/") if "/" in args.data_id else ( None, args.data_id) try: c.publish(data_id, group, content) except: import traceback traceback.print_exc() print("Push %s failed." % args.data_id) sys.exit(1) print("content has been pushed to [dataId:%s].\n" % (_colored(args.data_id, "green")))
def pull(args): e, ep, n, ns = _process_namespace(args) c = ACMClient(endpoint=e, namespace=(None if n == "[default]" else n), ak=ns["ak"], sk=ns["sk"]) if ep["tls"]: c.set_options(tls_enabled=True) try: if "/" in args.data_id: g, d = args.data_id.split("/") content = c.get(d, g, no_snapshot=True) else: content = c.get(args.data_id, None, no_snapshot=True) except: print("Pull %s failed." % args.data_id) sys.exit(1) if content is None: print("%s does not exist." % _colored(args.data_id, "red")) sys.exit(1) os.write(1, content.encode("utf8"))
def import_to_server(args): e, ep, n, ns = _process_namespace(args) c = ACMClient(endpoint=e, namespace=(None if n == "[default]" else n), ak=ns["ak"], sk=ns["sk"]) if ep["tls"]: c.set_options(tls_enabled=True) if args.dir and not os.path.isdir(args.dir): print("%s does not exist." % _colored(args.dir, "red")) sys.exit(1) src_file = args.file or args.file or "%s-%s.zip" % (e, n) zip_file = None if not args.dir and not os.path.isfile(src_file): print("%s does not exist." % _colored(src_file, "red")) sys.exit(1) data_to_import = list() if args.dir: for f in os.listdir(args.dir): if f.startswith("."): continue if os.path.isfile(os.path.join(args.dir, f)): data_to_import.append((f, DEFAULT_GROUP_NAME)) else: for ff in os.listdir(os.path.join(args.dir, f)): if not ff.startswith(".") and os.path.isfile( os.path.join(args.dir, f, ff)): data_to_import.append((ff, f)) else: zip_file = zipfile.ZipFile(src_file, 'r', zipfile.ZIP_DEFLATED) for info in zip_file.infolist(): sp = info.filename.split(os.path.sep) if len(sp) == 1: data_to_import.append((sp[0], DEFAULT_GROUP_NAME)) elif len(sp) == 2 and sp[1]: data_to_import.append((sp[1], sp[0])) else: print("ignoring invalid path: %s" % info.filename) # process deleting if args.delete: # pick up candidates delete_list = list() configs = c.list_all() for i in configs: if (i["dataId"], i["group"]) not in data_to_import: delete_list.append(i) # deleting if delete_list: print("Following dataIds are not exist in %s:\n" % _colored(args.dir or src_file, "yellow")) for i in delete_list: print(" - %s:%s" % (i["group"], i["dataId"])) delete = True if not args.force: while True: if sys.version_info[0] == 3: choice = input( "\nDeleting all dataIds above in ACM server? (y/n)" ) else: choice = raw_input( "\nDeleting all dataIds above in ACM server? (y/n)" ) if choice.lower() in ["y", "n"]: delete = choice.lower() == "y" break print("Invalid choice, please input y or n.") if delete: for i in delete_list: c.remove(i["dataId"], i["group"]) print("Delete complete, continue to import...\n") print( _colored(len(data_to_import), "green") + " files will be imported to ACM server.\n") i = 0 for data in data_to_import: i += 1 sys.stdout.write("\033[K\rImporting: %s/%s %s:%s" % (i, len(data_to_import), data[1], data[0])) sys.stdout.flush() if args.dir: f = os.path.join( args.dir, data[1], data[0]) if data[1] != DEFAULT_GROUP_NAME else os.path.join( args.dir, data[0]) content = _read_file(f) else: name = os.path.join( data[1], data[0]) if data[1] != DEFAULT_GROUP_NAME else data[0] content = zip_file.read(name) try: c.publish(data[0], data[1], content) except: print("Publish %s/%s failed." % (data[1], data[0])) sys.exit(1) if zip_file: zip_file.close() print("") print("All files imported.\n")
def export(args): e, ep, n, ns = _process_namespace(args) c = ACMClient(endpoint=e, namespace=(None if n == "[default]" else n), ak=ns["ak"], sk=ns["sk"]) if ep["tls"]: c.set_options(tls_enabled=True) try: configs = c.list_all() except: print("Get config list failed.") sys.exit(1) groups = set() elements = set() for i in configs: groups.add(i["group"]) elements.add( os.path.join(i["group"], i["dataId"]) if i["group"] != DEFAULT_GROUP_NAME else i["dataId"]) dest_file = args.file or "%s-%s.zip" % (e, n) zip_file = None if args.dir: try: os.makedirs(args.dir) except OSError: pass # process deleting if args.delete: candidates = list() # get candidates for root, dirs, files in os.walk(args.dir): if not os.path.basename(root).startswith("."): for i in dirs: if i.startswith("."): continue if i not in groups: candidates.append(os.path.join(root, i)) for i in files: if i.startswith("."): continue candidates.append(os.path.join(root, i)) # kick out elements delete_list = list() trunc_len = len(args.dir) + len(os.path.sep) for i in candidates: if i[trunc_len:] not in elements: delete_list.append(i) # deleting if delete_list: print( "Following files and dirs are not exist in ACM Server:\n") for i in delete_list: print(" - " + i) delete = True if not args.force: while True: if sys.version_info[0] == 3: choice = input("\nDeleting all files above? (y/n)") else: choice = raw_input( "\nDeleting all files above? (y/n)") if choice.lower() in ["y", "n"]: delete = choice.lower() == "y" break print("Invalid choice, please input y or n.") if delete: for i in delete_list: try: if os.path.isfile(i): os.remove(i) else: shutil.rmtree(i) except OSError: pass print("Delete complete, continue to export...\n") else: zip_file = zipfile.ZipFile(dest_file, 'w', zipfile.ZIP_DEFLATED) print( _colored(len(configs), "green") + " dataIds on ACM server will be exported to %s.\n" % _colored(args.dir or dest_file, "yellow")) i = 0 for config in configs: rel_path = config[ "group"] if config["group"] != DEFAULT_GROUP_NAME else "" if args.dir: try: os.makedirs(os.path.join(args.dir, rel_path)) except OSError: pass i += 1 sys.stdout.write("\033[K\rExporting: %s/%s %s:%s" % (i, len(configs), config["group"], config["dataId"])) sys.stdout.flush() try: content = c.get(config["dataId"], config["group"], no_snapshot=True) except: print("Get content of %s:%s failed." % (config["group"] or DEFAULT_GROUP_NAME, config["dataId"])) sys.exit(1) if args.dir: _write_file(os.path.join(args.dir, rel_path, config["dataId"]), content) else: zip_file.writestr(os.path.join(rel_path, config["dataId"]), content.encode("utf8")) if zip_file: zip_file.close() print("") print("All dataIds exported.\n")
def add(args): if ":" in args.namespace: pos = args.namespace.index(":") e = args.namespace[:pos] ns = args.namespace[pos + 1:] else: e = DEFAULT_ENDPOINT ns = args.namespace tls = args.tls config = read_config() ak = args.ak sk = args.sk alias = args.alias or ns if args.alias is not None and ":" in args.alias: print('":" is invalid symbol in alias.') sys.exit(1) # detect alias, ensure unique globally for ep, ep_info in config["endpoints"].items(): for k, v in ep_info["namespaces"].items(): if args.alias is None and v["alias"] == alias and (k != ns or ep != e): alias = "-".join([e, ns]) elif v["alias"] == alias and k != ns: print("Alias %s has been taken by %s:%s, choose another one." % (_colored(alias, "red"), ep, k)) sys.exit(1) # new endpoint if e not in config["endpoints"]: config["endpoints"][e] = { "tls": tls, "is_current": False, "namespaces": {} } print("Adding a new endpoint: %s, using TLS is %s.\n" % (_colored(e, "yellow"), _colored(tls, "yellow"))) else: if config["endpoints"][e]["tls"] != tls: config["endpoints"][e]["tls"] = tls print("TLS attr of %s has changed to %s.\n" % (_colored(e, "yellow"), _colored(tls, "yellow"))) if ns in config["endpoints"][e]["namespaces"]: if ak is not None: config["endpoints"][e]["namespaces"][ns]["ak"] = ak if sk is not None: config["endpoints"][e]["namespaces"][ns]["sk"] = sk if args.alias is not None: config["endpoints"][e]["namespaces"][ns]["alias"] = alias config["endpoints"][e]["namespaces"][ns]["updated"] = datetime.now( ).strftime("%Y-%m-%d %H:%M:%S") print("Namespace %s is already exist in %s, updating configs.\n" % (_colored(ns, "green"), _colored(e, "yellow"))) else: config["endpoints"][e]["namespaces"][ns] = { "ak": ak, "sk": sk, "alias": alias, "is_current": False, "updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } print("Add new namespace %s(%s) to %s.\n" % (_colored( ns, "green"), _colored(alias, "green"), _colored(e, "yellow"))) write_config(config) try: print("Try to access the namespace...") c = ACMClient(endpoint=e, namespace=(None if ns == "[default]" else ns), ak=config["endpoints"][e]["namespaces"][ns]["ak"], sk=config["endpoints"][e]["namespaces"][ns]["sk"]) if config["endpoints"][e]["tls"]: c.set_options(tls_enabled=True) c.list(1, 1) print("Namespace access succeed.") except: print( _colored( "\nWarning: Access test failed, there may be mistakes in configuration.\n", "grey"))
def add(args): if ":" in args.namespace: pos = args.namespace.index(":") e = args.namespace[:pos] ns = args.namespace[pos + 1:] else: e = DEFAULT_ENDPOINT ns = args.namespace config = read_config() alias = args.alias or ns if args.alias is not None and ":" in args.alias: print('":" is invalid symbol in alias.') sys.exit(1) # detect alias, ensure unique globally for ep, ep_info in config["endpoints"].items(): for k, v in ep_info["namespaces"].items(): if args.alias is None and v["alias"] == alias and (k != ns or ep != e): alias = "-".join([e, ns]) elif v["alias"] == alias and k != ns: print("Alias %s has been taken by %s:%s, choose another one." % (_colored(alias, "red"), ep, k)) sys.exit(1) # new endpoint if e not in config["endpoints"]: if args.kms: if not args.region_id: print( _colored("Region ID", "red") + " must be specified to use KMS.") sys.exit(1) config["endpoints"][e] = { "tls": args.tls, "is_current": False, "region_id": args.region_id, "kms_enabled": args.kms, "namespaces": {} } print("Adding a new endpoint: %s, using TLS is %s.\n" % (_colored(e, "yellow"), _colored(args.tls, "yellow"))) else: endpoint = config["endpoints"][e] if args.kms and not args.region_id and not endpoint.get("region_id"): print( _colored("Region ID", "red") + " must be specified to use KMS.") sys.exit(1) if endpoint.get("tls") != args.tls: endpoint["tls"] = args.tls print("TLS attr of %s has changed to %s.\n" % (_colored(e, "yellow"), _colored(args.tls, "yellow"))) if endpoint.get("kms_enabled") != args.kms: endpoint["kms_enabled"] = args.kms print("KMS enabled of %s has turned to %s.\n" % (_colored(e, "yellow"), _colored(args.kms, "yellow"))) if args.region_id is not None: if endpoint.get("region_id") != args.region_id: endpoint["region_id"] = args.region_id print("Region ID of %s has changed to %s.\n" % (_colored( e, "yellow"), _colored(args.region_id, "yellow"))) if ns in config["endpoints"][e]["namespaces"]: namespace = config["endpoints"][e]["namespaces"][ns] if args.ak is not None: namespace["ak"] = args.ak if args.sk is not None: namespace["sk"] = args.sk if args.alias is not None: namespace["alias"] = alias if args.kms_ak is not None: namespace["kms_ak"] = args.kms_ak if args.kms_secret is not None: namespace["kms_secret"] = args.kms_secret if args.key_id is not None: namespace["key_id"] = args.key_id if args.ram_role_name is not None: namespace["ram_role_name"] = args.ram_role_name if args.kms: if not namespace.get("kms_ak"): if not namespace.get("ak") and not namespace["ram_role_name"]: print( _colored("AccessKey", "red") + ' or ' + _colored("RAM role name", "red") + ' must be specified to use KMS.') sys.exit(1) namespace["kms_ak"] = namespace.get("ak") if not namespace.get( "kms_secret") and not namespace["ram_role_name"]: if not namespace.get("sk"): print( _colored("SecretKey", "red") + ' or ' + _colored("RAM role name", "red") + ' must be specified to use KMS.') sys.exit(1) namespace["kms_secret"] = namespace.get("sk") namespace["updated"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") print("Namespace %s is already exist in %s, updating configs.\n" % (_colored(ns, "green"), _colored(e, "yellow"))) else: namespace = { "ak": args.ak, "sk": args.sk, "alias": alias, "is_current": False, "updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "kms_ak": None, "kms_secret": None, "key_id": None, "ram_role_name": args.ram_role_name } if args.kms: kms_ak = args.kms_ak or args.ak if not kms_ak and not args.ram_role_name: print( _colored("AccessKey", "red") + ' or ' + _colored("RAM role name", "red") + ' must be specified to use KMS.') sys.exit(1) kms_secret = args.kms_secret or args.sk if not kms_secret and not args.ram_role_name: print( _colored("SecretKey", "red") + ' or ' + _colored("RAM role name", "red") + ' must be specified to use KMS.') sys.exit(1) namespace["kms_ak"] = kms_ak namespace["kms_secret"] = kms_secret namespace["key_id"] = args.key_id config["endpoints"][e]["namespaces"][ns] = namespace print("Add new namespace %s(%s) to %s.\n" % (_colored( ns, "green"), _colored(alias, "green"), _colored(e, "yellow"))) write_config(config) try: print("Try to access the namespace...") c = ACMClient(endpoint=e, namespace=(None if ns == "[default]" else ns), ak=config["endpoints"][e]["namespaces"][ns]["ak"], sk=config["endpoints"][e]["namespaces"][ns]["sk"], ram_role_name=config["endpoints"][e]["namespaces"] [ns].get("ram_role_name")) if config["endpoints"][e]["tls"]: c.set_options(tls_enabled=True) c.list(1, 1) print("Namespace access succeed.") except: print( _colored( "\nWarning: Access test failed, there may be mistakes in configuration.\n", "grey"))