Commit e757e742 authored by ibuler's avatar ibuler

[Stash] 暂存

parent 4bd6cea6
......@@ -2,3 +2,4 @@
*.pyc
*.pyo
luna/keys/.access_key
logs/*.log
# coding: utf-8
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
PROJECT_DIR = os.path.dirname(BASE_DIR)
\ No newline at end of file
# ~*~ coding: utf-8 ~*~
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
class Config(object):
DEBUG = True
# NAME = 'luna'
# BIND_HOST = '0.0.0.0'
# LISTEN_PORT = 5000
# JUMPSERVER_ENDPOINT = 'http://localhost:8080'
# ACCESS_KEY = None
# ACCESS_KEY_ENV = 'LUNA_ACCESS_KEY'
# ACCESS_KEY_STORE = os.path.join(BASE_DIR, 'luna', 'keys', '.access_key')
# LOG_DIR = os.path.join(BASE_DIR, 'luna', 'logs')
# LOG_LEVEL = 'DEBUG'
# ASSET_LIST_SORT_BY = 'ip'
# HEATBEAT_INTERVAL = 5
DEBUG = True
# NAME = 'luna'
# BIND_HOST = '0.0.0.0'
# LISTEN_PORT = 5000
# JUMPSERVER_ENDPOINT = 'http://localhost:8080'
# ACCESS_KEY = None
# ACCESS_KEY_ENV = 'LUNA_ACCESS_KEY'
# ACCESS_KEY_STORE = os.path.join(BASE_DIR, 'luna', 'keys', '.access_key')
# LOG_DIR = os.path.join(BASE_DIR, 'luna', 'logs')
# LOG_LEVEL = 'DEBUG'
# ASSET_LIST_SORT_BY = 'ip'
# HEATBEAT_INTERVAL = 5
......@@ -4,6 +4,6 @@
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
from .luna import app, socket_io
from .app import app, socket_io
from . import authentication, views
import logger
# ~*~ coding: utf-8 ~*~
import os
import logging
import time
......@@ -8,28 +7,17 @@ from flask import Flask
import socketio
from jms import AppService, UserService
from jms.mixin import AppMixin
from .conf import config
logger = logging.getLogger(__file__)
from . import BASE_DIR
__version__ = '0.4.0'
class Luna(Flask, AppMixin):
default_config = dict(Flask.default_config)
default_config.update({
'NAME': 'luna',
'BIND_HOST': '0.0.0.0',
'LISTEN_PORT': 5000,
'JUMPSERVER_ENDPOINT': os.environ.get('JUMPSERVER_ENDPOINT') or 'http://localhost:8080',
'ACCESS_KEY': None,
'SECRET_KEY': 'Keep_secret!!',
'ACCESS_KEY_ENV': 'LUNA_ACCESS_KEY',
'ACCESS_KEY_STORE': os.path.join(BASE_DIR, 'keys', '.access_key'),
'LOG_LEVEL': 'DEBUG',
'LOG_DIR': os.path.join(BASE_DIR, 'logs'),
'ASSET_LIST_SORT_BY': 'ip',
'HEATBEAT_INTERVAL': 5,
})
default_config = config
app_service = None
clients = {}
......@@ -56,7 +44,13 @@ class Luna(Flask, AppMixin):
return Flask.run(self, host=host, port=port, debug=debug, **options)
async_mode = None
@classmethod
def stop(cls):
for i in cls.clients:
i.disconnect()
socket_io.stop()
async_mode = 'threading'
app = Luna(__name__, template_folder='dist')
socket_io = socketio.Server(logger=True, async_mode='threading')
socket_io = socketio.Server(logger=True, async_mode=async_mode)
app.wsgi_app = socketio.Middleware(socket_io, app.wsgi_app)
# ~*~ coding: utf-8 ~*~
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import os
from six import string_types
from werkzeug.utils import import_string
# from . import PROJECT_DIR
PROJECT_DIR = os.path.dirname(os.path.dirname(__file__))
class ConfigAttribute(object):
"""Makes an attribute forward to the config"""
def __init__(self, name, get_converter=None):
self.__name__ = name
self.get_converter = get_converter
def __get__(self, obj, type=None):
if obj is None:
return self
rv = obj.config[self.__name__]
if self.get_converter is not None:
rv = self.get_converter(rv)
return rv
def __set__(self, obj, value):
obj.config[self.__name__] = value
class Config(dict):
"""使用该类作为配置类, 方便设置值和属性, 使用默认值, 本类精简与flask.config
See: https://github.com/pallets/flask/blob/master/flask/settings.py
defaults_config = {
"NAME": "luna",
}
config = Config(defaults=defaults_config)
config['HOST'] = '0.0.0.0'
config.NAME 属性访问
或使用小写key作为变量
config.name
"""
default_config = {
'NAME': 'luna',
'BIND_HOST': '0.0.0.0',
'LISTEN_PORT': 5000,
'JUMPSERVER_ENDPOINT': 'http://localhost:8080',
'DEBUG': True,
'SECRET_KEY': '2vym+ky!997d5kkcc64mnz06y1mmui3lut#(^wd=%s_qj$1%x',
'ACCESS_KEY': None,
'ACCESS_KEY_ENV': 'COCO_ACCESS_KEY',
'ACCESS_KEY_STORE': os.path.join(PROJECT_DIR, 'keys', '.access_key'),
'LOG_LEVEL': 'DEBUG',
'LOG_DIR': os.path.join(PROJECT_DIR, 'logs'),
'ASSET_LIST_SORT_BY': 'ip',
'SSH_PASSWORD_AUTH': True,
'SSH_PUBLIC_KEY_AUTH': True,
'HEATBEAT_INTERVAL': 5,
'BROKER_URL': 'redis://localhost:6379',
'CELERY_RESULT_BACKEND': 'redis://localhost:6379',
# 'CELERY_ACCEPT_CONTENT': ['json']
}
def __init__(self, defaults=default_config):
super(Config, self).__init__(defaults or {})
def from_object(self, obj):
"""从object对象获取配置, 或者导入一个配置模块
from local_config import Config
config.from_object(Config)
或从配置模块导入
config.from_object('some_settings')
"""
if isinstance(obj, string_types):
obj = import_string(obj)
for key in dir(obj):
if key.isupper():
self[key] = getattr(obj, key)
def __getattr__(self, item):
try:
return self.__getitem__(item)
except KeyError:
return self.__getitem__(item.upper())
config = Config()
config.from_object(os.environ.get('LUNA_CONFIG_MODULE', object()))
# ~*~ coding: utf-8 ~*~
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import os
import logging
from logging import StreamHandler
from logging.handlers import TimedRotatingFileHandler
from .conf import config
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
LOG_LEVELS = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARN': logging.WARNING,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'FATAL': logging.FATAL,
'CRITICAL': logging.CRITICAL,
}
def create_logger():
level = config.get('LOG_LEVEL', None)
level = LOG_LEVELS.get(level, logging.INFO)
log_dir = config.get('LOG_DIR', os.path.join(PROJECT_DIR, 'logs'))
log_path = os.path.join(log_dir, 'luna.log')
logger_root = logging.getLogger()
logger = logging.getLogger(config.get('NAME', 'luna'))
main_formatter = logging.Formatter(
fmt='%(asctime)s [%(module)s %(levelname)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
console_handler = StreamHandler()
file_handler = TimedRotatingFileHandler(
filename=log_path, when='D', backupCount=10)
for handler in [console_handler, file_handler]:
handler.setFormatter(main_formatter)
logger.addHandler(handler)
logger_root.addHandler(console_handler)
logger_root.setLevel(logging.WARNING)
logger.setLevel(level)
def get_logger(name):
return logging.getLogger('luna.%s' % name)
create_logger()
......@@ -7,6 +7,7 @@ import select
import threading
import collections
import json
import logging
import paramiko
......@@ -14,6 +15,7 @@ from .. import app, socket_io
from ..nav import nav
clients = app.clients
logger = logging.getLogger(__file__)
__all__ = [
......@@ -39,16 +41,12 @@ def handle_machine(sid, message):
t = threading.Thread(target=forward, args=(sid,))
t.setDaemon(True)
t.start()
# global thread
# if thread is None:
# thread = socket_io.start_background_task(forward, sid)
socket_io.emit('data', 'Connect to %s:%s \r\n' % (host, port), room=sid)
print(t.is_alive())
@socket_io.on('data')
def handle_data(sid, message):
print('Receive data: %s' % message)
logger.debug('Receive data: %s' % message)
if clients[sid]['chan']:
clients[sid]['chan'].send(message)
......@@ -61,7 +59,7 @@ def handle_term_disconnect(sid):
@socket_io.on('resize')
def handle_term_resize(sid, json):
print(json)
logger.debug('Resize term: %s' % json)
def forward(sid):
......
#!/usr/bin/env python
# coding: utf-8
import select
import threading
import collections
import json
import paramiko
from flask import render_template, send_from_directory
from . import app, socket_io
from .nav import nav
clients = app.clients
@app.route('/')
def index():
return render_template('index.html')
@app.route('/luna/')
def luna():
return render_template('index.html')
@app.route('/luna/<path:path>')
def send_dist(path):
return send_from_directory('dist', path)
@socket_io.on('nav')
def handle_api(sid):
socket_io.emit('nav', json.dumps(nav), room=sid)
@socket_io.on('connect', namespace='/')
def handle_term_connect(sid, environ):
clients[sid] = collections.defaultdict(dict)
@socket_io.on('machine')
def handle_machine(sid, message):
clients[sid]['host'] = host = '192.168.152.129'
clients[sid]['port'] = port = 22
t = threading.Thread(target=forward, args=(sid,))
t.setDaemon(True)
t.start()
# global thread
# if thread is None:
# thread = socket_io.start_background_task(forward, sid)
socket_io.emit('data', 'Connect to %s:%s \r\n' % (host, port), room=sid)
print(t.is_alive())
@socket_io.on('data')
def handle_data(sid, message):
print('Receive data: %s' % message)
if clients[sid]['chan']:
clients[sid]['chan'].send(message)
@socket_io.on('disconnect')
def handle_term_disconnect(sid):
del clients[sid]
print('term disconnect')
@socket_io.on('resize')
def handle_term_resize(sid, json):
print(json)
def forward(sid):
try:
host = clients[sid]['host']
port = clients[sid]['port']
except KeyError as e:
socket_io.emit('data', e, room=sid)
return
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port=port, username='root', password='redhat')
clients[sid]['ssh'] = ssh
clients[sid]['chan'] = chan = ssh.invoke_shell()
while True:
r, w, x = select.select([chan], [], [])
if chan in r:
data = chan.recv(1024)
if not len(data):
break
socket_io.emit('data', data, room=sid)
#!/usr/bin/env python
# ~*~ coding: utf-8 ~*~
import os
from config import Config
from luna import app, socket_io
# import subprocess
from luna import app
os.environ.setdefault('LUNA_CONFIG_MODULE', 'luna.config')
app.config.from_object(Config)
host = app.config['BIND_HOST']
port = app.config['LISTEN_PORT']
if __name__ == '__main__':
if socket_io.async_mode == 'threading':
app.run(threaded=True)
elif socket_io.async_mode == 'eventlet':
import eventlet
import eventlet.wsgi
eventlet.wsgi.server(eventlet.listen(('', 5000)), app)
elif socket_io.async_mode == 'gevent':
# deploy with gevent
from gevent import pywsgi
try:
app.run(threaded=True, host=host, port=port)
except KeyboardInterrupt:
app.stop()
try:
from geventwebsocket.handler import WebSocketHandler
websocket = True
except ImportError:
websocket = False
if websocket:
pywsgi.WSGIServer(('', 5000), app,
handler_class=WebSocketHandler).serve_forever()
else:
pywsgi.WSGIServer(('', 5000), app).serve_forever()
else:
print('Unkonw async_mode: ' + socket_io.async_mode)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment