def object_command(self, object_type, object_action): """ Process object-based commands such as "distro add" or "profile rename" """ task_id = -1 # if assigned, we must tail the logfile settings = self.remote.get_settings() fields = self.get_fields(object_type) network_interface_fields = None if object_type == "system": network_interface_fields = item_system.NETWORK_INTERFACE_FIELDS if object_action in ["add", "edit", "copy", "rename", "find", "remove"]: add_options_from_fields(object_type, self.parser, fields, network_interface_fields, settings, object_action) elif object_action in ["list"]: pass elif object_action not in ("reload", "update"): self.parser.add_option("--name", dest="name", help="name of object") elif object_action == "reload": self.parser.add_option("--filename", dest="filename", help="filename to load data from") (options, args) = self.parser.parse_args() # the first three don't require a name if object_action == "report": if options.name is not None: report_item(self.remote, object_type, None, options.name) else: report_items(self.remote, object_type) elif object_action == "list": list_items(self.remote, object_type) elif object_action == "find": items = self.remote.find_items(object_type, utils.strip_none(vars(options), omit_none=True), "name", False) for item in items: print item elif object_action in OBJECT_ACTIONS: if opt(options, "name") == "" and object_action not in ("reload", "update"): print "--name is required" sys.exit(1) if object_action in ["add", "edit", "copy", "rename", "remove"]: try: if object_type == "setting": settings = self.remote.get_settings() if options.value is None: raise RuntimeError("You must specify a --value when editing a setting") elif not settings.get('allow_dynamic_settings', False): raise RuntimeError("Dynamic settings changes are not enabled. Change the allow_dynamic_settings to 1 and restart cobblerd to enable dynamic settings changes") elif options.name == 'allow_dynamic_settings': raise RuntimeError("Cannot modify that setting live") elif self.remote.modify_setting(options.name, options.value, self.token): raise RuntimeError("Changing the setting failed") else: self.remote.xapi_object_edit(object_type, options.name, object_action, utils.strip_none(vars(options), omit_none=True), self.token) except xmlrpclib.Fault, (err): (etype, emsg) = err.faultString.split(":", 1) print "exception on server: %s" % emsg sys.exit(1) except RuntimeError, (err): print err.args[0] sys.exit(1)
def test_strip_none(input_data, expected_output): # Arrange # Act result = utils.strip_none(input_data) # Assert assert expected_output == result
def start_task(self, name: str, options: dict) -> str: r""" Start an asynchronous task in the background. :param name: "background\_" % name function must exist in remote.py. This function will be called in a subthread. :param options: Dictionary of options passed to the newly started thread :return: Id of the newly started task """ options = utils.strip_none(vars(options), omit_none=True) fn = getattr(self.remote, "background_%s" % name) return fn(options, self.token)
def genlist(request, what, page=None): """ Lists all object types, complete with links to actions on those objects. """ check_auth(request) # get details from the session if page == None: page = int(request.session.get("%s_page" % what, 1)) limit = int(request.session.get("%s_limit" % what, 50)) sort_field = request.session.get("%s_sort_field" % what, "name") filters = simplejson.loads(request.session.get("%s_filters" % what, "{}")) pageditems = remote.find_items_paged(what, utils.strip_none(filters), sort_field, page, limit) # what columns to show for each page? if what == "distro": columns = ["name"] if what == "profile": columns = ["name", "distro"] if what == "system": # FIXME: also list network, once working columns = ["name", "profile", "netboot_enabled"] if what == "repo": columns = ["name", "mirror"] if what == "image": columns = ["name", "file"] if what == "network": columns = ["name"] if what == "mgmtclass": columns = ["name"] if what == "package": columns = ["name", "installer"] if what == "file": columns = ["name"] # render the list t = get_template("generic_list.tmpl") html = t.render( RequestContext( request, { "what": what, "columns": __format_columns(columns, sort_field), "items": __format_items(pageditems["items"], columns), "pageinfo": pageditems["pageinfo"], "filters": filters, "username": username, "limit": limit, }, ) ) return HttpResponse(html)
def genlist(request, what, page=None): """ Lists all object types, complete with links to actions on those objects. """ check_auth(request) # get details from the session if page == None: page = int(request.session.get("%s_page" % what, 1)) limit = int(request.session.get("%s_limit" % what, 50)) sort_field = request.session.get("%s_sort_field" % what, "name") filters = simplejson.loads(request.session.get("%s_filters" % what, "{}")) pageditems = remote.find_items_paged(what, utils.strip_none(filters), sort_field, page, limit) # what columns to show for each page? if what == "distro": columns = ["name"] if what == "profile": columns = ["name", "distro"] if what == "system": # FIXME: also list network, once working columns = ["name", "profile", "netboot_enabled"] if what == "repo": columns = ["name", "mirror"] if what == "image": columns = ["name", "file"] if what == "network": columns = ["name"] if what == "mgmtclass": columns = ["name"] if what == "package": columns = ["name", "installer"] if what == "file": columns = ["name"] # render the list t = get_template('generic_list.tmpl') html = t.render( RequestContext( request, { 'what': what, 'columns': __format_columns(columns, sort_field), 'items': __format_items(pageditems["items"], columns), 'pageinfo': pageditems["pageinfo"], 'filters': filters, 'username': username, 'limit': limit, })) return HttpResponse(html)
def object_command(self, object_type, object_action): """ Process object-based commands such as "distro add" or "profile rename" """ task_id = -1 # if assigned, we must tail the logfile settings = self.remote.get_settings() fields = self.get_fields(object_type) network_interface_fields = None if object_type == "system": network_interface_fields = item_system.NETWORK_INTERFACE_FIELDS if object_action in ["add", "edit", "copy", "rename", "find", "remove"]: add_options_from_fields(object_type, self.parser, fields, network_interface_fields, settings, object_action) elif object_action in ["list"]: pass elif object_action not in ("reload", "update"): self.parser.add_option("--name", dest="name", help="name of object") elif object_action == "reload": self.parser.add_option("--filename", dest="filename", help="filename to load data from") (options, args) = self.parser.parse_args() # the first three don't require a name if object_action == "report": if options.name is not None: report_item(self.remote, object_type, None, options.name) else: report_items(self.remote, object_type) elif object_action == "list": list_items(self.remote, object_type) elif object_action == "find": items = self.remote.find_items(object_type, utils.strip_none(vars(options), omit_none=True), "name", False) for item in items: print(item) elif object_action in OBJECT_ACTIONS: if opt(options, "name") == "" and object_action not in ("reload", "update"): print("--name is required") sys.exit(1) if object_action in ["add", "edit", "copy", "rename", "remove"]: try: if object_type == "setting": settings = self.remote.get_settings() if options.value is None: raise RuntimeError("You must specify a --value when editing a setting") elif not settings.get('allow_dynamic_settings', False): raise RuntimeError("Dynamic settings changes are not enabled. Change the allow_dynamic_settings to 1 and restart cobblerd to enable dynamic settings changes") elif options.name == 'allow_dynamic_settings': raise RuntimeError("Cannot modify that setting live") elif self.remote.modify_setting(options.name, options.value, self.token): raise RuntimeError("Changing the setting failed") else: self.remote.xapi_object_edit(object_type, options.name, object_action, utils.strip_none(vars(options), omit_none=True), self.token) except xmlrpc.client.Fault as xxx_todo_changeme: (err) = xxx_todo_changeme (etype, emsg) = err.faultString.split(":", 1) print("exception on server: %s" % emsg) sys.exit(1) except RuntimeError as xxx_todo_changeme1: (err) = xxx_todo_changeme1 print(err.args[0]) sys.exit(1) elif object_action == "get-autoinstall": if object_type == "profile": data = self.remote.generate_profile_autoinstall(options.name) elif object_type == "system": data = self.remote.generate_system_autoinstall(options.name) print(data) elif object_action == "dumpvars": if object_type == "profile": data = self.remote.get_blended_data(options.name, "") elif object_type == "system": data = self.remote.get_blended_data("", options.name) # FIXME: pretty-printing and sorting here keys = list(data.keys()) keys.sort() for x in keys: print("%s: %s" % (x, data[x])) elif object_action in ["poweron", "poweroff", "powerstatus", "reboot"]: power = {} power["power"] = object_action.replace("power", "") power["systems"] = [options.name] task_id = self.remote.background_power_system(power, self.token) elif object_action == "update": task_id = self.remote.background_signature_update(utils.strip_none(vars(options), omit_none=True), self.token) elif object_action == "reload": filename = opt(options, "filename", "/var/lib/cobbler/distro_signatures.json") try: utils.load_signatures(filename, cache=True) except: print("There was an error loading the signature data in %s." % filename) print("Please check the JSON file or run 'cobbler signature update'.") return else: print("Signatures were successfully loaded") else: raise NotImplementedException() else: raise NotImplementedException() # FIXME: add tail/polling code here if task_id != -1: self.print_task(task_id) self.follow_task(task_id)
def start_task(self, name, options): options = utils.strip_none(vars(options), omit_none=True) fn = getattr(self.remote, "background_%s" % name) return fn(options, self.token)
def object_command(self, object_type, object_action): """ Process object-based commands such as "distro add" or "profile rename" """ task_id = -1 # if assigned, we must tail the logfile settings = self.remote.get_settings() fields = self.get_fields(object_type) network_interface_fields = None if object_type == "system": network_interface_fields = system.NETWORK_INTERFACE_FIELDS if object_action in ["add", "edit", "copy", "rename", "find", "remove"]: add_options_from_fields(object_type, self.parser, fields, network_interface_fields, settings, object_action) elif object_action in ["list"]: pass elif object_action not in ("reload", "update"): self.parser.add_option("--name", dest="name", help="name of object") elif object_action == "reload": self.parser.add_option("--filename", dest="filename", help="filename to load data from") (options, args) = self.parser.parse_args() # the first three don't require a name if object_action == "report": if options.name is not None: report_item(self.remote, object_type, None, options.name) else: report_items(self.remote, object_type) elif object_action == "list": list_items(self.remote, object_type) elif object_action == "find": items = self.remote.find_items(object_type, utils.strip_none(vars(options), omit_none=True), "name", False) for item in items: print(item) elif object_action in OBJECT_ACTIONS: if opt(options, "name") == "" and object_action not in ("reload", "update"): print("--name is required") sys.exit(1) if object_action in ["add", "edit", "copy", "rename", "remove"]: try: if object_type == "setting": settings = self.remote.get_settings() if options.value is None: raise RuntimeError("You must specify a --value when editing a setting") elif not settings.get('allow_dynamic_settings', False): raise RuntimeError("Dynamic settings changes are not enabled. Change the allow_dynamic_settings to 1 and restart cobblerd to enable dynamic settings changes") elif options.name == 'allow_dynamic_settings': raise RuntimeError("Cannot modify that setting live") elif self.remote.modify_setting(options.name, options.value, self.token): raise RuntimeError("Changing the setting failed") else: self.remote.xapi_object_edit(object_type, options.name, object_action, utils.strip_none(vars(options), omit_none=True), self.token) except xmlrpc.client.Fault as xxx_todo_changeme: (err) = xxx_todo_changeme (etype, emsg) = err.faultString.split(":", 1) print("exception on server: %s" % emsg) sys.exit(1) except RuntimeError as xxx_todo_changeme1: (err) = xxx_todo_changeme1 print(err.args[0]) sys.exit(1) elif object_action == "get-autoinstall": if object_type == "profile": data = self.remote.generate_profile_autoinstall(options.name) elif object_type == "system": data = self.remote.generate_system_autoinstall(options.name) print(data) elif object_action == "dumpvars": if object_type == "profile": data = self.remote.get_blended_data(options.name, "") elif object_type == "system": data = self.remote.get_blended_data("", options.name) # FIXME: pretty-printing and sorting here keys = list(data.keys()) keys.sort() for x in keys: print("%s: %s" % (x, data[x])) elif object_action in ["poweron", "poweroff", "powerstatus", "reboot"]: power = {} power["power"] = object_action.replace("power", "") power["systems"] = [options.name] task_id = self.remote.background_power_system(power, self.token) elif object_action == "update": task_id = self.remote.background_signature_update(utils.strip_none(vars(options), omit_none=True), self.token) elif object_action == "reload": filename = opt(options, "filename", "/var/lib/cobbler/distro_signatures.json") try: utils.load_signatures(filename, cache=True) except: print("There was an error loading the signature data in %s." % filename) print("Please check the JSON file or run 'cobbler signature update'.") return else: print("Signatures were successfully loaded") else: raise NotImplementedException() else: raise NotImplementedException() # FIXME: add tail/polling code here if task_id != -1: self.print_task(task_id) self.follow_task(task_id)
# FIXME: pretty-printing and sorting here keys = data.keys() keys.sort() for x in keys: print "%s: %s" % (x, data[x]) elif object_action in [ "poweron", "poweroff", "powerstatus", "reboot" ]: power = {} power["power"] = object_action.replace("power", "") power["systems"] = [options.name] task_id = self.remote.background_power_system( power, self.token) elif object_action == "update": task_id = self.remote.background_signature_update( utils.strip_none(vars(options), omit_none=True), self.token) elif object_action == "reload": filename = opt(options, "filename", "/var/lib/cobbler/distro_signatures.json") try: utils.load_signatures(filename, cache=True) except: print "There was an error loading the signature data in %s." % filename print "Please check the JSON file or run 'cobbler signature update'." return else: print "Signatures were successfully loaded" else: raise exceptions.NotImplementedError() else:
if object_type == "profile": data = self.remote.get_blended_data(options.name, "") elif object_type == "system": data = self.remote.get_blended_data("", options.name) # FIXME: pretty-printing and sorting here keys = data.keys() keys.sort() for x in keys: print "%s: %s" % (x, data[x]) elif object_action in ["poweron", "poweroff", "powerstatus", "reboot"]: power = {} power["power"] = object_action.replace("power", "") power["systems"] = [options.name] task_id = self.remote.background_power_system(power, self.token) elif object_action == "update": task_id = self.remote.background_signature_update(utils.strip_none(vars(options), omit_none=True), self.token) elif object_action == "reload": filename = opt(options, "filename", "/var/lib/cobbler/distro_signatures.json") try: utils.load_signatures(filename, cache=True) except: print "There was an error loading the signature data in %s." % filename print "Please check the JSON file or run 'cobbler signature update'." return else: print "Signatures were successfully loaded" else: raise exceptions.NotImplementedError() else: raise exceptions.NotImplementedError()
def genlist(request, what, page=None): """ Lists all object types, complete with links to actions on those objects. """ if not test_user_authenticated(request): return login(request, next="/cobbler_web/%s/list" % what, expired=True) # get details from the session if page is None: page = int(request.session.get("%s_page" % what, 1)) limit = int(request.session.get("%s_limit" % what, 50)) sort_field = request.session.get("%s_sort_field" % what, "name") filters = simplejson.loads(request.session.get("%s_filters" % what, "{}")) pageditems = remote.find_items_paged(what, utils.strip_none(filters), sort_field, page, limit) # what columns to show for each page? # we also setup the batch actions here since they're dependent # on what we're looking at # everythng gets batch delete batchactions = [ ["Delete", "delete", "delete"], ] if what == "distro": columns = ["name"] batchactions += [ ["Build ISO", "buildiso", "enable"], ] if what == "profile": columns = ["name", "distro"] batchactions += [ ["Build ISO", "buildiso", "enable"], ] if what == "system": # FIXME: also list network, once working columns = ["name", "profile", "status", "netboot_enabled"] batchactions += [ ["Power on", "power", "on"], ["Power off", "power", "off"], ["Reboot", "power", "reboot"], ["Change profile", "profile", ""], ["Netboot enable", "netboot", "enable"], ["Netboot disable", "netboot", "disable"], ["Build ISO", "buildiso", "enable"], ] if what == "repo": columns = ["name", "mirror"] batchactions += [ ["Reposync", "reposync", "go"], ] if what == "image": columns = ["name", "file"] if what == "network": columns = ["name"] if what == "mgmtclass": columns = ["name"] if what == "package": columns = ["name", "installer"] if what == "file": columns = ["name"] # render the list t = get_template('generic_list.tmpl') html = t.render(RequestContext(request, { 'what': what, 'columns': __format_columns(columns, sort_field), 'items': __format_items(pageditems["items"], columns), 'pageinfo': pageditems["pageinfo"], 'filters': filters, 'version': remote.extended_version(request.session['token'])['version'], 'username': username, 'limit': limit, 'batchactions': batchactions, })) return HttpResponse(html)
def genlist(request, what, page=None): """ Lists all object types, complete with links to actions on those objects. """ if not test_user_authenticated(request): return login(request, next="/cobbler_web/%s/list" % what, expired=True) # get details from the session if page == None: page = int(request.session.get("%s_page" % what, 1)) limit = int(request.session.get("%s_limit" % what, 50)) sort_field = request.session.get("%s_sort_field" % what, "name") filters = simplejson.loads(request.session.get("%s_filters" % what, "{}")) pageditems = remote.find_items_paged(what,utils.strip_none(filters),sort_field,page,limit) # what columns to show for each page? # we also setup the batch actions here since they're dependent # on what we're looking at # everythng gets batch delete batchactions = [ ["Delete","delete","delete"], ] if what == "distro": columns = [ "name" ] batchactions += [ ["Build ISO","buildiso","enable"], ] if what == "profile": columns = [ "name", "distro" ] batchactions += [ ["Build ISO","buildiso","enable"], ] if what == "system": # FIXME: also list network, once working columns = [ "name", "profile", "status", "netboot_enabled" ] batchactions += [ ["Power on","power","on"], ["Power off","power","off"], ["Reboot","power","reboot"], ["Change profile","profile",""], ["Netboot enable","netboot","enable"], ["Netboot disable","netboot","disable"], ["Build ISO","buildiso","enable"], ] if what == "repo": columns = [ "name", "mirror" ] batchactions += [ ["Reposync","reposync","go"], ] if what == "image": columns = [ "name", "file" ] if what == "network": columns = [ "name" ] if what == "mgmtclass": columns = [ "name" ] if what == "package": columns = [ "name", "installer" ] if what == "file": columns = [ "name" ] # render the list t = get_template('generic_list.tmpl') html = t.render(RequestContext(request,{ 'what' : what, 'columns' : __format_columns(columns,sort_field), 'items' : __format_items(pageditems["items"],columns), 'pageinfo' : pageditems["pageinfo"], 'filters' : filters, 'version' : remote.extended_version(request.session['token'])['version'], 'username' : username, 'limit' : limit, 'batchactions' : batchactions, })) return HttpResponse(html)
# which are the only objects in cobbler that will ever work this way if what == "system": interface_field_list = [] for field in fields: if field['name'].startswith("*"): field = field['name'].replace("*", "") interface_field_list.append(field) interfaces = request.POST.get('interface_list', "").split(",") for interface in interfaces: if interface == "": continue ifdata = {} for item in interface_field_list: ifdata["%s-%s" % (item, interface)] = request.POST.get( "%s-%s" % (item, interface), "") ifdata = utils.strip_none(ifdata) # FIXME: I think this button is missing. present = request.POST.get("present-%s" % interface, "") original = request.POST.get("original-%s" % interface, "") try: if present == "0" and original == "1": remote.modify_system(obj_id, 'delete_interface', interface, token) elif present == "1": remote.modify_system(obj_id, 'modify_interface', ifdata, token) except Exception, e: return error_page(request, str(e)) try: remote.save_item(what, obj_id, token, editmode)
# special handling for system interface fields # which are the only objects in cobbler that will ever work this way if what == "system": interface_field_list = [] for field in fields: if field['name'].startswith("*"): field = field['name'].replace("*","") interface_field_list.append(field) interfaces = request.POST.get('interface_list', "").split(",") for interface in interfaces: if interface == "": continue ifdata = {} for item in interface_field_list: ifdata["%s-%s" % (item,interface)] = request.POST.get("%s-%s" % (item,interface), "") ifdata=utils.strip_none(ifdata) # FIXME: I think this button is missing. present = request.POST.get("present-%s" % interface, "") original = request.POST.get("original-%s" % interface, "") try: if present == "0" and original == "1": remote.modify_system(obj_id, 'delete_interface', interface, token) elif present == "1": remote.modify_system(obj_id, 'modify_interface', ifdata, token) except Exception, e: return error_page(request, str(e)) try: remote.save_item(what, obj_id, token, editmode) except Exception, e: return error_page(request, str(e))
data = self.remote.get_blended_data(options.name, "") elif object_type == "system": data = self.remote.get_blended_data("", options.name) # FIXME: pretty-printing and sorting here keys = data.keys() keys.sort() for x in keys: print "%s: %s" % (x, data[x]) elif object_action in ["poweron", "poweroff", "powerstatus", "reboot"]: power = {} power["power"] = object_action.replace("power", "") power["systems"] = [options.name] task_id = self.remote.background_power_system(power, self.token) elif object_action == "update": task_id = self.remote.background_signature_update( utils.strip_none(vars(options), omit_none=True), self.token ) elif object_action == "reload": filename = opt(options, "filename", "/var/lib/cobbler/distro_signatures.json") try: utils.load_signatures(filename, cache=True) except: print "There was an error loading the signature data in %s." % filename print "Please check the JSON file or run 'cobbler signature update'." return else: print "Signatures were successfully loaded" else: raise exceptions.NotImplementedError() else: raise exceptions.NotImplementedError()