Esempio n. 1
0
    def store_contents(self,
                       content_type: ContentType,
                       container_name: str,
                       content_name: str,
                       content_data: str = None,
                       content_path: str = None):
        """Function that stores file content. Based on the ContentType the function
        can either save a text or can read a file path (content_path) and copies it

        :param content_type: Content type, can be file or text
        :type content_type: enum
        :param container_name: Container name
        :type container_name: str
        :param content_name: File name
        :type content_name: str
        :param content_data: File content as text
        :type content_data: str
        :param content_path: File path to be copied into the storage
        :type content_path: str
        
        :raises: :class:`CustomException`
        """

        try:
            self._logger.info('storing contents')

            if self._vdc_storage_account_key == None:
                self._vdc_storage_account_key = self.get_storage_account_key()

            block_blob_service = BlockBlobService(
                account_name=self._vdc_storage_account_name,
                account_key=self._vdc_storage_account_key)

            # Create container if does not exists
            if not block_blob_service.exists(container_name):
                self._logger.info(
                    'container {} does not exists, proceeding to create it'.
                    format(container_name))
                block_blob_service.create_container(container_name)

            self._logger.info('saving blob')

            if content_type == ContentType.TEXT:
                block_blob_service.create_blob_from_text(
                    container_name=container_name,
                    blob_name=content_name,
                    text=content_data)
            elif content_type == ContentType.FILE:
                if Path(content_path).exists():
                    block_blob_service.create_blob_from_path(
                        container_name=container_name,
                        blob_name=content_name,
                        file_path=content_path)
                else:
                    raise CustomException('File does not exist.')

        except Exception as ex:
            raise CustomException(
                'There was an unhandled exception: {}'.format(str(ex)))
    def get_student(self, student_id):
        if student_id is None:
            raise CustomException("Student id missing")

        student = self.students_collection.find_one({"_id": student_id})
        if student is None:
            raise CustomException("Student not found")

        return student
Esempio n. 3
0
    def get_contents(self, content_type: ContentType, container_name: str,
                     content_name: str):
        """Function that retrieves the content data, based on the content type.
        Currently, it only retrieves text content data

        :param content_type: Content type, can be file or text
        :type content_type: enum
        :param container_name: Container name
        :type container_name: str
        :param content_name: File name
        :type content_name: str

        :raises: :class:`CustomException`
        """

        if content_type == ContentType.TEXT:
            try:
                if self._vdc_storage_account_key == None:
                    self._vdc_storage_account_key = self.get_storage_account_key(
                    )

                block_blob_service = BlockBlobService(
                    account_name=self._vdc_storage_account_name,
                    account_key=self._vdc_storage_account_key)

                response: Blob = block_blob_service.get_blob_to_text(
                    container_name=container_name, blob_name=content_name)

                return response.content

            except Exception as ex:
                raise CustomException(
                    'There was an unhandled exception: {}'.format(str(ex)))
    def get_all_class_students(self, class_id):
        if class_id is None:
            raise CustomException("Class id is missing")

        results = list(
            self.grades_collection.aggregate([{
                "$match": {
                    "class_id": class_id
                }
            }, {
                "$lookup": {
                    "from": "students",
                    "localField": "student_id",
                    "foreignField": "_id",
                    "as": "student"
                }
            }, {
                "$unwind": {
                    "path": "$student",
                    "preserveNullAndEmptyArrays": False
                }
            }, {
                "$project": {
                    "student_id": "$student._id",
                    "student_name": "$student.name",
                    "_id": 0
                }
            }]))

        return {"class_id": class_id, "students": results}
    def get_student_class_scores(self, student_id, class_id):
        self.get_student(student_id)

        if class_id is None:
            raise CustomException("Class id is missing")

        results = list(
            self.grades_collection.aggregate([{
                "$match": {
                    "student_id": student_id,
                    "class_id": class_id
                }
            }, {
                "$lookup": {
                    "from": "students",
                    "localField": "student_id",
                    "foreignField": "_id",
                    "as": "student"
                }
            }, {
                "$unwind": {
                    "path": "$student",
                    "preserveNullAndEmptyArrays": False
                }
            }, {
                "$project": {
                    "class_id": 1,
                    "student_id": "$student._id",
                    "student_name": "$student.name",
                    "_id": 0,
                    "marks": "$scores",
                    "total_marks": {
                        "$toInt": {
                            "$sum": "$scores.score"
                        }
                    }
                }
            }]))

        if results is None:
            raise ValidationError("Score not found")

        result = results[0]
        for score in result['marks']:
            score['marks'] = int(score['score'])
            del score['score']

        result['marks'].append({
            "type": "total",
            "score": result['total_marks']
        })
        del result['total_marks']

        return result
    def get_class_studentwise_performance(self, class_id):
        if class_id is None:
            raise CustomException("Class id is missing")

        results = list(
            self.grades_collection.aggregate([{
                "$match": {
                    "class_id": class_id
                }
            }, {
                "$lookup": {
                    "from": "students",
                    "localField": "student_id",
                    "foreignField": "_id",
                    "as": "student"
                }
            }, {
                "$unwind": {
                    "path": "$student",
                    "preserveNullAndEmptyArrays": False
                }
            }, {
                "$project": {
                    "student_id": "$student._id",
                    "student_name": "$student.name",
                    "_id": 0,
                    "total_marks": {
                        "$toInt": {
                            "$sum": "$scores.score"
                        }
                    }
                }
            }, {
                "$group": {
                    "_id": {
                        "student_id": "$student_id"
                    },
                    "max_marks": {
                        "$max": "$total_marks"
                    }
                }
            }]))

        return {"class_id": class_id, "students": results}
Esempio n. 7
0
    def create_or_update_resource_group(self, resource_group_name: str,
                                        location: str):
        """Function that creates or updates a resource group

        :param resource_group_name: Resource group name to analyze
        :type resource_group_name: str
        :param location: Resource group location
        :type location: str

        :raises: :class:`Exception`
        """

        if location is None or location == '':
            raise CustomException('No location has been set')

        try:
            resource_group_parameters = \
                ResourceGroup(location = location)

            new_resource_group: ResourceGroup = \
                self._resource_management_client\
                    .resource_groups\
                    .create_or_update(
                        resource_group_name,
                        resource_group_parameters)

            self._logger.info(
                'resource group {} created on {} location'.format(
                    new_resource_group.name, new_resource_group.location))
        except Exception as e:
            self._logger.error(
                'The following error occurred while creating a resource group: '
                + str(e))
            self._logger.error(e)
            sys.exit(
                1
            )  # Exit the module as it is not possible to progress the deployment.
            raise (e)
Esempio n. 8
0
    def create(self) -> list:
        '''Main function used to execute a module(s) deployment.

        This function creates a storage repository to place all deployment outputs, and to to place
        custom scripts if --upload-scripts argument passed is set to true.
        :param parameter_initializer: Object containing all required properties used during a module provisioning
        :type parameter_initializer: ParameterInitializer
        :param deployment_path: Path that contains deployment and parameters folders
        :type deployment_path: str
        :raises: :class:`CustomException<Exception>`
        '''

        try:

            # Append dummy sas key to default parameters, the key will now be
            # appended to all deploy templates
            self.append_to_default_parameters(
                dict({
                    'sas-key': 'xxxxxxxxxx',
                    'output-params-storage-key': 'xxxxxxxxxx',
                    'output-params-storage-account-name': 'xxxxxxxxxx'
                }))

            module_names = list()

            if self._deploy_all_modules == True:
                # Let's get all the deployment folders
                module_names = self._module_deployment_order
                self._logger.info(
                    'validating all modules:{}'.format(module_names))
            else:
                if self._single_module is None or self._single_module == '':
                    raise CustomException('No module has been passed')

                # Single module, let's add it to the list
                module_names.append(self._single_module)

            # Let's create a dummy resource group for the validation to pass
            self._resource_management_integration_service\
                .create_or_update_resource_group(
                        self._resource_group,
                        self._location)

            self._provision_module_validation_dependencies(
                self._module_dependencies)

            for module in module_names:
                self._deploy(self._module_dependencies, module,
                             self._resource_group)

            # Let's prepare to delete resource groups created during the validation process
            self._validation_resource_groups.append(self._resource_group)

            self._logger\
                .info('About to delete the following resource groups: {}'.format(
                self._validation_resource_groups))

            for validation_resource_group in self._validation_resource_groups:
                # After the validation, let's delete the dummy resource group
                self._logger\
                    .info('Deleting the following resource group: {}'.format(
                    validation_resource_group))
                self._management_lock_integration_service\
                    .delete_all_resource_group_locks(
                        validation_resource_group)
                self._resource_management_integration_service\
                    .delete_resource_group(
                        validation_resource_group)

            return list()

        except Exception as ex:
            self._logger.error(
                'There was an unhandled error while provisioning the modules.')
            self._logger.error(ex)
            sys.exit(
                1
            )  # Exit the module as it is not possible to progress the deployment.
            raise ex
    def get_student_wise_gradesheet(self, class_id):
        if class_id is None:
            raise CustomException("Class id is missing")

        results = list(
            self.grades_collection.aggregate([{
                "$match": {
                    "class_id": class_id
                }
            }, {
                "$lookup": {
                    "from": "students",
                    "localField": "student_id",
                    "foreignField": "_id",
                    "as": "student"
                }
            }, {
                "$unwind": {
                    "path": "$student",
                    "preserveNullAndEmptyArrays": False
                }
            }, {
                "$project": {
                    "student_id": "$student._id",
                    "student_name": "$student.name",
                    "_id": 0,
                    "details": "$scores",
                    "total_marks": {
                        "$toInt": {
                            "$sum": "$scores.score"
                        }
                    }
                }
            }, {
                "$sort": {
                    "total_marks": -1
                }
            }]))

        count = len(results)

        for index, student in enumerate(results):
            for score in student['details']:
                score['marks'] = int(score['score'])
                del score['score']

            student['details'].append({
                "marks": student['total_marks'],
                "type": "total"
            })
            del student['total_marks']

            if index < count / 12:
                student['grade'] = 'A'
            elif index < count / 4:
                student['grade'] = 'B'
            elif index < count / 2:
                student['grade'] = 'C'
            else:
                student['grade'] = 'D'

        return {"class_id": class_id, "students": results}
Esempio n. 10
0
    def validate_deployment(self, mode: str, template: dict, parameters: dict,
                            resource_group_name: str, deployment_name: str):
        """Function that validates whether a template is syntactically correct.

        :param mode: Deployment mode
         Values can be Incremental or complete (use: DeploymentMode.incremental or DeploymentMode.complete)
        :type mode: str
        :param template: Template file deserialized
        :type template: dict
        :param parameters: Parameters file deserialized
        :type parameters: dict
        :param resource_group_name: Resource group name to use in the deployment
        :type resource_group_name: str
        :param deployment_name: Deployment name to use
        :type deployment_name: str
        
        :return: Deployment output, if any, otherwise None is returned
        :rtype: dict
        :raises: :class:`Exception`
        """

        try:
            deployment_properties = {
                'mode': mode,
                'template': template,
                'parameters': parameters
            }

            validation_response = \
                self._resource_management_client\
                    .deployments\
                    .validate(
                        resource_group_name,
                        deployment_name,
                        deployment_properties)

            if validation_response.error is not None:
                inner_exception = 'None'

                if validation_response.error.details is not None and\
                    len(validation_response.error.details) > 0 and\
                    validation_response.error.details[0].message is not None:
                    inner_exception = validation_response.error.details[
                        0].message

                if validation_response.error.details is not None and\
                 len(validation_response.error.details) > 0 and\
                 validation_response.error.details[0].details is not None and\
                 len(validation_response.error.details[0].details) > 0 and\
                 validation_response.error.details[0].details[0].message is not None:
                    inner_exception = validation_response.error.details[
                        0].details[0].message

                raise CustomException("ERROR: {}, INNER EXCEPTION: {}".format(
                    validation_response.error, inner_exception))

            self._logger.info('Deployment successfully validated')

        except Exception as e:
            self._logger.error(
                'The following error occurred while checking executing a deployment validation: '
                + str(e))
            self._logger.error(e)
            self._logger.error(validation_response)
            sys.exit(
                1
            )  # Exit the module as it is not possible to progress the deployment.
            raise (e)