コード例 #1
0
    def load(self) -> None:
        """
        Attempts to load the file from disk. If the file doesn't exist, it will
        create an empty JSON structure in memory.

        Raises:
            InvalidInputError:      Raised when the file cannot be loaded from
                                    disk or its content cannot be parsed as a
                                    valid JSON.
        """

        if self._file_exists():

            if self._cb_retrieve_key is None:

                # Try to load the file as an unencrypted JSON file.
                try:
                    with open(self._path, 'r+') as json_file:
                        # Parse the file and load the content to memory.
                        self._content = json.load(json_file)
                except OSError:
                    self._content = None
                    raise InvalidInputError(
                        'Failed to read the contents of JSON file {}.'.format(
                            self._path))
                except json.JSONDecodeError:
                    self._content = None
                    raise InvalidInputError(
                        'Failed to parse the content of JSON file {}.'.format(
                            self._path))
            else:

                # Try to load and decrypt the file
                raw_content = None
                try:
                    with open(self._path, 'rb') as raw_file:
                        raw_content = raw_file.read()
                except OSError:
                    raise InvalidInputError(
                        'Failed to read the file from disk: {}.'.format(
                            self._path))

                if raw_content is not None:

                    # Try to load as a regular JSON file
                    try:
                        cipher = AESCipher(self._cb_retrieve_key())
                        self._content = json.loads(cipher.decrypt(raw_content))
                    except json.JSONDecodeError:
                        raise InvalidInputError(
                            'Failed to parse the content of JSON file {}. '
                            'Either the decryption key was wrong or the file '
                            'is not a valid JSON file.'.format(self._path))

        else:
            # Just create an empty structure.
            self._content = {}
コード例 #2
0
    def __init__(self,
                 counter_name: str,
                 counter_type: PmCounterTypes,
                 owner: ManagedObject,
                 initial_value: int = 0,
                 maximum_value: int = None) -> None:
        """
        Creates a new PmCounter instance.

        Args:
            counter_name:       Name of the PM counter.
            counter_type:       Type of the PM counter.
            owner:              The managed object that owns the counter.
            initial_value:      The initial value of the PM counter.
            maximum_value:      The maximum value of the PM counter.

        Raises:
            InvalidInputError:      Raised when trying to create a PERCENTAGE
                                    type PM counter without setting a maximum
                                    value.
        """

        self._name = counter_name
        self._type = counter_type
        self._owner = owner
        self._value = initial_value
        self._initial_value = initial_value

        if self._type == PmCounterTypes.PERCENTAGE and maximum_value is None:
            raise InvalidInputError(
                'Trying to create a PERCENTAGE type PM counter without '
                'setting a maximum value. Counter: {}({}).{}'.format(
                    self._owner.Name, self._owner.UUID, self.Name))

        self._max_value = maximum_value
コード例 #3
0
    def _load_release_level(self, version_data: dict) -> None:
        """
        Loads the release level from the configuration.
        """

        try:
            release_level = version_data['release'].lower()

            if release_level == 'internal':
                self._release_level = ProductVersion.ReleaseLevels.INTERNAL
            elif release_level == 'alpha':
                self._release_level = ProductVersion.ReleaseLevels.ALPHA
            elif release_level == 'beta':
                self._release_level = ProductVersion.ReleaseLevels.BETA
            elif release_level == 'eap':
                self._release_level = ProductVersion.ReleaseLevels.EAP
            elif release_level == 'rc':
                self._release_level = ProductVersion.ReleaseLevels.RC
            elif release_level == 'ga':
                self._release_level = ProductVersion.ReleaseLevels.GA
            else:
                raise InvalidInputError(
                    'Unknown release level is configured: {}'.format(
                        release_level))

        except KeyError:
            self._release_level = ProductVersion.ReleaseLevels.GA
コード例 #4
0
    def _load_components(self, components: dict) -> None:

        """
        Parses the component configuration from the passed in JSON structure.

        Args:
            components:     The component configuration in JSON format.

        Raises:
            InvalidInputError:      Raised when there is no component ID in the
                                    configuration of the component.
        """

        from suisei.murasame.exceptions import InvalidInputError

        for component in components:

            try:
                component_id = component['id']
            except KeyError:
                raise InvalidInputError(
                    'Component ID was not found in the configuration.')

            if component_id in self._components:
                continue

            self._components[component_id] = ComponentConfiguration(component)
コード例 #5
0
    def _parse_configuration(self, configuration: dict) -> None:

        """
        Parses the configuration from the passed in JSON representation.

        Args:
            coniguration:       The configuration as a JSON object.

        Raises:
            InvalidInputError:  Raised when a required element is not found
                                in the configuration.
        """

        from suisei.murasame.exceptions import InvalidInputError

        self._id = configuration['id']

        try:
            self._ut_out_dir = os.path.abspath(
                configuration['unittest']['outdir'])
            self._ut_log_format = configuration['unittest']['logformat']
            self._ut_path = os.path.abspath(
                configuration['unittest']['testdir'])
        except KeyError:
            raise InvalidInputError(
                'Unittest configuration was not found in the configuration.')

        try:
            self._ut_verbosity = int(configuration['unittest']['verbosity'])
        except KeyError:
            # Default to verbosity level 1 if the configuration is not present
            # in the configuration file.
            self._ut_verbosity = 1
コード例 #6
0
    def _load_patch_level(self, version_data: dict) -> None:
        """
        Loads the patch level from the configuration.
        """

        try:
            patch = int(version_data['patch'])
            if patch < 0:
                raise InvalidInputError(
                    'Invalid product version. Patch level cannot be a '
                    'negative number.')
            self._patch = patch
        except KeyError:
            raise InvalidInputError(
                'Invalid product version. Patch level not found.')
        except ValueError:
            raise InvalidInputError(
                'Invalid product version. Patch level is not integer.')
コード例 #7
0
    def _load_minor_version(self, version_data: dict) -> None:
        """
        Loads the minor product version from the configuration.
        """

        try:
            minor = int(version_data['minor'])
            if minor < 0:
                raise InvalidInputError(
                    'Invalid product version. Minor version cannot be a '
                    'negative number.')
            self._minor = minor
        except KeyError:
            raise InvalidInputError(
                'Invalid product version. Minor version not found.')
        except ValueError:
            raise InvalidInputError(
                'Invalid product version. Minor version is not integer.')
コード例 #8
0
    def __init__(self,
                 name: str,
                 logic: Callable,
                 task_type: int = TaskTypes.NORMAL,
                 priority: int = TaskPriorities.NORMAL,
                 data: Any = None,
                 frequency: int = 1000) -> None:
        """
        Creates a new Task instance.

        Args:
            name:           Name of the task.
            logic:          A callback function to the business logic that will
                            be executed by the task when it's scheduled.
            task_type:      Type of the task.
            priority:       The task execution priority.
            data:           Custom data to be passed to the execution logic of
                            the task.
            frequency:      The repetition frequency of the task in
                            milliseconds. Only valid for RECURRING type tasks.

        Raises:
            InvalidInputError:      Raised when the task type is invalid.
            InvalidInputError:      Raised when the task priority is invalid.
        """

        if task_type not in [TaskTypes.NORMAL, TaskTypes.RECURRING]:
            raise InvalidInputError('Trying to configure an invalid '
                                    'task type: {}'.format(task_type))

        if priority not in [
                TaskPriorities.HIGH, TaskPriorities.NORMAL, TaskPriorities.IO
        ]:
            raise InvalidInputError('Trying to configure an invalid '
                                    'task priority: {}'.format(priority))

        self._name = name
        self._type = task_type
        self._priority = priority
        self._logic = logic
        self._data = data
        self._frequency = frequency
        self._expected_execution = None
コード例 #9
0
    def decrypt(self, content: bytes) -> str:
        """
        Decrypts the content using AES.

        Args:
            encoded_contet:         The encrypted content encoded in a base64
                                    format.

        Raises:
            InvalidInputError:      Raised if the input file is not properly
                                    encoded.

        Returns:
            The decrypted content.
        """

        import binascii
        from suisei.murasame.exceptions import InvalidInputError

        # Base64 decode the input data
        try:
            content = base64.b64decode(content)
        except binascii.Error:
            raise InvalidInputError('The input file is not properly encoded.')

        # Retrieve the initialization vector
        initialization_vector = content[:16]

        # Remove the initialization vector from the content
        content = content[16:]

        # Decrypt the data
        cipher = self._create_cipher(initialization_vector)
        decryptor = cipher.decryptor()
        content = decryptor.update(content) + decryptor.finalize()

        # Unpad the data
        unpadder = padding.PKCS7(128).unpadder()
        content = unpadder.update(content)
        content += unpadder.finalize()

        # Decode the content
        content = content.decode('utf-8')

        return content
コード例 #10
0
    def __init__(self,
                 name: str,
                 parent: 'ManagedObject',
                 access_mode: MOAttributeAccessModes,
                 data_type: MOAttributeDataTypes,
                 initial_value: object,
                 default_value: object = None,
                 min_value: object = None,
                 max_value: object = None) -> None:
        """
        Creates a new MOAttribute instance.

        Args:
            name:           Name of the MO attribute.
            parent:         The managed object this attribute belongs to.
            access_mode:    The access mode of the MO attribute.
            data_type:      The data type of the MO attribute.
            initial_value:  The initial value of the MO attribute.
            default_value:  The default value of the MO attribute.
            min_value:      The minimum value of the MO attribute.
            max_value:      The maximum value of the MO attribute.

        Raises:
            InvalidInputError:      Raised when trying to create an attribute
                                    without specifying a parent MO.
        """

        self._name = name

        if parent is None:
            raise InvalidInputError('No parent MO specified when creating MO '
                                    'attribute {}'.format(name))

        self._parent = parent
        self._access_mode = access_mode
        self._data_type = data_type
        self._initial_value = initial_value
        self._value = initial_value
        self._default_value = default_value
        self._min_value = min_value
        self._max_value = max_value
        self._changelog = []
コード例 #11
0
    def schedule(self, task: Task) -> None:

        """
        Adds the task to the execution queue to be scheduled.

        Args:
            task:       The task to be scheduled.
        """

        if task is None or not isinstance(task, Task):
            return

        if task.Priority == TaskPriorities.HIGH:
            self._high_prio_tasks.put(task)
        elif task.Priority == TaskPriorities.NORMAL:
            self._normal_prio_tasks.put(task)
        elif task.Priority == TaskPriorities.IO:
            self._io_tasks.put(task)
        else:
            raise InvalidInputError(
                'TaskExecutor.schedule() was called with an unsupported '
                'task priority {}'.format(task.Priority))