Skip to content

Commit 8d57ded

Browse files
committed
测试web端登录docker容器
1 parent 60c92ac commit 8d57ded

12 files changed

Lines changed: 1532 additions & 1248 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ wheels/
3030
.installed.cfg
3131
*.egg
3232
MANIFEST
33+
.idea
3334

3435
# PyInstaller
3536
# Usually these files are written by a python script from a template

Ops/celery.py

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
1-
# -*- coding: utf-8 -*-
2-
"""
3-
-------------------------------------------------
4-
File Name: celery
5-
Description:
6-
Author: Administrator
7-
date: 2018-07-16
8-
-------------------------------------------------
9-
Change Activity:
10-
2018-07-16:
11-
-------------------------------------------------
12-
"""
13-
import os
14-
from celery import Celery
15-
from kombu import Queue, Exchange
16-
17-
# set the default Django settings module for the 'celery' program.
18-
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Ops.settings')
19-
20-
app = Celery('Ops', broker='redis://127.0.0.1:6379/0')
21-
22-
app.conf.task_queues = (
23-
Queue('default', Exchange('default', type='direct'), routing_key='default'),
24-
Queue('ansible', Exchange('ansible', type='direct'), routing_key='ansible'),
25-
Queue('fort', Exchange('fort', type='direct'), routing_key='fort'),
26-
Queue('plan', Exchange('plan', type='direct'), routing_key='plan'),
27-
Queue('commons', Exchange('commons', type='direct'), routing_key='commons'),
28-
)
29-
30-
app.conf.task_default_queue = 'default'
31-
app.conf.task_default_exchange = 'default'
32-
app.conf.task_default_exchange_type = 'direct'
33-
app.conf.task_default_routing_key = 'default'
34-
app.conf.timezone = 'Asia/Shanghai'
35-
app.conf.enable_utc = False
36-
37-
# Using a string here means the worker doesn't have to serialize
38-
# the configuration object to child processes.
39-
# - namespace='CELERY' means all celery-related configuration keys
40-
# should have a `CELERY_` prefix.
41-
app.config_from_object('django.conf:settings', namespace='CELERY')
42-
43-
# Load task modules from all registered Django app configs.
44-
app.autodiscover_tasks()
1+
# -*- coding: utf-8 -*-
2+
"""
3+
-------------------------------------------------
4+
File Name: celery
5+
Description:
6+
Author: Administrator
7+
date: 2018-07-16
8+
-------------------------------------------------
9+
Change Activity:
10+
2018-07-16:
11+
-------------------------------------------------
12+
"""
13+
import os
14+
from celery import Celery
15+
from kombu import Queue, Exchange
16+
17+
# set the default Django settings module for the 'celery' program.
18+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Ops.settings')
19+
20+
app = Celery('Ops', broker='redis://127.0.0.1:7779/0')
21+
22+
app.conf.task_queues = (
23+
Queue('default', Exchange('default', type='direct'), routing_key='default'),
24+
Queue('ansible', Exchange('ansible', type='direct'), routing_key='ansible'),
25+
Queue('fort', Exchange('fort', type='direct'), routing_key='fort'),
26+
Queue('plan', Exchange('plan', type='direct'), routing_key='plan'),
27+
Queue('commons', Exchange('commons', type='direct'), routing_key='commons'),
28+
)
29+
30+
app.conf.task_default_queue = 'default'
31+
app.conf.task_default_exchange = 'default'
32+
app.conf.task_default_exchange_type = 'direct'
33+
app.conf.task_default_routing_key = 'default'
34+
app.conf.timezone = 'Asia/Shanghai'
35+
app.conf.enable_utc = False
36+
37+
# Using a string here means the worker doesn't have to serialize
38+
# the configuration object to child processes.
39+
# - namespace='CELERY' means all celery-related configuration keys
40+
# should have a `CELERY_` prefix.
41+
app.config_from_object('django.conf:settings', namespace='CELERY')
42+
43+
# Load task modules from all registered Django app configs.
44+
app.autodiscover_tasks()

Ops/routing.py

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
1-
# -*- coding: utf-8 -*-
2-
"""
3-
-------------------------------------------------
4-
File Name: routing
5-
Description:
6-
Author: pythonzm
7-
date: 2018/6/6
8-
-------------------------------------------------
9-
Change Activity:
10-
2018/6/6:
11-
-------------------------------------------------
12-
"""
13-
from django.urls import path, re_path
14-
from channels.routing import ProtocolTypeRouter, URLRouter
15-
from channels.auth import AuthMiddlewareStack
16-
from projs.utils.log_websocket import LogConsumer
17-
from fort.utils.webssh import FortConsumer
18-
from assets.utils.webssh import SSHConsumer
19-
from fort.utils.webguacamole import GuacamoleConsumer
20-
from assets.utils.webguacamole import AdminGuacamole
21-
from task.utils.ans_module_websocket import AnsModuleConsumer
22-
from task.utils.ans_playbook_websocket import AnsPlaybookConsumer
23-
from projs.utils.deploy_websocket import DeployConsumer
24-
25-
application = ProtocolTypeRouter({
26-
27-
"websocket": AuthMiddlewareStack(
28-
URLRouter([
29-
# URLRouter just takes standard Django path() or url() entries.
30-
path(r'ws/deploy/', DeployConsumer),
31-
path(r'ws/ans_module_log/', AnsModuleConsumer),
32-
path(r'ws/ans_playbook_log/', AnsPlaybookConsumer),
33-
path(r'ws/deploy_log/', LogConsumer),
34-
re_path(r'ws/fortssh/([0-9]+)/([0-9]+)/', FortConsumer),
35-
re_path(r'ws/webssh/([0-9]+)/', SSHConsumer),
36-
re_path(r'ws/fort_guacamole/([0-9]+)/([0-9]+)/(?P<group_name>.*)/', GuacamoleConsumer),
37-
re_path(r'ws/admin_guacamole/([0-9]+)/(?P<group_name>.*)/', AdminGuacamole),
38-
]),
39-
),
40-
})
1+
# -*- coding: utf-8 -*-
2+
"""
3+
-------------------------------------------------
4+
File Name: routing
5+
Description:
6+
Author: pythonzm
7+
date: 2018/6/6
8+
-------------------------------------------------
9+
Change Activity:
10+
2018/6/6:
11+
-------------------------------------------------
12+
"""
13+
from django.urls import path, re_path
14+
from channels.routing import ProtocolTypeRouter, URLRouter
15+
from channels.auth import AuthMiddlewareStack
16+
from projs.utils.log_websocket import LogConsumer
17+
from fort.utils.webssh import FortConsumer
18+
from assets.utils.webssh import SSHConsumer
19+
from assets.utils.docker_ssh import DockerConsumer
20+
from fort.utils.webguacamole import GuacamoleConsumer
21+
from assets.utils.webguacamole import AdminGuacamole
22+
from task.utils.ans_module_websocket import AnsModuleConsumer
23+
from task.utils.ans_playbook_websocket import AnsPlaybookConsumer
24+
from projs.utils.deploy_websocket import DeployConsumer
25+
26+
application = ProtocolTypeRouter({
27+
28+
"websocket": AuthMiddlewareStack(
29+
URLRouter([
30+
# URLRouter just takes standard Django path() or url() entries.
31+
path(r'ws/deploy/', DeployConsumer),
32+
path(r'ws/ans_module_log/', AnsModuleConsumer),
33+
path(r'ws/ans_playbook_log/', AnsPlaybookConsumer),
34+
path(r'ws/deploy_log/', LogConsumer),
35+
path(r'ws/dockerssh/', DockerConsumer),
36+
re_path(r'ws/fortssh/([0-9]+)/([0-9]+)/', FortConsumer),
37+
re_path(r'ws/webssh/([0-9]+)/', SSHConsumer),
38+
re_path(r'ws/fort_guacamole/([0-9]+)/([0-9]+)/(?P<group_name>.*)/', GuacamoleConsumer),
39+
re_path(r'ws/admin_guacamole/([0-9]+)/(?P<group_name>.*)/', AdminGuacamole),
40+
]),
41+
),
42+
})

Ops/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
'django.contrib.messages.middleware.MessageMiddleware',
128128
'django.middleware.clickjacking.XFrameOptionsMiddleware',
129129
'utils.middleware.UserLoginMiddleware',
130-
'utils.middleware.RecordMiddleware',
130+
# 'utils.middleware.RecordMiddleware',
131131
]
132132

133133
REST_FRAMEWORK = {

assets/urls.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
# -*- coding: utf-8 -*-
2-
3-
from django.urls import path, re_path
4-
from assets import views
5-
6-
urlpatterns = [
7-
path(r'assets_charts/', views.get_assets_charts, name='assets_charts'),
8-
path(r'assets_list/', views.get_assets_list, name='assets_list'),
9-
path(r'update_pwd/', views.update_pwd, name='update_pwd'),
10-
path(r'add_asset/', views.add_asset, name='add_asset'),
11-
path(r'add_base_asset/', views.add_base_asset, name='add_base_asset'),
12-
re_path(r'update_asset/(?P<asset_type>(.*?))/(?P<pk>[0-9]+)/', views.update_asset, name='update_asset'),
13-
path(r'server_facts/', views.server_facts, name='server_facts'),
14-
re_path(r'get_server_info/(?P<pk>[0-9]+)/', views.get_asset_info, name='get_asset_info'),
15-
path(r'import_assets/', views.import_assets, name='import_assets'),
16-
re_path(r'export_assets/', views.export_assets, name='export_assets'),
17-
re_path(r'ssh/(?P<pk>[0-9]+)/', views.ssh_terminal, name='ssh_terminal'),
18-
re_path(r'guacamole/(?P<pk>[0-9]+)/', views.guacamole_terminal, name='guacamole_terminal'),
19-
path(r'login_record/', views.login_record, name='login_record'),
20-
re_path(r'admin_play/(?P<pk>[0-9]+)/', views.admin_play, name='admin_play'),
21-
re_path(r'monitor/(?P<pk>[0-9]+)/', views.monitor, name='monitor'),
22-
re_path(r'get_top_data/(?P<pk>[0-9]+)/', views.get_top_data, name='get_top_data'),
23-
]
1+
# -*- coding: utf-8 -*-
2+
3+
from django.urls import path, re_path
4+
from assets import views
5+
6+
urlpatterns = [
7+
path(r'assets_charts/', views.get_assets_charts, name='assets_charts'),
8+
path(r'assets_list/', views.get_assets_list, name='assets_list'),
9+
path(r'update_pwd/', views.update_pwd, name='update_pwd'),
10+
path(r'add_asset/', views.add_asset, name='add_asset'),
11+
path(r'add_base_asset/', views.add_base_asset, name='add_base_asset'),
12+
path(r'docker_ssh/', views.docker_ssh, name='docker_ssh'),
13+
re_path(r'update_asset/(?P<asset_type>(.*?))/(?P<pk>[0-9]+)/', views.update_asset, name='update_asset'),
14+
path(r'server_facts/', views.server_facts, name='server_facts'),
15+
re_path(r'get_server_info/(?P<pk>[0-9]+)/', views.get_asset_info, name='get_asset_info'),
16+
path(r'import_assets/', views.import_assets, name='import_assets'),
17+
re_path(r'export_assets/', views.export_assets, name='export_assets'),
18+
re_path(r'ssh/(?P<pk>[0-9]+)/', views.ssh_terminal, name='ssh_terminal'),
19+
re_path(r'guacamole/(?P<pk>[0-9]+)/', views.guacamole_terminal, name='guacamole_terminal'),
20+
path(r'login_record/', views.login_record, name='login_record'),
21+
re_path(r'admin_play/(?P<pk>[0-9]+)/', views.admin_play, name='admin_play'),
22+
re_path(r'monitor/(?P<pk>[0-9]+)/', views.monitor, name='monitor'),
23+
re_path(r'get_top_data/(?P<pk>[0-9]+)/', views.get_top_data, name='get_top_data'),
24+
]

assets/utils/docker_ssh.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
-------------------------------------------------
4+
File Name: ssh
5+
Description:
6+
Author: pythonzm
7+
date: 2019-11-05
8+
-------------------------------------------------
9+
Change Activity:
10+
2019-11-05:
11+
-------------------------------------------------
12+
"""
13+
# -*- coding: utf-8 -*-
14+
15+
import time
16+
import docker
17+
import paramiko
18+
import threading
19+
from socket import timeout
20+
21+
from docker.models.containers import Container
22+
23+
from conf.logger import fort_logger
24+
from django.http.request import QueryDict
25+
from channels.generic.websocket import WebsocketConsumer
26+
27+
28+
class MyThread(threading.Thread):
29+
def __init__(self, sock):
30+
super(MyThread, self).__init__()
31+
self.sock = sock
32+
self._stop_event = threading.Event()
33+
34+
def stop(self):
35+
self._stop_event.set()
36+
37+
def run(self):
38+
while not self._stop_event.is_set():
39+
try:
40+
data = self.sock.tty._sock.recv(1024)
41+
if data:
42+
str_data = data.decode('utf-8', 'ignore')
43+
self.sock.send(str_data)
44+
else:
45+
return
46+
except timeout:
47+
break
48+
self.sock.send('\n由于长时间没有操作,连接已断开!', close=True)
49+
self.sock.close()
50+
51+
52+
class DockerConsumer(WebsocketConsumer):
53+
def __init__(self, *args, **kwargs):
54+
super(DockerConsumer, self).__init__(*args, **kwargs)
55+
self.client = docker.from_env()
56+
self.t1 = MyThread(self)
57+
# self.query = QueryDict(query_string=self.scope.get('query_string'), encoding='utf-8')
58+
# self.height = int(self.query.get('height'))
59+
# self.width = int(self.query.get('width'))
60+
self.tty = None
61+
62+
def connect(self):
63+
if self.scope["user"].is_anonymous:
64+
self.close(code=1007)
65+
else:
66+
self.accept()
67+
68+
try:
69+
resp = self.client.api.exec_create('ae89214140b5', cmd='/bin/bash', stdout=True, stderr=True, stdin=True,
70+
tty=True)
71+
72+
self.tty = self.client.api.exec_start(
73+
resp['Id'], detach=False, tty=True, stream=False, socket=True
74+
)
75+
except Exception as e:
76+
self.send('通过web连接容器失败!原因:{}'.format(e), close=True)
77+
78+
self.t1.setDaemon(True)
79+
self.t1.start()
80+
81+
def receive(self, text_data=None, bytes_data=None):
82+
self.tty._sock.send(text_data.encode('utf-8'))
83+
84+
def disconnect(self, close_code):
85+
self.client.close()
86+
self.t1.stop()

0 commit comments

Comments
 (0)