Commit e757e742 authored by ibuler's avatar ibuler

[Stash] 暂存

parent 4bd6cea6
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
*.pyc *.pyc
*.pyo *.pyo
luna/keys/.access_key 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 ~*~ # ~*~ coding: utf-8 ~*~
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__)) DEBUG = True
# NAME = 'luna'
# BIND_HOST = '0.0.0.0'
class Config(object): # LISTEN_PORT = 5000
DEBUG = True # JUMPSERVER_ENDPOINT = 'http://localhost:8080'
# NAME = 'luna' # ACCESS_KEY = None
# BIND_HOST = '0.0.0.0' # ACCESS_KEY_ENV = 'LUNA_ACCESS_KEY'
# LISTEN_PORT = 5000 # ACCESS_KEY_STORE = os.path.join(BASE_DIR, 'luna', 'keys', '.access_key')
# JUMPSERVER_ENDPOINT = 'http://localhost:8080' # LOG_DIR = os.path.join(BASE_DIR, 'luna', 'logs')
# ACCESS_KEY = None # LOG_LEVEL = 'DEBUG'
# ACCESS_KEY_ENV = 'LUNA_ACCESS_KEY' # ASSET_LIST_SORT_BY = 'ip'
# ACCESS_KEY_STORE = os.path.join(BASE_DIR, 'luna', 'keys', '.access_key') # HEATBEAT_INTERVAL = 5
# LOG_DIR = os.path.join(BASE_DIR, 'luna', 'logs')
# LOG_LEVEL = 'DEBUG'
# ASSET_LIST_SORT_BY = 'ip'
# HEATBEAT_INTERVAL = 5
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
import os import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__)) 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 from . import authentication, views
import logger
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
import os
import logging import logging
import time import time
...@@ -8,28 +7,17 @@ from flask import Flask ...@@ -8,28 +7,17 @@ from flask import Flask
import socketio import socketio
from jms import AppService, UserService from jms import AppService, UserService
from jms.mixin import AppMixin from jms.mixin import AppMixin
from .conf import config
logger = logging.getLogger(__file__)
from . import BASE_DIR
__version__ = '0.4.0' __version__ = '0.4.0'
class Luna(Flask, AppMixin): class Luna(Flask, AppMixin):
default_config = dict(Flask.default_config) default_config = 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,
})
app_service = None app_service = None
clients = {} clients = {}
...@@ -56,7 +44,13 @@ class Luna(Flask, AppMixin): ...@@ -56,7 +44,13 @@ class Luna(Flask, AppMixin):
return Flask.run(self, host=host, port=port, debug=debug, **options) 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') 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) 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 ...@@ -7,6 +7,7 @@ import select
import threading import threading
import collections import collections
import json import json
import logging
import paramiko import paramiko
...@@ -14,6 +15,7 @@ from .. import app, socket_io ...@@ -14,6 +15,7 @@ from .. import app, socket_io
from ..nav import nav from ..nav import nav
clients = app.clients clients = app.clients
logger = logging.getLogger(__file__)
__all__ = [ __all__ = [
...@@ -39,16 +41,12 @@ def handle_machine(sid, message): ...@@ -39,16 +41,12 @@ def handle_machine(sid, message):
t = threading.Thread(target=forward, args=(sid,)) t = threading.Thread(target=forward, args=(sid,))
t.setDaemon(True) t.setDaemon(True)
t.start() 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) socket_io.emit('data', 'Connect to %s:%s \r\n' % (host, port), room=sid)
print(t.is_alive())
@socket_io.on('data') @socket_io.on('data')
def handle_data(sid, message): def handle_data(sid, message):
print('Receive data: %s' % message) logger.debug('Receive data: %s' % message)
if clients[sid]['chan']: if clients[sid]['chan']:
clients[sid]['chan'].send(message) clients[sid]['chan'].send(message)
...@@ -61,7 +59,7 @@ def handle_term_disconnect(sid): ...@@ -61,7 +59,7 @@ def handle_term_disconnect(sid):
@socket_io.on('resize') @socket_io.on('resize')
def handle_term_resize(sid, json): def handle_term_resize(sid, json):
print(json) logger.debug('Resize term: %s' % json)
def forward(sid): 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 #!/usr/bin/env python
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
import os
from config import Config from luna import app
from luna import app, socket_io
# import subprocess os.environ.setdefault('LUNA_CONFIG_MODULE', 'luna.config')
app.config.from_object(Config)
host = app.config['BIND_HOST'] host = app.config['BIND_HOST']
port = app.config['LISTEN_PORT'] port = app.config['LISTEN_PORT']
if __name__ == '__main__': if __name__ == '__main__':
if socket_io.async_mode == 'threading': try:
app.run(threaded=True) app.run(threaded=True, host=host, port=port)
elif socket_io.async_mode == 'eventlet': except KeyboardInterrupt:
import eventlet app.stop()
import eventlet.wsgi
eventlet.wsgi.server(eventlet.listen(('', 5000)), app)
elif socket_io.async_mode == 'gevent':
# deploy with gevent
from gevent import pywsgi
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