【GO】K8s 管理系统项目[API部分--Service]

news2024/12/23 3:06:12

K8s 管理系统项目[API部分–Service]

1. 接口实现

service/dataselector.go

// service
type serviceCell corev1.Service

func(s serviceCell) GetCreation() time.Time {
	return s.CreationTimestamp.Time
}

func(s serviceCell) GetName() string {
	return s.Name
}

2. service功能

service/service.go

2.1 获取service详情

// 获取service详情
func (s *servicev1) GetServicetDetail(serviceName, namespace string) (service *corev1.Service, err error) {
	service, err = K8s.ClientSet.CoreV1().Services(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
	if err != nil {
		logger.Error(errors.New("获取Service详情失败, " + err.Error()))
		return nil, errors.New("获取Service详情失败, " + err.Error())
	}

	return service, nil
}

2.2 创建service

// 创建service,,接收ServiceCreate对象
func (s *servicev1) CreateService(data *ServiceCreate) (err error) {
	//将data中的数据组装成corev1.Service对象
	service := &corev1.Service{
		//ObjectMeta中定义资源名、命名空间以及标签
		ObjectMeta: metav1.ObjectMeta{
			Name:      data.Name,
			Namespace: data.Namespace,
			Labels:    data.Label,
		},
		//Spec中定义类型,端口,选择器
		Spec: corev1.ServiceSpec{
			Type: corev1.ServiceType(data.Type),
			Ports: []corev1.ServicePort{
				{
					Name:     "http",
					Port:     data.Port,
					Protocol: "TCP",
					TargetPort: intstr.IntOrString{
						Type:   0,
						IntVal: data.ContainerPort,
					},
				},
			},
			Selector: data.Label,
		},
	}
	//默认ClusterIP,这里是判断NodePort,添加配置
	if data.NodePort != 0 && data.Type == "NodePort" {
		service.Spec.Ports[0].NodePort = data.NodePort
	}
	//创建Service
	_, err = K8s.ClientSet.CoreV1().Services(data.Namespace).Create(context.TODO(), service, metav1.CreateOptions{})
	if err != nil {
		logger.Error(errors.New("创建Service失败, " + err.Error()))
		return errors.New("创建Service失败, " + err.Error())
	}

	return nil
}

2.3 删除service

// 删除service
func (s *servicev1) DeleteService(serviceName, namespace string) (err error) {
	err = K8s.ClientSet.CoreV1().Services(namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{})
	if err != nil {
		logger.Error(errors.New("删除Service失败, " + err.Error()))
		return errors.New("删除Service失败, " + err.Error())
	}

	return nil
}

2.4 更新service

// 更新service
func (s *servicev1) UpdateService(namespace, content string) (err error) {
	var service = &corev1.Service{}

	err = json.Unmarshal([]byte(content), service)
	if err != nil {
		logger.Error(errors.New("反序列化失败, " + err.Error()))
		return errors.New("反序列化失败, " + err.Error())
	}

	_, err = K8s.ClientSet.CoreV1().Services(namespace).Update(context.TODO(), service, metav1.UpdateOptions{})
	if err != nil {
		logger.Error(errors.New("更新service失败, " + err.Error()))
		return errors.New("更新service失败, " + err.Error())
	}
	return nil
}

2.5 service完整

package service

import (
	"context"
	"encoding/json"
	"errors"

	"github.com/wonderivan/logger"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
)

var Servicev1 servicev1

type servicev1 struct{}

type ServicesResp struct {
	Items []corev1.Service `json:"items"`
	Total int              `json:"total"`
}

type ServiceCreate struct {
	Name          string            `json:"name"`
	Namespace     string            `json:"namespace"`
	Type          string            `json:"type"`
	ContainerPort int32             `json:"container_port"`
	Port          int32             `json:"port"`
	NodePort      int32             `json:"node_port"`
	Label         map[string]string `json:"label"`
}

// 获取service列表,支持过滤、排序、分页
func (s *servicev1) GetServices(filterName, namespace string, limit, page int) (servicesResp *ServicesResp, err error) {
	//获取serviceList类型的service列表
	serviceList, err := K8s.ClientSet.CoreV1().Services(namespace).List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		logger.Error(errors.New("获取Service列表失败, " + err.Error()))
		return nil, errors.New("获取Service列表失败, " + err.Error())
	}
	//将serviceList中的service列表(Items),放进dataselector对象中,进行排序
	selectableData := &dataSelector{
		GenericDataList: s.toCells(serviceList.Items),
		DataSelect: &DataSelectQuery{
			Filter: &FilterQuery{Name: filterName},
			Paginate: &PaginateQuery{
				Limit: limit,
				Page:  page,
			},
		},
	}

	filtered := selectableData.Filter()
	total := len(filtered.GenericDataList)
	data := filtered.Sort().Paginate()

	//将[]DataCell类型的service列表转为v1.service列表
	services := s.fromCells(data.GenericDataList)

	return &ServicesResp{
		Items: services,
		Total: total,
	}, nil
}

// 获取service详情
func (s *servicev1) GetServicetDetail(serviceName, namespace string) (service *corev1.Service, err error) {
	service, err = K8s.ClientSet.CoreV1().Services(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
	if err != nil {
		logger.Error(errors.New("获取Service详情失败, " + err.Error()))
		return nil, errors.New("获取Service详情失败, " + err.Error())
	}

	return service, nil
}

// 创建service,,接收ServiceCreate对象
func (s *servicev1) CreateService(data *ServiceCreate) (err error) {
	//将data中的数据组装成corev1.Service对象
	service := &corev1.Service{
		//ObjectMeta中定义资源名、命名空间以及标签
		ObjectMeta: metav1.ObjectMeta{
			Name:      data.Name,
			Namespace: data.Namespace,
			Labels:    data.Label,
		},
		//Spec中定义类型,端口,选择器
		Spec: corev1.ServiceSpec{
			Type: corev1.ServiceType(data.Type),
			Ports: []corev1.ServicePort{
				{
					Name:     "http",
					Port:     data.Port,
					Protocol: "TCP",
					TargetPort: intstr.IntOrString{
						Type:   0,
						IntVal: data.ContainerPort,
					},
				},
			},
			Selector: data.Label,
		},
	}
	//默认ClusterIP,这里是判断NodePort,添加配置
	if data.NodePort != 0 && data.Type == "NodePort" {
		service.Spec.Ports[0].NodePort = data.NodePort
	}
	//创建Service
	_, err = K8s.ClientSet.CoreV1().Services(data.Namespace).Create(context.TODO(), service, metav1.CreateOptions{})
	if err != nil {
		logger.Error(errors.New("创建Service失败, " + err.Error()))
		return errors.New("创建Service失败, " + err.Error())
	}

	return nil
}

// 删除service
func (s *servicev1) DeleteService(serviceName, namespace string) (err error) {
	err = K8s.ClientSet.CoreV1().Services(namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{})
	if err != nil {
		logger.Error(errors.New("删除Service失败, " + err.Error()))
		return errors.New("删除Service失败, " + err.Error())
	}

	return nil
}

// 更新service
func (s *servicev1) UpdateService(namespace, content string) (err error) {
	var service = &corev1.Service{}

	err = json.Unmarshal([]byte(content), service)
	if err != nil {
		logger.Error(errors.New("反序列化失败, " + err.Error()))
		return errors.New("反序列化失败, " + err.Error())
	}

	_, err = K8s.ClientSet.CoreV1().Services(namespace).Update(context.TODO(), service, metav1.UpdateOptions{})
	if err != nil {
		logger.Error(errors.New("更新service失败, " + err.Error()))
		return errors.New("更新service失败, " + err.Error())
	}
	return nil
}

func (s *servicev1) toCells(std []corev1.Service) []DataCell {
	cells := make([]DataCell, len(std))
	for i := range std {
		cells[i] = serviceCell(std[i])
	}
	return cells
}

func (s *servicev1) fromCells(cells []DataCell) []corev1.Service {
	services := make([]corev1.Service, len(cells))
	for i := range cells {
		services[i] = corev1.Service(cells[i].(serviceCell))
	}

	return services
}

3. 获取Service列表

controller/service.go

package controller

import (
	"github.com/gin-gonic/gin"
	"github.com/wonderivan/logger"
	"k8s-plantform/service"
	"net/http"
)

var Servicev1 servicev1

type servicev1 struct {}

//获取service列表,支持过滤、排序、分页
func(s *servicev1) GetServices(ctx *gin.Context) {
	params := new(struct {
		FilterName  string `form:"filter_name"`
		Namespace   string `form:"namespace"`
		Page        int    `form:"page"`
		Limit       int    `form:"limit"`
	})
	if err := ctx.Bind(params); err != nil {
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	data, err := service.Servicev1.GetServices(params.FilterName, params.Namespace, params.Limit, params.Page)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg": "获取Servicet列表成功",
		"data": data,
	})
}

//获取service详情
func(s *servicev1) GetServiceDetail(ctx *gin.Context) {
	params := new(struct {
		ServiceName    string `form:"service_name"`
		Namespace      string `form:"namespace"`
	})
	if err := ctx.Bind(params); err != nil {
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	data, err := service.Servicev1.GetServicetDetail(params.ServiceName, params.Namespace)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg": "获取Service详情成功",
		"data": data,
	})
}

//创建service
func(s *servicev1) CreateService(ctx *gin.Context) {
	var (
		serviceCreate = new(service.ServiceCreate)
		err error
	)

	if err = ctx.ShouldBindJSON(serviceCreate); err != nil {
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	if err = service.Servicev1.CreateService(serviceCreate); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg": "创建Service成功",
		"data": nil,
	})
}

//删除service
func(s *servicev1) DeleteService(ctx *gin.Context) {
	params := new(struct{
		ServiceName    string `json:"service_name"`
		Namespace      string `json:"namespace"`
	})
	//DELETE请求,绑定参数方法改为ctx.ShouldBindJSON
	if err := ctx.ShouldBindJSON(params); err != nil {
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	err := service.Servicev1.DeleteService(params.ServiceName, params.Namespace)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "删除Service成功",
		"data": nil,
	})
}

//更新service
func(s *servicev1) UpdateService(ctx *gin.Context) {
	params := new(struct{
		Namespace       string  `json:"namespace"`
		Content         string  `json:"content"`
	})
	//PUT请求,绑定参数方法改为ctx.ShouldBindJSON
	if err := ctx.ShouldBindJSON(params); err != nil {
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}

	err := service.Servicev1.UpdateService(params.Namespace, params.Content)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "更新Service成功",
		"data": nil,
	})
}

4. 定义路由

controller/router.go

		//service操作
		GET("/api/k8s/services", Servicev1.GetServices).
		GET("/api/k8s/service/detail", Servicev1.GetServiceDetail).
		DELETE("/api/k8s/service/del", Servicev1.DeleteService).
		PUT("/api/k8s/service/update", Servicev1.UpdateService).
		POST("/api/k8s/service/create", Servicev1.CreateService)

5. 测试Service方法

5.1 获取service

/api/k8s/services

请添加图片描述

5.2 获取service详情

/api/k8s/service/detail

请添加图片描述

5.3 删除service

/api/k8s/service/del
root@master-01:~# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.200.0.1    <none>        443/TCP   3d20h
my-nginx     ClusterIP   10.200.3.78   <none>        80/TCP    3d17h

请添加图片描述

root@master-01:~# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.200.0.1   <none>        443/TCP   3d20h

5.4 更新service

/api/k8s/service/update

这个结合前端一起测

5.5 创建service

/api/k8s/service/create

这个结合前端一起测

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】-- 海量数据处理

目录 位图 位图概念的引入 位图的实现 实现功能 开辟bit空间 数据输入set 数据删除reset 数据确认test 代码汇总 容器位图的衍生使用 布隆过滤器 布隆过滤器提出 布隆过滤器概念 ​布隆过滤器的实现 布隆过滤器的删除 布隆过滤器的特点 ​布隆过滤器的误判率 …

【电动车】基于削峰填谷的电动汽车多目标优化调度策略研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

计算机组成原理复习:计算机系统概述

1. 计算机系统概述 1.1 计算机系统的层次结构 &#xff08;1&#xff09; 硬件上&#xff0c;计算机系统可以分为五大功能部件&#xff1a; 运算器、控制器、存储器、输入设备、输出设备 将围绕其工作原理、逻辑实现、设计方法以及相互连接构成整机的方法展开 在典型的冯诺…

Android metaRTC6.0 编译指南

概述 metaRTC新版本优化了安卓系统支持&#xff0c;demo将C和C生成lib库&#xff0c;在lib库上提供了纯Java的webRTC推拉流demo。 demo支持软硬编解码&#xff0c;软编码为openh264&#xff0c;软解码为yangh264decoder&#xff0c;gpu编解码为mediacodec。 metaRTC android…

全长扩增子医学版新增内容来啦(一)

随着全长扩增子报告内容的扩充&#xff0c;医学版报告单的呼声越来越高&#xff0c;今天就给大家介绍一下凌恩生物针对医学客户&#xff0c;变更/新增了哪些报告内容~ 首先我们来看一下变更的内容吧&#xff01; CCA/RDA分析、PICRUSt2功能预测、随机森林-biomarker鉴定、随机…

多线程之Thread类常见方法及线程的状态

Thread类常见方法&#xff1a; 创建、启动线程、终止线程、线程等待、获取线程实例、线程休眠 1.关于如何创建线程&#xff0c;在专栏的上一篇文章已经谈到了有5中创建线程的方式。 2.启动线程&#xff08;t.start&#xff09;&#xff1a;调用 start 方法, 才在操作系统的底…

ArcGIS基础实验操作100例--实验39编辑公共边与顶点

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验39 编辑公共边与顶点 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

《操作系统-真象还原》14. 文件系统

文章目录文件系统概念inode目录项与目录通过文件名查找文件的流程超级块与文件系统布局文件控制块 —— FCB创建文件系统创建相关结构创建文件系统挂载分区文件描述符文件描述符和文件表文件描述符文件表文件描述符与 inode 关联关系文件描述符的实现文件操作相关的基础函数ino…

单例模式

单例模式 1. 单例模式介绍 单例模式可以说是整个设计中最简单的模式之一&#xff0c;而且这种方式即使在没有看设计模式相关资料也会常用在编码开发中。 因为在编程开发中经常会遇到这样一种场景&#xff0c;那就是需要保证一个类只有一个实例哪怕多线程同时访问&#xff0c;…

C#语言实例源码系列-实现IC卡的读写

专栏分享点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断反思前进的过程。在这个过程中…

机器学习:通俗理解马尔科夫随机场(MRF)及其应用(附例题)

目录0 写在前面1 无向概率图2 马尔科夫随机场3 马尔科夫独立性4 例题分析0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器学习模型&#xff1a;决策树、支持…

Git使用,在github中创建仓库

一.本地生成密钥&#xff1a; ssh-keygen //生成密钥 cat id_rsa.pub # 查看公钥 查看公钥&#xff0c;并将公钥添加到github的服务器上 二.创建文件&#xff0c;并且将文件上传到GitHub 设置全局用户信息&#xff1a; git config --global user.name dwerrwgit config…

LabVIEW NI数字万用表与开关握手扫描速率

LabVIEW NI数字万用表与开关握手扫描速率 在决定需要哪些设备来满足系统要求时&#xff0c;对扫描速率数据进行基准测试非常有用。数字万用表&#xff08;DMM&#xff09;和开关系统也是如此&#xff0c;因为扫描速率取决于数字万用表、开关和它们之间的触发器的速度。本文包含…

高并发系统设计 -- 抢红包设计

抢红包的业务分析 可以明显的看到打开了红包不一定可以抢到。这样做的好处是&#xff1a; 符合现实生活逻辑&#xff0c;有仪式感防止误领&#xff0c;发现不对劲可以马上退出流程拆的长一些&#xff0c;平摊高并发下的压力 预拆包&#xff1a;我在发红包的时候&#xff0c;就…

ansible的静态清单配置文件

清单文件 定义主机清单文件 清单中定义ansible将要管理的一批主机&#xff0c;这些主机也可以分配到组中&#xff0c;以进行集中管理。组中也可以包含子组&#xff0c;一台主机也可以是多个组中的成员。清单还可以设置应用到它所定义的主机和组的变量。 编写主机清单文件 主机…

归置归置,我的 2022

J3code杂文&#xff08;程序人生 # 年终总结&#xff09; 记得 2021 年我没有进行年终总结&#xff0c;也就没有发出过相关的内容出来。总结原因就是一个&#xff0c;躺平了&#xff0c;自毕业换工作之后&#xff0c;就一直在适应工作环境与生活环境中默默的度过了 2021 年。 …

你真的懂树吗?二叉树、AVL平衡二叉树、伸展树、B-树和B+树原理和实现代码详解...

树&#xff08;Tree&#xff09;是一种相当灵活的数据结构&#xff08;上一节已经详细讲解了基本的数据结构&#xff1a;线性表、栈和队列&#xff09;&#xff0c;你可能接触过二叉树&#xff0c;但是树的使用并不限于此&#xff0c;从简单的使用二叉树进行数据排序&#xff0…

(深度学习快速入门)第三章第一节:多层感知器简介

文章目录一&#xff1a;引入二&#xff1a;定义三&#xff1a;反向传播算法四&#xff1a;构建多层感知器完成波士顿房价预测一&#xff1a;引入 前文所讲到的波士顿房价预测案例中&#xff0c;涉及到的仅仅是一个非常简单的神经网络&#xff0c;它只含有输入层和输出层 但观…

vue3 antd项目实战——Form表单的重置与清空【resetFields重置表单未生效(手写重置函数)】

vue3 antd项目实战——resetFields重置表单无效【手写重置函数重置表单数据】关于form表单的文章合集场景复现原因分析解决方案(手写清空函数)关于form表单的文章合集 文章内容文章链接Form表单提交和校验https://blog.csdn.net/XSL_HR/article/details/128495087?spm1001.20…

面向对象定义一个hero类

问题定义一个hero类&#xff0c;属性有power&#xff0c;name&#xff0c;分别代表体力值和英雄的名字&#xff0c;体力值默认为100&#xff1b;方法有&#xff1a;1.行走的方法如果体力值为0&#xff0c;则输出不能行走&#xff0c;此英雌已死亡的信息&#xff1b;2.吃的方法&…