Compare commits
2 Commits
74894991b0
...
9e182c4b94
Author | SHA1 | Date | |
---|---|---|---|
9e182c4b94 | |||
8cff562e64 |
17
Dockerfile
Normal file
17
Dockerfile
Normal file
|
@ -0,0 +1,17 @@
|
|||
# pull official base image
|
||||
FROM python:3.9.6-alpine
|
||||
|
||||
# set work directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE 1
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
# install dependencies
|
||||
RUN pip install --upgrade pip
|
||||
COPY ./requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
# copy project
|
||||
COPY . .
|
9
config.ini
Normal file
9
config.ini
Normal file
|
@ -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
|
||||
|
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
command: python main.py
|
||||
volumes:
|
||||
- mailsend_server:/usr/src/app/
|
||||
ports:
|
||||
- 8081:8081
|
||||
env_file:
|
||||
- ./config.ini
|
||||
|
||||
volumes:
|
||||
mailsend_server:
|
171
main.py
Normal file
171
main.py
Normal file
|
@ -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()
|
18
requirements.txt
Normal file
18
requirements.txt
Normal file
|
@ -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
|
Loading…
Reference in New Issue
Block a user