@@ -55,10 +55,13 @@ class KmsKeyring(Keyring):
55
55
but for the keyring to attempt to use them on decrypt
56
56
you MUST specify the CMK ARN.
57
57
58
- If you specify neither ``generator_key_id`` nor ``child_key_ids``
59
- then the keyring will operate in `discovery mode`_,
58
+ If you specify ``is_discovery=True`` the keyring will be a KMS discovery keyring,
60
59
doing nothing on encrypt and attempting to decrypt any AWS KMS-encrypted data key on decrypt.
61
60
61
+ .. notice::
62
+
63
+ You must either set ``is_discovery=True`` or provide key IDs.
64
+
62
65
You can use the :class:`ClientSupplier` to customize behavior further,
63
66
such as to provide different credentials for different regions
64
67
or to restrict which regions are allowed.
@@ -75,12 +78,14 @@ class KmsKeyring(Keyring):
75
78
.. versionadded:: 1.5.0
76
79
77
80
:param ClientSupplier client_supplier: Client supplier that provides AWS KMS clients (optional)
81
+ :param bool is_discovery: Should this be a discovery keyring (optional)
78
82
:param str generator_key_id: Key ID of AWS KMS CMK to use when generating data keys (optional)
79
83
:param List[str] child_key_ids: Key IDs that will be used to encrypt and decrypt data keys (optional)
80
84
:param List[str] grant_tokens: AWS KMS grant tokens to include in requests (optional)
81
85
"""
82
86
83
87
_client_supplier = attr .ib (default = attr .Factory (DefaultClientSupplier ), validator = is_callable ())
88
+ _is_discovery = attr .ib (default = False , validator = instance_of (bool ))
84
89
_generator_key_id = attr .ib (default = None , validator = optional (instance_of (six .string_types )))
85
90
_child_key_ids = attr .ib (
86
91
default = attr .Factory (tuple ),
@@ -93,6 +98,22 @@ class KmsKeyring(Keyring):
93
98
94
99
def __attrs_post_init__ (self ):
95
100
"""Configure internal keyring."""
101
+ key_ids_provided = self ._generator_key_id is not None or self ._child_key_ids
102
+ both = key_ids_provided and self ._is_discovery
103
+ neither = not key_ids_provided and not self ._is_discovery
104
+
105
+ if both :
106
+ raise TypeError ("is_discovery cannot be True if key IDs are provided" )
107
+
108
+ if neither :
109
+ raise TypeError ("is_discovery cannot be False if no key IDs are provided" )
110
+
111
+ if self ._is_discovery :
112
+ self ._inner_keyring = _AwsKmsDiscoveryKeyring (
113
+ client_supplier = self ._client_supplier , grant_tokens = self ._grant_tokens
114
+ )
115
+ return
116
+
96
117
if self ._generator_key_id is None :
97
118
generator_keyring = None
98
119
else :
@@ -107,14 +128,7 @@ def __attrs_post_init__(self):
107
128
for key_id in self ._child_key_ids
108
129
]
109
130
110
- self ._is_discovery = generator_keyring is None and not child_keyrings
111
-
112
- if self ._is_discovery :
113
- self ._inner_keyring = _AwsKmsDiscoveryKeyring (
114
- client_supplier = self ._client_supplier , grant_tokens = self ._grant_tokens
115
- )
116
- else :
117
- self ._inner_keyring = MultiKeyring (generator = generator_keyring , children = child_keyrings )
131
+ self ._inner_keyring = MultiKeyring (generator = generator_keyring , children = child_keyrings )
118
132
119
133
def on_encrypt (self , encryption_materials ):
120
134
# type: (EncryptionMaterials) -> EncryptionMaterials
0 commit comments