Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
StackPath Adaptation API (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
mendrugory authored Oct 14, 2020
1 parent cfae3d1 commit 3769ed5
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 3 deletions.
5 changes: 4 additions & 1 deletion pystackpath/stacks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pystackpath.util import BaseObject, PageInfo, pagination_query
from pystackpath.stacks.cdnsites import CdnSites
from pystackpath.stacks.deliverysites import DeliverySites
from pystackpath.stacks.wafsites import WafSites
from pystackpath.stacks.wafsites import WafSites, WafSitesV2
from pystackpath.stacks.metrics import Metrics
from pystackpath.stacks.certificates import Certificates
from pystackpath.stacks.zones import Zones
Expand Down Expand Up @@ -91,6 +91,9 @@ def cdnsites(self):
def wafsites(self):
return WafSites(self._client, f"/waf/v1/stacks/{self.id}")

def wafsites_v2(self):
return WafSitesV2(self._client, f"/waf/v2/stacks/{self.id}")

def metrics(self):
return Metrics(self._client, f"/cdn/v1/stacks/{self.id}")

Expand Down
15 changes: 14 additions & 1 deletion pystackpath/stacks/wafsites/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
from pystackpath.stacks.wafsites.policy_groups import PolicyGroups
from pystackpath.stacks.wafsites.rules import Rules
from pystackpath.stacks.wafsites.events import Events
from pystackpath.stacks.wafsites.requests import Requests
from pystackpath.stacks.wafsites.traffic import Traffic
from pystackpath.stacks.wafsites.traffic_v2 import Traffic as TrafficV2


class WafSites(BaseSite):
Expand All @@ -29,7 +31,18 @@ def set_monitoring(self):
return Monitoring(self._client, f"{self._base_api}/sites/{self.id}")

def events(self):
return Events(self._client, f"{self._base_api}/sites/{self.id}")
return Events(self._client, f"{self._base_api}/sites/{self.id}")

def requests(self):
return Requests(self._client, f"{self._base_api}/sites/{self.id}")

def traffic(self):
'''
deprecated
'''
return Traffic(self._client, f"{self._base_api}")


class WafSitesV2(BaseSite):
def traffic(self):
return TrafficV2(self._client, f"{self._base_api}")
2 changes: 1 addition & 1 deletion pystackpath/stacks/wafsites/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Events(BaseObject):

def get(self, event_id):
"""
Get an Event by its ID
Get an Event summary by its ID
"""
response = self._client.get(f"{self._base_api}/events/{event_id}")
return self.loaddict(response.json())
Expand Down
132 changes: 132 additions & 0 deletions pystackpath/stacks/wafsites/requests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import json
from pystackpath.util import BaseObject, api_time_format
from datetime import datetime as dt
from datetime import timedelta


ACCEPTED_ACTIONS = (
'ANY_ACTION', 'ALLOW_ACTION',
'BLOCK_ACTION', 'CAPTCHA_ACTION',
'HANDSHAKE_ACTION', 'MONITOR_ACTION'
)
ACCEPTED_RESULTS = ('ANY_RESULT', 'BLOCKED_RESULT')
ACCEPTED_SORT_BY = ('TIMESTAMP', 'COUNTRY', 'RULE_NAME')
ACCEPTED_SORT_ORDER = ('ASCENDING', 'DESCENDING')
DEFAULT_DELTA_TIME = 1 # day


class Requests(BaseObject):

def get(self, request_id):
"""
Get a Request by its ID
"""
response = self._client.get(f"{self._base_api}/requests/{request_id}")
return self.loaddict(response.json())

def index(
self,
page_request_first=None,
page_request_after=None,
page_request_filter=None,
page_request_sort_by=None,
start_date=None,
end_date=None,
filter_action_value=ACCEPTED_ACTIONS[0],
filter_result_value=ACCEPTED_RESULTS[0],
filter_client_ip=None,
filter_reference_id=None,
sort_by=ACCEPTED_SORT_BY[0],
sort_order=ACCEPTED_SORT_ORDER[0]
):
"""
Get all the Requests.
You can use the parameters to add options to your request.
"""

params = Requests._common_params(start_date, end_date, filter_action_value, \
filter_result_value, filter_client_ip, filter_reference_id)

if page_request_first:
params['page_request.first'] = page_request_first

if page_request_after:
params['page_request.after'] = page_request_after

if page_request_filter:
params['page_request.filter'] = page_request_filter

if page_request_sort_by:
params['page_request.sort_by'] = page_request_sort_by

if sort_by not in ACCEPTED_SORT_BY:
raise ValueError(f"{sort_by} is not a valid sort type: {ACCEPTED_SORT_BY}")
params['sort_by'] = sort_by

if sort_order not in ACCEPTED_SORT_ORDER:
raise ValueError(f"{sort_order} is not a valid sort type: {ACCEPTED_SORT_ORDER}")
params['sort_order'] = sort_order

response = self._client.get(f"{self._base_api}/requests", params=params)
return self.loaddict(response.json())


def get_request_statistics(
self,
start_date=None,
end_date=None,
filter_action_value=ACCEPTED_ACTIONS[0],
filter_result_value=ACCEPTED_RESULTS[0],
filter_client_ip=None,
filter_reference_id=None
):
"""
Get WAF Request statistics
You can use the parameters to add options to your request.
"""
params = Requests._common_params(start_date, end_date, filter_action_value, \
filter_result_value, filter_client_ip, filter_reference_id)
response = self._client.get(f"{self._base_api}/request_stats", params=params)
return self.loaddict(response.json())


@staticmethod
def _common_params(
start_date,
end_date,
filter_action_value,
filter_result_value,
filter_client_ip,
filter_reference_id
):
params = dict()

if end_date is None:
end_date = dt.today()
if start_date is None:
start_date = end_date - timedelta(days=DEFAULT_DELTA_TIME)

end_date_iso = api_time_format(end_date)
start_date_iso = api_time_format(start_date)

if start_date_iso > end_date_iso:
raise ValueError(f"Search start date, \"{start_date_iso}\", is later than end date, \"{end_date_iso}\"!")

params['start_date'] = start_date_iso
params['end_date'] = end_date_iso

if filter_action_value not in ACCEPTED_ACTIONS:
raise ValueError(f"{filter_action_value} is not a valid action filter: {ACCEPTED_ACTIONS}")
params['filter.action_value'] = filter_action_value

if filter_result_value not in ACCEPTED_RESULTS:
raise ValueError(f"{filter_result_value} is not a valid action filter: {ACCEPTED_RESULTS}")
params['filter.result_value'] = filter_result_value

if filter_client_ip:
params['filter.client_ip'] = filter_client_ip

if filter_reference_id:
params['filter.reference_id'] = filter_reference_id

return params
48 changes: 48 additions & 0 deletions pystackpath/stacks/wafsites/traffic_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import json
from pystackpath.util import BaseObject, api_time_format
from datetime import datetime as dt
from datetime import timedelta


ACCEPTED_RESOLUTIONS = ('HOURLY', 'MINUTELY', 'DAILY')
DEFAULT_DELTA_TIME = 1 # day


class Traffic(BaseObject):

def get(
self,
site_id=None,
start_date=None,
end_date=None,
resolution=ACCEPTED_RESOLUTIONS[0]
):
"""
Get Waf Traffic
"""

params = dict()

if site_id is None:
params['site_id'] = site_id

if end_date is None:
end_date = dt.today()
if start_date is None:
start_date = end_date - timedelta(days=DEFAULT_DELTA_TIME)

end_date_iso = api_time_format(end_date)
start_date_iso = api_time_format(start_date)

if start_date_iso > end_date_iso:
raise ValueError(f"Search start date, \"{start_date_iso}\", is later than end date, \"{end_date_iso}\"!")

params['start_date'] = start_date_iso
params['end_date'] = end_date_iso

if resolution not in ACCEPTED_RESOLUTIONS:
raise ValueError(f"{resolution} is not a valid resolution: {ACCEPTED_RESOLUTIONS}")
params['resolution'] = resolution

response = self._client.get(f"{self._base_api}/traffic", params=params)
return self.loaddict(response.json())

0 comments on commit 3769ed5

Please sign in to comment.