Repository: cloud-custodian/cloud-custodian

Issue:
Add KMS support for c7n_mailer when not deploying via lambda
Currently c7n_mailer does a kms decrypt of the `ldap_bind_password` for lambda based executions but not when using `--run`


Discussion:
should probably just do it in a try/except with a default of use what was given, so its automatic.
Alternatively should we use the ‘ldap_password_in_kms’ option that is already for the configuration file and move the logic to resolve the kms key out of handler.py?
@alfredgamulo do you want to pick this up?

Resolving patch:
diff --git a/tools/c7n_mailer/c7n_mailer/email_delivery.py b/tools/c7n_mailer/c7n_mailer/email_delivery.py
--- a/tools/c7n_mailer/c7n_mailer/email_delivery.py
+++ b/tools/c7n_mailer/c7n_mailer/email_delivery.py
@@ -11,8 +11,10 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+import base64
 import smtplib
 
+from botocore.exceptions import ClientError
 from email.mime.text import MIMEText
 from email.utils import parseaddr
 
@@ -28,11 +30,28 @@ class EmailDelivery(object):
     def __init__(self, config, session, logger):
         self.config      = config
         self.logger      = logger
+        self.session     = session
         self.aws_ses     = session.client('ses', region_name=config.get('ses_region'))
         self.ldap_lookup = self.get_ldap_connection()
 
     def get_ldap_connection(self):
         if self.config.get('ldap_uri'):
+            try:
+                if self.config.get('ldap_bind_password', None):
+                    kms = self.session.client('kms')
+                    self.config['ldap_bind_password'] = kms.decrypt(
+                        CiphertextBlob=base64.b64decode(self.config['ldap_bind_password']))[
+                            'Plaintext']
+            except (TypeError, base64.binascii.Error) as e:
+                self.logger.warning(
+                    "Error: %s Unable to base64 decode ldap_bind_password, will assume plaintext." % (e)
+                )
+            except ClientError as e:
+                if e.response['Error']['Code'] != 'InvalidCiphertextException':
+                    raise
+                self.logger.warning(
+                    "Error: %s Unable to decrypt ldap_bind_password with kms, will assume plaintext." % (e)
+                )
             return LdapLookup(self.config, self.logger)
         return None
 
diff --git a/tools/c7n_mailer/c7n_mailer/handle.py b/tools/c7n_mailer/c7n_mailer/handle.py
--- a/tools/c7n_mailer/c7n_mailer/handle.py
+++ b/tools/c7n_mailer/c7n_mailer/handle.py
@@ -16,7 +16,6 @@
 """
 from __future__ import absolute_import, division, print_function, unicode_literals
 
-import base64
 import boto3
 import json
 import os
@@ -24,17 +23,12 @@
 from .sqs_queue_processor import MailerSqsQueueProcessor
 
 
-def config_setup(session, config=None):
+def config_setup(config=None):
     task_dir = os.environ.get('LAMBDA_TASK_ROOT')
     os.environ['PYTHONPATH'] = "%s:%s" % (task_dir, os.environ.get('PYTHONPATH', ''))
     if not config:
         with open(os.path.join(task_dir, 'config.json')) as fh:
             config = json.load(fh)
-    if config['ldap_bind_password'] and config.get('ldap_bind_password_in_kms', True):
-        kms = session.client('kms')
-        config['ldap_bind_password'] = kms.decrypt(
-            CiphertextBlob=base64.b64decode(config['ldap_bind_password']))[
-                'Plaintext']
     if 'http_proxy' in config:
         os.environ['http_proxy'] = config['http_proxy']
     if 'https_proxy' in config:
@@ -46,7 +40,7 @@ def start_c7n_mailer(logger, config=None, parallel=False):
     try:
         session = boto3.Session()
         if not config:
-            config = config_setup(session)
+            config = config_setup()
         logger.info('c7n_mailer starting...')
         mailer_sqs_queue_processor = MailerSqsQueueProcessor(config, session, logger)
         mailer_sqs_queue_processor.run(parallel)
diff --git a/tools/c7n_mailer/c7n_mailer/ldap_lookup.py b/tools/c7n_mailer/c7n_mailer/ldap_lookup.py
--- a/tools/c7n_mailer/c7n_mailer/ldap_lookup.py
+++ b/tools/c7n_mailer/c7n_mailer/ldap_lookup.py
@@ -27,12 +27,12 @@
 class LdapLookup(object):
 
     def __init__(self, config, logger):
+        self.log          = logger
         self.connection = self.get_connection(
             config.get('ldap_uri'),
             config.get('ldap_bind_user', None),
             config.get('ldap_bind_password', None)
         )
-        self.log          = logger
         self.base_dn      = config.get('ldap_bind_dn')
         self.email_key    = config.get('ldap_email_key', 'mail')
         self.manager_attr = config.get('ldap_manager_attribute', 'manager')


Test patch: