文章目录
- 简介
- 一.k8s读取k8s事件
- 1.1.controllers控制器代码
- 1.2.models模型代码
- 二.路由设置
- 2.1.路由设置
- 三.前端代码
- 5.1.列表部分html代码
- 四.完整代码
- 4.1.控制器event.go的完整代码
- 4.2.模型eventModel.go的完整代码
- 五.效果图
简介
本章节主要讲解通过client-go实现读取k8s事件信息,并通过layui实现界面操作,其中包含控制器这部分的代码,模型这部分代码,以及前端的html代码。
一.k8s读取k8s事件
1.1.controllers控制器代码
通过传递集群id、命名空间、资源类型来进行过滤,并调用模型代码中EventList函数来读取事件
func (this *EventController) List() {clusterId := this.GetString("clusterId")namespace := this.GetString("nameSpace")kind := this.GetString("kind") //类型包括:Pod/Namespace/Ingress/Service/Node/Configmap/Deployment/Stateful/Job/Cronjob/Secret可参考阿里云k8s事件中心类型objName := this.GetString("objName")limitd, _ := this.GetInt64("limit")List, err := m.EventList(clusterId, namespace, kind, objName, limitd)msg := "success"code := 0count := len(List)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &List}this.ServeJSON()
}
1.2.models模型代码
先定义一个结构体Events,然后定义一个结构体数组
var bbb = make([]Events, 0)
,并循环读取Items中的数据并赋值到结构体,然后再追加到数组中bbb
。
type Events struct {EventType string `json:"eventType"` //事件类型 warnningKind string `json:"kind"` //对象类型 pod or deploymentObjName string `json:"objName"` //对象:pod的名称Message string `json:"message"` //信息Reason string `json:"reason"` //原因、内容CreateTime string `json:"createTime"`
}func EventList(kubeconfig, namespace, kind, objName string, limitd int64) ([]Events, error) {clientset := common.ClientSet(kubeconfig)var err errorvar events *corev1.EventListvar listOptions = metav1.ListOptions{}if limitd > 0 {listOptions = metav1.ListOptions{Limit: limitd,}}//根据传递的类型进行过滤事件if kind != "" && objName != "" {listOptions = metav1.ListOptions{FieldSelector: fmt.Sprintf("involvedObject.name=%s", objName),TypeMeta: metav1.TypeMeta{Kind: fmt.Sprintf("%s", kind)},}events, err = clientset.CoreV1().Events(namespace).List(context.TODO(), listOptions)} else if kind != "" && objName == "" {listOptions = metav1.ListOptions{TypeMeta: metav1.TypeMeta{Kind: fmt.Sprintf("%s", kind)},}events, err = clientset.CoreV1().Events(namespace).List(context.TODO(), listOptions)} else {events, err = clientset.CoreV1().Events(namespace).List(context.TODO(), listOptions)}if err != nil {log.Printf("list deployment error, err:%v\n", err)}//将事件按照时间进行倒序输出lessFunc := func(i, j int) bool {return events.Items[j].CreationTimestamp.Before(&events.Items[i].CreationTimestamp)}sort.SliceStable(events.Items, lessFunc)var bbb = make([]Events, 0)for _, item := range events.Items {//用于过滤和搜索if objName != "" && kind == "" {if !strings.Contains(item.InvolvedObject.Name, objName) {continue}}Items := &Events{EventType: item.Type,Kind: item.InvolvedObject.Kind,ObjName: item.InvolvedObject.Name,Message: item.Message,Reason: item.Reason,CreateTime: item.CreationTimestamp.Format("2006-01-02 15:04:05"),}bbb = append(bbb, *Items)//log.Println(item)}return bbb, err
}
二.路由设置
2.1.路由设置
将以下代码放到routers/route.go中
//eventbeego.Router("/event/v1/List", &controllers.EventController{}, "*:List")
三.前端代码
5.1.列表部分html代码
3.1 eventList.html,放到views/front/page/xkube下
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>configmap列表</title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="/lib/layui-v2.6.3/css/layui.css" media="all"><link rel="stylesheet" href="/css/public.css" media="all"><script type="text/javascript" src="/lib/jquery-3.4.1/jquery-3.4.1.min.js"></script><script src="/lib/layui-v2.6.3/layui.js" charset="utf-8"></script><script src="/js/xkube.js?v=1" charset="utf-8"></script><script src="/js/lay-config.js?v=1.0.4" charset="utf-8"></script><style type="text/css">.layui-table-cell {height: auto;line-height: 22px !important;text-overflow: inherit;overflow: visible;white-space: normal;}.layui-table-cell .layui-table-tool-panel li {word-break: break-word;}
</style>
</head>
<body>
<div class="layuimini-container"><div class="layuimini-main"><fieldset class="table-search-fieldset"><legend>搜索信息</legend><div style="margin: 10px 10px 10px 10px"><form class="layui-form layui-form-pane" action=""><div class="layui-form-item"><div class="layui-inline"><label class="layui-form-label">事件类型</label><div class="layui-input-inline"><select name="kind"><option value="warnning" selected="">warnning</option></select></div></div><div class="layui-inline"><label class="layui-form-label">对象</label><div class="layui-input-inline"><select name="kind"><option value="deployment" selected="">deployment</option><option value="daemonset">daemonset</option><option value="pod">pod</option><option value="job">job</option> <option value="cronjob">cronjob</option></select></div></div><div class="layui-inline"><label class="layui-form-label">命名空间</label><div class="layui-input-inline"><select name="nameSpace" id="nameSpace"><option value="default" selected="">default</option><option value="">所有空间</option></select></div></div><div class="layui-inline"><button type="submit" class="layui-btn" lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button></div></div></form></div></fieldset><table class="layui-table" id="currentTableId" lay-filter="currentTableFilter"></table></div>
</div>
</body>
<script>
var clusterId = getQueryString("clusterId");
if (clusterId == null) {clusterId = getCookie("clusterId")
}layui.use(['form', 'table','miniTab'], function () {var $ = layui.jquery,form = layui.form,table = layui.table;miniTab = layui.miniTab,miniTab.listen();table.render({elem: '#currentTableId',url: '/event/v1/List?clusterId='+clusterId,toolbar: '#toolbarDemo',//initSort: {field:'createTime', type:'desc'},defaultToolbar: ['filter', 'exports', 'print', {title: '提示',layEvent: 'LAYTABLE_TIPS',icon: 'layui-icon-tips'}],parseData: function(res) { //实现加载全部数据后再分页if(this.page.curr) {result=res.data.slice(this.limit*(this.page.curr-1),this.limit*this.page.curr);}else{result=res.data.slice(0,this.limit);}return {"code": res.code,"msg":'',"count":res.count,"data":result};},cols: [[//{type: "checkbox", width: 50},{field: 'eventType', width: 130,title: '类型', sort: true},{field: 'kind', width: 150,title: '对象', sort: true},{field: 'objName', width: 180,title: '名称', sort: true}, {field: 'message',title: '消息', sort: true},{field: 'reason', title: '原因',width: 200, sort: true},{field: 'createTime', width:180, title: '创建时间'}]],//size:'lg',limits: [25, 50, 100],limit: 25,page: true});});
</script></body>
</html>
四.完整代码
4.1.控制器event.go的完整代码
4.1 event.go,放到contrillers下
package controllersimport (//"encoding/json""log"m "myk8s/models"beego "github.com/beego/beego/v2/server/web"
)type EventController struct {beego.Controller
}func (this *EventController) List() {clusterId := this.GetString("clusterId")namespace := this.GetString("nameSpace")kind := this.GetString("kind") //Pod/Namespace/Ingress/Service/Node/Configmap/Deployment/Stateful/Job/Cronjob/Secret可参考阿里云k8s事件中心类型objName := this.GetString("objName")limitd, _ := this.GetInt64("limit")List, err := m.EventList(clusterId, namespace, kind, objName, limitd)msg := "success"code := 0count := len(List)if err != nil {log.Println(err)msg = err.Error()code = -1}this.Data["json"] = &map[string]interface{}{"code": code, "msg": msg, "count": count, "data": &List}//this.Data["json"] = &datasthis.ServeJSON()
}
4.2.模型eventModel.go的完整代码
4.2 eventModel.go,放到models下
// eventModel.go
package modelsimport ("context""fmt"//"time""log""myk8s/common""sort""strings"corev1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)type Events struct {EventType string `json:"eventType"` //事件类型 warnningKind string `json:"kind"` //对象类型 pod or deploymentObjName string `json:"objName"` //对象:pod的名称Message string `json:"message"` //信息Reason string `json:"reason"` //原因、内容CreateTime string `json:"createTime"`
}func EventList(kubeconfig, namespace, kind, objName string, limitd int64) ([]Events, error) {clientset := common.ClientSet(kubeconfig)var err errorvar events *corev1.EventListvar listOptions = metav1.ListOptions{}if limitd > 0 {listOptions = metav1.ListOptions{Limit: limitd,}}if kind != "" && objName != "" {listOptions = metav1.ListOptions{FieldSelector: fmt.Sprintf("involvedObject.name=%s", objName),TypeMeta: metav1.TypeMeta{Kind: fmt.Sprintf("%s", kind)},}events, err = clientset.CoreV1().Events(namespace).List(context.TODO(), listOptions)} else if kind != "" && objName == "" {listOptions = metav1.ListOptions{TypeMeta: metav1.TypeMeta{Kind: fmt.Sprintf("%s", kind)},}events, err = clientset.CoreV1().Events(namespace).List(context.TODO(), listOptions)} else {events, err = clientset.CoreV1().Events(namespace).List(context.TODO(), listOptions)}if err != nil {log.Printf("list deployment error, err:%v\n", err)}lessFunc := func(i, j int) bool {return events.Items[j].CreationTimestamp.Before(&events.Items[i].CreationTimestamp)}sort.SliceStable(events.Items, lessFunc)var bbb = make([]Events, 0)for _, item := range events.Items {if objName != "" && kind == "" {if !strings.Contains(item.InvolvedObject.Name, objName) {continue}}Items := &Events{EventType: item.Type,Kind: item.InvolvedObject.Kind,ObjName: item.InvolvedObject.Name,Message: item.Message,Reason: item.Reason,CreateTime: item.CreationTimestamp.Format("2006-01-02 15:04:05"),}bbb = append(bbb, *Items)//log.Println(item)}return bbb, err
}