Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
L
luna
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
luna
Commits
e757e742
Commit
e757e742
authored
Feb 20, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Stash] 暂存
parent
4bd6cea6
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
198 additions
and
162 deletions
+198
-162
.gitignore
.gitignore
+1
-0
__init__.py
__init__.py
+6
-0
config.py
config.py
+12
-17
.gitkeep
logs/.gitkeep
+0
-0
__init__.py
luna/__init__.py
+2
-2
app.py
luna/app.py
+13
-19
conf.py
luna/conf.py
+99
-0
logger.py
luna/logger.py
+52
-0
websocket.py
luna/views/websocket.py
+4
-6
views123.py
luna/views123.py
+0
-93
mac_requirements.txt
requirements/mac_requirements.txt
+0
-0
requirements.txt
requirements/requirements.txt
+0
-0
rpm_requirements.txt
requirements/rpm_requirements.txt
+0
-0
run_server.py
run_server.py
+9
-25
No files found.
.gitignore
View file @
e757e742
...
@@ -2,3 +2,4 @@
...
@@ -2,3 +2,4 @@
*.pyc
*.pyc
*.pyo
*.pyo
luna/keys/.access_key
luna/keys/.access_key
logs/*.log
__init__.py
View file @
e757e742
# 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
config.py
View file @
e757e742
# ~*~ 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
mac_requirements.txt
→
logs/.gitkeep
View file @
e757e742
File moved
luna/__init__.py
View file @
e757e742
...
@@ -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
luna/
luna
.py
→
luna/
app
.py
View file @
e757e742
# ~*~ 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
)
luna/conf.py
0 → 100644
View file @
e757e742
# ~*~ 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
()))
luna/logger.py
0 → 100644
View file @
e757e742
# ~*~ 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
()
luna/views/websocket.py
View file @
e757e742
...
@@ -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
):
...
...
luna/views123.py
deleted
100644 → 0
View file @
4bd6cea6
#!/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
)
requirements/mac_requirements.txt
0 → 100644
View file @
e757e742
requirements.txt
→
requirements
/requirements
.txt
View file @
e757e742
File moved
rpm_requirements.txt
→
r
equirements/r
pm_requirements.txt
View file @
e757e742
File moved
run_server.py
View file @
e757e742
#!/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
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment