kubernetes platform后端开发-cluster相关组件

一、接口定义

1、namespace
type NamespaceService interface {
    GetNamespaceList(ctx context.Context, request *structs.GetNamespaceListRequest) (*structs.NamespaceListResp, error)
    DescribeNamespace(ctx context.Context, request *structs.DescribeNamespaceRequest) (*corev1.Namespace, error)
    DeleteNamespace(ctx context.Context, request *structs.DeleteNamespaceRequest) error
    CreateNamespace(ctx context.Context, request *structs.CreateNamespaceRequest) (*corev1.Namespace, error)
    UpdateNamespace(ctx context.Context, request *structs.UpdateNamespaceRequest) (*corev1.Namespace, error)
}
2、node
type NodeService interface {
    GetNodeList(ctx context.Context, request *structs.GetNodeListRequest) (*structs.NodeListResp, error)
    DescribeNode(ctx context.Context, request *structs.DescribeNodeRequest) (*corev1.Node, error)
}

二、结构体定义

1、namespace
package structs

import corev1 "k8s.io/api/core/v1"

type GetNamespaceListRequest struct {
    FilterName string `json:"filterName"`
    *DataPagination
}
type DescribeNamespaceRequest struct {
    Name string `json:"name"`
}
type DeleteNamespaceRequest struct {
    Name string `json:"name"`
}
type CreateNamespaceRequest struct {
    Name string `json:"name"`
}
type NamespaceListResp struct {
    Total int `json:"total"`
    Items []corev1.Namespace
}
type UpdateNamespaceRequest struct {
    Name    string `json:"name"`
    Content string `json:"content"`
}
2、node
package structs

import (
    corev1 "k8s.io/api/core/v1"
)

type GetNodeListRequest struct {
    IsMaster   int    `json:"isMaster"`
    FilterName string `json:"filterName"`
    *DataPagination
}
type DescribeNodeRequest struct {
    NodeName string `json:"nodeName"`
}
type NodeListResp struct {
    Total int `json:"total"`
    Items []corev1.Node
}
type AddNodeRequest struct {
}
三、实现类
1、namespace
package impl

import (
    "context"
    "encoding/json"
    "fmt"
    "k8s-platform/apps/k8sclient"
    "k8s-platform/apps/k8sclient/cell"
    config2 "k8s-platform/apps/k8sclient/impl/config"
    "k8s-platform/apps/k8sclient/structs"
    "k8s-platform/config"
    "k8s-platform/exception"
    "k8s-platform/ioc"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func init() {
    ioc.Controller().Register(&NamespaceImpl{})
}

type NamespaceImpl struct {
    K8sClientInstance *k8sclient.K8sClient
}

func (n *NamespaceImpl) Init() error {
    n.K8sClientInstance = ioc.Controller().GetObj(config.IOC_KUBECLIENT).(*k8sclient.K8sClient)
    return nil
}
func (n *NamespaceImpl) Name() string {
    return config.NAMESPACE_IOC
}
func (n *NamespaceImpl) GetNamespaceList(ctx context.Context,
    request *structs.GetNamespaceListRequest) (*structs.NamespaceListResp, error) {
    nsList, err := n.K8sClientInstance.ClientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
    if err != nil {
        return nil, exception.GetNamespaceFailed("获取namespace列表失败:%s", err.Error())
    }
    f := structs.DataFilter{FilterName: request.FilterName}
    data := f.Filter(&structs.DataSort{DataList: n.toCell(nsList.Items)})
    data.Sort()
    d := structs.DataPagination{
        PageSize:   request.PageSize,
        PageNumber: request.PageNumber,
    }
    data, err = d.Paginate(data)
    if err != nil {
        return nil, exception.NewGetPaginateFailed("获取分页数据失败:%s", err.Error())
    }
    result := &structs.NamespaceListResp{
        Total: len(nsList.Items),
        Items: n.FromCell(data.DataList),
    }
    return result, nil
}
func (n *NamespaceImpl) DescribeNamespace(ctx context.Context,
    request *structs.DescribeNamespaceRequest) (*corev1.Namespace, error) {
    ns, err := n.K8sClientInstance.ClientSet.CoreV1().Namespaces().Get(ctx, request.Name, metav1.GetOptions{})
    if err != nil {
        return nil, exception.DescribeNamespaceFailed("获取namespace详情失败:%s", err.Error())
    }
    return ns, nil
}
func (n *NamespaceImpl) DeleteNamespace(ctx context.Context, request *structs.DeleteNamespaceRequest) error {
    fmt.Println("删除啊啊啊啊啊啊", request.Name)
    err := n.K8sClientInstance.ClientSet.CoreV1().Namespaces().Delete(ctx, request.Name, metav1.DeleteOptions{})
    if err != nil {
        return exception.DeleteNamespaceFailed("删除失败:%s", err.Error())
    }
    return nil
}
func (n *NamespaceImpl) CreateNamespace(ctx context.Context,
    request *structs.CreateNamespaceRequest) (*corev1.Namespace, error) {

    namespace := config2.NewNamespaceConfig(request)
    result, err := n.K8sClientInstance.ClientSet.CoreV1().Namespaces().Create(ctx, namespace, metav1.CreateOptions{})
    if err != nil {
        return nil, exception.CreateNamespaceFailed("创建失败:%s", err.Error())
    }
    return result, nil
}
func (n *NamespaceImpl) UpdateNamespace(ctx context.Context, request *structs.UpdateNamespaceRequest) (*corev1.Namespace, error) {
    var namespace = &corev1.Namespace{}
    fmt.Println(request.Content, "——————————————————————————")
    //  2、将前端传入的字符串反序列化为json格式并赋给deployment资源实例
    err := json.Unmarshal([]byte(request.Content), &namespace)
    fmt.Println()
    if err != nil {
        return nil, exception.JsonUmarshalFailed("Json反序列化失败:%s", err.Error())
    }
    // 3、更新deployment
    newNamespace, err := n.K8sClientInstance.ClientSet.CoreV1().
        Namespaces().Update(ctx, namespace, metav1.UpdateOptions{})
    if err != nil {
        return nil, exception.UpdateDeploymentFailed("更新Namespace失败:%s", err.Error())
    }
    return newNamespace, nil
}

/*
 * toCell
 * @Description: 将k8s中的nodelist对象转换成DataMeta对象
 * @receiver d
 * @param data
 * @return []structs.DataMeta
 */
func (d *NamespaceImpl) toCell(data []corev1.Namespace) []structs.DataMeta {
    cells := make([]structs.DataMeta, len(data))
    for i := range data {
        cells[i] = cell.NamespaceCell(data[i])
    }
    return cells
}

/*
 * FromCell
 * @Description: 将DataMeta列表转为k8s中的[]node对象
 * @receiver d
 * @param data
 * @return []corev1.Node
 */
func (d *NamespaceImpl) FromCell(data []structs.DataMeta) []corev1.Namespace {
    cells := make([]corev1.Namespace, len(data))
    for i := range data {
        cells[i] = corev1.Namespace(data[i].(cell.NamespaceCell))
    }
    return cells
}
2、node
package impl

import (
    "context"
    "fmt"
    "k8s-platform/apps/k8sclient"
    "k8s-platform/apps/k8sclient/cell"
    "k8s-platform/apps/k8sclient/structs"
    "k8s-platform/config"
    "k8s-platform/exception"
    "k8s-platform/ioc"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

/*
 * init
 * @Description: 将node impl对象注入ioc
 */
func init() {
    ioc.Controller().Register(&NodeImpl{})
}

type NodeImpl struct {
    K8sClientInstance *k8sclient.K8sClient
}

func (n *NodeImpl) Init() error {
    n.K8sClientInstance = ioc.Controller().GetObj(config.IOC_KUBECLIENT).(*k8sclient.K8sClient)
    return nil
}
func (n *NodeImpl) Name() string {
    return config.NODE_IOCNAME
}
func (n *NodeImpl) GetNodeList(ctx context.Context, request *structs.GetNodeListRequest) (*structs.NodeListResp, error) {
    // 1、首先查询出所有node列表(包括master和node)
    allNodeList, err := n.K8sClientInstance.ClientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
    if err != nil {
        return nil, exception.GetNodeListFailed("获取node列表失败:%s", err.Error())
    }
    // 2、遍历所有node,找出master和node节点
    masterList := []corev1.Node{}
    nodeList := []corev1.Node{}
    for _, node := range allNodeList.Items {
        if node.Labels["node-role.kubernetes.io/master"] == "true" {
            masterList = append(masterList, node)
        } else {
            nodeList = append(nodeList, node)
        }
    }
    fmt.Println(request.IsMaster)
    fmt.Println(len(masterList), masterList)
    fmt.Println(len(nodeList), nodeList)
    // 判断查出的node列表是master还是node,1为master,2为node,其余参数无效
    switch request.IsMaster {
    case 1:
        return GetNodeList(request, n, masterList, allNodeList.Items)
    case 2:
        return GetNodeList(request, n, nodeList, allNodeList.Items)
    case 3:
        return GetNodeList(request, n, allNodeList.Items, allNodeList.Items)
    default:
        return nil, exception.InvalidParameter("参数无效!")
    }
    //if request.IsMaster == 1 {
    //    return GetNodeList(request, n, masterList)
    //} else if request.IsMaster == 2 {
    //    return GetNodeList(request, n, nodeList)
    //} else {
    //    return nil, exception.InvalidParameter("参数无效!")
    //}
}
func (n *NodeImpl) DescribeNode(ctx context.Context, request *structs.DescribeNodeRequest) (*corev1.Node, error) {
    node, err := n.K8sClientInstance.ClientSet.CoreV1().Nodes().Get(ctx, request.NodeName, metav1.GetOptions{})
    if err != nil {
        return nil, exception.DescribeNodeListFailed("获取node详情失败:%s", err.Error())
    }
    return node, nil
}

/*
 * toCell
 * @Description: 将k8s中的nodelist对象转换成DataMeta对象
 * @receiver d
 * @param data
 * @return []structs.DataMeta
 */
func (d *NodeImpl) toCell(data []corev1.Node) []structs.DataMeta {
    cells := make([]structs.DataMeta, len(data))
    for i := range data {
        cells[i] = cell.NodeCell(data[i])
    }
    return cells
}

/*
 * FromCell
 * @Description: 将DataMeta列表转为k8s中的[]node对象
 * @receiver d
 * @param data
 * @return []corev1.Node
 */
func (d *NodeImpl) FromCell(data []structs.DataMeta) []corev1.Node {
    cells := make([]corev1.Node, len(data))
    for i := range data {
        cells[i] = corev1.Node(data[i].(cell.NodeCell))
    }
    return cells
}

config/namespace_config

package config

import (
    "k8s-platform/apps/k8sclient/structs"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

//
//  StatefulsetConfig
//  @Description: 生成k8s  statefulset资源的结构体
//
type NamespaceConfig struct {
    namespace *corev1.Namespace
}

func NewNamespaceConfig(request *structs.CreateNamespaceRequest) *corev1.Namespace {
    // 将对应的参数传入appsv1.Deployment
    return &corev1.Namespace{
        ObjectMeta: metav1.ObjectMeta{
            Name: request.Name,
        },
        Spec: corev1.NamespaceSpec{},
    }
}

四、实现restful接口

1、namespace
package http

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-platform/apps/k8sclient"
    "k8s-platform/apps/k8sclient/structs"
    "k8s-platform/config"
    "k8s-platform/ioc"
    "k8s-platform/response"
    "strconv"
)

var NamespaceHttpHandler *namespaceHttpHandler = NewnamespaceHttpHandler()

/*
 * init
 * @Description: 将deploymentAPIHandler注入ioc
 */
func init() {
    ioc.Controller().Register(NamespaceHttpHandler)
}

var (
    nsSvc k8sclient.NamespaceService
)

func NewnamespaceHttpHandler() *namespaceHttpHandler {
    return &namespaceHttpHandler{
        svc: ioc.Controller().GetObj(config.NAMESPACE_IOC).(k8sclient.NamespaceService),
    }
}

type namespaceHttpHandler struct {
    svc k8sclient.NamespaceService
}

/*
 * Init
 * @Description: 注入ioc后初始化的操作
 * @receiver d
 * @return error
 */
func (d *namespaceHttpHandler) Init() error {
    d.svc = ioc.Controller().GetObj(config.NAMESPACE_IOC).(k8sclient.NamespaceService)

    return nil
}
func (d *namespaceHttpHandler) Name() string {
    return config.NAMESPACE_API
}

/*
 * GetDeploymentList
 * @Description: 获取deployment列表
 * @receiver d
 * @param c
 */
func (d *namespaceHttpHandler) GetNamespaceList(c *gin.Context) {
    filtername := c.Query("filterName")
    pagesize, _ := strconv.Atoi(c.Query("page_size"))
    pagenumber, _ := strconv.Atoi(c.Query("page_number"))
    data := structs.GetNamespaceListRequest{
        FilterName: filtername,
        DataPagination: &structs.DataPagination{
            PageSize:   pagesize,
            PageNumber: pagenumber,
        },
    }
    fmt.Println(",,,", data)
    result, err := d.svc.GetNamespaceList(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

/*
 * DescribeDeployment
 * @Description: 查看namespace详情
 * @receiver d
 * @param c
 */
func (d *namespaceHttpHandler) DescribeNamespace(c *gin.Context) {
    nsName := c.Query("name")
    data := structs.DescribeNamespaceRequest{
        Name: nsName,
    }
    fmt.Println(data)
    result, err := d.svc.DescribeNamespace(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)

}

/*
 * UpdateDeploymentScale
 * @Description: 删除namespace
 * @receiver d
 * @param c
 */
func (d *namespaceHttpHandler) DeleteNamespace(c *gin.Context) {
    fmt.Println(c.Request)
    name := c.Param("name")
    data := structs.DeleteNamespaceRequest{}
    data.Name = name
    fmt.Println(data, "--------------------------------")
    var err error
    fmt.Println("router delete = ", data)
    err = d.svc.DeleteNamespace(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, "删除成功")
}
func (d *namespaceHttpHandler) CreateNamespace(c *gin.Context) {
    data := &structs.CreateNamespaceRequest{}
    c.BindJSON(&data)
    namespace, err := d.svc.CreateNamespace(c.Request.Context(), data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, namespace)
}
func (d *namespaceHttpHandler) UpdateNamespace(c *gin.Context) {
    data := structs.UpdateNamespaceRequest{}
    err := c.BindJSON(&data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    fmt.Println(data)
    result, err := d.svc.UpdateNamespace(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}
2、node
package http

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-platform/apps/k8sclient"
    "k8s-platform/apps/k8sclient/structs"
    "k8s-platform/config"
    "k8s-platform/ioc"
    "k8s-platform/response"
    "strconv"
)

var NodeHttpHandler *nodeHttpHandler = NewnodeHttpHandler()

/*
 * init
 * @Description: 将deploymentAPIHandler注入ioc
 */
func init() {
    ioc.Controller().Register(NodeHttpHandler)
}

func NewnodeHttpHandler() *nodeHttpHandler {
    return &nodeHttpHandler{
        svc: ioc.Controller().GetObj(config.NODE_IOCNAME).(k8sclient.NodeService),
    }
}

type nodeHttpHandler struct {
    svc k8sclient.NodeService
}

/*
 * Init
 * @Description: 注入ioc后初始化的操作
 * @receiver d
 * @return error
 */
func (d *nodeHttpHandler) Init() error { // todo 这里已经获取到了svc
    d.svc = ioc.Controller().GetObj(config.NODE_IOCNAME).(k8sclient.NodeService)
    return nil
}
func (d *nodeHttpHandler) Name() string {
    return config.NODE_API
}

/*
 * GetDeploymentList
 * @Description: 获取deployment列表
 * @receiver d
 * @param c
 */
func (d *nodeHttpHandler) GetNodeList(c *gin.Context) {
    size, _ := strconv.Atoi(c.Query("page_size"))
    number, _ := strconv.Atoi(c.Query("page_number"))
    isMaster, _ := strconv.Atoi(c.Query("isMaster"))
    fmt.Printf("DeployList:%p,%v\n", d, d.svc)
    data := structs.GetNodeListRequest{
        FilterName: c.Query("filterName"),
        IsMaster:   isMaster,
        DataPagination: &structs.DataPagination{
            PageSize:   size,
            PageNumber: number,
        },
    }
    result, err := d.svc.GetNodeList(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

func (d *nodeHttpHandler) DescribeNode(c *gin.Context) {
    nodeName := c.Query("nodeName")
    data := structs.DescribeNodeRequest{NodeName: nodeName}
    node, err := d.svc.DescribeNode(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, node)

}