首页 > 技术文章 > Django实现OSS日志下载

jcici 2019-11-07 16:02 原文

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、最终访问效果

 

 

 

 

    

推荐阅读