Skip to content

Commit 23922e8

Browse files
author
mganisin
authored
Merge pull request 3scale-qe#106 from azgabur/azgabur_tenant_billing
Add billing endpoints for tenant in master api
2 parents b1e5b02 + a6cd289 commit 23922e8

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from datetime import date
2+
3+
4+
def test_trigger_billing(master_api, custom_tenant):
5+
assert master_api.tenants.trigger_billing(custom_tenant, date.today().isoformat())
6+
7+
8+
def test_trigger_billing_resource(custom_tenant):
9+
assert custom_tenant.trigger_billing(date.today().isoformat())
10+
11+
12+
def test_trigger_billing_account(master_api, custom_tenant):
13+
# this test can sometimes fail randomly because of tenant not being 100% ready
14+
account = custom_tenant.admin_api(wait=True).accounts.list()[0]
15+
assert master_api.tenants.trigger_billing_account(custom_tenant, account, date.today().isoformat())
16+
17+
18+
def test_trigger_billing_account_resource(custom_tenant):
19+
# this test can sometimes fail randomly because of tenant not being 100% ready
20+
account = custom_tenant.admin_api(wait=True).accounts.list()[0]
21+
assert custom_tenant.trigger_billing_account(account, date.today().isoformat())

threescale_api/resources.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from threescale_api import errors
88
from threescale_api.defaults import DefaultClient, DefaultPlanClient, DefaultPlanResource, \
99
DefaultResource, DefaultStateClient, DefaultUserResource, DefaultStateResource
10+
from threescale_api import client
11+
import backoff
1012

1113
log = logging.getLogger(__name__)
1214

@@ -391,6 +393,37 @@ def __init__(self, *args, entity_name='tenant', entity_collection='tenants', **k
391393
def url(self) -> str:
392394
return self.threescale_client.master_api_url + '/providers'
393395

396+
def trigger_billing(self, tenant: Union['Tenant', int], date: str):
397+
"""Trigger billing for whole tenant
398+
Args:
399+
tenant: Tenant id or tenant resource
400+
date: Date for billing
401+
402+
Returns(bool): True if successful
403+
"""
404+
provider_id = _extract_entity_id(tenant)
405+
url = self.url + f"/{provider_id}/billing_jobs"
406+
params = dict(date=date)
407+
response = self.rest.post(url=url, json=params)
408+
return response.ok
409+
410+
def trigger_billing_account(self, tenant: Union['Tenant', int], account: Union['Account', int],
411+
date: str) -> dict:
412+
"""Trigger billing for one account in tenant
413+
Args:
414+
tenant: Tenant id or tenant resource
415+
account: Account id or account resource
416+
date: Date for billing
417+
418+
Returns(bool): True if successful
419+
"""
420+
account_id = _extract_entity_id(account)
421+
provider_id = _extract_entity_id(tenant)
422+
url = self.url + f"/{provider_id}/accounts/{account_id}/billing_jobs"
423+
params = dict(date=date)
424+
response = self.rest.post(url=url, json=params)
425+
return response.ok
426+
394427

395428
class Proxies(DefaultClient):
396429
def __init__(self, *args, entity_name='proxy', **kwargs):
@@ -1055,11 +1088,51 @@ def __init__(self, entity_name='name', **kwargs):
10551088
class Tenant(DefaultResource):
10561089
def __init__(self, entity_name='system_name', **kwargs):
10571090
super().__init__(entity_name=entity_name, **kwargs)
1091+
self.admin_base_url = self["signup"]["account"]["admin_base_url"]
1092+
self.admin_token = self["signup"]["access_token"]["value"]
10581093

10591094
@property
10601095
def entity_id(self) -> int:
10611096
return self.entity["signup"]["account"]["id"]
10621097

1098+
@backoff.on_predicate(backoff.fibo, lambda ready: not ready, max_tries=8, jitter=None)
1099+
def wait_tenant_ready(self) -> bool:
1100+
"""
1101+
When True is returned, there is some chance the tenant is actually ready.
1102+
"""
1103+
api = self.admin_api()
1104+
return api.account_plans.exists() and len(api.account_plans.list()) >= 1 and\
1105+
api.accounts.exists() and len(api.accounts.list()) >= 1
1106+
1107+
def admin_api(self, wait=False) -> 'client.ThreeScaleClient':
1108+
"""
1109+
Returns admin api client for tenant.
1110+
Its strongly recommended to call this with wait=True
1111+
"""
1112+
if wait:
1113+
self.wait_tenant_ready()
1114+
ssl_verify = self.threescale_client.rest._ssl_verify
1115+
return client.ThreeScaleClient(self.admin_base_url, self.admin_token, ssl_verify=ssl_verify)
1116+
1117+
def trigger_billing(self, date: str):
1118+
"""Trigger billing for whole tenant
1119+
Args:
1120+
date: Date for billing
1121+
1122+
Returns(bool): True if successful
1123+
"""
1124+
return self.threescale_client.tenants.trigger_billing(self, date)
1125+
1126+
def trigger_billing_account(self, account: Union['Account', int], date: str) -> dict:
1127+
"""Trigger billing for one account in tenant
1128+
Args:
1129+
account: Account id or account resource
1130+
date: Date for billing
1131+
1132+
Returns(bool): True if successful
1133+
"""
1134+
return self.threescale_client.tenants.trigger_billing_account(self, account, date)
1135+
10631136

10641137
class Application(DefaultResource):
10651138
def __init__(self, entity_name='name', **kwargs):

0 commit comments

Comments
 (0)