Example #1
0
    def get_connections(self, *, provider=None, sort=None, skip=None, limit=None):
        """Returns all the connections

        Args:
            provider (list[str]): Type or list of types to filter for
            sort (str): Field by which the results should be sorted. Ascending by default, descending if prefixed by -
            skip (int): Number of results to skip from the start of the data set.
                Skip is to be used with the limit parameter for paging
            limit (int): How many results should be returned. limit is to be used with the skip parameter for paging
        """

        query_params = {
            'sort': sort,
            'skip': skip,
            'limit': limit
        }
        provider = PySenseUtils.make_iterable(provider)
        resp_json = self.connector.rest_call('get', 'api/v1/connection', query_params=query_params)

        ret_arr = []
        for connection in resp_json:
            connection = PySenseConnection.Connection(self, connection)
            if len(provider) > 0:
                if connection.get_provider() in provider:
                    ret_arr.append(connection)
            else:
                ret_arr.append(connection)
        return ret_arr
Example #2
0
    def remove_shares(self, shares):
        """Unshare a cube to groups and users

        To unshare a cube we have to:
            - Query for the whom the cube is currently shared with
            - Delete the users/groups we want to unshare with
            - Re upload the reduced share

        Args:
            shares (list[Group,User]): Users and groups to unshare the cube to
        """

        curr_shares_arr = self.get_shares_json()
        curr_id_arr = []
        for share in curr_shares_arr:
            curr_id_arr.append(share['partyId'])

        for share in PySenseUtils.make_iterable(shares):
            share_id = share.get_id()
            if share_id is None:
                raise PySenseException.PySenseException(
                    'No id found for {}'.format(share))
            elif share_id in curr_id_arr:
                index = curr_id_arr.index(share_id)
                del curr_shares_arr[index]
                del curr_id_arr[index]

        self.py_client.connector.rest_call(
            'put',
            'api/elasticubes/{}/{}/permissions'.format(
                self.server_address, self.get_title(url_encoded=True)),
            json_payload=curr_shares_arr)
Example #3
0
    def delete_connections(self, connections):
        """Deletes the given PySense connections

        Args:
            connections (list[Connection]): The connections to delete
        """

        for connection in PySenseUtils.make_iterable(connections):
            self.connector.rest_call('delete', 'api/v1/connection/{}'.format(connection.get_oid()))
Example #4
0
    def delete_users(self, users):
        """Deletes the specified users

        Args:
            users: Users to delete
        """

        for user in PySenseUtils.make_iterable(users):
            self.connector.rest_call('delete', 'api/v1/users/{}'.format(user.get_id()))
Example #5
0
    def delete_groups(self, groups):
        """Delete groups.

        Args:
            groups (list[Group]): Groups to delete
        """

        for group in PySenseUtils.make_iterable(groups):
            self.connector.rest_call('delete', 'api/groups/{}'.format(group.get_id()))
Example #6
0
    def add_share(self,
                  shares,
                  rule,
                  subscribe,
                  *,
                  share_cube=True,
                  admin_access=None):
        """Share a dashboard to a new group or user.

        If dashboard is already shared with user or group, nothing happens

        By default gives query permission to the cube as well. Set share_cubes to false to not update cube shares

        Args:
            shares (list[Group,User]): One to many PySense Groups or Users
            rule (str): The permission of the user on the dashboard (view, edit, etc)
            subscribe (bool): Whether to subscribe the user to reports
            share_cube (bool): (Optional) If set to false user will not get dashboard results.
            admin_access (bool): (Optional) Set to true if logged in as admin and getting unowned dashboard
        """

        query_params = {'adminAccess': admin_access}

        curr_shares = self.get_shares_json(admin_access=admin_access)

        for share in PySenseUtils.make_iterable(shares):
            share_id = share.get_id()
            for curr_share in curr_shares['sharesTo']:
                if share_id == curr_share['shareId']:
                    share_id = None

            if share_id is not None:
                if isinstance(share, PySenseUser.User):
                    curr_shares['sharesTo'].append({
                        'shareId': share.get_id(),
                        'type': 'user',
                        'rule': rule,
                        'subscribe': subscribe
                    })
                elif isinstance(share, PySenseGroup.Group):
                    curr_shares['sharesTo'].append({
                        'shareId': share.get_id(),
                        'type': 'group',
                        'rule': rule,
                        'subscribe': subscribe
                    })

        self.py_client.connector.rest_call('post',
                                           'api/shares/dashboard/{}'.format(
                                               self.get_oid()),
                                           json_payload=curr_shares,
                                           query_params=query_params)
        if share_cube:
            data_source = self.get_datasource()
            data_source.add_share(shares)
Example #7
0
    def delete_widget(self, widgets):
        """Deletes widgets from its dashboard.

        Args:
            widgets (list[Widget]): Widgets to delete
        """

        for widget in PySenseUtils.make_iterable(widgets):
            self.py_client.connector.rest_call('delete', 'api/v1/dashboards/{}/widgets/{}'
                                               .format(self.get_oid(), widget.get_oid()))
        self._reset()
Example #8
0
    def remove_user(self, users):
        """Remove users from group

        Args:
            users (list[User]): Users to remove from the group
        """

        payload = []
        for user in PySenseUtils.make_iterable(users):
            payload.append(user.get_id())

        self.py_client.connector.rest_call('delete', 'api/groups/{}/users'.format(self.get_id()), json_payload=payload)
Example #9
0
    def delete_blox_actions(self, actions):
        """Deletes the blox actions

        Args:
            actions (list[BloxAction]): Actions to delete
        """

        for action in PySenseUtils.make_iterable(actions):
            json_payload = {"type": action.get_type()}
            self.connector.rest_call('post',
                                     'api/v1/deleteCustomAction/Blox',
                                     json_payload=json_payload)
Example #10
0
    def delete_data_models(self, data_models):
        """Deletes the given data models

        Args:
            data_models: One to many data models to delete
        """
        PySenseUtils.validate_version(self, SisenseVersion.Version.LINUX,
                                      'delete_data_model')

        for data_model in PySenseUtils.make_iterable(data_models):
            self.connector.rest_call(
                'delete', 'api/v2/datamodels/{}'.format(data_model.get_oid()))
Example #11
0
    def add_user(self, users):
        """Adds users to group.

        Args:
            users (list[User]): The users to add to the group
        """

        payload = []
        for user in PySenseUtils.make_iterable(users):
            payload.append(user.get_id())

        self.py_client.connector.rest_call('post', 'api/groups/{}/users'.format(self.get_id()), json_payload=payload)
Example #12
0
    def add_share(self, shares, *, can_edit=False):
        """Share a cube to new groups and users

        By default will give query access. Set can_edit to True for editor access.

        Args:
            shares (list[Group,User]): Users and groups to share the cube to
            can_edit (bool): (Optional) True for edit privileges
        """

        shares = PySenseUtils.make_iterable(shares)
        curr_shares_arr = self.get_shares_json()
        rule = 'r' if can_edit is False else 'w'
        curr_id_arr = []
        for share in curr_shares_arr:
            party_id = share['partyId']
            curr_id_arr.append(party_id)
            del share['partyId']
            share['party'] = party_id

        for share in shares:
            share_id = share.get_id()
            if share_id is None:
                raise PySenseException.PySenseException(
                    'No id found for {}'.format(share))
            elif share_id in curr_id_arr:
                index = curr_id_arr.index(share_id)
                curr_shares_arr[index]['permission'] = rule
            elif isinstance(share, PySenseUser.User):
                curr_shares_arr.append({
                    'party': share.get_id(),
                    'type': 'user',
                    'permission': rule
                })
            elif isinstance(share, PySenseGroup.Group):
                curr_shares_arr.append({
                    'party': share.get_id(),
                    'type': 'group',
                    'rule': rule
                })
            else:
                raise PySenseException.PySenseException(
                    'Add Share expected User or group, got {}'.format(
                        type(share)))

        self.py_client.connector.rest_call(
            'put',
            'api/elasticubes/{}/{}/permissions'.format(
                self.server_address, self.get_title(url_encoded=True)),
            json_payload=curr_shares_arr)
Example #13
0
    def delete_folders(self, folders):
        """Delete given folders

        Args:
            folders (list[Folder]): Folders to delete
        """

        folder_arr = []
        for folder in PySenseUtils.make_iterable(folders):
            folder_arr.append(folder.get_oid())

        query_params = {"folderIds": ','.join(folder_arr)}
        self.connector.rest_call('delete',
                                 'api/v1/folders/bulk',
                                 query_params=query_params)
Example #14
0
    def add_groups(self, names):
        """Add groups with given names.

        Args:
            names (str): The names of the new groups

        Returns:
            list[Group]: The new groups
        """

        ret_arr = []
        for name in PySenseUtils.make_iterable(names):
            payload = {'name': name}
            resp_json = self.connector.rest_call('post', 'api/v1/groups', json_payload=payload)
            ret_arr.append(PySenseGroup.Group(self, resp_json))
        return ret_arr
Example #15
0
    def update(self,
               *,
               email=None,
               user_name=None,
               first_name=None,
               last_name=None,
               role=None,
               groups=None,
               preferences=None):
        """Updates given fields for user object.

        Args:
            email (str): (Optional) Value to update email to
            user_name (str): (Optional) Value to update username to
            first_name (str): (Optional) Value to update firstName to
            last_name (str): (Optional) Value to update lastName to
            role (Role): (Optional) New role for user
            groups (list[Group]): (Optional) New set of groups for user
            preferences (JSON): (Optional) Preferences to be updated for user
        """

        user_groups = groups if groups is not None else self.get_groups()
        group_arr = []
        for group in PySenseUtils.make_iterable(user_groups):
            group_arr.append(group.get_oid())

        user_json = {
            'email':
            email if email else self.get_email(),
            'userName':
            user_name if user_name else self.get_user_name(),
            'firstName':
            first_name if first_name else self.get_first_name(),
            'lastName':
            last_name if last_name else self.get_last_name(),
            'roleId':
            self.py_client.get_role_id(role) if role else self.get_role_id(),
            'groups':
            group_arr,
            'preferences':
            preferences if preferences else self.get_preferences()
        }
        resp_json = self.py_client.connector.rest_call(
            'patch',
            'api/v1/users/{}'.format(self.get_id()),
            json_payload=user_json)
        self._reset(resp_json)
Example #16
0
    def add_dashboards(self, dashboards):
        """Import given dashboards.

        Args:
            dashboards (list[Dashboard]): Dashboards to import to Sisense

        Returns:
            list[Dashboard]: The new dashboards
        """

        ret_arr = []
        for dashboard in PySenseUtils.make_iterable(dashboards):
            resp = self.connector.rest_call('post',
                                            'api/v1/dashboards',
                                            json_payload=dashboard.json)
            ret_arr.append(PySenseDashboard.Dashboard(self, resp))
        return ret_arr
Example #17
0
    def add_user(self, email, role, *, user_name=None, first_name=None, last_name=None,
                 groups=[], preferences={}, ui_settings={}, password=None):
        """Creates a user in Sisense.

        Args:
            email (str): email address for user
            role (Role): SisenseRole enum for the role of the user
            user_name (str): (Optional) User user name. Email used if None
            first_name (str): (Optional) User first name
            last_name (str): (Optional) User last name
            groups (str): (Optional) The groups to add the user to
            preferences (str): (Optional) User preferences
            ui_settings (JSON): (Optional) User ui settings
            password (str): (Optional) The password to set for the user

        Returns:
             User: Newly created user object
        """

        user_obj = {
            'email': email,
            'username': user_name if user_name is not None else email,
            'roleId': self.get_role_id(role)
        }

        group_ids = []
        for group in PySenseUtils.make_iterable(groups):
            group_ids.append(group.get_id())
        if len(group_ids) > 0:
            user_obj['groups'] = group_ids

        if first_name is not None:
            user_obj['firstName'] = first_name
        if last_name is not None:
            user_obj['lastName'] = last_name
        if preferences is not None:
            user_obj['preferences'] = preferences
        if ui_settings is not None:
            user_obj['uiSettings'] = ui_settings
        if password is not None:
            user_obj['password'] = password

        resp_json = self.connector.rest_call('post', 'api/v1/users', json_payload=user_obj)
        return PySenseUser.User(self, resp_json)
Example #18
0
    def delete_dashboards(self, dashboards, *, admin_access=None):
        """Delete dashboards.

        Args:
            dashboards (list[Dashboard]): Dashboards to delete
            admin_access (bool): (Optional) Set to true if logged in as admin and deleting unowned dashboard
        """

        for dashboard in PySenseUtils.make_iterable(dashboards):
            if admin_access is True:
                query_params = {'adminAccess': admin_access}
                self.connector.rest_call('delete',
                                         'api/dashboards/{}'.format(
                                             dashboard.get_oid()),
                                         query_params=query_params)
            else:
                self.connector.rest_call(
                    'delete',
                    'api/v1/dashboards/{}'.format(dashboard.get_oid()))
Example #19
0
    def get_groups_by_name(self, group_names):
        """Returns an array of groups matching the given names

        Args:
            group_names (list[str]): Group names to look for

        Returns:
            list[Group]: Groups with the given names
        """

        if group_names is None:
            return []

        server_groups = self.get_groups()
        ret = []
        group_names = PySenseUtils.make_iterable(group_names)
        for group in server_groups:
            if group.get_name() in group_names:
                ret.append(group)
        return ret
Example #20
0
    def export_dashboards(self, dashboards, path, *, admin_access=None):
        """Get dashboard as dash file.

        Args:
            dashboards (list[Dashboard]): One to many dashboards to back up to dash file
            path (str): Path to save location of dash file
            admin_access (bool): (Optional) Set to true if logged in as admin and exporting unowned dashboard
        Returns:
            str: The path of the created file
        """

        query_params = {'dashboardIds': [], 'adminAccess': admin_access}
        for dashboard in PySenseUtils.make_iterable(dashboards):
            query_params['dashboardIds'].append(dashboard.get_oid())

        self.connector.rest_call('get',
                                 'api/v1/dashboards/export',
                                 path=path,
                                 query_params=query_params)

        return path
Example #21
0
    def remove_shares(self, shares, *, admin_access=None):
        """Unshare a dashboard to a list of groups and users

        Args:
            shares (list[Group,User]): Groups and users to unshare the dashboard with
            admin_access (bool): (Optional) Set to true if logged in as admin and getting unowned dashboard
        """

        query_params = {
            'adminAccess': admin_access
        }

        share_ids_to_delete = []
        for shares in PySenseUtils.make_iterable(shares):
            share_ids_to_delete.append(shares.get_id())
        current_shares = self.get_shares_json(admin_access=admin_access)
        for share_id in share_ids_to_delete:
            for i, shares in enumerate(current_shares['sharesTo']):
                if shares['shareId'] == share_id:
                    del current_shares['sharesTo'][i]
        self.py_client.connector.rest_call('post', 'api/shares/dashboard/{}'.format(self.get_oid()),
                                           json_payload=current_shares, query_params=query_params)
Example #22
0
    def add_data_security_rule(self,
                               table,
                               column,
                               data_type,
                               *,
                               shares=None,
                               members=None,
                               server_address=None,
                               exclusionary=False,
                               all_members=None):
        """Define a data security rule

        Args:
            table (str): The table to apply security on
            column (str): The column to apply security on
            data_type (str): The data type of the column
            shares (list[Group,User]): (Optional) The users or groups to assign the security rule to.
                If none, will be 'everyone else' rule.
            members (list[str]): (Optional) An array of values which users should have access to
                If left blank, user will get 'Nothing'.
            server_address (str): (Optional) The server address of the ElastiCube.
                Set this to your server ip if this method fails without it set.
                Use 'Set' for Elasticube Set. Required for elasticube sets.
            exclusionary (bool): (Optional) Set to True if exclusionary rule
            all_members (bool): (Optional) Set to True to set 'Everything' rule

        Returns:
             Rule: The new security rule
        """

        server_address = server_address if server_address else self.server_address

        rule_json = [{
            "column": column,
            "datatype": data_type,
            "table": table,
            "elasticube": self.get_title(),
            "server": server_address,
            "exclusionary": exclusionary,
            "allMembers": all_members
        }]

        shares_json = []
        if shares is None:
            # Default rule
            rule_json[0]['shares'] = [{"type": "default"}]
        else:
            for party in PySenseUtils.make_iterable(shares):
                if isinstance(party, PySenseUser.User):
                    shares_json.append({
                        'party': party.get_id(),
                        'type': 'user'
                    })
                elif isinstance(party, PySenseGroup.Group):
                    shares_json.append({
                        'party': party.get_id(),
                        'type': 'group'
                    })
                else:
                    raise PySenseException.PySenseException(
                        '{} is not a user or a group object'.format(party))
            rule_json[0]['shares'] = shares_json

        member_arr = []
        if members is None:
            rule_json[0]['members'] = []
            rule_json[0][
                'allMembers'] = False if all_members is None else all_members
        else:
            rule_json[0]['allMembers'] = None
            for member in members:
                member_arr.append(str(member))
            rule_json[0]['members'] = member_arr
        resp_json = self.py_client.connector.rest_call(
            'post',
            'api/elasticubes/{}/{}/datasecurity'.format(
                server_address, self.get_title(url_encoded=True)),
            json_payload=rule_json)

        return PySenseRule.Rule(self.py_client, resp_json[0])
Example #23
0
    def get_users(self, *, user_name=None, email=None, first_name=None, last_name=None, role=None, group=None,
                  active=None, origin=None, ids=None, fields=[], sort=None, skip=None, limit=None, expand=None):
        """Returns a list of users.

        Results can be filtered by parameters such as username and email.
        The expandable fields for the user object are groups, adgroups and role.

        Args:
            user_name (str): (Optional) Username to filter by
            email (str): (Optional) Email to filter by
            first_name (str): (Optional) First name to filter by
            last_name (str): (Optional) Last name to filter by
            role (Role): (Optional) SisenseRole enum for the role of the user to filter by
            group (Group): (Optional) Group to filter by
            active (bool): (Optional) User state to filter by (true for active users, false for inactive users)
            origin (str): (Optional) User origin to filter by (ad for active directory or sisense)
            ids (list[str]): (Optional) User ids to get
            fields (list[str]): (Optional) An array of fields to return for each document.
                Fields can also define which fields to exclude by prefixing field names with -
            sort (str): (Optional) Field by which the results should be sorted.
                Ascending by default, descending if prefixed by -
            skip (int): (Optional) Number of results to skip from the start of the data set.
                Skip is to be used with the limit parameter for paging
            limit (int): (Optional) How many results should be returned.
                limit is to be used with the skip parameter for paging
            expand (list[str]): (Optional) List of fields that should be expanded
                May be nested using the resource.subResource format

        Returns:
             list[User]: Users found
        """

        fields = PySenseUtils.make_iterable(fields)

        # Ensure we get the fields we need to manage the user even if fields is set
        fields.extend(
            ['_id', 'lastLogin', 'groups', 'email', 'userName', 'firstName', 'lastName', 'roleId', 'preferences']
        )

        fields = list(dict.fromkeys(fields))
        query_params = {
            'userName': user_name,
            'email': email,
            'firstName': first_name,
            'lastName': last_name,
            'role': self.get_role_id(role),
            'group': None if group is None else group.get_id(),
            'active': active,
            'origin': origin,
            'ids': ids,
            'fields': fields,
            'sort': sort,
            'skip': skip,
            'limit': limit,
            'expand': expand
        }
        ret_arr = []
        resp_json = self.connector.rest_call('get', 'api/v1/users', query_params=query_params)
        for user in resp_json:
            ret_arr.append((PySenseUser.User(self, user)))
        return ret_arr
Example #24
0
    def update_rule(self,
                    *,
                    table=None,
                    column=None,
                    data_type=None,
                    shares='',
                    members='',
                    exclusionary='',
                    all_members=''):
        """Updates the current rule.

        Any arguments given will replace the current value and update the rule in place

        Args:
            shares (list[User,Group]): (Optional) Array of users and groups to share the rule with
            table (str): (Optional) Table of the data security rule
            column (str): (Optional) Column of the data security rule
            data_type (str): (Optional) Data security rule data type
            members (list[str]): (Optional) The values to specify in the rule. If blank, will use nothing
            exclusionary (bool): (Optional) Set to true to make an exclusionary rule
            all_members (bool): (Optional) Set to true for a rule to allow user to see all values
        """

        rule_json = {
            "column":
            column if column is not None else self.get_column(),
            "datatype":
            data_type if data_type is not None else self.get_data_type(),
            "table":
            table if table is not None else self.get_table(),
            "exclusionary":
            exclusionary if exclusionary != '' else self.get_exclusionary(),
            "allMembers":
            all_members if all_members != '' else self.get_all_members(),
        }
        shares_json = []
        if shares != '':
            for party in PySenseUtils.make_iterable(shares):
                if isinstance(party, PySenseUser.User):
                    shares_json.append({
                        'party': party.get_id(),
                        'type': 'user'
                    })
                elif isinstance(party, PySenseGroup.Group):
                    shares_json.append({
                        'party': party.get_id(),
                        'type': 'group'
                    })
            rule_json['shares'] = shares_json
        else:
            rule_json['shares'] = self.get_shares_json()

        if members != '':
            if members is None:
                rule_json['members'] = []
                rule_json[
                    'allMembers'] = False if all_members == '' else all_members
            else:
                member_arr = []
                for member in PySenseUtils.make_iterable(members):
                    member_arr.append(str(member))
                rule_json['members'] = member_arr
                rule_json['allMembers'] = None
        else:
            rule_json['members'] = self.get_members()

        resp_json = self.py_client.connector.rest_call(
            'put',
            'api/elasticubes/datasecurity/{}'.format(self.get_id()),
            json_payload=rule_json)
        self._reset(resp_json)
Example #25
0
Sample script for building data models in sequence.

Linux only

To use this script update the following values:
- wait_time_seconds: How often to poll for the current build status
- build_type: The build type to perform (schema_changes, by_table, full, publish)

Sample Config: https://github.com/nathangiusti/PySense/blob/master/Snippets/SampleConfig.yaml
"""
import time

from PySense import PySense
from PySense import PySenseUtils

config_file_location = 'path//SampleConfig.yaml'
wait_time_seconds = 5
build_type = 'full'

py_client = PySense.authenticate_by_file(config_file_location)

data_models = py_client.get_data_models()

for data_model in PySenseUtils.make_iterable(data_models):
    build_task = data_model.start_build(build_type)
    print('Building data model {}'.format(data_model.get_title()))
    while build_task.get_status() not in ['done', 'failed']:
        time.sleep(wait_time_seconds)
    print('{} build status: {}'.format(data_model.get_title(), build_task.get_status()))