Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import requests
import json
import bisect
import copy

from ansible_collections.nhsd.apigee.plugins.module_utils.models.ansible.add_jwks_resource_url import (
AddJwksResourceUrlToApp
)
Expand All @@ -8,10 +12,52 @@
from ansible_collections.nhsd.apigee.plugins.module_utils import utils
from ansible_collections.nhsd.apigee.plugins.module_utils import constants


ATTRIBUTE_NAME = "jwks-resource-url"


class LazyDeveloperDetails:
"""
Gets a list of all developers for an apigee organization. Lazily
looks up details based on __getitem__ access. Since Apigee
returns the entire list developers sorted by their internal
'developerId' attribute, this allows us to quickly binary search
our way to a developer's details when we only know their
developerId.
"""

def __init__(self, org, token):
self._base_url = (constants.APIGEE_BASE_URL
+ f"organizations/{org}/developers/")
self._token = token
self._session = requests.Session()

self.emails = self._get("")
self.details = [None for email in self.emails]

def _get(self, email: str):
"""
Get developer details from email.
Get all developers if email = ''

Raises a RuntimeError if the request does not return 200.
This allows us to bubble the exception up to an ansible
response.
"""
resp = utils.get(self._base_url + email,
self._token, session=self._session)
if resp.get("failed"):
raise RuntimeError(json.dumps(resp))
return resp["response"]["body"]

def __getitem__(self, i: int):
if self.details[i] is None:
self.details[i] = self._get(self.emails[i])
return self.details[i]["developerId"]

def __len__(self):
return len(self.emails)


class ActionModule(ApigeeAction):
def run(self, tmp=None, task_vars=None):
super(ActionModule, self).run(tmp, task_vars)
Expand Down Expand Up @@ -39,15 +85,23 @@ def run(self, tmp=None, task_vars=None):
if diff_mode:
result["diff"] = [{"before": before, "after": after}]

developer_details = LazyDeveloperDetails(args.organization, args.access_token)
try:
i = bisect.bisect_left(developer_details, args._app_data["developerId"])
except RuntimeError as e:
return json.loads(str(e))
developer = developer_details.details[i]

result["developer"] = developer
if check_mode:
return result

developer_email = args._app_data["createdBy"]
app_name = args._app_data["name"]
app_attribute_url = (
constants.APIGEE_BASE_URL
+ f"organizations/{args.organization}/developers/{developer_email}/apps/{app_name}/attributes"
+ f"organizations/{args.organization}/developers/{developer['email']}/apps/{app_name}/attributes"
)

app_data2 = utils.post(app_attribute_url, args.access_token,
json={"attribute": after["attributes"]})
if app_data2.get("failed"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def delta(before, after, keys_to_ignore=None):
)


def request(method, url, access_token, json=None, headers=None, status_code=None):
def request(method, url, access_token, json=None, headers=None, status_code=None, session=None):
if not status_code:
status_code = [200]

Expand All @@ -34,7 +34,9 @@ def request(method, url, access_token, json=None, headers=None, status_code=None

headers["authorization"] = f"Bearer {access_token}"

response = requests.request(method, url, json=json, headers=headers)
if session is None:
session = requests
response = session.request(method, url, json=json, headers=headers)

response_dict = {
"response": {"status_code": response.status_code, "reason": response.reason,},
Expand Down