Fix: nextToken value in logs:DescribeLogGroups response (#3398)

The pagination for this endpoint has been modified to more closely
model the real AWS behavior:
* Log Groups are now sorted alphabetically by `logGroupName`.
* `nextToken` is now a string containing the last `logGroupName` in the
  current response.
* Specifying an invalid `nextToken` does not generate an error, but does
  return an empty group list.
* `nextToken` is not included in the response if there are no additional
  items to return.

Fixes #3395
This commit is contained in:
Brian Pandola 2020-10-21 01:47:09 -07:00 committed by GitHub
commit 9eb58eea41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 9 deletions

View file

@ -485,20 +485,39 @@ class LogsBackend(BaseBackend):
def describe_log_groups(self, limit, log_group_name_prefix, next_token):
if log_group_name_prefix is None:
log_group_name_prefix = ""
if next_token is None:
next_token = 0
groups = [
group.to_describe_dict()
for name, group in self.groups.items()
if name.startswith(log_group_name_prefix)
]
groups = sorted(groups, key=lambda x: x["creationTime"], reverse=True)
groups_page = groups[next_token : next_token + limit]
groups = sorted(groups, key=lambda x: x["logGroupName"])
next_token += limit
if next_token >= len(groups):
next_token = None
index_start = 0
if next_token:
try:
index_start = (
next(
index
for (index, d) in enumerate(groups)
if d["logGroupName"] == next_token
)
+ 1
)
except StopIteration:
index_start = 0
# AWS returns an empty list if it receives an invalid token.
groups = []
index_end = index_start + limit
if index_end > len(groups):
index_end = len(groups)
groups_page = groups[index_start:index_end]
next_token = None
if groups_page and index_end < len(groups):
next_token = groups_page[-1]["logGroupName"]
return groups_page, next_token

View file

@ -42,7 +42,10 @@ class LogsResponse(BaseResponse):
groups, next_token = self.logs_backend.describe_log_groups(
limit, log_group_name_prefix, next_token
)
return json.dumps({"logGroups": groups, "nextToken": next_token})
result = {"logGroups": groups}
if next_token:
result["nextToken"] = next_token
return json.dumps(result)
def create_log_stream(self):
log_group_name = self._get_param("logGroupName")