7
7
from botocore .config import Config
8
8
9
9
# ADF imports
10
+ from cache import Cache
10
11
from errors import ParameterNotFoundError
11
12
from paginator import paginator
12
13
from logger import configure_logger
13
14
14
15
LOGGER = configure_logger (__name__ )
15
- PARAMETER_DESCRIPTION = ' DO NOT EDIT - Used by The AWS Deployment Framework'
16
- PARAMETER_PREFIX = ' /adf'
16
+ PARAMETER_DESCRIPTION = " DO NOT EDIT - Used by The AWS Deployment Framework"
17
+ PARAMETER_PREFIX = " /adf"
17
18
SSM_CONFIG = Config (
18
19
retries = {
19
20
"max_attempts" : 10 ,
22
23
23
24
24
25
class ParameterStore :
25
- """Class used for modeling Parameters
26
- """
26
+ """Class used for modeling Parameters"""
27
27
28
- def __init__ (self , region , role ):
29
- self .client = role .client ('ssm' , region_name = region , config = SSM_CONFIG )
28
+ def __init__ (self , region , role , cache = None ):
29
+ self .cache = cache or Cache ()
30
+ self .client = role .client ("ssm" , region_name = region , config = SSM_CONFIG )
30
31
31
- def put_parameter (self , name , value , tier = 'Standard' ):
32
- """Puts a Parameter into Parameter Store
33
- """
32
+ def put_parameter (self , name , value , tier = "Standard" ):
33
+ """Puts a Parameter into Parameter Store"""
34
34
try :
35
35
current_value = self .fetch_parameter (name )
36
36
assert current_value == value
37
37
LOGGER .debug (
38
- ' No need to update parameter %s with value %s since they '
39
- ' are the same' ,
38
+ " No need to update parameter %s with value %s since they "
39
+ " are the same" ,
40
40
ParameterStore ._build_param_name (name ),
41
41
value ,
42
42
)
43
43
except (ParameterNotFoundError , AssertionError ):
44
44
param_name = ParameterStore ._build_param_name (name )
45
45
LOGGER .debug (
46
- ' Putting SSM Parameter %s with value %s' ,
46
+ " Putting SSM Parameter %s with value %s" ,
47
47
param_name ,
48
48
value ,
49
49
)
50
50
self .client .put_parameter (
51
51
Name = param_name ,
52
52
Description = PARAMETER_DESCRIPTION ,
53
53
Value = value ,
54
- Type = ' String' ,
54
+ Type = " String" ,
55
55
Overwrite = True ,
56
- Tier = tier
56
+ Tier = tier ,
57
57
)
58
+ self .cache .add (param_name , value )
58
59
59
60
def delete_parameter (self , name ):
60
61
param_name = ParameterStore ._build_param_name (name )
61
62
try :
62
- LOGGER .debug ('Deleting Parameter %s' , param_name )
63
+ LOGGER .debug ("Deleting Parameter %s" , param_name )
64
+ self .cache .remove (param_name )
63
65
self .client .delete_parameter (
64
66
Name = param_name ,
65
67
)
66
68
except self .client .exceptions .ParameterNotFound :
67
69
LOGGER .debug (
68
- ' Attempted to delete Parameter %s but it was not found' ,
70
+ " Attempted to delete Parameter %s but it was not found" ,
69
71
param_name ,
70
72
)
71
73
72
74
def fetch_parameters_by_path (self , path ):
73
- """Gets a Parameter(s) by Path from Parameter Store (Recursively)
74
- """
75
+ """Gets a Parameter(s) by Path from Parameter Store (Recursively)"""
75
76
param_path = ParameterStore ._build_param_name (path )
76
77
try :
77
78
LOGGER .debug (
78
- ' Fetching Parameters from path %s' ,
79
+ " Fetching Parameters from path %s" ,
79
80
param_path ,
80
81
)
81
82
return paginator (
82
83
self .client .get_parameters_by_path ,
83
84
Path = param_path ,
84
85
Recursive = True ,
85
- WithDecryption = False
86
+ WithDecryption = False ,
86
87
)
87
88
except self .client .exceptions .ParameterNotFound as error :
88
89
raise ParameterNotFoundError (
89
- f' Parameter Path { param_path } Not Found' ,
90
+ f" Parameter Path { param_path } Not Found" ,
90
91
) from error
91
92
92
93
@staticmethod
93
94
def _build_param_name (name , adf_only = True ):
94
- slash_name = name if name .startswith ('/' ) else f"/{ name } "
95
- add_prefix = (
96
- adf_only
97
- and not slash_name .startswith (f"{ PARAMETER_PREFIX } /" )
98
- )
99
- param_prefix = PARAMETER_PREFIX if add_prefix else ''
95
+ slash_name = name if name .startswith ("/" ) else f"/{ name } "
96
+ add_prefix = adf_only and not slash_name .startswith (f"{ PARAMETER_PREFIX } /" )
97
+ param_prefix = PARAMETER_PREFIX if add_prefix else ""
100
98
return f"{ param_prefix } { slash_name } "
101
99
102
100
def fetch_parameter (self , name , with_decryption = False , adf_only = True ):
103
- """Gets a Parameter from Parameter Store (Returns the Value)
104
- """
101
+ """Gets a Parameter from Parameter Store (Returns the Value)"""
105
102
param_name = ParameterStore ._build_param_name (name , adf_only )
103
+ if self .cache .exists (param_name ):
104
+ LOGGER .debug ("Reading Parameter from Cache: %s" , param_name )
105
+ cached_value = self .cache .get (param_name )
106
+ if isinstance (cached_value , ParameterNotFoundError ):
107
+ raise cached_value
108
+ return cached_value
106
109
try :
107
- LOGGER .debug (' Fetching Parameter %s' , param_name )
110
+ LOGGER .debug (" Fetching Parameter %s" , param_name )
108
111
response = self .client .get_parameter (
109
- Name = param_name ,
110
- WithDecryption = with_decryption
112
+ Name = param_name , WithDecryption = with_decryption
111
113
)
112
- return response ['Parameter' ]['Value' ]
114
+ fetched_value = response ["Parameter" ]["Value" ]
115
+ self .cache .add (param_name , fetched_value )
116
+ return fetched_value
113
117
except self .client .exceptions .ParameterNotFound as error :
114
- LOGGER .debug ('Parameter %s not found' , param_name )
115
- raise ParameterNotFoundError (
116
- f'Parameter { param_name } Not Found' ,
117
- ) from error
118
+ LOGGER .debug ("Parameter %s not found" , param_name )
119
+ not_found = ParameterNotFoundError (
120
+ f"Parameter { param_name } Not Found" ,
121
+ )
122
+ self .cache .add (param_name , not_found )
123
+ raise not_found from error
118
124
119
125
def fetch_parameter_accept_not_found (
120
126
self ,
@@ -131,5 +137,5 @@ def fetch_parameter_accept_not_found(
131
137
try :
132
138
return self .fetch_parameter (name , with_decryption , adf_only )
133
139
except ParameterNotFoundError :
134
- LOGGER .debug (' Using default instead: %s' , default_value )
140
+ LOGGER .debug (" Using default instead: %s" , default_value )
135
141
return default_value
0 commit comments