pulumi-django-azure 1.0.28__py3-none-any.whl → 1.0.59__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.
@@ -1,2 +0,0 @@
1
- from . import settings # noqa: F401
2
- from .django_deployment import DjangoDeployment, HostDefinition # noqa: F401
@@ -4,21 +4,22 @@ import logging
4
4
  import os
5
5
  import time
6
6
  from dataclasses import dataclass
7
+ from enum import Enum
7
8
  from subprocess import check_output
8
9
 
9
10
  from azure.identity import DefaultAzureCredential
10
11
  from azure.mgmt.resource import SubscriptionClient
11
12
  from azure.mgmt.resource.subscriptions.models import Subscription
12
13
 
13
- _redis_token_cache = None
14
- _database_token_cache = None
15
-
16
14
  logger = logging.getLogger("pulumi_django_azure.azure_helper")
17
15
 
18
16
 
19
17
  # Azure credentials
20
18
  AZURE_CREDENTIAL = DefaultAzureCredential()
21
19
 
20
+ # Buffer for token expiration (5 minutes)
21
+ TOKEN_EXPIRATION_BUFFER = 300
22
+
22
23
  # Get the local IP addresses of the machine (only when runnig on Azure)
23
24
  if os.environ.get("IS_AZURE_ENVIRONMENT"):
24
25
  LOCAL_IP_ADDRESSES = check_output(["hostname", "--all-ip-addresses"]).decode("utf-8").strip().split(" ")
@@ -26,30 +27,42 @@ else:
26
27
  LOCAL_IP_ADDRESSES = []
27
28
 
28
29
 
29
- def get_db_password() -> str:
30
+ class TokenType(Enum):
31
+ DATABASE = "https://ossrdbms-aad.database.windows.net/.default"
32
+ REDIS = "https://redis.azure.com/.default"
33
+
34
+
35
+ def _get_azure_token(type: TokenType) -> str:
30
36
  """
31
- Get a valid password for the database.
37
+ Get a valid token for the given scope.
32
38
  """
33
- global _database_token_cache
34
- _database_token_cache = AZURE_CREDENTIAL.get_token("https://ossrdbms-aad.database.windows.net/.default")
39
+ global AZURE_CREDENTIAL
35
40
 
36
- logger.debug("New database token: %s", _database_token_cache)
41
+ token = AZURE_CREDENTIAL.get_token(type.value)
37
42
 
38
- return _database_token_cache.token
43
+ if token.expires_on < time.time() + TOKEN_EXPIRATION_BUFFER:
44
+ # We received an expired or nearly expired token from the API. Force a new token by creating a new instance of the credential.
45
+ logger.debug(
46
+ "Received an expired or nearly expired %s token (current time: %s, token expiration: %s)."
47
+ "Creating a new instance of the credential.",
48
+ type.name,
49
+ time.time(),
50
+ token.expires_on,
51
+ )
39
52
 
53
+ AZURE_CREDENTIAL = DefaultAzureCredential()
54
+ token = AZURE_CREDENTIAL.get_token(type.value)
40
55
 
41
- def db_token_will_expire(treshold=300) -> bool:
42
- """
43
- Check if the database token will expire in the next treshold seconds.
44
- """
45
- # If the token is not cached, we consider it expired (so a new one will be fetched)
46
- if _database_token_cache is None:
47
- return True
56
+ logger.debug("New %s token (try 2): %s", type.name, token)
48
57
 
49
- logger.debug("Database token expires on: %s", _database_token_cache.expires_on)
58
+ return token.token
50
59
 
51
- # If the token is cached, check if it will expire in the next treshold seconds
52
- return _database_token_cache.expires_on - time.time() < treshold
60
+
61
+ def get_db_password() -> str:
62
+ """
63
+ Get a valid password for the database.
64
+ """
65
+ return _get_azure_token(TokenType.DATABASE)
53
66
 
54
67
 
55
68
  @dataclass
@@ -62,28 +75,9 @@ def get_redis_credentials() -> RedisCredentials:
62
75
  """
63
76
  Get valid credentials for the Redis cache.
64
77
  """
65
- global _redis_token_cache
66
- _redis_token_cache = AZURE_CREDENTIAL.get_token("https://redis.azure.com/.default")
67
-
68
- t = _redis_token_cache.token
69
-
70
- logger.debug("New Redis token: %s", _redis_token_cache)
71
-
72
- return RedisCredentials(_extract_username_from_token(t), t)
73
-
74
-
75
- def redis_token_will_expire(treshold=300) -> bool:
76
- """
77
- Check if the Redis token will expire in the next treshold seconds.
78
- """
79
- # If the token is not cached, we consider it expired (so a new one will be fetched)
80
- if _redis_token_cache is None:
81
- return True
82
-
83
- logger.debug("Redis token expires on: %s", _redis_token_cache.expires_on)
78
+ token = _get_azure_token(TokenType.REDIS)
84
79
 
85
- # If the token is cached, check if it will expire in the next treshold seconds
86
- return _redis_token_cache.expires_on - time.time() < treshold
80
+ return RedisCredentials(_extract_username_from_token(token), token)
87
81
 
88
82
 
89
83
  def get_subscription() -> Subscription:
@@ -0,0 +1,42 @@
1
+ import hashlib
2
+ import json
3
+ import os
4
+ from datetime import datetime
5
+
6
+ from django.conf import settings
7
+
8
+ _build_info_cache = None
9
+
10
+
11
+ def add_build_info(request):
12
+ if settings.DEBUG:
13
+ # Generate SHA-1 hash from current timestamp
14
+ timestamp = str(datetime.now().timestamp()).encode("utf-8")
15
+ dev_hash = hashlib.sha1(timestamp).hexdigest()
16
+ return {
17
+ "build_info": {
18
+ "commit": dev_hash,
19
+ "date": datetime.now(),
20
+ }
21
+ }
22
+
23
+ global _build_info_cache
24
+
25
+ if _build_info_cache is None:
26
+ path = settings.BASE_DIR / "build-info.json"
27
+
28
+ if os.path.exists(path):
29
+ with open(path) as f:
30
+ build_info = json.load(f)
31
+
32
+ _build_info_cache = {
33
+ "build_info": {
34
+ "commit": build_info["commit"],
35
+ "date": datetime.fromisoformat(build_info["date"]),
36
+ }
37
+ }
38
+ else:
39
+ # No build info available
40
+ _build_info_cache = {}
41
+
42
+ return _build_info_cache