diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | cobbler/webui/CobblerWeb.py | 259 | ||||
-rw-r--r-- | setup.py | 6 | ||||
-rw-r--r-- | webui_content/cobblerweb.css | 2 | ||||
-rw-r--r-- | webui_templates/master.tmpl | 2 | ||||
-rw-r--r-- | webui_templates/system_edit.tmpl | 51 | ||||
-rw-r--r-- | webui_templates/system_list.tmpl | 97 |
7 files changed, 316 insertions, 102 deletions
@@ -60,7 +60,6 @@ Patches and other contributions from: John L. Villalovos <john@sodarock.com> Peter Vreman <peter.vreman@acision.com> - [...send patches to get your name here...] -- End diff --git a/cobbler/webui/CobblerWeb.py b/cobbler/webui/CobblerWeb.py index ccdfe9c0..f29a9496 100644 --- a/cobbler/webui/CobblerWeb.py +++ b/cobbler/webui/CobblerWeb.py @@ -323,8 +323,193 @@ class CobblerWeb(object): else: return self.__render('empty.tmpl',{}) - def system_save(self,name=None,oldname=None,comment=None,editmode="edit",profile=None, - new_or_edit=None, + + def system_list_action(self,actionname=None,targetlist=None,**args): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + + if actionname is None: + return self.error_page("Actionname parameter is REQUIRED.") + + if actionname == 'add': + return self.system_edit_new() + + if targetlist is None: + return self.error_page("Targetlist parameter is REQUIRED.") + + # Single item actions + if actionname == 'copy': + return self.system_edit_copy(targetlist) + if actionname == 'edit': + return self.system_edit(targetlist) + + # Multiple items actions + systems=[] + for targetname in targetlist.split(): + systems.append(self.remote.get_system(targetname,self.token)) + + return self.__render( 'system_'+actionname+'.tmpl', { + 'systems' : systems, + 'profiles' : self.remote.get_profiles(), + 'targetlist' : targetlist, + } ) + + + def system_netboot(self,targetlist=None,netboot=None,**args): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + if targetlist is None: + return self.error_page("Targetlist parameter is REQUIRED.") + if netboot is None: + return self.error_page("Netboot parameter is REQUIRED.") + try: + systems=[] + for targetname in targetlist.split(): + systems.append(self.remote.get_system_handle(targetname,self.token)) + for system in systems: + self.remote.modify_system(system, 'netboot-enabled', netboot, self.token) + self.remote.save_system(system, self.token) + return self.system_list() + except Exception, e: + log_exc(self.apache) + return self.error_page("Error while saving system: %s" % str(e)) + + + def system_profile(self,targetlist=None,profile=None,**args): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + if targetlist is None: + return self.error_page("Targetlist parameter is REQUIRED.") + if profile is None: + return self.error_page("Profile parameter is REQUIRED.") + try: + systems=[] + for targetname in targetlist.split(): + systems.append(self.remote.get_system_handle(targetname,self.token)) + for system in systems: + self.remote.modify_system(system, 'profile', profile, self.token) + self.remote.save_system(system, self.token) + return self.system_list() + except Exception, e: + log_exc(self.apache) + return self.error_page("Error while saving system: %s" % str(e)) + + + def system_power(self,targetlist=None,power=None,**args): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + if targetlist is None: + return self.error_page("Targetlist parameter is REQUIRED.") + if power is None: + return self.error_page("Power parameter is REQUIRED.") + try: + systems=[] + for targetname in targetlist.split(): + systems.append(self.remote.get_system_handle(targetname,self.token)) + for system in systems: + self.remote.power_system(system, power, self.token) + return self.system_list() + except Exception, e: + log_exc(self.apache) + return self.error_page("Error while controlling power of system: %s" % str(e)) + + + def system_rename(self,targetlist=None,name=None,**args): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + if targetlist is None: + return self.error_page("Targetlist parameter is REQUIRED.") + try: + systems=[] + for targetname in targetlist.split(): + systems.append(self.remote.get_system_handle(targetname,self.token)) + for system in systems: + self.remote.rename_system(system, name, self.token) + return self.system_list() + except Exception, e: + log_exc(self.apache) + return self.error_page("Error while renaming system: %s" % str(e)) + + + def system_delete(self,targetlist=None,**args): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + if targetlist is None: + return self.error_page("Targetlist parameter is REQUIRED.") + try: + for targetname in targetlist.split(): + self.remote.remove_system(targetname, self.token) + return self.system_list() + except Exception, e: + log_exc(self.apache) + return self.error_page("Error while deleting system: %s" % str(e)) + + + + def system_edit(self, name=None,**spam): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + + if name is None: + return self.error_page("Name parameter is REQUIRED") + input_system = self.remote.get_system(name,True) + can_edit = self.remote.check_access_no_fail(self.token,"modify_system",name) + + return self.__render( 'system_edit.tmpl', { + 'user' : self.username, + 'editmode' : 'edit', + 'editable' : can_edit, + 'system': input_system, + 'profiles': self.remote.get_profiles() + } ) + + + def system_edit_new(self,**spam): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + + can_edit = self.remote.check_access_no_fail(self.token,"new_system",None) + if not can_edit: + return self.__render('message.tmpl', { + 'message1' : "Access denied.", + 'message2' : "You do not have permission to create new objects." + }) + + return self.__render( 'system_edit.tmpl', { + 'user' : self.username, + 'editmode' : 'new', + 'editable' : True, + 'system': None, + 'profiles': self.remote.get_profiles() + } ) + + + def system_edit_copy(self, name=None,**spam): + if not self.__xmlrpc_setup(): + return self.xmlrpc_auth_failure() + + if name is None: + return self.error_page("Name parameter is REQUIRED") + + can_edit = self.remote.check_access_no_fail(self.token,"new_system",None) + if not can_edit: + return self.__render('message.tmpl', { + 'message1' : "Access denied.", + 'message2' : "You do not have permission to create new objects." + }) + + input_system = self.remote.get_system(name,True) + + return self.__render( 'system_edit.tmpl', { + 'user' : self.username, + 'editmode' : 'copy', + 'editable' : True, + 'system': input_system, + 'profiles': self.remote.get_profiles() + } ) + + + def system_save(self,name=None,comment=None,editmode="edit",profile=None, kopts=None, koptspost=None, ksmeta=None, owners=None, server_override=None, netboot='n', virtpath=None,virtram=None,virttype=None,virtcpus=None,virtfilesize=None, name_servers=None, @@ -336,37 +521,27 @@ class CobblerWeb(object): return self.xmlrpc_auth_failure() # parameter checking - if name is None and oldname is not None: - name = oldname if name is None: return self.error_page("System name parameter is REQUIRED.") - if (editmode == 'rename' or editmode == 'copy') and name == oldname: - return self.error_page("The name has not been changed.") - - # handle deletes as a special case - if new_or_edit == 'edit' and delete1 and delete2: - try: - self.remote.remove_system(name,self.token) - except Exception, e: - return self.error_page("could not delete %s, %s" % (name,str(e))) - return self.system_list() # grab a reference to the object - if new_or_edit == "edit" and editmode in [ "edit", "rename" ] : + if editmode == "edit": try: - if editmode == "edit": - system = self.remote.get_system_handle( name, self.token ) - else: - system = self.remote.get_system_handle( oldname, self.token ) - + system = self.remote.get_system_handle( name, self.token ) except: return self.error_page("Failed to lookup system: %s" % name) else: + try: + system = self.remote.get_system_handle( name, self.token ) + except: + system = None + if system is not None: + return self.error_page("Failed to create new system: %s already exists." % name) system = self.remote.new_system( self.token ) # go! try: - if editmode != "rename" and name: + if editmode != "edit": self.remote.modify_system(system, 'name', name, self.token ) self.remote.modify_system(system, 'profile', profile, self.token) self.remote.modify_system(system, 'kopts', kopts, self.token) @@ -439,43 +614,9 @@ class CobblerWeb(object): log_exc(self.apache) return self.error_page("Error while saving system: %s" % str(e)) - - - if editmode == "rename" and name != oldname: - try: - self.remote.rename_system(system, name, self.token) - except Exception, e: - return self.error_page("Rename unsuccessful") - return self.system_list() - def system_edit(self, name=None,**spam): - - if not self.__xmlrpc_setup(): - return self.xmlrpc_auth_failure() - - input_system = None - if name is not None: - input_system = self.remote.get_system(name,True) - can_edit = self.remote.check_access_no_fail(self.token,"modify_system",name) - else: - can_edit = self.remote.check_access_no_fail(self.token,"new_system",None) - if not can_edit: - return self.__render('message.tmpl', { - 'message1' : "Access denied.", - 'message2' : "You do not have permission to create new objects." - }) - - - return self.__render( 'system_edit.tmpl', { - 'user' : self.username, - 'edit' : True, - 'editable' : can_edit, - 'system': input_system, - 'profiles': self.remote.get_profiles() - } ) - # ------------------------------------------------------------------------ # # Profiles # ------------------------------------------------------------------------ # @@ -992,7 +1133,15 @@ class CobblerWeb(object): profile_save.exposed = True system_edit.exposed = True + system_edit_new.exposed = True + system_edit_copy.exposed = True system_list.exposed = True + system_list_action.exposed = True + system_netboot.exposed = True + system_profile.exposed = True + system_power.exposed = True + system_rename.exposed = True + system_delete.exposed = True system_save.exposed = True repo_edit.exposed = True @@ -299,6 +299,11 @@ if __name__ == "__main__": (wwwtmpl, ['webui_templates/profile_list.tmpl']), (wwwtmpl, ['webui_templates/profile_edit.tmpl']), (wwwtmpl, ['webui_templates/system_list.tmpl']), + (wwwtmpl, ['webui_templates/system_netboot.tmpl']), + (wwwtmpl, ['webui_templates/system_rename.tmpl']), + (wwwtmpl, ['webui_templates/system_delete.tmpl']), + (wwwtmpl, ['webui_templates/system_profile.tmpl']), + (wwwtmpl, ['webui_templates/system_power.tmpl']), (wwwtmpl, ['webui_templates/system_edit.tmpl']), (wwwtmpl, ['webui_templates/repo_list.tmpl']), (wwwtmpl, ['webui_templates/repo_edit.tmpl']), @@ -306,6 +311,7 @@ if __name__ == "__main__": (wwwtmpl, ['webui_templates/image_edit.tmpl']), # Web UI common templates + (wwwtmpl, ['webui_templates/checkboxes.tmpl']), (wwwtmpl, ['webui_templates/paginate.tmpl']), (wwwtmpl, ['webui_templates/message.tmpl']), (wwwtmpl, ['webui_templates/error_page.tmpl']), diff --git a/webui_content/cobblerweb.css b/webui_content/cobblerweb.css index a1cc86a3..a535d89e 100644 --- a/webui_content/cobblerweb.css +++ b/webui_content/cobblerweb.css @@ -40,11 +40,13 @@ tr.roweven { background-color: #3f3d3d; } table.sortable th { background-color: #363a4e; margin: 0; + white-space: nowrap; } table.sortable caption { background-color: #202331; margin: 0; + white-space: nowrap; } td.nicedit { background-color: #444444; } diff --git a/webui_templates/master.tmpl b/webui_templates/master.tmpl index 2ef2d2a6..6080b819 100644 --- a/webui_templates/master.tmpl +++ b/webui_templates/master.tmpl @@ -45,7 +45,7 @@ <li><a href="$base_url?mode=system_list" class="menu">Systems</a></li> #if $mode == "system_list" <ul id="navaction"> - <li><a href="$base_url?mode=system_edit" class="menu">Add</a></li> + <li><a href="$base_url?mode=system_edit_new" class="menu">Add</a></li> </ul> #end if <li><a href="$base_url?mode=ksfile_list" class="menu">Kickstarts</a></li> diff --git a/webui_templates/system_edit.tmpl b/webui_templates/system_edit.tmpl index fd471c64..3b606b56 100644 --- a/webui_templates/system_edit.tmpl +++ b/webui_templates/system_edit.tmpl @@ -343,16 +343,14 @@ function page_onload() { <fieldset id="cform"> <input name="interface_list" type="hidden" value="" id="interface_list"/> - - #if $system - <input type="hidden" name="new_or_edit" value="edit"/> - <input type="hidden" name="oldname" value="$system.name"/> + <input type="hidden" name="editmode" value="$editmode"/> + + #if $editmode == "new" + <legend>Add a System</legend> #else - <input type="hidden" name="new_or_edit" value="new"/> + <legend>Edit a System</legend> #end if - - <legend>Edit a System</legend> - + <table border=0> <tr> @@ -360,14 +358,10 @@ function page_onload() { <label for="name">System Name</label> </td> <td> - #if $system - <input type="text" size="128" style="width: 150px;" name="name" id="name" disabled="true" - #else <input type="text" size="128" style="width: 150px;" name="name" id="name" + #if $editmode == "edit" + value="$system.name" disabled="true" #end if - #if $system - value="$system.name" - #end if /> <p class="context-tip">Example: vanhalen</p> </td> @@ -376,22 +370,6 @@ function page_onload() { #if $system <tr> <td> - <label for="mode">Edit Mode</label> - </td> - <td> - <input type="radio" name="editmode" value="edit" checked onclick="javascript:disablename(true)">Edit - <input type="radio" name="editmode" value="rename" onclick="javascript:disablename(false)">Rename + Edit - <input type="radio" name="editmode" value="copy" onclick="javascript:disablename(false)">Copy + Edit - <p class="context-tip">How do you want to modify this object?</p> - </td> - </tr> - #else - <input type="hidden" name="editmode" value="new"/> - #end if - - #if $system - <tr> - <td> <label>Created</label> </td> <td> @@ -969,19 +947,6 @@ redhatmanagementkey" </td> </tr> - #if $system and $editable == True - <tr> - <td> - <label for="delete">Delete</label> - </td> - <td> - <input type="checkbox" name="delete1" value="delete1">Yes - <input type="checkbox" name="delete2" value="delete2">Really - <p class="context-tip">Check both buttons and click save to delete this object</p> - </td> - </tr> - #end if - #if $editable == True <tr> <td> diff --git a/webui_templates/system_list.tmpl b/webui_templates/system_list.tmpl index 6ab5face..9899ca51 100644 --- a/webui_templates/system_list.tmpl +++ b/webui_templates/system_list.tmpl @@ -7,14 +7,71 @@ #include "/usr/share/cobbler/webui_templates/paginate.tmpl" ## ==== END PAGE NAVIGATION ==== -<table class="sortable"> + ## ==== BEGIN CHECKBOX SUPPORT ==== + #include "/usr/share/cobbler/webui_templates/checkboxes.tmpl" + ## ==== END CHECKBOX SUPPORT ==== + +<script language="Javascript"> +function action_selected(actionname) +{ + var itemcount=items_checked_count(); + if ( + (itemcount == 0) && + ( + (actionname == "delete") || + (actionname == "netboot") || + (actionname == "profile") || + (actionname == "power") + ) + ) + { + alert("Select the systems to " + actionname+" first"); + return; + } + else if ( + (itemcount != 1) && + ( + (actionname == "copy") || + (actionname == "rename") + ) + ) + { + alert("Select only one system to " + actionname); + return; + } + + document.getElementById("targetlist").value=items_checked_values(); + document.getElementById("actionname").value=actionname; + + document.myform.submit(); +} + +function action_single(actionname,target) +{ + document.getElementById("targetlist").value=target; + document.getElementById("actionname").value=actionname; + + document.myform.submit(); +} +</script> + +<form name="myform" method="post" action="$base_url?mode=system_list_action"> + <input type="hidden" name="actionname" id="actionname" value=""/> + <input type="hidden" name="targetlist" id="targetlist" value=""/> + + <table class="sortable"> <thead> <caption>Cobbler Systems</caption> <tr> + <th class="text"><input type="checkbox" id="itemsall" onclick="javascript:items_check_all();"></th> <th class="text">Name</th> + <th class="text">Netboot</th> <th class="text">Profile</th> <th class="text">Kickstart</th> + <th class="text"></th> + <th class="text"></th> + <th class="text"></th> </tr> </thead> <tbody> @@ -29,8 +86,21 @@ <tr class="$tr_class"> <td> + <input type="checkbox" name="items" value="${system.name}"> + </td> + + <td> <a href="$base_url?mode=system_edit&name=${system.name}">${system.name}</a> </td> + + <td> + #if str($system.netboot_enabled) != "False" + Yes + #else + No + #end if + </td> + <td> <a href="$base_url?mode=profile_edit&name=${system.profile}">${system.profile}</a> </td> @@ -55,10 +125,33 @@ #end if #end if </td> + + <td> + <input type="button" name="edit" onClick="javascript:action_single('edit','${system.name}')" value="Edit"/> + </td> + + <td> + <input type="button" name="rename" onClick="javascript:action_single('rename','${system.name}')" value="Rename"/> + </td> + + <td> + <input type="button" name="copy" onClick="javascript:action_single('copy','${system.name}')" value="Copy"/> + </td> + </tr> #end for </tbody> -</table> + </table> +</form> + + <br/> + Operations on selected systems: + <br/> + <input type="button" name="delete" onClick="javascript:action_selected('delete')" value="Delete"/> + <input type="button" name="netboot" onClick="javascript:action_selected('netboot')" value="Change Netboot"/> + <input type="button" name="profile" onClick="javascript:action_selected('profile')" value="Change Profile"/> + <input type="button" name="power" onClick="javascript:action_selected('power')" value="Power control"/> + #end block body |