Ejemplo n.º 1
0
 def test_translate_script_type(self):
     if hasattr(self, "exception"):
         with self.assertRaisesRegex(ValidationError, self.exception):
             translate_script_type(self.value)
     else:
         self.assertEqual(self.return_value,
                          translate_script_type(self.value))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    def _clean_script(self, parsed_yaml):
        """Clean script data and validate input."""
        # Tags and timeout may not be updated from new embedded YAML. This
        # allows users to receive updated scripts from an upstream maintainer,
        # such as Canonical, while maintaining user defined tags and timeout.

        # Tags must be a comma seperated string for the form.
        tags = parsed_yaml.pop("tags", None)
        if (tags is not None and self.instance.id is None
                and "tags" not in self.data):
            tags_valid = True
            if isinstance(tags, str):
                self.data["tags"] = tags
            elif isinstance(tags, list):
                for tag in tags:
                    if not isinstance(tag, str):
                        tags_valid = False
                        continue
                if tags_valid:
                    self.data["tags"] = ",".join(tags)
            else:
                tags_valid = False
            if not tags_valid:
                set_form_error(
                    self,
                    "tags",
                    "Embedded tags must be a string of comma seperated "
                    "values, or a list of strings.",
                )

        # Timeout must be a string for the form.
        timeout = parsed_yaml.pop("timeout", None)
        if (timeout is not None and self.instance.id is None
                and "timeout" not in self.data):
            self.data["timeout"] = str(timeout)

        # Packages and for_hardware must be a JSON string for the form.
        for key in ["packages", "for_hardware"]:
            value = parsed_yaml.pop(key, None)
            if value is not None and key not in self.data:
                self.data[key] = json.dumps(value)

        for key, value in parsed_yaml.items():
            if key in self.fields:
                error = False
                if key not in self.data:
                    self.data[key] = value
                elif key == "script_type":
                    # The deprecated Commissioning API always sets the
                    # script_type to commissioning as it has always only
                    # accepted commissioning scripts while the form sets
                    # the default type to testing. If the YAML matches the
                    # type allow it.
                    try:
                        if translate_script_type(
                                value) != translate_script_type(
                                    self.data[key]):
                            error = True
                    except ValidationError:
                        error = True
                elif value != self.data[key]:
                    # Only allow form data for fields defined in the YAML if
                    # the data matches.
                    error = True

                if error:
                    set_form_error(
                        self,
                        key,
                        "May not override values defined in embedded YAML.",
                    )