Esempio n. 1
0
    def __init__(self,
                 connection: "Connection",
                 name: str = None,
                 id: str = None) -> None:
        """Initialize UserGroup object by passing name or id.

        Args:
            connection: MicroStrategy connection object returned
                by `connection.Connection()`
            name: name of User Group
            id: ID of User Group
        """
        if id is None and name is None:
            helper.exception_handler(
                "Please specify either 'name' or 'id' parameter in the constructor."
            )

        if id is None:
            user_groups = UserGroup._get_usergroup_ids(connection=connection,
                                                       name_begins=name,
                                                       name=name)
            if user_groups:
                id = user_groups[0]
            else:
                helper.exception_handler(
                    "There is no User Group with the given name: '{}'".format(
                        name),
                    exception_type=ValueError)
        super().__init__(connection=connection, object_id=id)
Esempio n. 2
0
 def _list_all(cls,
               connection: "Connection",
               name: str = None,
               to_dictionary: bool = False,
               to_dataframe: bool = False,
               limit: int = None,
               **filters) -> Union[List["Document"], List[dict]]:
     msg = "Error retrieving documents from the environment."
     if to_dictionary and to_dataframe:
         helper.exception_handler(
             "Please select either `to_dictionary=True` or `to_dataframe=True`, but not both.",
             ValueError)
     objects = helper.fetch_objects_async(
         connection,
         api=documents.get_documents,
         async_api=documents.get_documents_async,
         dict_unpack_value='result',
         limit=limit,
         chunk_size=1000,
         error_msg=msg,
         filters=filters,
         search_term=name)
     if to_dictionary:
         return objects
     elif to_dataframe:
         return DataFrame(objects)
     else:
         return cls._from_bulk_response(connection, objects)
Esempio n. 3
0
    def __definition(self):
        """Get the definition of a report, including attributes and metrics. Implements GET /v2/reports/<report_id>"""

        res = reports.report_definition(connection=self._connection, report_id=self._report_id)

        definition = res.json()
        grid = definition["definition"]["grid"]
        if version.parse(self._connection.iserver_version) >= version.parse("11.2.0100"):
            self._subtotals = grid["subtotals"]

        self._name = definition["name"]
        self.cross_tab = grid["crossTab"]
        available_objects = definition['definition']['availableObjects']

        # Check if report have custom groups or consolidations
        if available_objects['customGroups']:
            helper.exception_handler(msg="Reports with custom groups are not supported.", exception_type=ImportError)
        if available_objects['consolidations']:
            helper.exception_handler(msg="Reports with consolidations are not supported.", exception_type=ImportError)

        metrics_position = grid["metricsPosition"]
        full_metrics = grid[metrics_position["axis"]][metrics_position["index"]]["elements"]

        full_attributes = []
        for elem in grid["rows"]:
            if elem["type"] == "attribute":
                full_attributes.append(elem)
        for elem in grid["columns"]:
            if elem["type"] == "attribute":
                full_attributes.append(elem)

        self._attributes = [{'name': attr['name'], 'id': attr['id']} for attr in full_attributes]
        self._metrics = [{'name': metr['name'], 'id': metr['id']} for metr in full_metrics]
Esempio n. 4
0
 def __already_recipient(recipient):
     if recipient in exisiting_recipients:
         helper.exception_handler(
             f"{recipient} is already a recipient of subscription",
             UserWarning)
     else:
         ready_recipients.append(recipient)
Esempio n. 5
0
    def __prepare_recipients(self, recipients):

        exisiting_recipients = [rec['id'] for rec in self.recipients]
        ready_recipients = []

        def __already_recipient(recipient):
            if recipient in exisiting_recipients:
                helper.exception_handler(
                    f"{recipient} is already a recipient of subscription",
                    UserWarning)
            else:
                ready_recipients.append(recipient)

        for recipient in recipients:
            not_dict_msg = """Wrong recipient format, expected format is
                              {"id": recipient_id,
                               "type": "CONTACT_GROUP" / "USER_GROUP" / "CONTACT" /
                                       "USER" / "PERSONAL_ADDRESS" / "UNSUPPORTED"
                               "includeType": "TO" / "CC" / "BCC" (optional)
                              }"""
            if isinstance(recipient, dict):
                if list(recipient.keys()) in [['id', 'type', 'includeType'],
                                              ['id', 'type']]:
                    __already_recipient(recipient['id'])
                else:
                    helper.exception_handler(not_dict_msg, TypeError)
            if isinstance(recipient, str):
                __already_recipient(recipient)
        return ready_recipients
Esempio n. 6
0
    def __multitable_definition(self):
        """Return all tables names and columns as a dictionary"""
        if not self._table_definition:
            try:
                res_tables = datasets.dataset_definition(
                    connection=self._connection,
                    dataset_id=self._cube_id,
                    fields=['tables', 'columns'])
                _ds_definition = res_tables.json()

                for table in _ds_definition['result']['definition'][
                        'availableObjects']['tables']:
                    column_list = [
                        column['columnName']
                        for column in _ds_definition['result']['definition']
                        ['availableObjects']['columns']
                        if table['name'] == column['tableName']
                    ]
                    self._table_definition[table['name']] = column_list
            except:
                helper.exception_handler(
                    "Some functionality is not available with this type of cube at the moment.",
                    throw_error=False,
                    exception_type=Warning,
                    stack_lvl=3)
        return self._table_definition
Esempio n. 7
0
    def is_loaded(self,
                  application_id: str = None,
                  application_name: str = None) -> bool:
        """Check if application is loaded, by passing application ID or name,
        returns True or False.

        Args:
            application_id: Application ID
            application_name: Application name
        """
        if application_id is None and application_name is None:
            helper.exception_handler(
                "Please specify either 'application_name' or 'application_id' argument."
            )
        if application_id is None:
            app_list = Application._list_application_ids(self.connection,
                                                         name=application_name)
            application_id = app_list[
                0] if app_list else helper.exception_handler(
                    "There is no application with the given name: '{}'".format(
                        application_name),
                    exception_type=ValueError)

        nodes = self.list_nodes(application_id=application_id)
        loaded = False
        for node in nodes:
            status = node['projects'][0]['status']
            loaded = True if status == 'loaded' else False
            if loaded:
                break
        return loaded
Esempio n. 8
0
    def __init__(self,
                 connection: "Connection",
                 name: str = None,
                 id: str = None):
        """Initialize Security Role object by passing name or id.

        Args:
            connection: MicroStrategy connection object returned
                by `connection.Connection()`.
            name: name of Security Role
            id: ID of Security Role
        """
        # initialize either by ID or name
        if id is None and name is None:
            helper.exception_handler(
                "Please specify either 'name' or 'id' parameter in the constructor.",
                ValueError)

        if id is None:
            security_roles = SecurityRole._list_security_role_ids(
                connection=connection, name=name)
            if security_roles:
                id = security_roles[0]
            else:
                helper.exception_handler(
                    "There is no Security Role associated with the given name: '{}'"
                    .format(name),
                    exception_type=ValueError)
        super().__init__(connection=connection, object_id=id, name=name)
Esempio n. 9
0
    def revoke_from(self, members: Union[List[str], List["User"],
                                         List["UserGroup"]],
                    application: Union["Application", str]) -> None:
        """Remove users/usergroups from a Security Role.

        Args:
            members(list): List of objects or IDs of Users or User Groups
                which will be removed from this Security Role.
            application(Application, str): Application object or name
                to which this removal will apply.
        """
        from mstrio.admin.application import Application
        from mstrio.admin.user import User
        from mstrio.admin.usergroup import UserGroup

        if isinstance(application, Application):
            application_id = application.id
            application_name = application.name
        elif isinstance(application, str):
            application_list = Application._list_applications(
                connection=self.connection,
                to_dictionary=True,
                name=application)
            if application_list:
                application_id = application_list[0]['id']
                application_name = application_list[0]['name']
            else:
                helper.exception_handler(
                    "Application name '{}' does not exist.".format(
                        application))
        else:
            helper.exception_handler(
                "Application parameter must be of type str or Application.")

        # create list of objects from strings/objects/lists
        members_list = members if isinstance(members, list) else [members]
        members_list = [
            obj.id if isinstance(obj, (User, UserGroup)) else str(obj)
            for obj in members_list
        ]

        existing_ids = [
            obj['id']
            for obj in self.list_members(application_name=application_name)
        ]
        succeeded = list(set(members_list).intersection(set(existing_ids)))
        failed = list(set(members_list) - set(succeeded))

        value = {"projectId": application_id, "memberIds": members_list}
        self._update_nested_properties(objects=value,
                                       path="members",
                                       op='remove')

        if succeeded:
            if config.verbose:
                print("Revoked Security Role '{}' from {}".format(
                    self.name, succeeded))
        if failed and config.verbose:
            print("Security Role '{}' does not have member(s) {}".format(
                self.name, failed))
Esempio n. 10
0
    def get_task(self, task_index: int) -> "SchemaTask":
        """Get all details of the task which is stored at a given
        `task_index` in a list from property `tasks`.

        Args:
            task_index (int): Index of the task in the list stored in property
                `tasks`.

        Returns:
            `SchemaTask` object with all details about the task from the given
            index. When index is not proper then `None` is returned and warning
            with explanation message is shown.
        """
        try:
            task_id = self.tasks[task_index].id
        except IndexError:
            msg = (
                f"Cannot get task with index {task_index} from the list of tasks for this "
                "schema management object. Check the list using property `tasks`."
            )
            exception_handler(msg, Warning)
            return

        res = schema.read_task_status(self.connection, task_id,
                                      self.project_id)
        return self._save_task(res.json())
Esempio n. 11
0
def remove_subscription(connection,
                        subscription_id,
                        project_id,
                        error_msg=None,
                        exception_type=None):
    """Remove (Unsubscribe) the subscription using subscription id.

    Args:
        connection(object): MicroStrategy connection object returned by
            `connection.Connection()`.
        subscription_id(str): ID of the subscription
        project_id(str): ID of the project
        error_msg(str, optional): Customized error message.
        exception_type (Exception): Instance of Exception or Warning class

    Returns:
        HTTP response object returned by the MicroStrategy REST server.
    """
    response = connection.session.delete(
        url=connection.base_url + '/api/subscriptions/' + subscription_id,
        headers={'X-MSTR-ProjectID': project_id})
    if config.debug:
        print(response.url)
    if not response.ok:
        if error_msg is None:
            error_msg = "Error unsubscribing Subscription {}".format(
                subscription_id)
        if exception_type is None:
            response_handler(response, error_msg)
        else:
            exception_handler(error_msg, exception_type)
    return response
Esempio n. 12
0
    def perform_full_migration(self) -> bool:
        """Perform 'create_package()' and 'migrate_package()' using
        configuration provided when creating `Migration` object.
        """
        if not isinstance(self.source_connection,
                          Connection) or self.source_connection is None:
            exception_handler(
                msg=("Migration object missing `source_connection`. "
                     "`perform_full_migration()` unavailable."),
                exception_type=AttributeError)
        if not isinstance(self.target_connection,
                          Connection) or self.target_connection is None:
            exception_handler(
                msg=("Migration object missing `target_connection`. "
                     "`perform_full_migration()` unavailable."),
                exception_type=AttributeError)

        self._display_progress_bar(
            desc='Migration status: ',
            unit='Migration',
            total=4,
            bar_format='{desc} |{bar:50}| {percentage:3.0f}%')

        if not self.create_package():
            return False

        if not self.migrate_package():
            return False

        self._close_progress_bar()
        return True
Esempio n. 13
0
    def __init__(self,
                 connection: "Connection",
                 name: Optional[str] = None,
                 id: Optional[str] = None) -> None:
        """Initialize DatasourceInstance object by passing name or id.

        To explore all available DatasourceInstance objects use the
        `list_datasource_instance()` method.

        Args:
            connection: MicroStrategy connection object returned by
                `connection.Connection()`.
            name: exact name of Datasource Instance
            id: ID of Datasource Instance
        """
        if id is None and name is None:
            helper.exception_handler(
                "Please specify either 'id' or 'name' parameter in the constructor."
            )

        if id is None:
            objects_info = DatasourceInstance._list_datasource_instances(
                connection=connection, name=name, to_dictionary=True)
            if objects_info:
                object_info, object_info["connection"] = objects_info[
                    0], connection
                self._init_variables(**object_info)
            else:
                helper.exception_handler(
                    f"There is no Datasource Instance: '{name}'",
                    exception_type=ValueError)
        else:
            super().__init__(connection=connection, object_id=id)
Esempio n. 14
0
    def save_as(self, name, description=None, folder_id=None, table_name=None):
        """Creates a new single-table cube with the data frame stored in the
        Cube instance (cube.dataframe).

        Before the update, make sure that the data exists.
        Args:
            name(str): Name of cube.
            description(str): Description of the cube.
            folder_id (str, optional): ID of the shared folder that the dataset
                should be created within. If `None`, defaults to the user's
                My Reports folder.
            table_name (str, optional): Name of the table. If None (default),
                the first table name of the original cube will be used.
        """
        if len(self._tables) > 1:
            helper.exception_handler(
                msg="""This feature works only for the single-table cubes.
                                            \rTo export multi-table cube use Dataset class."""
            )
        else:
            if table_name is None:
                table_name = self._tables[0]["name"]

            dataset = Dataset(self._connection,
                              name=name,
                              description=description)
            dataset.add_table(name=table_name,
                              data_frame=self.dataframe,
                              update_policy="add")
            dataset.create(folder_id=folder_id)
Esempio n. 15
0
    def _list_security_roles(
        cls,
        connection: "Connection",
        to_dictionary: bool = False,
        to_dataframe: bool = False,
        limit: int = None,
        **filters
    ) -> Union[List["SecurityRole"], List[Dict[str, Any]], DataFrame]:
        if to_dictionary and to_dataframe:
            helper.exception_handler(
                "Please select either to_dictionary=True or to_dataframe=True, but not both.",
                ValueError)

        objects = helper.fetch_objects(
            connection=connection,
            api=security.get_security_roles,
            limit=limit,
            filters=filters,
        )
        if to_dictionary:
            return objects
        elif to_dataframe:
            return DataFrame(objects)
        else:
            return [
                cls.from_dict(source=obj, connection=connection)
                for obj in objects
            ]
Esempio n. 16
0
    def revoke_privilege(self, privilege: Union[str, List[str], "Privilege",
                                                List["Privilege"]]) -> None:
        """Revoke directly granted User Group privileges.

        Args:
            privilege: List of privilege objects, ids or names
        """
        from mstrio.access_and_security.privilege import Privilege
        privileges = set(
            [priv['id'] for priv in Privilege._validate_privileges(self.connection, privilege)])
        existing_ids = [
            privilege['privilege']['id'] for privilege in self.list_privileges(mode='ALL')
        ]
        directly_granted = set(
            [privilege['privilege']['id'] for privilege in self.list_privileges(mode='GRANTED')])
        to_revoke = list(privileges.intersection(directly_granted))
        not_directly_granted = list(
            (set(existing_ids) - directly_granted).intersection(privileges))

        if not_directly_granted:
            msg = (f"Privileges {sorted(not_directly_granted)} are inherited and will be "
                   "ommited. Only directly granted privileges can be revoked by this method.")
            helper.exception_handler(msg, exception_type=Warning)

        succeeded, failed = self._update_nested_properties(to_revoke, "privileges", "remove",
                                                           existing_ids)
        if succeeded:
            self.fetch('privileges')  # fetch the object privileges
            if config.verbose:
                print("Revoked privilege(s) {} from '{}'".format(succeeded, self.name))
        if failed and config.verbose:
            print("User group '{}' does not have privilege(s) {}".format(self.name, failed))
Esempio n. 17
0
    def _list_applications(cls,
                           connection: "Connection",
                           to_dictionary: bool = False,
                           limit: int = None,
                           **filters) -> List["Application"]:
        msg = "Error getting information for a set of Applications."
        objects = helper.fetch_objects_async(connection,
                                             monitors.get_projects,
                                             monitors.get_projects_async,
                                             dict_unpack_value='projects',
                                             limit=limit,
                                             chunk_size=50,
                                             error_msg=msg,
                                             filters=filters)
        if to_dictionary:
            return objects
        else:
            apps = cls._from_bulk_response(connection, objects)
            apps_loaded = Application._list_loaded_applications(
                connection, to_dictionary=True)
            apps_loaded_ids = [app['id'] for app in apps_loaded]
            unloaded = [app for app in apps if app.id not in apps_loaded_ids]

            if unloaded:
                msg = "Applications {} are either unloaded or idled. Change status using the 'load()' or 'resume()' method to use all functionality.".format(
                    [app.name for app in unloaded])
                helper.exception_handler(msg, exception_type=UserWarning)
            return apps
Esempio n. 18
0
    def update_acl(self,
                   op: str,
                   rights: int,
                   ids: List[str],
                   propagate_to_children: bool = None,
                   denied: bool = None,
                   inheritable: bool = None):
        """Updates the access control list for this entity, performs operation
        defined by the `op` parameter on all objects from `ids` list.

        Args:
            op (str): ACL update operator, available values are "ADD",
                "REMOVE" and "REPLACE"
            rights (int): value of rights to use by the operator
            ids (list of str): list of ids to update the acl on
            propagate_to_children (optional, bool): used for folder objects
                only,  default value is None, if set to True/False adds
                `propagateACLToChildren` keyword to the request body
                and sets its value accordingly
        """

        # TODO move (op, rights, ids, propagate_to_children=None,
        #                    denied=None, inheritable=None, types=None) to separate AccesControlEntry class
        if op not in ["ADD", "REMOVE", "REPLACE"]:
            helper.exception_handler(
                "Wrong ACL operator passed. Please use ADD, REMOVE or REPLACE")

        if rights not in range(256) and rights not in range(
                536_870_912, 536_871_168):
            helper.exception_handler(
                "Wrong `rights` value, please provide value in range 0-255, or to control inheritability use value 536870912"
            )
Esempio n. 19
0
    def is_loaded(self,
                  project_id: Optional[str] = None,
                  project_name: Optional[str] = None) -> bool:
        """Check if project is loaded, by passing project ID or name,
        returns True or False.

        Args:
            project_id: Project ID
            project_name: Project name
        """
        if project_id is None and project_name is None:
            helper.exception_handler(
                "Please specify either 'project_name' or 'project_id' argument."
            )
        if project_id is None:
            project_list = Project._list_project_ids(self.connection,
                                                     name=project_name)
            if project_list:
                project_id = project_list[0]
            else:
                msg = f"There is no project with the given name: '{project_name}'"
                raise ValueError(msg)

        nodes = self.list_nodes(project=project_id)
        loaded = False
        for node in nodes:
            status = node['projects'][0]['status']
            loaded = True if status == 'loaded' else False
            if loaded:
                break
        return loaded
Esempio n. 20
0
    def __init__(self,
                 connection: Connection,
                 id: str = None,
                 name: str = None) -> None:
        """Initialize the Schedule object, populates it with I-Server data.

        Args:
            connection: MicroStrategy connection object returned
                by `connection.Connection()`.
            id: Schedule ID
            name: Schedule name
        """

        if id is None and name is None:
            helper.exception_handler(
                "Please specify either 'name' or 'id' parameter in the constructor."
            )
        if id is None:
            sm = ScheduleManager(connection)
            schedule = sm.list_schedules(name=name)
            if schedule:
                id = schedule[0]['id']
            else:
                helper.exception_handler(
                    "There is no schedule with the given name: '{}'".format(
                        name),
                    exception_type=ValueError)

        self.connection = connection
        self.id = id
        self.__fetch()
Esempio n. 21
0
    def _migrate_package(self,
                         binary: bytes,
                         is_undo: bool = False,
                         custom_package_path: Optional[str] = None) -> bool:
        if binary is None:
            exception_handler(
                msg=("Import package is None. Run `create_package()` first, "
                     "or specify `custom_package_path`."),
                exception_type=AttributeError)

        self.__private_status = MigrationStatus.MIGRATION_IN_PROGRESS
        self._create_package_holder(self.target_connection)
        self._upload_package_binary(binary)
        if not self._create_import(self.target_connection):
            self.__private_status = MigrationStatus.MIGRATION_FAILED
            return False

        if not is_undo and self.create_undo:
            self._download_undo_binary()
            file_path = custom_package_path if custom_package_path else self.save_path
            filename, file_extension = self._decompose_file_path(file_path)
            self._save_package_binary_locally(filename=f"{filename}_undo",
                                              file_extension=file_extension,
                                              _bytes=self.undo_binary)

        self._delete_package_holder()
        self._delete_import()

        self.__private_status = MigrationStatus.MIGRATION_COMPLETED
        return True
Esempio n. 22
0
    def migrate_package(self,
                        custom_package_path: Optional[str] = None,
                        is_undo=False) -> bool:
        """Performs migration of already created package to the target
        environment. Import package will be loaded from `custom_package_path`.
        If `custom_package_path` not provided, the object previously acquired
        with the `create_package()` will be used.
        If `create_undo` parameter is set to True, package needed for undo
        process will be downloaded.

        Raises AttributeError if `target_connection` is not specified.
        """

        if not isinstance(self.target_connection,
                          Connection) or self.target_connection is None:
            exception_handler(
                msg=("Migration object does not have `target_connection`. "
                     "Export unavailable."),
                exception_type=AttributeError)

        if custom_package_path and self._check_file_path(
                custom_package_path, "custom_package_path"):
            self.save_path = custom_package_path
            filename, file_extension = self._decompose_file_path(
                custom_package_path)
            with open(f"{filename}{file_extension}", "rb") as f:
                return self._migrate_package(f.read(), is_undo=is_undo)
        return self._migrate_package(self._package_binary,
                                     custom_package_path=custom_package_path,
                                     is_undo=is_undo)
Esempio n. 23
0
    def _validate_settings(self, settings: dict = None, bad_setting=Warning, bad_type=Warning,
                           bulk_error=True) -> None:
        """Validate setting-value pairs and raise AttributeError or TypeError
        if invalid. If `bad_setting` or `bad_type` is of type Exception, then
        Exception is raised as soon as the first invalid pair is found. If they
        are of type Warning the validation will continue and not raise error.

        Raises:
            ValueError if `bulk_error` True, tries to evaluate all settings.
        """
        settings = settings if settings else self.list_properties(show_names=False)
        bad_settings_keys = []

        for setting, value in settings.items():
            if setting not in self._CONFIG.keys():
                msg = "Setting '{}' is not supported.".format(setting)
                helper.exception_handler(msg, bad_setting)
                bad_settings_keys.append((setting, value))
            else:
                setting_obj = getattr(self, setting)
                if isinstance(setting_obj, DeprecatedSetting):
                    continue
                else:
                    valid = setting_obj._validate_value(value, exception=not bulk_error)
                    if not valid:
                        bad_settings_keys.append((setting, value))
        if bulk_error and bad_settings_keys:
            helper.exception_handler(
                "Invalid settings: {}".format(
                    [item[0] + ': ' + str(item[1]) for item in bad_settings_keys]),
                exception_type=ValueError)
Esempio n. 24
0
    def list_privileges(cls, connection: Connection, to_dictionary: bool = False,
                        to_dataframe: bool = False,
                        **filters) -> Union[List["Privilege"], List[dict], DataFrame]:
        """Get list of privilege objects or privilege dicts. Filter the
        privileges by specifying the `filters` keyword arguments.

        Optionally use `to_dictionary` or `to_dataframe` to choose output
        format.

        Args:
            connection: MicroStrategy connection object returned by
                `connection.Connection()`.
            to_dictionary: If `True` returns dict, by default (False) returns
                User objects.
            to_dataframe: If `True`, returns `DataFrame`.
            **filters: Available filter parameters: ['id', 'name',
                'description', 'categories', 'is_project_level_privilege']

        Examples:
            >>> Privilege.list_privileges(connection, to_dataframe=True,
            >>>                           is_project_level_privilege='True',
            >>>                           id=[1,2,3,4,5])
        """
        if to_dictionary and to_dataframe:
            helper.exception_handler(
                "Please select either `to_dictionary=True` or `to_dataframe=True`, but not both.",
                ValueError)
        objects = helper.fetch_objects(connection=connection, api=security.get_privileges,
                                       limit=None, filters=filters)
        if to_dictionary:
            return objects
        elif to_dataframe:
            return DataFrame(objects)
        else:
            return [cls.from_dict(source=obj, connection=connection) for obj in objects]
Esempio n. 25
0
 def _list_all(cls,
               connection: Connection,
               name: Optional[str] = None,
               to_dictionary: bool = False,
               to_dataframe: bool = False,
               limit: Optional[int] = None,
               **filters) -> Union[List["Dossier"], List[dict], DataFrame]:
     msg = "Error retrieving documents from the environment."
     if to_dictionary and to_dataframe:
         helper.exception_handler(
             "Please select either to_dictionary=True or to_dataframe=True, but not both.",
             ValueError)
     objects = helper.fetch_objects_async(
         connection,
         api=documents.get_dossiers,
         async_api=documents.get_dossiers_async,
         dict_unpack_value='result',
         limit=limit,
         chunk_size=1000,
         error_msg=msg,
         filters=filters,
         search_term=name)
     if to_dictionary:
         return objects
     elif to_dataframe:
         return DataFrame(objects)
     else:
         return [
             cls.from_dict(source=obj, connection=connection)
             for obj in objects
         ]
Esempio n. 26
0
    def __init__(self,
                 connection: Connection,
                 name: Optional[str] = None,
                 id: Optional[str] = None) -> None:
        """Initialize UserGroup object by passing `name` or `id`. When `id` is
        provided (not `None`), `name` is omitted.

        Args:
            connection: MicroStrategy connection object returned
                by `connection.Connection()`
            name: name of User Group
            id: ID of User Group
        """
        if id is None and name is None:
            helper.exception_handler(
                "Please specify either 'name' or 'id' parameter in the constructor."
            )

        if id is None:
            user_groups = UserGroup._get_user_group_ids(connection=connection,
                                                        name_begins=name,
                                                        name=name)
            if user_groups:
                id = user_groups[0]
            else:
                helper.exception_handler(
                    f"There is no User Group with the given name: '{name}'",
                    exception_type=ValueError)
        super().__init__(connection=connection, object_id=id, name=name)
Esempio n. 27
0
    def _select(self, object_id):
        attr_form_object_id = None
        if isinstance(object_id, list):
            for i in set(object_id):
                self._select(object_id=i)
        else:
            # object_id = object_id.split(";")
            # if isinstance(object_id, list):
            if len(object_id) > 32 and object_id[32] == ';':
                attr_form_object_id = [object_id[:32], object_id[33:]]
                object_id = attr_form_object_id[0]

            if self.__invalid(object_id):
                raise ValueError(self.err_msg_invalid.format(object_id))
            if self.__duplicated(object_id):
                helper.exception_handler(msg=self.err_msg_duplicated.format(object_id),
                                         exception_type=Warning)
            else:
                typ = self.__type(object_id)

                if typ == "attribute":
                    if attr_form_object_id:
                        self.attr_selected.append(attr_form_object_id)
                    else:
                        self.attr_selected.append([object_id])

                if typ == "metric":
                    self.metr_selected.append(object_id)
Esempio n. 28
0
 def dataframe(self):
     if self._dataframe is None:
         helper.exception_handler(
             msg=
             "Dataframe not loaded. Retrieve with Report.to_dataframe().",
             exception_type=Warning)
     return self._dataframe
Esempio n. 29
0
 def __init__(self,
              id: str,
              action: Union[Action, str] = Action.USE_EXISTING,
              name: Optional[str] = None,
              version: Optional[str] = None,
              type: Optional[ObjectTypes] = None,
              owner: Optional[Owner] = None,
              date_created: Optional[str] = None,
              date_modified: Optional[str] = None,
              include_dependents: Optional[bool] = None,
              explicit_included: Optional[bool] = None,
              level: Optional[Union[Level, str]] = None):
     self.id = id
     self.name = name
     self.version = version
     self.type = type
     self.owner = owner
     self.date_created = date_created
     self.date_modified = date_modified
     self.include_dependents = include_dependents
     self.explicit_included = explicit_included
     try:
         self.level = PackageContentInfo.Level(level) if isinstance(
             level, str) else level
         self.action = PackageContentInfo.Action(action) if isinstance(
             action, str) else action
     except ValueError:
         exception_handler(msg="Wrong enum value",
                           exception_type=ValueError)
Esempio n. 30
0
    def disconnect_users(self,
                         connection_ids: Union[str, List[str]] = None,
                         users: Union[List["User"], List[str]] = None,
                         nodes: Union[str, List[str]] = None,
                         force: bool = False,
                         **filters) -> None:
        """Disconnect user connections by passing in users (objects) or
        connection_ids. Optionally disconnect users by specifying the `filters`
        keyword arguments.

        Args:
            connection_ids: chosen ids that can be retrieved with
                `list_connections()`
            users: List of User objects or usernames
            nodes: Node (server) names on which users will be disconnected
            force: if True, no additional prompt will be showed before
                disconnecting users
            **filters: Available filter parameters: ['id', 'parent_id',
                'username', 'user_full_name', 'project_index', 'project_id',
                'project_name', 'open_jobs_count', 'application_type',
                'date_connection_created', 'duration', 'session_id', 'client',
                'config_level']
        """
        from mstrio.admin.user import User  # import here to avoid circular imports

        if self.connection and not connection_ids and not users and not filters and not force:
            helper.exception_handler(
                "You need to pass connection_ids or users or specify filters. To disconnect all connections use `disconnect_all_users()` method."
            )

        if connection_ids:
            # disconnect specific user connections without fetching connections
            self.__disconnect_by_connection_id(connection_ids)
        else:
            # get all user connections to filter locally
            all_connections = self.list_connections(nodes, **filters)
            if users:  # filter user connections by user objects
                users = users if isinstance(users, list) else [users]
                usernames = []
                for user in users:
                    if isinstance(user, User):
                        usernames.append(user.username)
                    elif isinstance(user, str):
                        usernames.append(user)
                    else:
                        helper.exception_handler(
                            "'user' param must be a list of User objects or usernames.",
                            exception_type=TypeError)

                all_connections = list(
                    filter(lambda conn: conn['username'] in usernames,
                           all_connections))

            if all_connections:
                # extract connection ids and disconnect
                connection_ids = [conn['id'] for conn in all_connections]
                self.__disconnect_by_connection_id(connection_ids)
            elif config.verbose:
                print("Selected user(s) do not have any active connections")