kubernetes platform后端开发-cluster相关组件
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)
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 J.のblog!
评论