summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--cobbler/webui/CobblerWeb.py259
-rw-r--r--setup.py6
-rw-r--r--webui_content/cobblerweb.css2
-rw-r--r--webui_templates/master.tmpl2
-rw-r--r--webui_templates/system_edit.tmpl51
-rw-r--r--webui_templates/system_list.tmpl97
7 files changed, 316 insertions, 102 deletions
diff --git a/AUTHORS b/AUTHORS
index 717f5bc7..08cb9549 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
diff --git a/setup.py b/setup.py
index 92fa40d5..c3f07520 100644
--- a/setup.py
+++ b/setup.py
@@ -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