kubernetes platform后端开发-workload

一、定义接口

####### 首先创建interface文件,定义所有workload需要使用的接口
apps/k8sclient/interface.go

package k8sclient

import (
    "context"
    "k8s-platform/apps/k8sclient/structs"
    v1 "k8s.io/api/networking/v1"

    //"k8s-platform/apps/k8sclient/structs"
    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
)

//
//  PodService
//  @Description: Pod相关接口
//
type PodService interface {
    // 获取pod列表
    GetPodsList(ctx context.Context, request *structs.GetPodsListRequest) (*structs.PodsResp, error)
    // 查询Pod详细信息
    DescribePod(ctx context.Context, request *structs.DescribePodRequest) (*corev1.Pod, error)
    // 删除Pod
    DeletePod(ctx context.Context, request *structs.DeletePodRequest) error
    // 更新Pod
    UpdatePod(ctx context.Context, request *structs.UpdatePodRequest) (*corev1.Pod, error)
    // 获取Pod中的容器信息
    GetContainers(ctx context.Context, request *structs.GetContainersRequest) ([]corev1.Container, error)
    // 获取Pod日志
    GetPodLogs(ctx context.Context, request *structs.GetPodLogsRequest) (string, error)

    GetNamespacePodsCount(ctx context.Context, request *structs.GetNamespacePodsCountRequest) ([]*structs.NsCount, error)
    GetPodsListByDeployment(ctx context.Context, request *structs.GetPodsListByDeploymentRequest) (*structs.PodsResp, error)
    GetPodsListByDaemonset(ctx context.Context, request *structs.GetPodsListByDaemonsetRequest) (*structs.PodsResp, error)
    GetPodsListByStatefulset(ctx context.Context, request *structs.GetPodsListByStatefulsetRequest) (*structs.PodsResp, error)
}

type DeploymentService interface {
    GetDeploymentList(ctx context.Context, request *structs.GetDeploymentListRequest) (*structs.DeployResp, error)
    DescribeDeployments(ctx context.Context, request *structs.DescribeDeploymentsRequest) (*appsv1.Deployment, error)
    UpdateDeploymentScale(ctx context.Context, request *structs.UpdateDeploymentScaleRequest) (int32, error)
    CreateDeployment(ctx context.Context, request *structs.CreateDeploymentRequest) (*appsv1.Deployment, error)
    DeleteDeployment(ctx context.Context, request *structs.DeleteDeploymentRequest) error
    RestartDeployment(ctx context.Context, request *structs.RestartDeploymentRequest) error
    UpdateDeployment(ctx context.Context, request *structs.UpdateDeploymentRequest) (*appsv1.Deployment, error)
    GetNamespaceDeploymentCount(ctx context.Context, request *structs.GetNamespaceDeploymentCountRequest) ([]*structs.NsDeployCount, error)
}

type DaemonSetService interface {
    CreateDaemonSet(ctx context.Context, request *structs.CreateDaemonSetRequest) (*appsv1.DaemonSet, error)
    GetDaemonSetList(ctx context.Context, request *structs.GetDaemonSetListRequest) (*structs.DaemonsetResp, error)
    DescribeDaemonSet(ctx context.Context, request *structs.DescribeDaemonSet) (*appsv1.DaemonSet, error)
    DeleteDaemonSet(ctx context.Context, request *structs.DeleteDaemonSet) error
    UpdateDaemonSet(ctx context.Context, request *structs.UpdateDaemonSet) (*appsv1.DaemonSet, error)
}

type StatefulSetService interface {
    CreateStatefulSet(ctx context.Context, request *structs.CreateStatefulSetRequest) (*appsv1.StatefulSet, error)
    GetStatefulSetList(ctx context.Context, request *structs.GetStatefulSetListRequest) (*structs.StatefulSetResp, error)
    DescribeStatefulSet(ctx context.Context, request *structs.DescribeStatefulSet) (*appsv1.StatefulSet, error)
    DeleteStatefulSet(ctx context.Context, request *structs.DeleteStatefulSet) error
    UpdateStatefulSet(ctx context.Context, request *structs.UpdateStatefulSet) (*appsv1.StatefulSet, error)
}

二、定义结构体

1、deployment

apps/k8sclient/structs/deployment.go

package structs

import (
    "fmt"
    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/resource"
    "k8s.io/apimachinery/pkg/util/intstr"
    "k8s.io/apimachinery/pkg/util/json"
)

//
//  GetDeploymentListRequest
//  @Description:  获取Deployment列表的结构体
//
type GetDeploymentListRequest struct {
    FilterName string `json:"filterName"`
    Namespace  string `json:"namespace"`
    *DataPagination
}

//
//  DeployResp
//  @Description: 返回给用户的结构体,包括deployment总数,还有每个deployment的信息
//
type DeployResp struct {
    Total int `json:"total"`
    Items []appsv1.Deployment
}

type DataTemplateResponse struct {
    Namespace      string `json:"namespace"`
    DeploymentName string `json:"deploymentName"`
}

//
//  DescribeDeploymentsRequest
//  @Description: deployment详细信息
//
type DescribeDeploymentsRequest struct {
    *DataTemplateResponse
}

type UpdateDeploymentScaleRequest struct {
    *DataTemplateResponse
    ScaleNum int `json:"scaleNum"`
}
type CreateDeploymentRequest struct {
    Namespace      string             `json:"namespace"`
    DeploymentName string             `json:"deploymentName"`
    PodName        string             `json:"podName"`
    Replicas       *int32             `json:"replicas"`
    Image          string             `json:"image"`
    Label          map[string]string  `json:"label"`
    Containers     []ContainerRequest `json:"containers"`
}

func (c *CreateDeploymentRequest) String() string {
    data, _ := json.Marshal(c)
    return string(data)
}

//
//  ContainerRequest
//  @Description: deployment 容器的实例配置
//
type ContainerRequest struct {
    // 容器名
    Name string `json:"name"`
    // 镜像名
    Image string `json:"image"`
    // 镜像版本号
    Version string `json:"version"`
    // 端口号
    Ports []int32 `json:"ports"`
    // cpu最大限制
    LimitsCpu string `json:"limits_cpu"`
    // 内存最大限制
    LimitMemory string `json:"limit_memory"`
    // 启动容器的最小cpu
    RequestsCpu string `json:"requests_cpu"`
    // 启动容器的最小内存
    RequestsMemory string `json:"requests_memory"`
    // 指定工作目录
    WorkSpace string `json:"work_space"`
    // 运行命令
    Command string `json:"command"`
    // 运行参数
    Args []string `json:"args"`
    // 是否开启就绪检查
    ReadinessHealthCheck bool `json:"readiness_healthCheck"`
    // liveiness健康检查类型
    HealthCheckTypeLive HealthCheckType `json:"healthcheckTypeLive"`
    // readiness健康检查类型
    HealthCheckTypeRead HealthCheckType `json:"healthcheckTypeRead"`

    // 是否开启存活性检查
    LivenessHealthCheck bool `json:"liveness_healthCheck"`
    // 健康检查相关配置
    LivenessProbe  HealthCheckConfig `json:"livenessProbe"`
    ReadinessProbe HealthCheckConfig `json:"readinessProbe"`

    // 资源限制
    Resource corev1.ResourceRequirements `json:"resource"`
}

type HealthCheckConfig struct {
    // HTTPGet 类型的路径
    Path string `json:"path"`
    // HTTPGet 或 TCP 类型需要检查的端口
    Port int32 `json:"port"`
    // Exec 类型需要执行的命令
    Cmd string `json:"cmd"`
    // 启动延时时间
    InitialDelaySecond int32 `json:"initialDelaySecond"`
    // 响应超时时间
    TimeoutSeconds int32 `json:"timeoutSeconds"`
    // 间隔多少时间进行一次
    PeriodSeconds int32 `json:"periodSeconds"`
    // 健康阈值
    SuccessThreshold int32 `json:"successThreshold"`
    // 不健康阈值
    FailureThreshold int32 `json:"failureThreshold"`
}

/*
 * ToK8sContainer
 * @Description: 将ContainerRequest转换为k8s中的Container对象
 * @receiver c
 * @return corev1.Container
 */
func (c *ContainerRequest) ToK8sContainer() corev1.Container {

    var ports []corev1.ContainerPort
    for _, p := range c.Ports {
        ports = append(ports, corev1.ContainerPort{ContainerPort: p})
    }
    var liveniness *corev1.Probe
    var readness *corev1.Probe
    if c.LivenessHealthCheck != false {
        liveniness = ConfigureHealthCheck(c.HealthCheckTypeLive, c.LivenessProbe)
    }
    if c.ReadinessHealthCheck != false {
        readness = ConfigureHealthCheck(c.HealthCheckTypeRead, c.ReadinessProbe)
    }
    data :=
        corev1.Container{
            Name:           c.Name,
            Image:          c.Image,
            Ports:          ports,
            LivenessProbe:  liveniness,
            ReadinessProbe: readness,
            Command:        []string{c.Command},
            WorkingDir:     c.WorkSpace,
            Resources:      NewResourceRequirements(c.LimitsCpu, c.LimitMemory, c.RequestsCpu, c.RequestsMemory),
        }
    fmt.Println(data, "----------------------------------------------------------------")
    return data
}
func NewResourceRequirements(cpuLimit, memoryLimit, cpuRequests, memoryRequests string) corev1.ResourceRequirements {
    fmt.Println(cpuLimit)
    fmt.Println(memoryLimit)
    fmt.Println(cpuRequests)
    fmt.Println(memoryRequests)
    defaultCPULimit := "100m"
    defaultMemoryLimit := "512Mi"
    defaultCPURequests := "50m"
    defaultMemoryRequests := "256Mi"
    if cpuLimit == "" {
        cpuLimit = defaultCPULimit
    }
    if memoryLimit == "" {
        memoryLimit = defaultMemoryLimit
    }
    if cpuRequests == "" {
        cpuRequests = defaultCPURequests
    }
    if memoryRequests == "" {
        memoryRequests = defaultMemoryRequests
    }
    return corev1.ResourceRequirements{
        Limits: corev1.ResourceList{
            // corev1.ResourceCPU 是一个常量,表示 CPU 资源。
            // resource.MustParse 解析 cpuLimit 字符串为一个资源数量对象。
            // 这里的 "200m"  200 millicores,也就是 0.2 核的 CPU。
            corev1.ResourceCPU: resource.MustParse(cpuLimit),
            // corev1.ResourceMemory 是一个常量,表示内存资源。
            // resource.MustParse 解析 memoryLimit 字符串为一个资源数量对象。
            // "256Mi" 表示 256 Mebibytes 的内存。
            corev1.ResourceMemory: resource.MustParse(memoryLimit),
        },
        Requests: corev1.ResourceList{
            corev1.ResourceCPU:    resource.MustParse(cpuRequests),
            corev1.ResourceMemory: resource.MustParse(memoryRequests),
        },
    }
}

// 生成健康检查配置
/*
 * ConfigureHealthCheck
 * @Description: 生成健康检查配置
 * @param htype
 * @param config
 * @return *corev1.Probe
 */
func ConfigureHealthCheck(htype HealthCheckType, config HealthCheckConfig) *corev1.Probe {
    if config.Port == 0 {
        return nil
    }
    // 健康检查参数配置
    probe := &corev1.Probe{
        InitialDelaySeconds: config.InitialDelaySecond,
        TimeoutSeconds:      config.TimeoutSeconds,
        PeriodSeconds:       config.PeriodSeconds,
        SuccessThreshold:    config.SuccessThreshold,
        FailureThreshold:    config.FailureThreshold,
    }
    fmt.Println("port ======", config.Port)
    // 判断传入的健康检查类型
    switch htype {
    case TYPE_HTTPGET:
        probe.ProbeHandler.HTTPGet = &corev1.HTTPGetAction{
            Path: config.Path,
            Port: intstr.FromInt32(config.Port),
        }
    case TYPE_TCP:
        probe.ProbeHandler.TCPSocket = &corev1.TCPSocketAction{
            Port: intstr.FromInt32(config.Port),
        }
    case TYPE_EXEC:
        probe.ProbeHandler.Exec = &corev1.ExecAction{
            Command: []string{config.Cmd},
        }

    }

    fmt.Println("probe================================================================", probe)
    return probe

}

type DeleteDeploymentRequest struct {
    Namespace      string `json:"namespace"`
    DeploymentName string `json:"deploymentName"`
}
type RestartDeploymentRequest struct {
    *DataTemplateResponse
}
type UpdateDeploymentRequest struct {
    *DataTemplateResponse
    Content string `json:"content"`
}
type GetNamespaceDeploymentCountRequest struct {
    *DataTemplateResponse
}
type NsDeployCount struct {
    DeploymentCount int    `json:"deploymentCount"`
    Namespace       string `json:"namespace"`
}
2、daemonset

apps/k8sclient/structs/daemonset.go

package structs

import (
    appsv1 "k8s.io/api/apps/v1"
    "k8s.io/apimachinery/pkg/util/json"
)

//
//  DaemonSetTemplate
//  @Description:  daemonset 通用模板
//
type DaemonSetTemplate struct {
    Namespace     string `json:"namespace"`
    DaemonSetName string `json:"daemonSetName"`
}

//
//  GetDaemonSetListRequest
//  @Description: 获取damonset列表,包括分页、过滤、排序
//
type GetDaemonSetListRequest struct {
    FilterName string `json:"filterName"`
    Namespace  string `json:"namespace"`
    *DataPagination
}

//
//  CreateDaemonSetRequest
//  @Description: 创建daemonset
//
type CreateDaemonSetRequest struct {
    *DaemonSetTemplate
    PodName    string            `json:"podName"`
    Replicas   *int32            `json:"replicas"`
    Image      string            `json:"image"`
    Label      map[string]string `json:"label"`
    Containers []ContainerRequest
}

func (c *CreateDaemonSetRequest) String() string {
    data, _ := json.Marshal(c)
    return string(data)
}

//
//  DescribeDaemonSet
//  @Description: 查看daemonset详情
//
type DescribeDaemonSet struct {
    *DaemonSetTemplate
}

//
//  DeleteDaemonSet
//  @Description: 删除daemonset
//
type DeleteDaemonSet struct {
    *DaemonSetTemplate
}

//
//  UpdateDaemonSet
//  @Description: 更新daemonset
//
type UpdateDaemonSet struct {
    *DaemonSetTemplate
    Content string `json:"content"`
}

//
//  DaemonsetResp
//  @Description: 返回daemonset总数、列表
//
type DaemonsetResp struct {
    Items []appsv1.DaemonSet `json:"items"`
    Count int                `json:"count"`
}
3、statefulset
package structs

import appsv1 "k8s.io/api/apps/v1"

type StatefulSetTemplate struct {
    StatefulSetName string `json:"statefulset_name"`
    Namespace       string `json:"namespace"`
}

type CreateStatefulSetRequest struct {
    *StatefulSetTemplate
    PodName    string            `json:"podName"`
    Replicas   *int32            `json:"replicas"`
    Image      string            `json:"image"`
    Label      map[string]string `json:"label"`
    Containers []ContainerRequest
}
type GetStatefulSetListRequest struct {
    FilterName string `json:"filterName"`
    Namespace  string `json:"namespace"`
    *DataPagination
}
type DescribeStatefulSet struct {
    *StatefulSetTemplate
}
type DeleteStatefulSet struct {
    *StatefulSetTemplate
}
type UpdateStatefulSet struct {
    *StatefulSetTemplate
    Content string `json:"content"`
}
type StatefulSetResp struct {
    Items []appsv1.StatefulSet `json:"items"`
    Count int                  `json:"count"`
}

三、实现类

1、deployment

apps/k8sclient/impl/deploymentImpl.go

package impl

import (
    "context"
    "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"
    appsv1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/json"
    "k8s.io/client-go/util/retry"
    "time"
)

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

//
//  DeploymentImpl
//  @Description: 定义deployment接口实现
//
type DeploymentImpl struct {
    K8sClientInstance *k8sclient.K8sClient
}

/*
 * Init
 * @Description: 获取kubernetes注入的对象
 * @receiver d
 * @return error
 */
func (d *DeploymentImpl) Init() error {
    d.K8sClientInstance = ioc.Controller().GetObj(config.IOC_KUBECLIENT).(*k8sclient.K8sClient)
    return nil
}
func (d *DeploymentImpl) Name() string {
    return config.DEPLOYMENT_IOCNAME
}

/*
 * GetDeploymentList
 * @Description: 获取deployment列表
 * @receiver d
 * @param ctx
 * @param request
 * @return *structs.DeployResp
 * @return error
 */
func (d *DeploymentImpl) GetDeploymentList(ctx context.Context,
    request *structs.GetDeploymentListRequest) (*structs.DeployResp, error) {
    deployList, err := d.K8sClientInstance.ClientSet.AppsV1().Deployments(request.Namespace).List(ctx, metav1.ListOptions{})
    if err != nil {
        return nil, exception.GetDeploymentListFailed("获取deployment列表失败:%s", err.Error())
    }
    var data *structs.DataSort
    f := structs.DataFilter{FilterName: request.FilterName}
    data = f.Filter(&structs.DataSort{DataList: d.toCell(deployList)})
    fmt.Println(data)
    data = data.Sort()
    p := structs.DataPagination{
        PageSize:   request.PageSize,
        PageNumber: request.PageNumber,
    }
    data, err = p.Paginate(data)
    if err != nil {
        return nil, err
    }
    //f := k8sclient.DataFilter{FilterName: request.FilterName}
    //d.toCell(deployList)
    fmt.Println(deployList, "——————————————")
    result := structs.DeployResp{
        Total: len(data.DataList),
        Items: d.FromCell(data.DataList),
    }
    //f.Filter(f)

    return &result, nil
}

/*
 * DescribeDeployments
 * @Description: 查看deployment详细信息
 * @receiver d
 * @param ctx
 * @param request
 * @return *appsv1.Deployment
 * @return error
 */
func (d *DeploymentImpl) DescribeDeployments(ctx context.Context,
    request *structs.DescribeDeploymentsRequest) (*appsv1.Deployment, error) {
    deployInfo, err := d.K8sClientInstance.ClientSet.AppsV1().
        Deployments(request.Namespace).
        Get(ctx, request.DeploymentName, metav1.GetOptions{})

    if err != nil {
        return nil, exception.DescribeDeploymentFailed("获取deployment详情失败:%s", err.Error())
    }
    return deployInfo, nil
}

/*
 * UpdateDeploymentScale
 * @Description: 修改deployment副本数
 * @receiver d
 * @param ctx
 * @param request
 * @return int32
 * @return error
 */
func (d *DeploymentImpl) UpdateDeploymentScale(ctx context.Context,
    request *structs.UpdateDeploymentScaleRequest) (int32, error) {
    // 先获取到当前deployment的副本数
    scale, err := d.K8sClientInstance.ClientSet.AppsV1().
        Deployments(request.Namespace).GetScale(ctx, request.DeploymentName, metav1.GetOptions{})
    if err != nil {
        return 0, exception.GetDeploymentScaleFailed("获取deployment副本失败:%s", err.Error())
    }
    // 修改副本数
    scale.Spec.Replicas = int32(request.ScaleNum)
    // 更新deployment
    newScale, err := d.K8sClientInstance.ClientSet.AppsV1().Deployments(request.Namespace).
        UpdateScale(ctx, request.DeploymentName, scale, metav1.UpdateOptions{})
    if err != nil {
        return 0, exception.UpdateDeploymentScaleFailed("修改deployment副本数失败:%s", err.Error())
    }

    return newScale.Spec.Replicas, nil
}

/*
 * CreateDeployment
 * @Description: 创建deployment
 * @receiver d
 * @param ctx
 * @param request
 * @return *appsv1.Deployment
 * @return error
 */
func (d *DeploymentImpl) CreateDeployment(ctx context.Context, request *structs.CreateDeploymentRequest) (*appsv1.Deployment, error) {
    // 根据传入的request 创建k8s deployment资源
    deployment := config2.NewDeploymentConfig(request)
    // 创建deployment 资源
    result, err := d.K8sClientInstance.ClientSet.AppsV1().Deployments(request.Namespace).Create(ctx, deployment, metav1.CreateOptions{})
    if err != nil {
        return nil, err
    }
    fmt.Println("result = ", result)
    return result, nil
}

/*
 * DeleteDeployment
 * @Description: 删除deployment
 * @receiver d
 * @param ctx
 * @param request
 * @return error
 */
func (d *DeploymentImpl) DeleteDeployment(ctx context.Context, request *structs.DeleteDeploymentRequest) error {
    err := d.K8sClientInstance.ClientSet.AppsV1().Deployments(request.Namespace).
        Delete(ctx, request.DeploymentName, metav1.DeleteOptions{})
    if err != nil {
        return exception.DeleteDeploymentFailed("删除deployment失败:%s", err.Error())
    }
    return nil
}

/*
 * RestartDeployment
 * @Description: 重启deployment
 * @receiver d
 * @param ctx
 * @param request
 * @return error
 */
func (d *DeploymentImpl) RestartDeployment(ctx context.Context, request *structs.RestartDeploymentRequest) error {
    // 1、获取deployment对象
    deployment, err := d.K8sClientInstance.ClientSet.AppsV1().
        Deployments(request.Namespace).Get(ctx, request.DeploymentName, metav1.GetOptions{})
    if err != nil {
        return exception.DescribeDeploymentFailed("获取deployment信息失败:%s", err.Error())
    }
    // 2、设置注释
    annotation := "kubectl.kubernetes.io/restartedAt"
    currentTime := time.Now().Format("2006-01-02 15:04:05")
    if deployment.Spec.Template.Annotations == nil {
        deployment.Spec.Template.Annotations = make(map[string]string)
    }
    deployment.Spec.Template.Annotations[annotation] = currentTime
    //  3、更新注释后会自动重启所有pod,retry 解决冲突(多个客户端同时更改一个deployment)问题,如果有冲突会自动重试更新
    err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
        _, updateErr := d.K8sClientInstance.ClientSet.AppsV1().Deployments(request.Namespace).
            Update(ctx, deployment, metav1.UpdateOptions{})
        return updateErr
    })
    if err != nil {
        return exception.UpdateDeploymentFailed("更新deployment失败:%s", err.Error())
    }
    return nil
}

/*
 * UpdateDeployment
 * @Description: 更新deployment
 * @receiver d
 * @param ctx
 * @param request
 * @return *appsv1.Deployment
 * @return error
 */
func (d *DeploymentImpl) UpdateDeployment(ctx context.Context,
    request *structs.UpdateDeploymentRequest) (*appsv1.Deployment, error) {
    // 1、 创建deployment资源实例
    var deoloyment = &appsv1.Deployment{}
    fmt.Println(request.Content)
    //  2、将前端传入的字符串反序列化为json格式并赋给deployment资源实例
    err := json.Unmarshal([]byte(request.Content), &deoloyment)
    fmt.Println()
    if err != nil {
        return nil, exception.JsonUmarshalFailed("Json反序列化失败:%s", err.Error())
    }
    // 3、更新deployment
    newDeployment, err := d.K8sClientInstance.ClientSet.AppsV1().
        Deployments(request.Namespace).Update(ctx, deoloyment, metav1.UpdateOptions{})
    if err != nil {
        return nil, exception.UpdateDeploymentFailed("更新deployment失败:%s", err.Error())
    }

    return newDeployment, nil
}

/*
 * GetNamespaceDeploymentCount
 * @Description: 获取每个namespace的deplpyment数量
 * @receiver d
 * @param ctx
 * @param request
 * @return []*structs.NsDeployCount
 * @return error
 */
func (d *DeploymentImpl) GetNamespaceDeploymentCount(ctx context.Context,
    request *structs.GetNamespaceDeploymentCountRequest) ([]*structs.NsDeployCount, error) {
    // 1、获取所有namespace列表
    nslist, err := d.K8sClientInstance.ClientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
    if err != nil {
        return nil, exception.NewGetNamespacePodsCountFailed("获取namespace列表失败:%s", err.Error())
    }
    // 根据每个namespace,获取每个namespace对应的deplyoment数量
    nsDeploy := []*structs.NsDeployCount{}
    for _, namespace := range nslist.Items {
        deploymentlist, err := d.K8sClientInstance.ClientSet.AppsV1().
            Deployments(namespace.Name).List(ctx, metav1.ListOptions{})
        if err != nil {
            return nil, exception.GetDeploymentListFailed("获取deployment列表失败:%s", err.Error())
        }
        nsDeploy = append(nsDeploy, &structs.NsDeployCount{
            DeploymentCount: len(deploymentlist.Items),
            Namespace:       namespace.Name,
        })
    }

    return nsDeploy, nil
}

/*
 * toCell
 * @Description: 将k8s中的deploymentList对象转换成DataMeta对象
 * @receiver d
 * @param data
 * @return []structs.DataMeta
 */
func (d *DeploymentImpl) toCell(data *appsv1.DeploymentList) []structs.DataMeta {
    cells := make([]structs.DataMeta, len(data.Items))
    for i := range data.Items {
        cells[i] = cell.DeploymentCell(data.Items[i])
    }
    return cells
}

/*
 * FromCell
 * @Description: 将DataMeta列表转为k8s中的[]deployment对象
 * @receiver d
 * @param data
 * @return []appsv1.Deployment
 */
func (d *DeploymentImpl) FromCell(data []structs.DataMeta) []appsv1.Deployment {
    cells := make([]appsv1.Deployment, len(data))
    for i := range data {
        cells[i] = appsv1.Deployment(data[i].(cell.DeploymentCell))
    }
    return cells
}
2、daemonset

apps/k8sclient/impl/daemonsetImpl.go

package impl

import (
    "context"
    "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"
    appsv1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/json"
)

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

type DaemonSetImpl struct {
    K8sClientInstance *k8sclient.K8sClient
}

func (d *DaemonSetImpl) Init() error {
    d.K8sClientInstance = ioc.Controller().GetObj(config.IOC_KUBECLIENT).(*k8sclient.K8sClient)
    return nil
}
func (d *DaemonSetImpl) Name() string {
    return config.DAEMONSET_IOCNAME
}

/*
 * CreateDaemonSet
 * @Description: 创建daemonset
 * @receiver d
 * @param ctx
 * @param request
 * @return *appsv1.DaemonSet
 * @return error
 */
func (d *DaemonSetImpl) CreateDaemonSet(ctx context.Context,
    request *structs.CreateDaemonSetRequest) (*appsv1.DaemonSet, error) {
    daemonset := config2.NewDaemonsetConfig(request)
    fmt.Println(daemonset)
    result, err := d.K8sClientInstance.ClientSet.AppsV1().DaemonSets(request.Namespace).
        Create(ctx, daemonset, metav1.CreateOptions{})
    if err != nil {
        return nil, exception.CreateDaemonSetFailed("创建daemonset失败:%s", err.Error())
    }
    //d.K8sClientInstance.ClientSet.AppsV1().DaemonSets(request.Namespace).cr
    return result, nil
}

/*
 * GetDaemonSetList
 * @Description: 获取daemonset列表
 * @receiver d
 * @param ctx
 * @param request
 * @return *structs.DaemonsetResp
 * @return error
 */
func (d *DaemonSetImpl) GetDaemonSetList(ctx context.Context,
    request *structs.GetDaemonSetListRequest) (*structs.DaemonsetResp, error) {
    fmt.Println(d.K8sClientInstance)
    daemonSetlist, err := d.K8sClientInstance.ClientSet.AppsV1().
        DaemonSets(request.Namespace).List(ctx, metav1.ListOptions{})
    if err != nil {
        return nil, exception.GetDaemonSetListFailed("获取daemonsetList失败:%s", err.Error())
    }
    f := structs.DataFilter{FilterName: request.FilterName}
    data := f.Filter(&structs.DataSort{DataList: d.toCell(daemonSetlist)})
    data = data.Sort()
    p := &structs.DataPagination{
        PageSize:   request.PageSize,
        PageNumber: request.PageNumber,
    }
    data, err = p.Paginate(data)
    if err != nil {
        return nil, exception.NewGetPaginateFailed("获取分页数据失败:%s", err.Error())
    }
    result := &structs.DaemonsetResp{
        Count: len(daemonSetlist.Items),
        Items: d.FromCell(data.DataList),
    }
    return result, nil
}
func (d *DaemonSetImpl) DescribeDaemonSet(ctx context.Context,
    request *structs.DescribeDaemonSet) (*appsv1.DaemonSet, error) {
    daemonset, err := d.K8sClientInstance.ClientSet.AppsV1().DaemonSets(request.Namespace).
        Get(ctx, request.DaemonSetName, metav1.GetOptions{})
    if err != nil {
        return nil, exception.DescribeDaemonSetFailed("获取daemonset详情失败:%s", err.Error())
    }
    return daemonset, nil
}
func (d *DaemonSetImpl) DeleteDaemonSet(ctx context.Context, request *structs.DeleteDaemonSet) error {
    err := d.K8sClientInstance.ClientSet.AppsV1().DaemonSets(request.Namespace).
        Delete(ctx, request.DaemonSetName, metav1.DeleteOptions{})
    if err != nil {
        return exception.DeleteDaemonSetFailed("删除daemonset失败:%s", err.Error())
    }
    return nil
}
func (d *DaemonSetImpl) UpdateDaemonSet(ctx context.Context, request *structs.UpdateDaemonSet) (*appsv1.DaemonSet, error) {
    daemonset := &appsv1.DaemonSet{}
    err := json.Unmarshal([]byte(request.Content), daemonset)
    if err != nil {
        return nil, exception.JsonUmarshalFailed("Json 反序列化失败:%s", err.Error())
    }
    result, err := d.K8sClientInstance.ClientSet.AppsV1().DaemonSets(request.Namespace).
        Update(ctx, daemonset, metav1.UpdateOptions{})
    if err != nil {
        return nil, exception.UpdateDaemonSetFailed("更新daemonset失败:%s", err.Error())
    }
    return result, nil
}
func (d *DaemonSetImpl) toCell(data *appsv1.DaemonSetList) []structs.DataMeta {
    cells := make([]structs.DataMeta, len(data.Items))
    for i := range data.Items {
        cells[i] = cell.DaemonSetCell(data.Items[i])
    }
    return cells
}
func (d *DaemonSetImpl) FromCell(data []structs.DataMeta) []appsv1.DaemonSet {
    cells := make([]appsv1.DaemonSet, len(data))
    for i := range data {
        cells[i] = appsv1.DaemonSet((data[i].(cell.DaemonSetCell)))
    }
    return cells
}
3、statefulset

apps/k8sclient/impl/statefulsetImpl.go

package impl

import (
    "context"
    "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"
    appsv1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/json"
)

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

type StatefulSetImpl struct {
    K8sClientInstance *k8sclient.K8sClient
}

func (s *StatefulSetImpl) Init() error {
    s.K8sClientInstance = ioc.Controller().GetObj(config.IOC_KUBECLIENT).(*k8sclient.K8sClient)
    fmt.Println(s.K8sClientInstance)
    return nil
}
func (s *StatefulSetImpl) Name() string {
    return config.STATEFULSET_IOCNAME
}

/*
 * CreateStatefulSet
 * @Description: 创建statefulset
 * @receiver s
 * @param ctx
 * @param request
 * @return *appsv1.StatefulSet
 * @return error
 */
func (s *StatefulSetImpl) CreateStatefulSet(ctx context.Context,
    request *structs.CreateStatefulSetRequest) (*appsv1.StatefulSet, error) {
    statefulset := config2.NewStatefulsetConfig(request)
    data, err := s.K8sClientInstance.ClientSet.AppsV1().StatefulSets(request.Namespace).
        Create(ctx, statefulset, metav1.CreateOptions{})
    if err != nil {
        return nil, exception.CreateStatefulSetFailed("创建失败:%s", err.Error())
    }

    return data, nil
}
func (s *StatefulSetImpl) GetStatefulSetList(ctx context.Context,
    request *structs.GetStatefulSetListRequest) (*structs.StatefulSetResp, error) {
    statefullist, err := s.K8sClientInstance.ClientSet.AppsV1().
        StatefulSets(request.Namespace).List(ctx, metav1.ListOptions{})
    f := structs.DataFilter{FilterName: request.FilterName}
    data := f.Filter(&structs.DataSort{DataList: s.ToCell(statefullist)})
    data = data.Sort()
    p := structs.DataPagination{
        PageSize:   request.PageSize,
        PageNumber: request.PageNumber,
    }
    data, err = p.Paginate(data)
    if err != nil {
        return nil, exception.GetStatefulSetListFailed("获取statefulset列表失败:%s", err.Error())
    }
    result := &structs.StatefulSetResp{
        Items: s.FromCell(data.DataList),
        Count: len(statefullist.Items),
    }
    return result, nil
}
func (s *StatefulSetImpl) DescribeStatefulSet(ctx context.Context,
    request *structs.DescribeStatefulSet) (*appsv1.StatefulSet, error) {
    statefulset, err := s.K8sClientInstance.ClientSet.AppsV1().StatefulSets(request.Namespace).
        Get(ctx, request.StatefulSetName, metav1.GetOptions{})
    if err != nil {
        return nil, exception.DescribeStatefulSetFailed("获取statefulset详情失败:%s", err.Error())
    }
    return statefulset, nil
}
func (s *StatefulSetImpl) DeleteStatefulSet(ctx context.Context, request *structs.DeleteStatefulSet) error {
    err := s.K8sClientInstance.ClientSet.AppsV1().StatefulSets(request.Namespace).
        Delete(ctx, request.StatefulSetName, metav1.DeleteOptions{})
    return exception.DeleteStatefulSetFailed("删除失败:%s", err.Error())
}
func (s *StatefulSetImpl) UpdateStatefulSet(ctx context.Context,
    request *structs.UpdateStatefulSet) (*appsv1.StatefulSet, error) {
    statefulSet := &appsv1.StatefulSet{}
    err := json.Unmarshal([]byte(request.Content), statefulSet)
    if err != nil {
        return nil, exception.JsonUmarshalFailed("Json反序列化失败:%s", err.Error())
    }
    result, err := s.K8sClientInstance.ClientSet.AppsV1().StatefulSets(request.Namespace).
        Update(ctx, statefulSet, metav1.UpdateOptions{})
    if err != nil {
        return nil, exception.UpdateStatefulSetFailed("更新失败:%s", err.Error())
    }
    return result, nil
}

/*
 * toCell
 * @Description: 将k8s中的deploymentList对象转换成DataMeta对象
 * @receiver d
 * @param data
 * @return []structs.DataMeta
 */
func (d *StatefulSetImpl) ToCell(data *appsv1.StatefulSetList) []structs.DataMeta {
    cells := make([]structs.DataMeta, len(data.Items))
    for i := range data.Items {
        cells[i] = cell.StatefulsetCell(data.Items[i])
    }
    return cells
}

/*
 * FromCell
 * @Description: 将DataMeta列表转为k8s中的[]deployment对象
 * @receiver d
 * @param data
 * @return []appsv1.Deployment
 */
func (d *StatefulSetImpl) FromCell(data []structs.DataMeta) []appsv1.StatefulSet {
    cells := make([]appsv1.StatefulSet, len(data))
    for i := range data {
        cells[i] = appsv1.StatefulSet(data[i].(cell.StatefulsetCell))
    }
    return cells
}

impl/config/deployment_config.go

package config

import (
    "fmt"
    "k8s-platform/apps/k8sclient/structs"
    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
    // k8s资源解析包
    "k8s.io/apimachinery/pkg/api/resource"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

//
//  DeploymentConfig
//  @Description: 生成k8s  deployment资源的结构体
//
type DeploymentConfig struct {
    deployment *appsv1.Deployment
}

/*
 * NewDeploymentConfig
 * @Description:  创建k8s deployment资源的方法,需要传入创建deplyoment的参数
 * @param request
 * @return *appsv1.Deployment
 */
func NewDeploymentConfig(request *structs.CreateDeploymentRequest) *appsv1.Deployment {
    fmt.Println(request)
    // 遍历deployment中所有的 container对象,并将所有container对象转换成k8s 中的container资源
    var containers []corev1.Container
    for _, c := range request.Containers {
        containers = append(containers, c.ToK8sContainer())
    }
    return ToK8sDeployment(request, containers)
}

/*
 * ToK8sDeployment
 * @Description:  将CreateDeploymentRequest 转换为k8s deployment对象
 * @receiver c
 * @param request
 * @return appsv1.Deployment
 */
func ToK8sDeployment(request *structs.CreateDeploymentRequest, container []corev1.Container) *appsv1.Deployment {
    // 将对应的参数传入appsv1.Deployment
    return &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name:      request.DeploymentName,
            Namespace: request.Namespace,
            Labels:    request.Label,
        },
        Spec: appsv1.DeploymentSpec{
            Selector: &metav1.LabelSelector{
                MatchLabels: request.Label,
            },
            Replicas: request.Replicas,
            Template: corev1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Name:      request.PodName,
                    Namespace: request.Namespace,
                    Labels:    request.Label,
                },
                Spec: corev1.PodSpec{
                    Containers: container,
                },
            },
        },
    }
}

/*
 * NewResourceRequirements
 * @Description:  将传入的资源参数转换成K8s中的ResourceRequirement对象
 * @param cpuLimit  容我可以使用的最大CPU资源,以字符串形式表示,如"200m"
 * @param memoryLimit 容器可以使用的最大内存资源,如"256Mi"
 * @param cpuRequests  k8s调度容器时所需要的最小cpu资源量,形式同上
 * @param memoryRequests  k8s调度容器时所需要的最小内存资源量,形式同上
 * @return corev1.ResourceRequirements   包含了Limits、Requests、Claims三个字段
 */
func NewResourceRequirements(cpuLimit, memoryLimit, cpuRequests, memoryRequests string) corev1.ResourceRequirements {
    return corev1.ResourceRequirements{
        Limits: corev1.ResourceList{
            // corev1.ResourceCPU 是一个常量,表示 CPU 资源。
            // resource.MustParse 解析 cpuLimit 字符串为一个资源数量对象。
            // 这里的 "200m"  200 millicores,也就是 0.2 核的 CPU。
            corev1.ResourceCPU: resource.MustParse(cpuLimit),
            // corev1.ResourceMemory 是一个常量,表示内存资源。
            // resource.MustParse 解析 memoryLimit 字符串为一个资源数量对象。
            // "256Mi" 表示 256 Mebibytes 的内存。
            corev1.ResourceMemory: resource.MustParse(memoryLimit),
        },
        Requests: corev1.ResourceList{
            corev1.ResourceCPU:    resource.MustParse(cpuRequests),
            corev1.ResourceMemory: resource.MustParse(memoryRequests),
        },
    }
}

func Int32Conversion(i int32) *int32 {
    return &i
}

impl/config/daemonset_config.go

package config

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

/*
 * NewDaemonsetConfig
 * @Description: 将用户传入的参数,转换成k8s中的Daemonset对象
 * @param request
 * @return *appsv1.DaemonSet
 */
func NewDaemonsetConfig(request *structs.CreateDaemonSetRequest) *appsv1.DaemonSet {
    // 遍历daemonset中所有的 container对象,并将所有container对象转换成k8s 中的container资源
    var containers []corev1.Container
    for _, c := range request.Containers {
        containers = append(containers, c.ToK8sContainer())
    }
    return ToK8sDaemonset(request, containers)
}

/*
 * ToK8sDaemonset
 * @Description: 将用户传入的参数,转换成k8s中的Daemonset对象
 * @param request
 * @param container
 * @return *appsv1.DaemonSet
 */
func ToK8sDaemonset(request *structs.CreateDaemonSetRequest, container []corev1.Container) *appsv1.DaemonSet {
    // 将对应的参数传入appsv1.Deployment
    return &appsv1.DaemonSet{
        ObjectMeta: metav1.ObjectMeta{
            Name:      request.DaemonSetName,
            Namespace: request.Namespace,
            Labels:    request.Label,
        },
        Spec: appsv1.DaemonSetSpec{
            Selector: &metav1.LabelSelector{
                MatchLabels: request.Label,
            },
            Template: corev1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Name:      request.PodName,
                    Namespace: request.Namespace,
                    Labels:    request.Label,
                },
                Spec: corev1.PodSpec{
                    Containers: container,
                },
            },
        },
    }
}

impl/config/statefulset_config.go

package config

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

/*
 * NewStatefulsetConfig
 * @Description:  创建k8s statefulset资源的方法,需要传入创建statefulset的参数
 * @param request
 * @return *appsv1.statefulset
 */
func NewStatefulsetConfig(request *structs.CreateStatefulSetRequest) *appsv1.StatefulSet {
    // 遍历deployment中所有的 container对象,并将所有container对象转换成k8s 中的container资源
    var containers []corev1.Container
    for _, c := range request.Containers {
        containers = append(containers, c.ToK8sContainer())
    }
    return ToK8sStatefulset(request, containers)
}

/*
 * ToK8sStatefulset
 * @Description:  CreateStatefulSetRequest 转换为k8s statefulset对象
 * @receiver c
 * @param request
 * @return appsv1.StatefulSet
 */
func ToK8sStatefulset(request *structs.CreateStatefulSetRequest, container []corev1.Container) *appsv1.StatefulSet {
    // 将对应的参数传入appsv1.Deployment
    return &appsv1.StatefulSet{
        ObjectMeta: metav1.ObjectMeta{
            Name:      request.StatefulSetName,
            Namespace: request.Namespace,
            Labels:    request.Label,
        },
        Spec: appsv1.StatefulSetSpec{
            Selector: &metav1.LabelSelector{
                MatchLabels: request.Label,
            },
            Replicas: request.Replicas,
            Template: corev1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Name:      request.PodName,
                    Namespace: request.Namespace,
                    Labels:    request.Label,
                },
                Spec: corev1.PodSpec{
                    Containers: container,
                },
            },
        },
    }
}

四、实现resetful接口访问

1、deployment
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 DeploymentHttpHandler *deploymentHttpHandler = NewdeploymentHttpHandler()

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

var (
    deploySvc k8sclient.DeploymentService
)

func NewdeploymentHttpHandler() *deploymentHttpHandler {
    return &deploymentHttpHandler{
        svc: ioc.Controller().GetObj(config.DEPLOYMENT_IOCNAME).(k8sclient.DeploymentService),
    }
}

type deploymentHttpHandler struct {
    svc k8sclient.DeploymentService
}

/*
 * Init
 * @Description: 注入ioc后初始化的操作
 * @receiver d
 * @return error
 */
func (d *deploymentHttpHandler) Init() error { // todo 这里已经获取到了svc
    d.svc = ioc.Controller().GetObj(config.DEPLOYMENT_IOCNAME).(k8sclient.DeploymentService)
    fmt.Println(d.svc, "http deployment ioc")
    fmt.Printf("Init : %p ,%v\n", d, d.svc)

    return nil
}
func (d *deploymentHttpHandler) Name() string {
    return config.DEPLOYMENT_API
}

func (d *deploymentHttpHandler) CreateDeployment(c *gin.Context) {
    data := &structs.CreateDeploymentRequest{}
    err := c.BindJSON(&data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    fmt.Println(data, "================================")
    deployment, err := d.svc.CreateDeployment(c.Request.Context(), data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, deployment)
}

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

/*
 * DescribeDeployment
 * @Description: 查看deployment详情
 * @receiver d
 * @param c
 */
func (d *deploymentHttpHandler) DescribeDeployment(c *gin.Context) {
    //namespace := c.Query("namespace")
    //deploymentName := c.Query("deploymentName")
    namespace := c.Query("namespace")
    deploymentName := c.Query("deploymentName")
    data := structs.DescribeDeploymentsRequest{
        &structs.DataTemplateResponse{
            Namespace:      namespace,
            DeploymentName: deploymentName,
        },
    }
    fmt.Println(data)
    result, err := d.svc.DescribeDeployments(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)

}

/*
 * UpdateDeploymentScale
 * @Description: 更新deployment副本数
 * @receiver d
 * @param c
 */
func (d *deploymentHttpHandler) UpdateDeploymentScale(c *gin.Context) {
    data := structs.UpdateDeploymentScaleRequest{}
    c.BindJSON(&data)
    result, err := d.svc.UpdateDeploymentScale(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

/*
 * DeleteDeployment
 * @Description: 删除deployment
 * @receiver d
 * @param c
 */
func (d *deploymentHttpHandler) DeleteDeployment(c *gin.Context) {
    data := structs.DeleteDeploymentRequest{}

    err := c.BindJSON(&data)
    if err != nil {
        fmt.Println("-----------?????")
        fmt.Println(err)
        response.Failure(c, err)
        return
    }
    fmt.Println("————————————————————————————————————————-")
    fmt.Println(data)
    err = d.svc.DeleteDeployment(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, "删除成功")

}

/*
 * RestartDeployment
 * @Description: 重启deployment
 * @receiver d
 * @param c
 */
func (d *deploymentHttpHandler) RestartDeployment(c *gin.Context) {
    data := structs.RestartDeploymentRequest{}
    c.BindJSON(&data)
    err := d.svc.RestartDeployment(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, "重启成功")
}

/*
 * UpdateDeployment
 * @Description: 更新deployment
 * @receiver d
 * @param c
 */
func (d *deploymentHttpHandler) UpdateDeployment(c *gin.Context) {
    data := structs.UpdateDeploymentRequest{}
    c.BindJSON(&data)
    result, err := d.svc.UpdateDeployment(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

/*
 * GetNamespaceDeploymentCount
 * @Description: 获取每个namespace的deployment数量
 * @receiver d
 * @param c
 */
func (d *deploymentHttpHandler) GetNamespaceDeploymentCount(c *gin.Context) {
    namespace := c.Query("namespace")
    depName := c.Query("deploymentName")
    data := structs.GetNamespaceDeploymentCountRequest{
        &structs.DataTemplateResponse{
            Namespace:      namespace,
            DeploymentName: depName,
        },
    }
    result, err := d.svc.GetNamespaceDeploymentCount(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}
2、daemonset
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 DaemonsetHttpHandler *daemonsetHttpHandler = NewdaemonsetHttpHandler()

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

var (
    daemonsetSvc k8sclient.DaemonSetService
)

func NewdaemonsetHttpHandler() *daemonsetHttpHandler {
    return &daemonsetHttpHandler{
        svc: ioc.Controller().GetObj(config.DAEMONSET_IOCNAME).(k8sclient.DaemonSetService),
    }
}

type daemonsetHttpHandler struct {
    svc k8sclient.DaemonSetService
}

/*
 * Init
 * @Description: 注入ioc后初始化的操作
 * @receiver d
 * @return error
 */
func (d *daemonsetHttpHandler) Init() error { // todo 这里已经获取到了svc
    d.svc = ioc.Controller().GetObj(config.DAEMONSET_IOCNAME).(k8sclient.DaemonSetService)
    fmt.Printf("Init : %p ,%v\n", d, d.svc)
    return nil
}
func (d *daemonsetHttpHandler) Name() string {
    return config.DAMONSET_API
}

/*
 * GetDeploymentList
 * @Description: 获取daemonset列表的handler函数
 * @receiver d
 * @param c
 */
func (d *daemonsetHttpHandler) GetDaemonSetList(c *gin.Context) {
    filtername := c.Query("filterName")
    namespace := c.Query("namespace")
    pagesize, _ := strconv.Atoi(c.Query("page_size"))
    pagenumber, _ := strconv.Atoi(c.Query("page_number"))
    data := structs.GetDaemonSetListRequest{
        FilterName: filtername,
        Namespace:  namespace,
        DataPagination: &structs.DataPagination{
            PageSize:   pagesize,
            PageNumber: pagenumber,
        },
    }
    fmt.Println(data)
    result, err := d.svc.GetDaemonSetList(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

/*
 * DescribeDaemonSet
 * @Description: 获取daemonset详情的handler函数
 * @receiver d
 * @param c
 */
func (d *daemonsetHttpHandler) DescribeDaemonSet(c *gin.Context) {
    namespace := c.Query("namespace")
    daemonSetName := c.Query("daemonSetName")
    data := structs.DescribeDaemonSet{
        &structs.DaemonSetTemplate{
            Namespace:     namespace,
            DaemonSetName: daemonSetName,
        },
    }
    result, err := d.svc.DescribeDaemonSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

/*
 * DeleteDaemonSet
 * @Description: 删除daemonset的handler函数
 * @receiver d
 * @param c
 */
func (d *daemonsetHttpHandler) DeleteDaemonSet(c *gin.Context) {
    data := structs.DeleteDaemonSet{}
    c.BindJSON(&data)
    err := d.svc.DeleteDaemonSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, "删除成功")
}

/*
 * UpdateDaemonSet
 * @Description: 更新daemonset的handler函数
 * @receiver d
 * @param c
 */
func (d *daemonsetHttpHandler) UpdateDaemonSet(c *gin.Context) {
    data := structs.UpdateDaemonSet{}
    c.BindJSON(&data)
    result, err := d.svc.UpdateDaemonSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

/*
 * CreateDaemonSet
 * @Description: 创建daemonset的handler函数
 * @receiver d
 * @param c
 */
func (d *daemonsetHttpHandler) CreateDaemonSet(c *gin.Context) {
    data := structs.CreateDaemonSetRequest{}
    c.BindJSON(&data)
    result, err := d.svc.CreateDaemonSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}

3、statefulset

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 StatefulSetHttpHandler *statefulsetHttpHandler = NewstatefulsetHttpHandler()

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

func NewstatefulsetHttpHandler() *statefulsetHttpHandler {
    return &statefulsetHttpHandler{
        svc: ioc.Controller().GetObj(config.STATEFULSET_IOCNAME).(k8sclient.StatefulSetService),
    }
}

type statefulsetHttpHandler struct {
    svc k8sclient.StatefulSetService
}

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

/*
 * GetDeploymentList
 * @Description: 获取statefulset列表
 * @receiver d
 * @param c
 */
func (d *statefulsetHttpHandler) GetStatefulSetList(c *gin.Context) {
    size, _ := strconv.Atoi(c.Query("page_size"))
    number, _ := strconv.Atoi(c.Query("page_number"))
    data := structs.GetStatefulSetListRequest{
        FilterName: c.Query("filterName"),
        Namespace:  c.Query("namespace"),
        DataPagination: &structs.DataPagination{
            PageSize:   size,
            PageNumber: number,
        },
    }
    result, err := d.svc.GetStatefulSetList(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}
func (d *statefulsetHttpHandler) DescribeStatefulSet(c *gin.Context) {
    data := structs.DescribeStatefulSet{
        &structs.StatefulSetTemplate{
            Namespace:       c.Query("namespace"),
            StatefulSetName: c.Query("statefulset_name"),
        },
    }
    result, err := d.svc.DescribeStatefulSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}
func (d *statefulsetHttpHandler) DeleteStatefulset(c *gin.Context) {
    data := structs.DeleteStatefulSet{}
    c.BindJSON(&data)
    err := d.svc.DeleteStatefulSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, "删除成功")
}
func (d *statefulsetHttpHandler) UpdateStatefulSet(c *gin.Context) {
    data := structs.UpdateStatefulSet{}

    c.BindJSON(&data)
    result, err := d.svc.UpdateStatefulSet(c.Request.Context(), &data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, result)
}
func (d *statefulsetHttpHandler) CreateStatefulset(c *gin.Context) {
    data := &structs.CreateStatefulSetRequest{}
    err := c.BindJSON(&data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    fmt.Println(data, "================================")
    deployment, err := d.svc.CreateStatefulSet(c.Request.Context(), data)
    if err != nil {
        response.Failure(c, err)
        return
    }
    response.Success(c, deployment)
}

cell/deploymentCell.go

package cell

import (
    appsv1 "k8s.io/api/apps/v1"
    "time"
)

//  实现DataMeta接口
type DeploymentCell appsv1.Deployment

func (d DeploymentCell) GetName() string {
    return d.Name
}
func (d DeploymentCell) GetCreateAt() time.Time {
    return d.CreationTimestamp.Time
}

cell/statefulsetCell.go

package cell

import (
    appsv1 "k8s.io/api/apps/v1"
    "time"
)

//  实现DataMeta接口
type StatefulsetCell appsv1.StatefulSet

func (d StatefulsetCell) GetName() string {
    return d.Name
}
func (d StatefulsetCell) GetCreateAt() time.Time {
    return d.CreationTimestamp.Time
}

cell/daemonsetCell.go

package cell

import (
    appsv1 "k8s.io/api/apps/v1"
    "time"
)

type DaemonSetCell appsv1.DaemonSet

/*
 * GetName
 * @Description: 获取k8s中的daemonset对象名
 * @receiver p
 * @return string
 */
func (d DaemonSetCell) GetName() string {
    return d.Name
}

/*
 * GetCreateAt
 * @Description: 获取k8s中的daemonset对象创建时间
 * @receiver p
 * @return time.Time
 */
func (d DaemonSetCell) GetCreateAt() time.Time {
    return d.CreationTimestamp.Time
}