Module: check_mk
Branch: master
Commit: 500837c54e43b059d21c1b1739a4841f28eebdd6
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=500837c54e43b0…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Thu Dec 17 14:41:27 2015 +0100
ValueSpec DualListChoice: fix hilighting of input errors
---
modules/automation.py | 15 +++++++++++
modules/packaging.py | 69 ++++++++++++++++++++++++++++++++++++++++++-----
web/htdocs/htmllib.py | 5 ++++
web/htdocs/pages.css | 2 +-
web/htdocs/valuespec.py | 10 +++++++
5 files changed, 94 insertions(+), 7 deletions(-)
diff --git a/modules/automation.py b/modules/automation.py
index 5e588a5..dad86be 100644
--- a/modules/automation.py
+++ b/modules/automation.py
@@ -48,6 +48,10 @@ def do_automation(cmd, args):
result = automation_get_package_info(args)
elif cmd == "get-package":
result = automation_get_package(args)
+ elif cmd == "create-package":
+ result = automation_create_or_edit_package(args, "create")
+ elif cmd == "edit-package":
+ result = automation_create_or_edit_package(args, "edit")
elif cmd == "install-package":
result = automation_install_package(args)
elif cmd == "remove-package":
@@ -118,6 +122,7 @@ def do_automation(cmd, args):
output_profile()
sys.exit(0)
+
# Does discovery for a list of hosts. Possible values for how:
# "new" - find only new services (like -I)
# "remove" - remove exceeding services
@@ -1322,6 +1327,16 @@ def automation_get_package(args):
return package, output_file.content()
+def automation_create_or_edit_package(args, mode):
+ load_module("packaging")
+ package_name = args[0]
+ new_package_info = eval(sys.stdin.read())
+ if mode == "create":
+ create_package(new_package_info)
+ else:
+ edit_package(package_name, new_package_info)
+
+
def automation_install_package(args):
load_module("packaging")
file_content = sys.stdin.read()
diff --git a/modules/packaging.py b/modules/packaging.py
index a219bc1..1e4ec3c 100644
--- a/modules/packaging.py
+++ b/modules/packaging.py
@@ -216,7 +216,7 @@ def package_create(args):
verbose(" %s\n" % f)
- write_package_info(pacname, package)
+ write_package_info(package)
verbose("New package %s created with %d files.\n" % (pacname, num_files))
verbose("Please edit package details in %s%s%s\n" % (tty_bold, pac_dir +
pacname, tty_normal))
@@ -245,7 +245,7 @@ def package_release(args):
pacname = args[0]
pacpath = pac_dir + pacname
- if not os.path.exists(pacpath):
+ if package_exists(pacname):
raise PackageException("No such package %s." % pacname)
package = read_package_info(pacname)
os.unlink(pacpath)
@@ -259,6 +259,11 @@ def package_release(args):
verbose(" %s\n" % f)
+def package_exists(pacname):
+ pacpath = pac_dir + pacname
+ return os.path.exists(pacpath)
+
+
def package_pack(args):
if len(args) != 1:
raise PackageException("Usage: check_mk -P pack NAME")
@@ -346,6 +351,55 @@ def remove_package(package):
os.remove(pac_dir + package["name"])
+def create_package(package_info):
+ pacname = package_info["name"]
+ if package_exists(pacname):
+ raise PackageException("Packet already exists.")
+
+ validate_package_files(pacname, package_info["files"])
+ write_package_info(package_info)
+
+
+def edit_package(pacname, new_package_info):
+ if not package_exists(pacname):
+ raise PackageException("No such package")
+
+ # Renaming: check for collision
+ if pacname != new_package_info["name"]:
+ if package_exists(new_package_info["name"]):
+ raise PackageException("Cannot rename package: a package with that name
already exists.")
+
+ validate_package_files(pacname, new_package_info["files"])
+
+ remove_package_info(pacname)
+ write_package_info(new_package_info)
+
+
+
+# Packaged files must either be unpackaged or already
+# belong to that package
+def validate_package_files(pacname, files):
+ packages = {}
+ for package_name in all_package_names():
+ packages[package_name] = read_package_info(package_name)
+
+ for part, title, perm, dir in package_parts:
+ validate_package_files_part(packages, pacname, part, dir, files.get(part, []))
+
+
+def validate_package_files_part(packages, pacname, part, dir, rel_paths):
+ for rel_path in rel_paths:
+ path = dir + "/" + rel_path
+ if not os.path.exists(path):
+ raise PackageException("File %s does not exist." % path)
+
+ for other_pacname, other_package_info in packages.items():
+ for other_rel_path in other_package_info["files"].get(part, []):
+ if other_rel_path == rel_path and other_pacname != pacname:
+ raise PackageException("File %s does already belong to package
%s" % (path, other_pacname))
+
+
+
def package_install(args):
if len(args) != 1:
raise PackageException("Usage: check_mk -P remove NAME")
@@ -431,8 +485,7 @@ def install_package(file_name=None, file_object=None):
sys.stderr.write("Error removing %s: %s\n" % (path,
e))
# Last but not least install package file
- file(pac_dir + pacname, "w").write(pprint.pformat(package))
-
+ write_package_info(package)
return package
@@ -507,8 +560,12 @@ def read_package_info(pacname):
return None
-def write_package_info(pacname, package):
- file(pac_dir + pacname, "w").write(pprint.pformat(package) +
"\n")
+def write_package_info(package):
+ file(pac_dir + package["name"],
"w").write(pprint.pformat(package) + "\n")
+
+
+def remove_package_info(pacname):
+ os.remove(pac_dir + pacname)
def all_package_names():
diff --git a/web/htdocs/htmllib.py b/web/htdocs/htmllib.py
index f5ac9a5..98618df 100644
--- a/web/htdocs/htmllib.py
+++ b/web/htdocs/htmllib.py
@@ -608,6 +608,9 @@ class html(GUITester):
attrs.setdefault('size', 1)
attributes = ' ' + ' '.join([ '%s="%s"' % (k,
v) for k, v in attrs.iteritems() ])
+ error = self.user_errors.get(varname)
+ if error:
+ self.write("<x class=\"inputerror\">")
self.write("<select%s name=\"%s\"
id=\"%s\"%s>\n" %
(onchange_code, varname, varname, attributes))
for value, text in choices:
@@ -617,6 +620,8 @@ class html(GUITester):
self.write("<option
value=\"%s\"%s>%s</option>\n" %
(self.attrencode(value), sel, self.attrencode(text)))
self.write("</select>\n")
+ if error:
+ self.write("<x class=\"inputerror\">")
if varname:
self.form_vars.append(varname)
diff --git a/web/htdocs/pages.css b/web/htdocs/pages.css
index 43245f0..1dfa38c 100644
--- a/web/htdocs/pages.css
+++ b/web/htdocs/pages.css
@@ -654,7 +654,7 @@ input.date, input.time {
font-family: monospace;
}
-.inputerror input, .inputerror textarea, .inputerror span.checkbox {
+.inputerror input, .inputerror textarea, .inputerror span.checkbox, .inputerror >
select {
background-color: #f84;
}
diff --git a/web/htdocs/valuespec.py b/web/htdocs/valuespec.py
index 0ec06bd..ff106c9 100644
--- a/web/htdocs/valuespec.py
+++ b/web/htdocs/valuespec.py
@@ -1676,6 +1676,7 @@ class DualListChoice(ListChoice):
self._rows = 5
self._size = kwargs.get("size") # Total with in ex
+
def render_input(self, varprefix, value):
self.load_elements()
if not self._elements:
@@ -1742,6 +1743,14 @@ class DualListChoice(ListChoice):
html.write('</td></tr></table>')
html.hidden_field(varprefix, '|'.join([k for k, v in selected]), id =
varprefix, add_var = True)
+
+ def validate_value(self, value, varprefix):
+ try:
+ ListChoice.validate_value(self, value, varprefix)
+ except MKUserError, e:
+ raise MKUserError(e.varname + "_selected", e.message)
+
+
def from_html_vars(self, varprefix):
self.load_elements()
selected = html.var(varprefix, '').split('|')
@@ -1758,6 +1767,7 @@ class DualListChoice(ListChoice):
value.append(key)
return value
+
# A type-save dropdown choice with one extra field that
# opens a further value spec for entering an alternative
# Value.