drone-kubernetes/k8s/client.go

149 lines
3.7 KiB
Go
Raw Normal View History

2023-11-02 17:24:36 +08:00
package k8s
import (
"context"
"errors"
"fmt"
appv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/client-go/kubernetes"
kindv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
"strings"
"time"
)
type client struct {
kubernetes.Interface
}
// Client
// @description: 获取客户端
// @receiver c
// @return *client
// @return error
func (c *config) Client() (*client, error) {
kubeClient, err := kubernetes.NewForConfig(c.resetConf)
if err != nil {
return nil, err
}
return &client{kubeClient}, nil
}
// Do
// @description: 执行
// @receiver c
// @param namespace
// @param kind
// @param resourceName
// @param actionMethod
// @param repo
// @return err
func (c client) Do(namespace, kind, resourceName, actionMethod, repo string) (err error) {
var kindType any // 应用类型
var resource any // 资源详情
switch kind {
case "Deployment":
kindType = c.AppsV1().Deployments(namespace)
// 获取一下资源
resource, err = kindType.(kindv1.DeploymentInterface).Get(context.Background(), resourceName, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("get deployment error: %v", err.Error())
}
switch actionMethod {
case "create":
case "update": // 更新目前仅支持更新镜像和tag
if err != nil && resource == nil {
return fmt.Errorf("get deployment error: %v", err.Error())
}
if repo == "" {
return fmt.Errorf("repo not empty")
}
// 解析规则判断是只单独变更tag还是镜像整个替换
if !strings.Contains(repo, ":") {
// 判断是镜像地址还是tag标签
if strings.Contains(repo, "/") {
// 镜像地址默认tag为 latest
repo = fmt.Sprintf("%s:latest", repo)
} else {
// 只是tag标签判断tag标签是否带有v开头的字符
if strings.HasPrefix(repo, "v") {
repo = strings.ReplaceAll(repo, "v", "")
}
}
2023-11-02 17:24:36 +08:00
resource.(*appv1.Deployment).Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", strings.Split(resource.(*appv1.Deployment).Spec.Template.Spec.Containers[0].Image, ":")[0], repo)
} else {
// 获取tag
image := strings.Split(repo, ":")[0]
tag := strings.Split(repo, ":")[1]
if strings.Contains(tag, "v") {
tag = strings.ReplaceAll(tag, "v", "")
}
repo = fmt.Sprintf("%s:%s", image, tag)
2023-11-02 17:24:36 +08:00
resource.(*appv1.Deployment).Spec.Template.Spec.Containers[0].Image = repo
}
_, err = kindType.(kindv1.DeploymentInterface).Update(context.Background(), resource.(*appv1.Deployment), metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("update deployment error: %v", err.Error())
}
case "delete": // 删除应用
if err != nil && resource == nil {
return fmt.Errorf("get deployment error: %v", err.Error())
}
err = kindType.(kindv1.DeploymentInterface).Delete(context.Background(), resourceName, metav1.DeleteOptions{})
if err != nil {
return err
}
case "restart": // 重启应用
if err != nil && resource == nil {
return fmt.Errorf("get deployment error: %v", err.Error())
}
rJ, _ := json.Marshal(resource)
fmt.Println(string(rJ))
resource.(*appv1.Deployment).Spec.Template.ObjectMeta.Annotations["kubectl.kubernetes.io/restartedAt"] = time.Now().Local().String()
_, err = kindType.(kindv1.DeploymentInterface).Update(context.Background(), resource.(*appv1.Deployment), metav1.UpdateOptions{})
if err != nil {
return err
}
}
default:
return errors.New("not support")
}
fmt.Println("命名空间: ", namespace)
fmt.Println("资源类型: ", kind)
fmt.Println("资源名称: ", resourceName)
fmt.Println("操作类型: ", actionMethod)
fmt.Println("镜像地址: ", repo)
2023-11-02 17:24:36 +08:00
return nil
}