Compare commits

..

No commits in common. "67a2395db3a4c467d00b340e3335302a43d7efee" and "360917be5d23af0fbaf34ae70de94b36bb3f1425" have entirely different histories.

107
main.py
View File

@ -1,78 +1,39 @@
#!/usr/bin/env python3
"""
Serve cloud init files
"""
import configparser
import os import os
import socket
import sys import sys
from ipaddress import AddressValueError, IPv4Address, IPv6Address
import yaml
import cherrypy import cherrypy
from cherrypy.lib.static import serve_file from cherrypy.lib.static import serve_file
import yaml
import socket
import configparser
PATH = os.path.dirname(os.path.abspath(__file__)) PATH = os.path.dirname(os.path.abspath(__file__))
CONFIG = configparser.ConfigParser() config = configparser.ConfigParser()
CONFIG.read(os.path.join(PATH, "config.ini")) config.read(os.path.join(PATH, "config.ini"))
USER_DATA_FILENAME = CONFIG["app"].get("user_data", "user-data") user_data_filename = config["app"].get("user_data", "sample_file.txt")
META_DATA_FILENAME = CONFIG["app"].get("meta_data", "meta-data") meta_data_filename = config["app"].get("meta_data", "meta_data_extra.txt")
REDIRECT_FILENAME = CONFIG["app"].get("redirect", "redirect")
class CloudInitApp: class MainApp:
"""
Serve cloud init files
"""
def __init__(self):
self.remoteip = None
self.hostinfo = ('localhost', )
def _can_ip_be_proxy(self):
self.remoteip = cherrypy.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): def _init_ip(self):
""" """
Get remote IP Get remote IP
""" """
if self._can_ip_be_proxy():
try: try:
self.remoteip = cherrypy.request.headers.get( self.remoteip = cherrypy.request.headers.get(
'X-Real-Ip', 'X-Real-Ip',
cherrypy.request.remote.ip cherrypy.request.remote.ip
) )
except KeyError: except:
pass self.remoteip = cherrypy.request.remote.ip
try: try:
self.hostinfo = socket.gethostbyaddr(self.remoteip) self.hostinfo = socket.gethostbyaddr(self.remoteip)
except socket.herror: except socket.herror:
pass self.hostinfo = ('localhost', )
def _redirect_if_needed(self):
filepath = os.path.join(PATH, "data", self.hostinfo[0],
REDIRECT_FILENAME)
if os.path.exists(filepath):
try:
with open(filepath) as redirect:
content = redirect.read().splitlines()
raise cherrypy.HTTPRedirect(content[0], 301)
except IOError:
return False
return False
@cherrypy.expose @cherrypy.expose
def user_data(self): def user_data(self):
@ -80,12 +41,11 @@ class CloudInitApp:
Serves a static file Serves a static file
""" """
self._init_ip() self._init_ip()
self._redirect_if_needed()
filepath = os.path.join(PATH, "data", self.hostinfo[0], filepath = os.path.join(PATH, "data", self.hostinfo[0],
USER_DATA_FILENAME) user_data_filename)
if not os.path.exists(filepath): if not os.path.exists(filepath):
filepath = os.path.join(PATH, "data", USER_DATA_FILENAME) filepath = os.path.join(PATH, "data", user_data_filename)
return serve_file(filepath, "text/yaml", "attachment") return serve_file(filepath, "application/x-download", "attachment")
@cherrypy.expose @cherrypy.expose
def meta_data(self): def meta_data(self):
@ -93,33 +53,18 @@ class CloudInitApp:
Return meta-data in YAML Return meta-data in YAML
""" """
self._init_ip() self._init_ip()
self._redirect_if_needed()
hostname =self.hostinfo[0] hostname =self.hostinfo[0]
data = { data = {"instance-id": hostname.split(".")[0], "local-hostname": hostname}
"instance-id": hostname.split(".")[0],
"local-hostname": hostname
}
filepath = os.path.join(PATH, "data", hostname, META_DATA_FILENAME) filepath = os.path.join(PATH, "data", hostname, meta_data_filename)
if os.path.exists(filepath): if os.path.exists(filepath):
with open(filepath, "r") as metadata: with open(filepath, "r") as f:
for line in metadata.readlines(): line = f.readlines()[0]
linesplit = list(map(lambda k: k.strip(), line.split(":"))) ls = list(map(lambda k: k.strip(), line.split(":")))
data[linesplit[0]] = linesplit[1] data[ls[0]] = ls[1]
cherrypy.response.headers['Content-Type'] = \
'text/yaml'
cherrypy.response.headers['Content-Disposition'] = \
'attachment; filename="user-data"'
return yaml.dump(data) return yaml.dump(data)
@cherrypy.expose
def vendor_data(self):
"""
Return empty vendor-data
"""
return ""
@cherrypy.expose @cherrypy.expose
def finished(self, data): def finished(self, data):
""" """
@ -132,17 +77,15 @@ class CloudInitApp:
if not os.path.exists(folder): if not os.path.exists(folder):
os.makedirs(folder) os.makedirs(folder)
with open(os.path.join(folder, META_DATA_FILENAME), "w") as fin: with open(os.path.join(folder, meta_data_filename), "w") as f:
fin.write(data) f.write(data)
ROOT = CloudInitApp() ROOT = MainApp()
if __name__ == "__main__": if __name__ == "__main__":
cherrypy.server.socket_host = \ cherrypy.server.socket_host = config["server"].get("server_host", "127.0.0.1")
CONFIG["server"].get("server_host", "127.0.0.1") cherrypy.server.socket_port = config["server"].getint("server_port", 8081)
cherrypy.server.socket_port = \
CONFIG["server"].getint("server_port", 8081)
ENGINE = cherrypy.engine ENGINE = cherrypy.engine
cherrypy.tree.mount(ROOT) cherrypy.tree.mount(ROOT)