diff --git a/tableauserverclient/models/property_decorators.py b/tableauserverclient/models/property_decorators.py index f1625d112..d7b7301cd 100644 --- a/tableauserverclient/models/property_decorators.py +++ b/tableauserverclient/models/property_decorators.py @@ -69,7 +69,7 @@ def wrapper(self, value): return wrapper -def property_is_int(range, allowed=None): +def property_is_int(valid_int_range, allowed=None): '''Takes a range of ints and a list of exemptions to check against when setting a property on a model. The range is a tuple of (min, max) and the allowed list (empty by default) allows values outside that range. @@ -86,15 +86,15 @@ def property_type_decorator(func): def wrapper(self, value): error = "Invalid property defined: '{}'. Integer value expected.".format(value) - if range is None: + if value in allowed: + return func(self, value) + if valid_int_range is None: if isinstance(value, int): return func(self, value) else: raise ValueError(error) - min, max = range - - if (value < min or value > max) and (value not in allowed): + if not (valid_int_range[0] < value < valid_int_range[1]): raise ValueError(error) return func(self, value) diff --git a/tableauserverclient/models/schedule_item.py b/tableauserverclient/models/schedule_item.py index c93ffe922..d4d705a33 100644 --- a/tableauserverclient/models/schedule_item.py +++ b/tableauserverclient/models/schedule_item.py @@ -76,7 +76,7 @@ def priority(self): return self._priority @priority.setter - @property_is_int(range=(1, 100)) + @property_is_int(valid_int_range=(1, 100)) def priority(self, value): self._priority = value diff --git a/tableauserverclient/models/site_item.py b/tableauserverclient/models/site_item.py index f562289ce..0b5a0f6f5 100644 --- a/tableauserverclient/models/site_item.py +++ b/tableauserverclient/models/site_item.py @@ -1,3 +1,4 @@ +import sys import xml.etree.ElementTree as ET from .property_decorators import (property_is_enum, property_is_boolean, property_matches, property_not_empty, property_not_nullable, property_is_int) @@ -197,6 +198,33 @@ def flows_enabled(self): def flows_enabled(self, value): self._flows_enabled = value + @property + def tier_creator_capacity(self): + return self._tier_creator_capacity + + @tier_creator_capacity.setter + @property_is_int((0, sys.maxsize), allowed=(-1, None,)) + def tier_creator_capacity(self, value): + self._tier_creator_capacity = value + + @property + def tier_explorer_capacity(self): + return self._tier_explorer_capacity + + @tier_explorer_capacity.setter + @property_is_int((0, sys.maxsize), allowed=(-1, None,)) + def tier_explorer_capacity(self, value): + self._tier_explorer_capacity = value + + @property + def tier_viewer_capacity(self): + return self._tier_viewer_capacity + + @tier_viewer_capacity.setter + @property_is_int((0, sys.maxsize), allowed=(-1, None,)) + def tier_viewer_capacity(self, value): + self._tier_viewer_capacity = value + def is_default(self): return self.name.lower() == 'default' @@ -761,6 +789,16 @@ def _parse_element(site_xml, ns): flows_enabled = string_to_bool(site_xml.get('flowsEnabled', '')) cataloging_enabled = string_to_bool(site_xml.get('catalogingEnabled', '')) + tier_creator_capacity = site_xml.get('tierCreatorCapacity', None) + tier_explorer_capacity = site_xml.get('tierExplorerCapacity', None) + tier_viewer_capacity = site_xml.get('tierViewerCapacity', None) + if tier_creator_capacity: + tier_creator_capacity = int(tier_creator_capacity) + if tier_explorer_capacity: + tier_explorer_capacity = int(tier_explorer_capacity) + if tier_viewer_capacity: + tier_viewer_capacity = int(tier_viewer_capacity) + return id, name, content_url, status_reason, admin_mode, state, subscribe_others_enabled,\ disable_subscriptions, revision_history_enabled, user_quota, storage_quota,\ revision_limit, num_users, storage, data_acceleration_mode, flows_enabled, cataloging_enabled,\ diff --git a/tableauserverclient/server/endpoint/sites_endpoint.py b/tableauserverclient/server/endpoint/sites_endpoint.py index c57cb3d4f..0007c68da 100644 --- a/tableauserverclient/server/endpoint/sites_endpoint.py +++ b/tableauserverclient/server/endpoint/sites_endpoint.py @@ -67,6 +67,14 @@ def update(self, site_item): error = 'You cannot set admin_mode to ContentOnly and also set a user quota' raise ValueError(error) + reset = (None, -1,) + if site_item.user_quota not in reset: + if any([site_item.tier_creator_capacity not in reset, + site_item.tier_explorer_capacity not in reset, + site_item.tier_viewer_capacity not in reset, ]): + error = 'You cannot set tiered capacity and a user quota.' + raise ValueError(error) + url = "{0}/{1}".format(self.baseurl, site_item.id) update_req = RequestFactory.Site.update_req(site_item) server_response = self.put_request(url, update_req) diff --git a/tableauserverclient/server/request_options.py b/tableauserverclient/server/request_options.py index 22d0a4ef0..a8d89ff89 100644 --- a/tableauserverclient/server/request_options.py +++ b/tableauserverclient/server/request_options.py @@ -125,7 +125,7 @@ def max_age(self): return self._max_age @max_age.setter - @property_is_int(range=(0, 240), allowed=[-1]) + @property_is_int(valid_int_range=(0, 240), allowed=[-1]) def max_age(self, value): self._max_age = value @@ -153,7 +153,7 @@ def max_age(self): return self._max_age @max_age.setter - @property_is_int(range=(0, 240), allowed=[-1]) + @property_is_int(valid_int_range=(0, 240), allowed=[-1]) def max_age(self, value): self._max_age = value @@ -198,7 +198,7 @@ def max_age(self): return self._max_age @max_age.setter - @property_is_int(range=(0, 240), allowed=[-1]) + @property_is_int(valid_int_range=(0, 240), allowed=[-1]) def max_age(self, value): self._max_age = value diff --git a/test/test_site.py b/test/test_site.py index 8fbb4eda3..91a251d93 100644 --- a/test/test_site.py +++ b/test/test_site.py @@ -206,3 +206,18 @@ def test_decrypt(self): with requests_mock.mock() as m: m.post(self.baseurl + '/0626857c-1def-4503-a7d8-7907c3ff9d9f/decrypt-extracts', status_code=200) self.server.sites.decrypt_extracts('0626857c-1def-4503-a7d8-7907c3ff9d9f') + + def test_quota_and_tiers_error(self): + with open(UPDATE_XML, 'rb') as f: + response_xml = f.read().decode('utf-8') + with requests_mock.mock() as m: + m.put(self.baseurl + '/6b7179ba-b82b-4f0f-91ed-812074ac5da6', text=response_xml) + single_site = TSC.SiteItem(name='Tableau', content_url='tableau', + admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers, + user_quota=15, storage_quota=1000, + disable_subscriptions=True, revision_history_enabled=False, + data_acceleration_mode='disable') + single_site.tier_creator_capacity = 11 + single_site._id = '6b7179ba-b82b-4f0f-91ed-812074ac5da6' + with self.assertRaises(ValueError): + single_site = self.server.sites.update(single_site)