cartography 0.85.1__py3-none-any.whl → 0.85.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cartography might be problematic. Click here for more details.

@@ -69,7 +69,7 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
69
69
  'InstanceId': network_interface.get('Attachment', {}).get('InstanceId'),
70
70
  'InterfaceType': network_interface['InterfaceType'],
71
71
  'MacAddress': network_interface['MacAddress'],
72
- 'PrivateDnsName': network_interface['PrivateDnsName'],
72
+ 'PrivateDnsName': network_interface.get('PrivateDnsName'),
73
73
  'PrivateIpAddress': network_interface['PrivateIpAddress'],
74
74
  'PublicIp': network_interface.get('Association', {}).get('PublicIp'),
75
75
  'RequesterId': network_interface.get('RequesterId'),
@@ -23,7 +23,7 @@ GITHUB_ORG_REPOS_PAGINATED_GRAPHQL = """
23
23
  {
24
24
  url
25
25
  login
26
- repositories(first: 100, after: $cursor){
26
+ repositories(first: 50, after: $cursor){
27
27
  pageInfo{
28
28
  endCursor
29
29
  hasNextPage
@@ -59,7 +59,7 @@ GITHUB_ORG_REPOS_PAGINATED_GRAPHQL = """
59
59
  login
60
60
  __typename
61
61
  }
62
- collaborators(affiliation: OUTSIDE, first: 100) {
62
+ collaborators(affiliation: OUTSIDE, first: 50) {
63
63
  edges {
64
64
  permission
65
65
  }
@@ -1,6 +1,9 @@
1
1
  import json
2
2
  import logging
3
3
  import time
4
+ from datetime import datetime
5
+ from datetime import timedelta
6
+ from datetime import timezone as tz
4
7
  from typing import Any
5
8
  from typing import Dict
6
9
  from typing import List
@@ -10,9 +13,11 @@ from typing import Tuple
10
13
 
11
14
  import requests
12
15
 
16
+
13
17
  logger = logging.getLogger(__name__)
14
18
  # Connect and read timeouts of 60 seconds each; see https://requests.readthedocs.io/en/master/user/advanced/#timeouts
15
19
  _TIMEOUT = (60, 60)
20
+ _GRAPHQL_RATE_LIMIT_REMAINING_THRESHOLD = 500
16
21
 
17
22
 
18
23
  class PaginatedGraphqlData(NamedTuple):
@@ -20,6 +25,30 @@ class PaginatedGraphqlData(NamedTuple):
20
25
  edges: List[Dict[str, Any]]
21
26
 
22
27
 
28
+ def handle_rate_limit_sleep(token: str) -> None:
29
+ '''
30
+ Check the remaining rate limit and sleep if remaining is below threshold
31
+ :param token: The Github API token as string.
32
+ '''
33
+ response = requests.get('https://api.github.com/rate_limit', headers={'Authorization': f"token {token}"})
34
+ response.raise_for_status()
35
+ response_json = response.json()
36
+ rate_limit_obj = response_json['resources']['graphql']
37
+ remaining = rate_limit_obj['remaining']
38
+ threshold = _GRAPHQL_RATE_LIMIT_REMAINING_THRESHOLD
39
+ if remaining > threshold:
40
+ return
41
+ reset_at = datetime.fromtimestamp(rate_limit_obj['reset'], tz=tz.utc)
42
+ now = datetime.now(tz.utc)
43
+ # add an extra minute for safety
44
+ sleep_duration = reset_at - now + timedelta(minutes=1)
45
+ logger.warning(
46
+ f'Github graphql ratelimit has {remaining} remaining and is under threshold {threshold},'
47
+ f' sleeping until reset at {reset_at} for {sleep_duration}',
48
+ )
49
+ time.sleep(sleep_duration.seconds)
50
+
51
+
23
52
  def call_github_api(query: str, variables: str, token: str, api_url: str) -> Dict:
24
53
  """
25
54
  Calls the GitHub v4 API and executes a query
@@ -116,6 +145,9 @@ def fetch_all(
116
145
  while has_next_page:
117
146
  exc: Any = None
118
147
  try:
148
+ # In the future, we may use also use the rateLimit object from the graphql response.
149
+ # But we still need at least one call to the REST endpoint in case the graphql remaining is already 0
150
+ handle_rate_limit_sleep(token)
119
151
  resp = fetch_page(token, api_url, organization, query, cursor, **kwargs)
120
152
  retry = 0
121
153
  except requests.exceptions.Timeout as err:
@@ -135,7 +167,7 @@ def fetch_all(
135
167
  )
136
168
  raise exc
137
169
  elif retry > 0:
138
- time.sleep(1 * retry)
170
+ time.sleep(2 ** retry)
139
171
  continue
140
172
 
141
173
  resource = resp['data']['organization'][resource_type]
@@ -148,5 +180,6 @@ def fetch_all(
148
180
 
149
181
  cursor = resource['pageInfo']['endCursor']
150
182
  has_next_page = resource['pageInfo']['hasNextPage']
183
+
151
184
  org_data = {'url': resp['data']['organization']['url'], 'login': resp['data']['organization']['login']}
152
185
  return data, org_data
cartography/util.py CHANGED
@@ -238,6 +238,7 @@ def aws_handle_regions(func: AWSGetFunc) -> AWSGetFunc:
238
238
  'AccessDeniedException',
239
239
  'AuthFailure',
240
240
  'InvalidClientTokenId',
241
+ 'UnauthorizedOperation',
241
242
  'UnrecognizedClientException',
242
243
  'InternalServerErrorException',
243
244
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cartography
3
- Version: 0.85.1
3
+ Version: 0.85.3
4
4
  Summary: Explore assets and their relationships across your technical infrastructure.
5
5
  Home-page: https://www.github.com/lyft/cartography
6
6
  Maintainer: Lyft
@@ -5,7 +5,7 @@ cartography/config.py,sha256=_WqfWKfoSkUAUkYEmwzNrLtrJkFkJNLZ6SwMIyymRoA,10712
5
5
  cartography/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  cartography/stats.py,sha256=dbybb9V2FuvSuHjjNwz6Vjwnd1hap2C7h960rLoKcl8,4406
7
7
  cartography/sync.py,sha256=rU2lHY3afwk2HrBPQxVI_nQ0bwkS_vDug9xXen-msBA,9536
8
- cartography/util.py,sha256=O509vZ7wvGfmAe5jSN68fOPVyc3InGdzlJkyrOpMENo,13845
8
+ cartography/util.py,sha256=vkL_flzSQP8WPiulNFQhamzgUNc836lRxggjYmTVgo8,13878
9
9
  cartography/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  cartography/client/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  cartography/client/aws/iam.py,sha256=dYsGikc36DEsSeR2XVOVFFUDwuU9yWj_EVkpgVYCFgM,1293
@@ -177,7 +177,7 @@ cartography/intel/aws/ec2/key_pairs.py,sha256=SvRgd56vE4eouvTSNoFK8PP8HYoECO91go
177
177
  cartography/intel/aws/ec2/launch_templates.py,sha256=UXqINdxBzpgPTJVjSZ9DXhO-Lo598aHswJapuo4QNXA,5099
178
178
  cartography/intel/aws/ec2/load_balancer_v2s.py,sha256=B7NbD8o2Qgd5J_EOKKr8v_tkD7Jr1EXFnyXGR9Ccuzw,8394
179
179
  cartography/intel/aws/ec2/load_balancers.py,sha256=1GwErzGqi3BKCARqfGJcD_r_D84rFKVy5kNMas9jAok,6756
180
- cartography/intel/aws/ec2/network_interfaces.py,sha256=GEp2z4xfJ1eeLu1cOtC61R2Z4sYGPvLUi8AYXMo_N_8,9195
180
+ cartography/intel/aws/ec2/network_interfaces.py,sha256=CzF8PooCYUQ2pk8DR8JDAhkWRUQSBj_27OsIfkL_-Cs,9199
181
181
  cartography/intel/aws/ec2/reserved_instances.py,sha256=jv8-VLI5KL8jN1QRI20yim8lzZ7I7wR8a5EF8DckahA,3122
182
182
  cartography/intel/aws/ec2/security_groups.py,sha256=vxLeaCpCowkbl-YpON1UdbjtPolMfj_reOEuKujN80Y,6060
183
183
  cartography/intel/aws/ec2/snapshots.py,sha256=HSeK8COoc1p399Y0LSg6Jo0bTiooCIh66jCv4DPsJsA,5393
@@ -228,10 +228,10 @@ cartography/intel/gcp/dns.py,sha256=y2pvbmV04cnrMyuu_nbW3oc7uwHX6yEzn1n7veCsjmk,
228
228
  cartography/intel/gcp/gke.py,sha256=qaTwsVaxkwNhW5_Mw4bedOk7fgJK8y0LwwcYlUABXDg,7966
229
229
  cartography/intel/gcp/storage.py,sha256=oO_ayEhkXlj2Gn7T5MU41ZXiqwRwe6Ud4wzqyRTsyf4,9075
230
230
  cartography/intel/github/__init__.py,sha256=y876JJGTDJZEOFCDiNCJfcLNxN24pVj4s2N0YmuuoaE,1914
231
- cartography/intel/github/repos.py,sha256=-4bX9U2G3FJhBW2c_NqbR2QcRUbS1FfSd2Fg8FRjNho,21768
231
+ cartography/intel/github/repos.py,sha256=YPDdBMk6NkZjwPcqPW5LlCy_OS9tKcrZD6ygiUG93J0,21766
232
232
  cartography/intel/github/teams.py,sha256=aX1dj7HHVjw0hv_VvG1dee3WzTfmVMraP1khlwvN7Xs,5287
233
233
  cartography/intel/github/users.py,sha256=kQp0dxzP08DVrdvfVeCciQbrKPbbFvwbR_p_I_XGt7s,3826
234
- cartography/intel/github/util.py,sha256=pPKqawBuMoz12_gsnNkmtts_s_kQscRX5u_m6Zaxur0,6056
234
+ cartography/intel/github/util.py,sha256=trigWITP7C44RjKpBT12fCcxtqo5WFqUOcB9VqtzifA,7465
235
235
  cartography/intel/gsuite/__init__.py,sha256=AGIUskGlLCVGHbnQicNpNWi9AvmV7_7hUKTt-hsB2J8,4306
236
236
  cartography/intel/gsuite/api.py,sha256=J0dkNdfBVMrEv8vvStQu7YKVxXSyV45WueFhUS4aOG4,10310
237
237
  cartography/intel/jamf/__init__.py,sha256=Nof-LrUeevoieo6oP2GyfTwx8k5TUIgreW6hSj53YjQ,419
@@ -321,10 +321,10 @@ cartography/models/semgrep/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
321
321
  cartography/models/semgrep/deployment.py,sha256=or5qZDuR51MXzINpH15jZrqmSUvXQevCNYWJ7D6v-JI,745
322
322
  cartography/models/semgrep/findings.py,sha256=fzoCbn3QPNAapellnkXT-SSngqaXtJo7ArEHSoCekM8,3883
323
323
  cartography/models/semgrep/locations.py,sha256=kSk7Nn5Mn4Ob84MVZOo2GR0YFi-9Okq9pgA3FfC6_bk,3061
324
- cartography-0.85.1.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
325
- cartography-0.85.1.dist-info/METADATA,sha256=P4iBpJEuqQ0TOGSbaxeWYS4OELc4tA1YxZ6W9oDsdJQ,1987
326
- cartography-0.85.1.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
327
- cartography-0.85.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
328
- cartography-0.85.1.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
329
- cartography-0.85.1.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
330
- cartography-0.85.1.dist-info/RECORD,,
324
+ cartography-0.85.3.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
325
+ cartography-0.85.3.dist-info/METADATA,sha256=uP8WvTjJDL7jKi7ztSmgZSdaqbnn-47IPcsmeVlw53A,1987
326
+ cartography-0.85.3.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
327
+ cartography-0.85.3.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
328
+ cartography-0.85.3.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
329
+ cartography-0.85.3.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
330
+ cartography-0.85.3.dist-info/RECORD,,