def test_translate_hardware_type(self): if hasattr(self, "exception"): with self.assertRaisesRegex(ValidationError, self.exception): translate_hardware_type(self.value) else: self.assertEqual(self.return_value, translate_hardware_type(self.value))
def read(self, request, system_id, id): """View a specific set of results. id can either by the script set id, current-commissioning, current-testing, or current-installation. :param hardware_type: Only return scripts for the given hardware type. Can be node, cpu, memory, or storage. Defaults to all. :type script_type: unicode :param include_output: Include base64 encoded output from the script. :type include_output: bool :param filters: A comma seperated list to show only results that ran with a script name, tag, or id. :type filters: unicode """ script_set = self._get_script_set(request, system_id, id) include_output = get_optional_param(request.GET, 'include_output', False, Bool) filters = get_optional_param(request.GET, 'filters', None, String) if filters is not None: filters = filters.split(',') hardware_type = get_optional_param(request.GET, 'hardware_type') if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) script_set.include_output = include_output script_set.filters = filters script_set.hardware_type = hardware_type return script_set
def read(self, request): """Return a list of stored scripts. :param type: Only return scripts with the given type. This can be testing or commissioning. Defaults to showing both. :type type: unicode :param hardware_type: Only return scripts for the given hardware type. Can be node, cpu, memory, or storage. Defaults to all. :type hardware_type: unicode :param include_script: Include the base64 encoded script content. :type include_script: bool :param filters: A comma seperated list to show only results with a script name or tag. :type filters: unicode """ qs = Script.objects.all() script_type = get_optional_param(request.GET, 'type') if script_type is not None: try: script_type = translate_script_type(script_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = qs.filter(script_type=script_type) hardware_type = get_optional_param(request.GET, 'hardware_type') if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = qs.filter(hardware_type=hardware_type) include_script = get_optional_param(request.GET, 'include_script', False, Bool) filters = get_optional_param(request.GET, 'filters', None, String) if filters is not None: filters = set(filters.split(',')) ret = [] for script in qs: if (filters is not None and script.name not in filters and filters.isdisjoint(script.tags)): continue else: script.include_script = include_script ret.append(script) return ret
def read(self, request, system_id): """Return a list of script results grouped by run. :param type: Only return scripts with the given type. This can be commissioning, testing, or installion. Defaults to showing all. :type type: unicode :param hardware_type: Only return scripts for the given hardware type. Can be node, cpu, memory, or storage. Defaults to all. :type script_type: unicode :param include_output: Include base64 encoded output from the script. :type include_output: bool :param filters: A comma seperated list to show only results with a script name or tag. :type filters: unicode """ node = Node.objects.get_node_or_404(system_id=system_id, user=request.user, perm=NODE_PERMISSION.VIEW) result_type = get_optional_param(request.GET, 'type') include_output = get_optional_param(request.GET, 'include_output', False, Bool) filters = get_optional_param(request.GET, 'filters', None, String) if filters is not None: filters = filters.split(',') if result_type is not None: try: result_type = translate_result_type(result_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = ScriptSet.objects.filter(node=node, result_type=result_type) else: qs = ScriptSet.objects.filter(node=node) hardware_type = get_optional_param(request.GET, 'hardware_type') if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) ret = [] for script_set in qs: script_set.include_output = include_output script_set.filters = filters script_set.hardware_type = hardware_type ret.append(script_set) return ret
def read(self, request, system_id, id): """@description-title Get specific script result @description View a set of test results for a given system_id and script id. "id" can either by the script set id, ``current-commissioning``, ``current-testing``, or ``current-installation``. @param (string) "{system_id}" [required=true] The machine's system_id. @param (string) "{id}" [required=true] The script result id. @param (string) "hardware_type" [required=false] Only return scripts for the given hardware type. Can be ``node``, ``cpu``, ``memory``, or ``storage``. Defaults to all. @param (string) "include_output" [required=false] Include the base64 encoded output from the script if any value for include_output is given. @param (string) "filters" [required=false] A comma seperated list to show only results that ran with a script name, tag, or id. @success (http-status-code) "server-success" 200 @success (json) "success-json" A JSON object containing the requested script result object. @success-example "success-json" [exkey=script-results-read-by-id] placeholder text @error (http-status-code) "404" 404 @error (content) "not-found" The requested machine or script result is not found. @error-example "not-found" Not Found """ script_set = self._get_script_set(request, system_id, id) include_output = get_optional_param(request.GET, "include_output", False, Bool) filters = get_optional_param(request.GET, "filters", None, String) if filters is not None: filters = filters.split(",") hardware_type = get_optional_param(request.GET, "hardware_type") if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) script_set.include_output = include_output script_set.filters = filters script_set.hardware_type = hardware_type return script_set
def clean(self): cleaned_data = super().clean() # If a field wasn't passed in keep the old values when updating. if self.instance.id is not None: for field in self._meta.fields: if field not in self.data: cleaned_data[field] = getattr(self.instance, field) script_type = cleaned_data["script_type"] if script_type == "": cleaned_data["script_type"] = self.instance.script_type else: try: cleaned_data["script_type"] = translate_script_type( script_type) except ValidationError as e: set_form_error(self, "script_type", e) hardware_type = cleaned_data["hardware_type"] if hardware_type == "": cleaned_data["hardware_type"] = self.instance.hardware_type else: try: cleaned_data["hardware_type"] = translate_hardware_type( hardware_type) except ValidationError as e: set_form_error(self, "hardware_type", e) parallel = cleaned_data["parallel"] if parallel == "": cleaned_data["parallel"] = self.instance.parallel else: try: cleaned_data["parallel"] = translate_script_parallel(parallel) except ValidationError as e: set_form_error(self, "parallel", e) return cleaned_data
def read(self, request): """@description-title List stored scripts @description Return a list of stored scripts. Note that parameters should be passed in the URI. E.g. ``/script/?type=testing``. @param (string) "type" [required=false] Only return scripts with the given type. This can be ``testing`` or ``commissioning``. Defaults to showing both. @param (string) "hardware_type" [required=false] Only return scripts for the given hardware type. Can be ``node``, ``cpu``, ``memory``, or ``storage``. Defaults to all. @param (string) "include_script" [required=false] Include the base64- encoded script content. @param (string) "filters" [required=false] A comma seperated list to show only results with a script name or tag. @success (http-status-code) "server-success" 200 @success (json) "success-json" A JSON object containing a list of script objects. @success-example "success-json" [exkey=scripts-read] placeholder text """ qs = Script.objects.all() script_type = get_optional_param(request.GET, 'type') if script_type is not None: try: script_type = translate_script_type(script_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = qs.filter(script_type=script_type) hardware_type = get_optional_param(request.GET, 'hardware_type') if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = qs.filter(hardware_type=hardware_type) include_script = get_optional_param(request.GET, 'include_script', False, Bool) filters = get_optional_param(request.GET, 'filters', None, String) if filters is not None: filters = set(filters.split(',')) ret = [] for script in qs: if (filters is not None and script.name not in filters and filters.isdisjoint(script.tags)): continue else: script.include_script = include_script ret.append(script) return ret
def read(self, request, system_id): """@description-title Return script results @description Return a list of script results grouped by run for the given system_id. @param (string) "{system_id}" [required=true] The machine's system_id. @param (string) "type" [required=false] Only return scripts with the given type. This can be ``commissioning``, ``testing``, or ``installion``. Defaults to showing all. @param (string) "hardware_type" [required=false] Only return scripts for the given hardware type. Can be ``node``, ``cpu``, ``memory``, or ``storage``. Defaults to all. @param (string) "include_output" [required=false] Include base64 encoded output from the script. Note that any value of include_output will include the encoded output from the script. @param (string) "filters" [required=false] A comma seperated list to show only results with a script name or tag. @success (http-status-code) "server-success" 200 @success (json) "success-json" A JSON object containing a list of script result objects. @success-example "success-json" [exkey=script-results-read] placeholder text @error (http-status-code) "404" 404 @error (content) "not-found" The requested machine is not found. @error-example "not-found" Not Found """ node = Node.objects.get_node_or_404(system_id=system_id, user=request.user, perm=NodePermission.view) result_type = get_optional_param(request.GET, "type") include_output = get_optional_param(request.GET, "include_output", False, Bool) filters = get_optional_param(request.GET, "filters", None, String) if filters is not None: filters = filters.split(",") if result_type is not None: try: result_type = translate_result_type(result_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = ScriptSet.objects.filter(node=node, result_type=result_type) else: qs = ScriptSet.objects.filter(node=node) hardware_type = get_optional_param(request.GET, "hardware_type") if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) ret = [] for script_set in qs: script_set.include_output = include_output script_set.filters = filters script_set.hardware_type = hardware_type ret.append(script_set) return ret
def download(self, request, system_id, id): """@description-title Download script results @description Download a compressed tar containing all results from the given system_id with the given id. "id" can either by the script set id, ``current-commissioning``, ``current-testing``, or ``current-installation``. @param (string) "{system_id}" [required=true] The machine's system_id. @param (string) "{id}" [required=true] The script result id. @param (string) "hardware_type" [required=false] Only return scripts for the given hardware type. Can be ``node``, ``cpu``, ``memory``, or ``storage``. Defaults to all. @param (string) "filters" [required=false] A comma seperated list to show only results that ran with a script name or tag. @param (string) "output" [required=false] Can be either ``combined``, ``stdout``, ``stderr``, or ``all``. By default only the combined output is returned. @param (string) "filetype" [required=false] Filetype to output, can be ``txt`` or ``tar.xz``. @success (http-status-code) "server-success" 200 @success (content) "success-text" Plain-text output containing the requested results. @success-example "success-text" [exkey=script-results-download] placeholder text @error (http-status-code) "404" 404 @error (content) "not-found" The requested machine or script result is not found. @error-example "not-found" Not Found """ script_set = self._get_script_set(request, system_id, id) filters = get_optional_param(request.GET, "filters", None, String) output = get_optional_param(request.GET, "output", "combined", String) filetype = get_optional_param(request.GET, "filetype", "txt", String) files = OrderedDict() times = {} if filters is not None: filters = filters.split(",") hardware_type = get_optional_param(request.GET, "hardware_type") if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) bin_regex = re.compile(r".+\.tar(\..+)?") for script_result in filter_script_results(script_set, filters, hardware_type): mtime = time.mktime(script_result.updated.timetuple()) if bin_regex.search(script_result.name) is not None: # Binary files only have one output files[script_result.name] = script_result.output times[script_result.name] = mtime elif output == "combined": title = self.__make_file_title(script_result, filetype) files[title] = script_result.output times[title] = mtime elif output == "stdout": title = self.__make_file_title(script_result, filetype, "out") files[title] = script_result.stdout times[title] = mtime elif output == "stderr": title = self.__make_file_title(script_result, filetype, "err") files[title] = script_result.stderr times[title] = mtime elif output == "result": title = self.__make_file_title(script_result, filetype, "yaml") files[title] = script_result.result times[title] = mtime elif output == "all": title = self.__make_file_title(script_result, filetype) files[title] = script_result.output times[title] = mtime title = self.__make_file_title(script_result, filetype, "out") files[title] = script_result.stdout times[title] = mtime title = self.__make_file_title(script_result, filetype, "err") files[title] = script_result.stderr times[title] = mtime title = self.__make_file_title(script_result, filetype, "yaml") files[title] = script_result.result times[title] = mtime if filetype == "txt" and len(files) == 1: # Just output the result with no break to allow for piping. return HttpResponse(list(files.values())[0], content_type="application/binary") elif filetype == "txt": binary = BytesIO() for filename, content in files.items(): dashes = "-" * int((80.0 - (2 + len(filename))) / 2) binary.write( ("%s %s %s\n" % (dashes, filename, dashes)).encode()) if bin_regex.search(filename) is not None: binary.write(b"Binary file") else: binary.write(content) binary.write(b"\n") return HttpResponse(binary.getvalue(), content_type="application/binary") elif filetype == "tar.xz": binary = BytesIO() root_dir = "%s-%s-%s" % ( script_set.node.hostname, script_set.result_type_name.lower(), script_set.id, ) with tarfile.open(mode="w:xz", fileobj=binary) as tar: for filename, content in files.items(): tarinfo = tarfile.TarInfo(name=os.path.join( root_dir, os.path.basename(filename))) tarinfo.size = len(content) tarinfo.mode = 0o644 tarinfo.mtime = times[filename] tar.addfile(tarinfo, BytesIO(content)) return HttpResponse(binary.getvalue(), content_type="application/x-tar") else: raise MAASAPIValidationError( 'Unknown filetype "%s" must be txt or tar.xz' % filetype)
def download(self, request, system_id, id): """Download a compressed tar containing all results. id can either by the script set id, current-commissioning, current-testing, or current-installation. :param hardware_type: Only return scripts for the given hardware type. Can be node, cpu, memory, or storage. Defaults to all. :type script_type: unicode :param filters: A comma seperated list to show only results that ran with a script name or tag. :type filters: unicode :param output: Can be either combined, stdout, stderr, or all. By default only the combined output is returned. :type output: unicode :param filetype: Filetype to output, can be txt or tar.xz :type format: unicode """ script_set = self._get_script_set(request, system_id, id) filters = get_optional_param(request.GET, 'filters', None, String) output = get_optional_param(request.GET, 'output', 'combined', String) filetype = get_optional_param(request.GET, 'filetype', 'txt', String) files = OrderedDict() times = {} if filters is not None: filters = filters.split(',') hardware_type = get_optional_param(request.GET, 'hardware_type') if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) for script_result in filter_script_results(script_set, filters, hardware_type): mtime = time.mktime(script_result.updated.timetuple()) if output == 'combined': files[script_result.name] = script_result.output times[script_result.name] = mtime elif output == 'stdout': filename = '%s.out' % script_result.name files[filename] = script_result.stdout times[filename] = mtime elif output == 'stderr': filename = '%s.err' % script_result.name files[filename] = script_result.stderr times[filename] = mtime elif output == 'result': filename = '%s.yaml' % script_result.name files[filename] = script_result.result times[filename] = mtime elif output == 'all': files[script_result.name] = script_result.output times[script_result.name] = mtime filename = '%s.out' % script_result.name files[filename] = script_result.stdout times[filename] = mtime filename = '%s.err' % script_result.name files[filename] = script_result.stderr times[filename] = mtime filename = '%s.yaml' % script_result.name files[filename] = script_result.result times[filename] = mtime if filetype == 'txt' and len(files) == 1: # Just output the result with no break to allow for piping. return HttpResponse(list(files.values())[0], content_type='application/binary') elif filetype == 'txt': binary = BytesIO() for filename, content in files.items(): dashes = '-' * int((80.0 - (2 + len(filename))) / 2) binary.write( ('%s %s %s\n' % (dashes, filename, dashes)).encode()) binary.write(content) binary.write(b'\n') return HttpResponse(binary.getvalue(), content_type='application/binary') elif filetype == 'tar.xz': binary = BytesIO() root_dir = '%s-%s-%s' % (script_set.node.hostname, script_set.result_type_name.lower(), script_set.id) with tarfile.open(mode='w:xz', fileobj=binary) as tar: for filename, content in files.items(): tarinfo = tarfile.TarInfo( name=os.path.join(root_dir, filename)) tarinfo.size = len(content) tarinfo.mode = 0o644 tarinfo.mtime = times[filename] tar.addfile(tarinfo, BytesIO(content)) return HttpResponse(binary.getvalue(), content_type='application/x-tar') else: raise MAASAPIValidationError( 'Unknown filetype "%s" must be txt or tar.xz' % filetype)
def update(self, request, system_id, id): """@description-title Update specific script result @description Update a set of test results for a given system_id and script id. "id" can either be the script set id, ``current-commissioning``, ``current-testing``, or ``current-installation``. @param (string) "{system_id}" [required=true] The machine's system_id. @param (string) "{id}" [required=true] The script result id. @param (string) "hardware_type" [required=false] Only return scripts for the given hardware type. Can be ``node``, ``cpu``, ``memory``, or ``storage``. Defaults to all. @param (string) "filters" [required=false] A comma seperated list to show only results that ran with a script name, tag, or id. @param (string) "include_output" [required=false] Include the base64 encoded output from the script if any value for include_output is given. @param (boolean) "suppressed" [required=false] Set whether or not this script result should be suppressed using 'true' or 'false'. @success (http-status-code) "server-success" 200 @success (json) "success-json" A JSON object containing the requested script result object. @success-example "success-json" [exkey=script-results-read-by-id] placeholder text @error (http-status-code) "404" 404 @error (content) "not-found" The requested machine or script result is not found. @error-example "not-found" Not Found """ script_set = self._get_script_set(request, system_id, id) include_output = get_optional_param(request.PUT, 'include_output', False, Bool) filters = get_optional_param(request.PUT, 'filters', None, String) if filters is not None: filters = filters.split(',') hardware_type = get_optional_param(request.PUT, 'hardware_type') if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) script_set.include_output = include_output script_set.filters = filters script_set.hardware_type = hardware_type suppressed = get_optional_param(request.data, 'suppressed', None, StringBool) # Set the suppressed flag for the script results. if suppressed is not None: for script_result in filter_script_results(script_set, filters, hardware_type): script_result.suppressed = suppressed script_result.save() return script_set
def read(self, request, system_id): """@description-title Return node devices @description Return a list of devices attached to the node given by a system_id. @param (string) "{system_id}" [required=true] The node's system_id. @param (string) "bus" [required=false] Only return devices attached to the specified bus. Can be PCIE or USB. Defaults to all. @param (string) "hardware_type" [required=false] Only return scripts for the given hardware type. Can be ``node``, ``cpu``, ``memory``, ``storage`` or ``gpu``. Defaults to all. @param (string) "vendor_id" [required=false] Only return devices which have the specified vendor id. @param (string) "product_id" [required=false] Only return devices which have the specified product id. @param (string) "vendor_name" [required=false] Only return devices which have the specified vendor_name. @param (string) "product_name" [required=false] Only return devices which have the specified product_name. @param (string) "commissioning_driver" [required=false] Only return devices which use the specified driver when commissioning. @success (http-status-code) "server-success" 200 @success (json) "success-json" A JSON object containing a list of script result objects. @success-example "success-json" [exkey=script-results-read] placeholder text @error (http-status-code) "404" 404 @error (content) "not-found" The requested machine is not found. @error-example "not-found" Not Found """ node = Node.objects.get_node_or_404(system_id=system_id, user=request.user, perm=NodePermission.view) qs = node.node_devices.prefetch_related("node", "numa_node", "physical_interface", "physical_blockdevice") bus = get_optional_param(request.GET, "bus") if bus is not None: try: bus = translate_bus(bus) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = qs.filter(bus=bus) hardware_type = get_optional_param(request.GET, "hardware_type") if hardware_type is not None: try: hardware_type = translate_hardware_type(hardware_type) except ValidationError as e: raise MAASAPIValidationError(e) else: qs = qs.filter(hardware_type=hardware_type) vendor_id = get_optional_param(request.GET, "vendor_id") if vendor_id is not None: qs = qs.filter(vendor_id__iexact=vendor_id) product_id = get_optional_param(request.GET, "product_id") if product_id is not None: qs = qs.filter(product_id__iexact=product_id) vendor_name = get_optional_param(request.GET, "vendor_name") if vendor_name is not None: qs = qs.filter(vendor_name__iexact=vendor_name) product_name = get_optional_param(request.GET, "product_name") if product_name is not None: qs = qs.filter(product_name__iexact=product_name) commissioning_driver = get_optional_param(request.GET, "commissioning_driver") if commissioning_driver is not None: qs = qs.filter(commissioning_driver__iexact=commissioning_driver) return qs