aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lava_server/management/commands/device-tags.py161
-rw-r--r--share/black.yaml4
2 files changed, 165 insertions, 0 deletions
diff --git a/lava_server/management/commands/device-tags.py b/lava_server/management/commands/device-tags.py
new file mode 100644
index 000000000..5815f7d78
--- /dev/null
+++ b/lava_server/management/commands/device-tags.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2018 Linaro Limited
+#
+# Author: Neil Williams <neil.williams@linaro.org>
+#
+# This file is part of LAVA.
+#
+# LAVA is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License version 3
+# as published by the Free Software Foundation
+#
+# LAVA is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with LAVA. If not, see <http://www.gnu.org/licenses/>.
+
+import contextlib
+from django.core.management.base import BaseCommand, CommandError, CommandParser
+from lava_scheduler_app.models import Device, Tag
+
+
+class Command(BaseCommand):
+ help = "Manage device tags"
+
+ def add_arguments(self, parser):
+ cmd = self
+
+ class SubParser(CommandParser):
+ """
+ Sub-parsers constructor that mimic Django constructor.
+ See http://stackoverflow.com/a/37414551
+ """
+
+ def __init__(self, **kwargs):
+ super().__init__(cmd, **kwargs)
+
+ sub = parser.add_subparsers(
+ dest="sub_command", help="Sub commands", parser_class=SubParser
+ )
+ sub.required = True
+
+ # "add" sub-command
+ add_parser = sub.add_parser(
+ "add", help="Add one or more existing device tag(s) to an existing device"
+ )
+ add_parser.add_argument("hostname", help="Hostname of the device")
+ add_parser.add_argument(
+ "--tags",
+ nargs="*",
+ required=False,
+ help="List of tags to add to the device",
+ )
+
+ # "show" sub-command
+ show_parser = sub.add_parser(
+ "show", help="Show all device tag(s) for an existing device"
+ )
+ show_parser.add_argument("hostname", help="Hostname of the device")
+
+ # "list" sub-command
+ list_parser = sub.add_parser("list", help="List all device tag(s)")
+
+ # "remove" sub-command
+ remove_parser = sub.add_parser(
+ "remove",
+ help="Remove one or more existing device tag(s) from an existing device",
+ )
+ remove_parser.add_argument("hostname", help="Hostname of the device")
+ remove_parser.add_argument(
+ "--tags",
+ nargs="*",
+ required=False,
+ help="List of tags to remove from the device",
+ )
+
+ # "create" sub-command
+ create_parser = sub.add_parser("create", help="Create a new device tag")
+ create_parser.add_argument("name", help="Name of the new tag")
+ create_parser.add_argument("description", help="Description of the new tag")
+
+ def handle(self, *args, **options):
+ """ Forward to the right sub-handler """
+ if options["sub_command"] == "add":
+ self.handle_add(options)
+ elif options["sub_command"] == "list":
+ self.handle_list(options)
+ elif options["sub_command"] == "show":
+ self.handle_show(options)
+ elif options["sub_command"] == "remove":
+ self.handle_remove(options)
+ else:
+ self.handle_create(options)
+
+ def handle_add(self, options):
+ hostname = options["hostname"]
+ try:
+ device = Device.objects.get(hostname=hostname)
+ except Device.DoesNotExist:
+ raise CommandError("Device '%s' does NOT exist!" % hostname)
+
+ tags = options["tags"]
+ if tags is not None:
+ for tag in tags:
+ try:
+ tag = Tag.objects.get(name=tag)
+ except Tag.DoesNotExist:
+ raise CommandError("Tag '%s' does NOT exist!" % tag)
+ device.tags.add(tag)
+ device.save()
+
+ def handle_show(self, options):
+ hostname = options["hostname"]
+ try:
+ device = Device.objects.get(hostname=hostname)
+ except Device.DoesNotExist:
+ raise CommandError("Device '%s' does NOT exist!" % hostname)
+ if device.tags.all():
+ self.stdout.write("Hostname: %s" % hostname)
+ for tag in device.tags.all():
+ self.stdout.write(
+ "Tag name: '%s' Description: '%s'" % (tag.name, tag.description)
+ )
+
+ def handle_remove(self, options):
+ hostname = options["hostname"]
+ try:
+ device = Device.objects.get(hostname=hostname)
+ except Device.DoesNotExist:
+ raise CommandError("Device '%s' does NOT exist!" % hostname)
+
+ tags = options["tags"]
+ if tags is not None:
+ for tag in tags:
+ try:
+ tag = Tag.objects.get(name=tag)
+ except Device.DoesNotExist:
+ raise CommandError("Tag '%s' does NOT exist!" % name)
+ if tag not in device.tags.all():
+ raise CommandError(
+ "Device %s does not have tag %s" % (hostname, tag.name)
+ )
+ device.tags.remove(tag)
+ device.save()
+
+ def handle_create(self, options):
+ name = options["name"]
+ description = options["description"]
+
+ with contextlib.suppress(Tag.DoesNotExist):
+ Tag.objects.get(name=name)
+ raise CommandError("Tag '%s' already exists" % name)
+ Tag.objects.create(name=name, description=description)
+
+ def handle_list(self, options):
+ for tag in Tag.objects.all():
+ self.stdout.write(
+ "Name: '%s' Description: '%s'" % (tag.name, tag.description)
+ )
diff --git a/share/black.yaml b/share/black.yaml
index 51ca02369..c920df752 100644
--- a/share/black.yaml
+++ b/share/black.yaml
@@ -1,3 +1,7 @@
+lava_server:
+ management:
+ commands:
+ device-tags.py
share:
check-devices.py
validate_devices.py