From 8cff562e6402e707ec738df9e34d1eea7e331fd5 Mon Sep 17 00:00:00 2001 From: "kuldeep.k@cisinlabs.com" Date: Thu, 3 Feb 2022 21:02:58 +0530 Subject: [PATCH] Updated code for send mail functionality --- config.ini | 9 +++ main.py | 171 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 18 +++++ 3 files changed, 198 insertions(+) create mode 100644 config.ini create mode 100644 main.py create mode 100644 requirements.txt diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..d0d3fc1 --- /dev/null +++ b/config.ini @@ -0,0 +1,9 @@ +[server] +server_host = 0.0.0.0 +server_port = 8081 + +[app] +to_mail = test111@mailinator.com +from_mail = test@gmail.com +from_mail_password = test@123 + diff --git a/main.py b/main.py new file mode 100644 index 0000000..009898e --- /dev/null +++ b/main.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +""" +Serve cloud init files +""" + +import configparser +import os +import json +import smtplib +import socket +import sys +from email.header import Header +from email.mime.text import MIMEText + +import uuid as uuid_module +from ipaddress import AddressValueError, IPv4Address, IPv6Address + +import cherrypy + +PATH = os.path.dirname(os.path.abspath(__file__)) +CONFIG = configparser.ConfigParser() +CONFIG.read(os.path.join(PATH, "config.ini")) + +TO_MAIL = CONFIG["app"].get("to_mail") +FROM_MAIL = CONFIG["app"].get("from_mail") +FROM_MAIL_PASSWORD = CONFIG["app"].get("from_mail_password") +print("TO_MAIL: ", TO_MAIL) +print("FROM_MAIL: ", FROM_MAIL) +print("FROM_MAIL_PASSWORD: ", FROM_MAIL_PASSWORD) + + +class CloudInitRequest: + """ + Request data for persistence across methods + """ + def __init__(self, request, uuid=None): + self.remoteip = None + self.hostinfo = ('localhost', ) + self.request = request + self.meta_data = None + self.meta_data_loaded = False + self.user_data = None + + try: + self.uuid = str(uuid_module.UUID('{' + uuid + '}')) + # ValueError is wrong UUID syntax + # TypeError is None + except (ValueError, TypeError): + self.uuid = None + + self._init_ip() + + def _can_ip_be_proxy(self): + """ + Assuming the connection is through a proxy, is this proxy permitted? + Can't proxy from a publicly reachable IP. + """ + self.remoteip = self.request.remote.ip + try: + ipobj = IPv4Address(self.remoteip) + except AddressValueError: + try: + ipobj = IPv6Address(self.remoteip) + except AddressValueError: + return False + return not ipobj.is_global + + def _init_ip(self): + """ + Get remote IP + """ + if self._can_ip_be_proxy(): + try: + self.remoteip = self.request.headers.get( + 'X-Real-Ip', + self.request.remote.ip + ) + except KeyError: + pass + + try: + self.hostinfo = socket.gethostbyaddr(self.remoteip) + forward_lookup = socket.gethostbyname(self.hostinfo[0]) + if forward_lookup != self.remoteip: + self.hostinfo = ('localhost', ) + except socket.herror: + self.hostinfo = ('localhost', ) + except socket.gaierror: + self.hostinfo = (self.remoteip, ) + + +class CloudInitApp: + """ + Serve cloud init files + """ + + @staticmethod + def _content_type(data): + if not data: + return "text/cloud-config" + if data.startswith("#include"): + return "text/x-include-url" + if data.startswith("## template: jinja"): + return "text/jinja2" + return "text/cloud-config" + + def _send_mail(self): + try: + # pylint: disable=deprecated-lambda + cl = cherrypy.request.headers['Content-Length'] + rawbody = cherrypy.request.body.read(int(cl)) + req_body = json.loads(rawbody) + subject = req_body['subject'] + body = req_body['body'] + client = smtplib.SMTP('smtp.gmail.com') + msg = MIMEText(body, 'plain', 'utf-8') + msg['Subject'] = Header(subject, 'utf-8') + msg['From'] = FROM_MAIL + msg['To'] = TO_MAIL + + client.ehlo() + client.starttls() + client.ehlo() + client.login(msg["From"], FROM_MAIL_PASSWORD) + client.sendmail(msg['From'], msg['To'], msg.as_string()) + client.quit() + return "mail sent successfully" + except Exception as e: + return "some error: {}".format(e) + + @cherrypy.expose + def send_mail(self): + """ + v1 api endpoint user-data + """ + return self._send_mail() + + +ROOT = CloudInitApp() + +if __name__ == "__main__": + cherrypy.server.socket_host = \ + CONFIG["server"].get("server_host", "127.0.0.1") + cherrypy.server.socket_port = \ + CONFIG["server"].getint("server_port", 8081) + ENGINE = cherrypy.engine + + CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) + CONFIG = { + '/include': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': os.path.join(CURRENT_DIR, + 'data', + 'include'), + 'tools.staticdir.content_types': { + 'yml': 'text/yaml' + } + } + } + cherrypy.tree.mount(ROOT, config=CONFIG) + + if hasattr(ENGINE, "signal_handler"): + ENGINE.signal_handler.subscribe() + if hasattr(ENGINE, "console_control_handler"): + ENGINE.console_control_handler.subscribe() + try: + ENGINE.start() + except Exception: # pylint: disable=broad-except + sys.exit(1) + else: + ENGINE.block() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ac9d4e8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +cheroot==8.6.0 +CherryPy==18.6.1 +importlib-resources==5.4.0 +jaraco.classes==3.2.1 +jaraco.collections==3.5.1 +jaraco.context==4.1.1 +jaraco.functools==3.5.0 +jaraco.text==3.7.0 +Jinja2==3.0.3 +MarkupSafe==2.0.1 +more-itertools==8.12.0 +portend==3.1.0 +pytz==2021.3 +PyYAML==6.0 +six==1.16.0 +tempora==5.0.1 +zc.lockfile==2.0 +zipp==3.7.0