Django实现OSS日志下载
Django实现OSS日志下载
一、python3.7安装
1、下载安装python3.7
[root@lvs-nginx1 ~]# wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz [root@lvs-nginx1 ~]# tar -xf Python-3.7.3.tgz [root@lvs-nginx1 ~]# mkdir /usr/local/python3.7.3 [root@lvs-nginx1 ~]# cd Python-3.7.3 [root@lvs-nginx1 ~]# ./configure --prefix=/usr/local/python3.7.3 --enable-optimizations [root@lvs-nginx1 ~]# make && make install [root@lvs-nginx1 Python-3.7.3]# ln -s /usr/local/python3.7.3/bin/python3.7 /usr/bin/python3.7 [root@lvs-nginx1 Python-3.7.3]# python3.7 Python 3.7.3 (default, Nov 7 2019, 16:07:52) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> exit()
二、创建Django
1、创建django
[root@k8s-es7 python]# /usr/local/python3.7/bin/django-admin startproject getoslogs [root@k8s-es7 python]# cd getoslogs/ [root@k8s-es7 getoslogs]# python manage.py startapp getlogs ##创建app [root@k8s-es7 getoslogs]# python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying sessions.0001_initial... OK [root@k8s-es7 getoslogs]# python manage.py createsuperuser Username (leave blank to use 'root'): root Email address: 547253687@qq.com Password: Password (again): This password is too short. It must contain at least 8 characters. This password is too common. This password is entirely numeric. Bypass password validation and create user anyway? [y/N]: y Superuser created successfully.
此时在getoslogs/settings.py里面INSTALLED_APPS添加刚刚创建的getlogs,将ALLOWED_HOSTS替换成ALLOWED_HOSTS = ['*'],允许所有人访问,这时候就创建好了项目和app。启动
python manget.py runserver 0.0.0.0:5566,这时候django已经正常启动,访问如下图
2、添加py脚本
这个脚本很简单,就是两个函数,listfile函数用来获取前端输入的时间,oss api来获取到该时间下的备份日志文件,返回给前端。
filejiedong这个函数用来获取前段勾选的文件,解冻以及下载文件
[root@k8s-es7 getoslogs]# cd /home/pb/python/test/ [root@k8s-es7 test]# cat listdir.py #!/usr/local/bin/python3.7 # -*- coding: utf-8 -*- import oss2,time,sys; from flask import Flask,send_file from django.shortcuts import render from django.http import HttpResponse; sys.path.append('/home/pb/python/getoslogs/getlogs'); import views; import threading; def environment(aliyun): if aliyun == "jinrongyun": auth = oss2.Auth('yourAccessKeyId','yourAccessKeySecret'); bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName'); return bucket; else: auth = oss2.Auth('yourAccessKeyId','yourAccessKeySecret'); bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName'); return bucket; def listfile(date_time,bucket): data = []; data1 = []; for obj in oss2.ObjectIterator(bucket, prefix = date_time): data.append(obj.key) for x in range(len(data)): if "tar.gz" in data[x]: data1.append(data[x]) return data1; def filejiedong(objectname,bucket,cc): #cc = []; file_list = []; file_list.append(objectname); meta = bucket.head_object(objectname); if "expiry-date" not in str(meta.resp.headers): bucket.restore_object(objectname); while True: time.sleep(3); meta = bucket.head_object(objectname); if "expiry-date" in str(meta.resp.headers): requesturl=(bucket.sign_url('GET',objectname,36000)); cc.append(requesturl); return cc; break; else: continue; else: requesturl=(bucket.sign_url('GET',objectname,36000)); cc.append(requesturl); return cc; def main(objectname,bucket): #存放线程的list cc = []; threads = []; for file_name in objectname: print("filename:",file_name); t = threading.Thread(target=filejiedong,args=(file_name,bucket,cc,)); threads.append(t); for t in threads: t.start(); #join方法作用是,让主线程等待该线程结束,所以join应该放在下面的循环里,放在这里就会导致这个启动线程的循环阻塞。结果就是顺序执行。 #join也可以设置超时时间 #join函数只在主线程进行等待的时候有用,如果主线程还有其他事情,没必要调用join阻塞自己。 #t.join() for t in threads: t.join(); return cc;
然后去前端页面准备一个简单的html页面
[root@k8s-es7 getlogs]# mkdir /home/pb/python/getoslogs/getlogs/templates [root@k8s-es7 getlogs]# cd /home/pb/python/getoslogs/getlogs/templates [root@k8s-es7 getlogs]# cat templates/listfile.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>日志下载</title> <link rel="stylesheet" href="../../static/css/layui.css" media="all"> </head> <body> <h1>日志下载</h1> <h2>请根据实际情况填写以下内容</h2> <form method="post" action="/listfile/"> <!-- <input type="text" name="file_date" placeholder="日期"> --> <div> <label><input type="radio" name="aliyun" value="jinrongyun">金融云</label> <label><input type="radio" name="aliyun" value="gongyouyun">公有云</label> </div> <div class="layui-inline"> <!-- 注意:这一层元素并不是必须的 --> <input type="text" class="layui-input" id="test1" name="file_date" placeholder="yyyy-MM-dd"> </div> <br> {{ error }} <br> <button id="btn" type="submit" class="layui-btn layui-btn-sm">查询</button> {% csrf_token %} </form> <form method="post" action="/listfile/"> <button id="btn" type="submit" class="layui-btn layui-btn-normal layui-btn-sm">解冻</button> <input type="text" value="{{ aliyun }}" name="aliyun"> {% for url in result %} </br> <input type="checkbox" value="{{ url }}" name="file_jiedong"> <a> {{url}} </a> {% endfor %} {{ error }}<br> {% csrf_token %} </form> {% for url in result1 %} </br> <a href={{url}}>{{url}}</a> {% endfor %} {{ error }}<br> {% csrf_token %} <script src="../../static/layui.js"></script> <script> layui.use('laydate', function() { var laydate = layui.laydate; //执行一个laydate实例 laydate.render({ elem : '#test1' //指定元素 }); }); </script> </body> </html>
添加一个login界面,可以自己去网上找模板下载
[root@k8s-es7 getlogs]# cat templates/index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>HTML5响应式用户登录界面模板</title> <meta name="description" content="particles.js is a lightweight JavaScript library for creating particles."> <meta name="author" content="Vincent Garreau" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="stylesheet" media="screen" href="/static/css/style.css"> <link rel="stylesheet" type="text/css" href="/static/css/reset.css"/> </head> <body> <form method="post" action="/login/"> <div id="particles-js"> <div class="login"> <div class="login-top"> 登录 </div> <div class="login-center clearfix"> <div class="login-center-img"><img src="/static/img/name.png"/></div> <div class="login-center-input"> <input type="text" name="username" value="" placeholder="请输入您的用户名" onfocus="this.placeholder=''" onblur="this.placeholder='请输入您的用户名'"/> <div class="login-center-input-text">用户名</div> </div> </div> <br> {{ error }} <br> <div class="login-center clearfix"> <div class="login-center-img"><img src="/static/img/password.png"/></div> <div class="login-center-input"> <input type="password" name="password" value="" placeholder="请输入您的密码" onfocus="this.placeholder=''" onblur="this.placeholder='请输入您的密码'"/> <div class="login-center-input-text">密码</div> </div> </div> <!-- <div type="submit" class="login-button"> 登录 </div> --> <button type="submit" class="login-button"> 登录 </button> {% csrf_token %} </div> <div class="sk-rotating-plane"></div> </div> </form> <!-- scripts --> <script src="/static/js/particles.min.js"></script> <script src="/static/js/app.js"></script> <script type="text/javascript"> function hasClass(elem, cls) { cls = cls || ''; if (cls.replace(/\s/g, '').length == 0) return false; //当cls没有参数时,返回false return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' '); } function addClass(ele, cls) { if (!hasClass(ele, cls)) { ele.className = ele.className == '' ? cls : ele.className + ' ' + cls; } } function removeClass(ele, cls) { if (hasClass(ele, cls)) { var newClass = ' ' + ele.className.replace(/[\t\r\n]/g, '') + ' '; while (newClass.indexOf(' ' + cls + ' ') >= 0) { newClass = newClass.replace(' ' + cls + ' ', ' '); } ele.className = newClass.replace(/^\s+|\s+$/g, ''); } } document.querySelector(".login-button").onclick = function(){ addClass(document.querySelector(".login"), "active") setTimeout(function(){ addClass(document.querySelector(".sk-rotating-plane"), "active") document.querySelector(".login").style.display = "none" },800) setTimeout(function(){ removeClass(document.querySelector(".login"), "active") removeClass(document.querySelector(".sk-rotating-plane"), "active") document.querySelector(".login").style.display = "block" alert("登录成功") },5000) } </script> <div style="text-align:center;"> <p>更多模板:<a href="http://www.mycodes.net/" target="_blank">源码之家</a></p> </div> </body> </html>
有了页面之后,就需要创建一个url指向这个这个页面,修改编写view.py里面的listfile函数
[root@k8s-es7 getlogs]# cat /home/pb/python/getoslogs/getoslogs/urls.py """getoslogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.2/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path from getlogs import views #将createyaml这个app的views变量插进来 urlpatterns = [ path('admin/', admin.site.urls), path(r'listfile/', views.listfile), #将这个listfile url指向getlogs/views.py里面的listfile函数 path(r'login/', views.login), #登录页面 ]
提前安装好oss2模块 pip install aliyun-python-sdk-core-v3
[root@k8s-es7 getlogs]# cat /home/pb/python/getoslogs/getlogs/views.py [root@k8s-es7 getlogs]# cat views.py # -*- coding:utf-8 -*- from django.shortcuts import render from django.http import HttpResponse; import subprocess; import os,oss2,ldap3; import sys; import json; from django.shortcuts import render_to_response from django.template import RequestContext sys.path.append('/home/pb/python/test'); import listdir; from ldap import LdapAdmin; ##查询某个日期下oss备份的日志 def listfile(request): if request.method == 'POST': file_date = request.POST.get('file_date', '') file_jiedong = request.POST.getlist('file_jiedong', '') aliyun = request.POST.get('aliyun', ''); bucket = listdir.environment(aliyun); env = request.POST.get('env') if file_date: result = listdir.listfile(file_date.strip(),bucket); context = {'result': result, 'aliyun': aliyun} return render(request,'listfile.html', context) else: pass; if file_jiedong: aliyun = request.POST.get('aliyun', ''); bucket = listdir.environment(aliyun); #context = for_file(file_jiedong,bucket); context = {'result1': listdir.main(file_jiedong,bucket)}; print("context",context); return render(request,'listfile.html', context) else: pass; else: return render(request,'listfile.html'); #def for_file(file_jiedong,bucket): # result_file = [] # for i in file_jiedong: # #result1 = listdir.filejiedong((i).strip(),bucket); # result1 = listdir.main((i).strip(),bucket); # print("result1:",result1); # result_file.append(result1) # context = {'result1': result_file} # return context; ##登录脚本 def login(request): if request.method == 'POST': username = request.POST.get('username', ''); password = request.POST.get('password', ''); #if username: # print("username: {}".format(username)); # #return render(request,'index.html', context) #else: # pass; #if password: # print("password: {}".format(password)); # #return render(request,'index.html', context) #else: # pass; ldap_ins = LdapAdmin(); resp = ldap_ins.login(username, password); if resp == True: return render(request,'listfile.html'); else: return render(request,'index.html'); else: return render(request,'index.html') #def login_ldap(username): # if request.method == 'POST': # username = request.POST.get('username', ''); # #password = request.POST.get('password', ''); # print("username: ".format(username)); # #print("password: ".format(password)); # else: # return render(request,'index.html') #def add_dict(list_test): # context = {} # a = 0 # for i in list_test: # a = a + 1 # context["result"+str(a)] = i # return context
添加ldap脚本
[root@k8s-es7 getlogs]# cat /home/pb/python/test/ldap.py #! /usr/bin/python # -*- coding:utf-8 -*- # Author: panb import logging from ldap3 import Server, Connection, ALL logger = logging.getLogger("oauth") LDAP = { "server": "172.27.27.220", "port": 389, "use_ssl": False, "domain": "jcici.com", "base": "ou=People,dc=jcici,dc=com" } class LdapAdmin(object): def __init__(self): """ init """ self.host = LDAP['server'] self.port = LDAP.get('port', 389) self.use_ssl = LDAP.get('use_ssl', False) self.domain = LDAP['domain'] self.base = LDAP['base'] self.search_filter = "uid={uid}" def login(self, username, password): """ 登录 :return: """ server = Server(host=self.host, port=self.port, use_ssl=self.use_ssl, connect_timeout=15, get_info=ALL) try: conn = Connection(server, user=f"uid={username},{self.base}", password=password, check_names=True, lazy=False, auto_bind=True, receive_timeout=30 ) except Exception as e: err_msg = f'LDAP 认证失败:{e}' logger.error(err_msg) return False else: msg = conn.result #print(msg) conn.unbind() return True # print(server.info) # print(server.schema) # _username = (conn.extend.standard.who_am_i()) # print(_username) #ldap_ins = LdapAdmin() #resp = ldap_ins.login(username, password) #print(resp)
还需要在getoslogs/settings.py添加static
STATIC_URL = '/static/' HERE = os.path.dirname(os.path.abspath(__file__)) HERE = os.path.join(HERE, '../') STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don‘t forget to use absolute paths, not relative paths. os.path.join(HERE, 'static/'), )
3、最终访问效果