854 lines
22 KiB
Go
854 lines
22 KiB
Go
package cmii_operator
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
v1 "k8s.io/api/apps/v1"
|
|
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/kubernetes/scheme"
|
|
restclient "k8s.io/client-go/rest"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
"k8s.io/client-go/tools/remotecommand"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
"wdd.io/agent-go/logger"
|
|
"wdd.io/agent-go/utils"
|
|
)
|
|
|
|
var log = logger.Log
|
|
|
|
type CmiiK8sOperator struct {
|
|
DevClient *kubernetes.Clientset
|
|
CoreClient *kubernetes.Clientset
|
|
CurrentNamespace string
|
|
CurrentClient *kubernetes.Clientset
|
|
DevConfig *restclient.Config
|
|
CoreConfig *restclient.Config
|
|
CurrentConfig *restclient.Config
|
|
}
|
|
|
|
const (
|
|
dev = "uavcloud-dev"
|
|
devFlight = "uavcloud-devflight"
|
|
devOperation = "uavcloud-devoperation"
|
|
validation = "uavcloud-feature"
|
|
integration = "uavcloud-test"
|
|
uat = "uavcloud-uat"
|
|
demo = "uavcloud-demo"
|
|
uavms = "uavcloud-uavms"
|
|
workerThread = 4
|
|
)
|
|
|
|
func (op *CmiiK8sOperator) checkAndBuildCmiiK8sOperator() {
|
|
|
|
if op.DevClient == nil {
|
|
log.InfoF("[client] - build devFlight k8s operator client !")
|
|
devConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(CmiiDevK8sConfig))
|
|
if err != nil {
|
|
msg := "[client] - build devFlight k8s operator error !"
|
|
log.Error(msg)
|
|
panic(msg)
|
|
}
|
|
op.DevConfig = devConfig
|
|
op.DevClient, err = kubernetes.NewForConfig(devConfig)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
}
|
|
|
|
if op.CoreClient == nil {
|
|
log.InfoF("[client] - build core k8s operator client !")
|
|
coreConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(CmiiCoreK8sConfig))
|
|
if err != nil {
|
|
msg := "[client] - build devFlight k8s operator error !"
|
|
log.Error(msg)
|
|
panic(msg)
|
|
}
|
|
op.CoreConfig = coreConfig
|
|
op.CoreClient, err = kubernetes.NewForConfig(coreConfig)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) changeOperatorEnv(cmiiEnv string) {
|
|
|
|
// ok
|
|
op.checkAndBuildCmiiK8sOperator()
|
|
// first key
|
|
op.CurrentNamespace = ""
|
|
|
|
if strings.Contains(cmiiEnv, "dev") {
|
|
if strings.Contains(cmiiEnv, "devf") {
|
|
op.CurrentNamespace = devFlight
|
|
} else if strings.Contains(cmiiEnv, "devo") {
|
|
op.CurrentNamespace = devOperation
|
|
} else {
|
|
op.CurrentNamespace = dev
|
|
}
|
|
}
|
|
|
|
if strings.Contains(cmiiEnv, "int") || strings.Contains(cmiiEnv, "test") {
|
|
op.CurrentNamespace = integration
|
|
}
|
|
|
|
if strings.Contains(cmiiEnv, "fe") || strings.Contains(cmiiEnv, "val") {
|
|
op.CurrentNamespace = validation
|
|
}
|
|
|
|
if strings.Contains(cmiiEnv, "uat") {
|
|
op.CurrentNamespace = uat
|
|
}
|
|
|
|
if strings.Contains(cmiiEnv, "demo") {
|
|
op.CurrentNamespace = demo
|
|
}
|
|
|
|
if strings.Contains(cmiiEnv, "uavms") {
|
|
op.CurrentNamespace = uavms
|
|
}
|
|
|
|
// key feature
|
|
if op.CurrentNamespace == "" {
|
|
op.CurrentNamespace = cmiiEnv
|
|
} else {
|
|
if strings.Contains(cmiiEnv, "dev") {
|
|
op.CurrentClient = op.DevClient
|
|
op.CurrentConfig = op.DevConfig
|
|
} else {
|
|
op.CurrentClient = op.CoreClient
|
|
op.CurrentConfig = op.CoreConfig
|
|
}
|
|
}
|
|
|
|
log.InfoF("[k8s env] - current env is => %s", op.CurrentNamespace)
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) BuildCurrentClientFromConfig(realClientConfig string) {
|
|
log.InfoF("[BuildCurrentClientFromConfig] - build real k8s operator client !")
|
|
realEnvConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(realClientConfig))
|
|
if err != nil {
|
|
msg := "[BuildCurrentClientFromConfig] - build real k8s operator error !"
|
|
log.Error(msg)
|
|
panic(msg)
|
|
}
|
|
op.CurrentConfig = realEnvConfig
|
|
op.CurrentClient, err = kubernetes.NewForConfig(realEnvConfig)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentAll(cmiiEnv string) []v1.Deployment {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
|
|
client := op.CurrentClient
|
|
|
|
deploymentList, err := client.AppsV1().Deployments(op.CurrentNamespace).List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[DeploymentAll] - list deployment in [%s] [%s] error => %s", cmiiEnv, op.CurrentNamespace, err.Error())
|
|
}
|
|
deployments := deploymentList.Items
|
|
|
|
length := len(deployments)
|
|
log.InfoF("[DeploymentAll] - deployment in [%s] count is => %d", op.CurrentNamespace, length)
|
|
results := make([]v1.Deployment, length)
|
|
ccc := make(chan v1.Deployment, length)
|
|
var wg sync.WaitGroup
|
|
//var mutex sync.Mutex
|
|
|
|
worker := workerThread
|
|
if length <= worker {
|
|
for i, deployment := range deployments {
|
|
objectMeta := deployment.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
deployment.ObjectMeta = objectMeta
|
|
|
|
results[i] = deployment
|
|
}
|
|
return results
|
|
}
|
|
|
|
pinch := (length + worker - 1) / worker
|
|
wg.Add(worker)
|
|
for splice := 0; splice < worker; splice++ {
|
|
|
|
// 计算每个goroutine处理的切片段
|
|
start := splice * pinch
|
|
end := start + pinch
|
|
if end > length {
|
|
end = length
|
|
}
|
|
//log.DebugF("[DeploymentAll] - deployment pinch from [%d - %d]", start, end)
|
|
|
|
go func(deploymentList []v1.Deployment, start int, results *[]v1.Deployment) {
|
|
|
|
for _, deployment := range deploymentList {
|
|
objectMeta := deployment.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
deployment.ObjectMeta = objectMeta
|
|
|
|
ccc <- deployment
|
|
//i := *results
|
|
//i[index+start] = deployment
|
|
}
|
|
|
|
wg.Done()
|
|
}(deployments[start:end], start, &results)
|
|
}
|
|
|
|
go func() {
|
|
wg.Wait()
|
|
close(ccc)
|
|
}()
|
|
|
|
wg.Wait()
|
|
index := 0
|
|
for deployment := range ccc {
|
|
results[index] = deployment
|
|
index++
|
|
}
|
|
|
|
return results[:index]
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentAllInterface(cmiiEnv string) []CmiiDeploymentInterface {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
|
|
client := op.CurrentClient
|
|
|
|
deploymentList, err := client.AppsV1().Deployments(op.CurrentNamespace).List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[DeploymentAllInterface] - list deployment in [%s] [%s] error => %s", cmiiEnv, op.CurrentNamespace, err.Error())
|
|
}
|
|
deployments := deploymentList.Items
|
|
|
|
length := len(deployments)
|
|
|
|
results := make([]CmiiDeploymentInterface, length)
|
|
ccc := make(chan CmiiDeploymentInterface, length)
|
|
var wg sync.WaitGroup
|
|
|
|
worker := workerThread
|
|
if length <= worker {
|
|
for i, deployment := range deployments {
|
|
objectMeta := deployment.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
deployment.ObjectMeta = objectMeta
|
|
|
|
results[i] = CmiiDeploymentInterface{}.Convert(deployment)
|
|
}
|
|
return results
|
|
}
|
|
|
|
pinch := length / worker
|
|
wg.Add(worker)
|
|
for splice := 0; splice < worker; splice++ {
|
|
go func(deploymentList []v1.Deployment) {
|
|
defer wg.Done()
|
|
for _, deployment := range deploymentList {
|
|
objectMeta := deployment.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
deployment.ObjectMeta = objectMeta
|
|
|
|
ccc <- CmiiDeploymentInterface{}.Convert(deployment)
|
|
}
|
|
|
|
}(deployments[splice*pinch : utils.MinInt((splice+1)*pinch, length)])
|
|
}
|
|
|
|
go func() {
|
|
wg.Wait()
|
|
close(ccc)
|
|
}()
|
|
|
|
index := 0
|
|
for deployment := range ccc {
|
|
results[index] = deployment
|
|
index++
|
|
}
|
|
|
|
return results[:index]
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentFizz(cmiiEnv, appFizz string) (fizzDeployment []v1.Deployment) {
|
|
|
|
deploymentAll := op.DeploymentAll(cmiiEnv)
|
|
|
|
if deploymentAll == nil {
|
|
log.ErrorF("[DeploymentFizz] - namespace [%s] can not get deployment [%s]", cmiiEnv, appFizz)
|
|
return nil
|
|
}
|
|
|
|
for _, deployment := range deploymentAll {
|
|
if strings.Contains(deployment.Name, appFizz) {
|
|
fizzDeployment = append(fizzDeployment, deployment)
|
|
}
|
|
}
|
|
|
|
return fizzDeployment
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentExist(cmiiEnv, appName string) (exists *v1.Deployment) {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
deployment, err := client.AppsV1().Deployments(op.CurrentNamespace).Get(context.TODO(), appName, metav1.GetOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[DeploymentExist] - deployments [%s] [%s] not exists ! %s", cmiiEnv, appName, err.Error())
|
|
return nil
|
|
}
|
|
|
|
return deployment
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentOneInterface(cmiiEnv, appName string) (deploy *CmiiDeploymentInterface) {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
deploymentInterface := CmiiDeploymentInterface{}
|
|
|
|
deployment, err := client.AppsV1().Deployments(op.CurrentNamespace).Get(context.TODO(), appName, metav1.GetOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[DeploymentExist] - deployments [%s] [%s] not exists ! %s", cmiiEnv, appName, err.Error())
|
|
return nil
|
|
}
|
|
|
|
convert := deploymentInterface.Convert(*deployment)
|
|
|
|
return &convert
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) StatefulSetOneInterface(cmiiEnv, appName string) (deploy *CmiiDeploymentInterface) {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
deploymentInterface := CmiiDeploymentInterface{}
|
|
|
|
statefulSet, err := client.AppsV1().StatefulSets(op.CurrentNamespace).Get(context.TODO(), appName, metav1.GetOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[StatefulSetOneInterface] - stateful set [%s] [%s] not exists ! %s", cmiiEnv, appName, err.Error())
|
|
return nil
|
|
}
|
|
|
|
convert := deploymentInterface.ConvertFromStatefulSet(*statefulSet)
|
|
|
|
return &convert
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentScale(cmiiEnv, appName string, scaleCount int32) bool {
|
|
|
|
deployment := op.DeploymentOneInterface(cmiiEnv, appName)
|
|
|
|
client := op.CurrentClient
|
|
|
|
log.DebugF("[DeploymentScale] - start to scale [%s] [%s] to %d", deployment.Namespace, deployment.Name, scaleCount)
|
|
|
|
scale := &autoscalingv1.Scale{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: deployment.Name,
|
|
Namespace: deployment.Namespace,
|
|
},
|
|
Spec: autoscalingv1.ScaleSpec{
|
|
Replicas: scaleCount,
|
|
},
|
|
}
|
|
|
|
updateScale, err := client.AppsV1().Deployments(deployment.Namespace).UpdateScale(
|
|
context.TODO(),
|
|
deployment.Name,
|
|
scale,
|
|
metav1.UpdateOptions{},
|
|
)
|
|
if err != nil {
|
|
log.ErrorF("[DeploymentScale] - scale error %s", err.Error())
|
|
return false
|
|
}
|
|
|
|
log.InfoF("[DeploymentScale] - scale of [%s] [%s] to %d success !", updateScale.Namespace, updateScale.Name, scaleCount)
|
|
|
|
return true
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentUpdateTag(cmiiEnv, appName, newTag string) bool {
|
|
|
|
if newTag == "" {
|
|
log.WarnF("[DeploymentUpdateTag] - can not update image tag to null!")
|
|
return false
|
|
}
|
|
|
|
deployment := op.DeploymentExist(cmiiEnv, appName)
|
|
if deployment == nil {
|
|
return false
|
|
}
|
|
|
|
containers := deployment.Spec.Template.Spec.Containers
|
|
if len(containers) == 1 {
|
|
// only update this kind
|
|
container := containers[0]
|
|
split := strings.Split(container.Image, ":")
|
|
|
|
container.Image = split[0] + ":" + newTag
|
|
log.InfoF("[DeploymentUpdateTag] - update [%s] [%s] from [%s] to [%s]", op.CurrentNamespace, appName, split[1], container.Image)
|
|
|
|
// re assign
|
|
deployment.Spec.Template.Spec.Containers[0] = container
|
|
|
|
// update
|
|
_, err := op.CurrentClient.AppsV1().Deployments(deployment.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[DeploymentUpdateTag] - update [%s] [%s] from [%s] to [%s] error ! %s", op.CurrentNamespace, appName, split[1], container.Image, err.Error())
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentRestart(cmiiEnv, appName string) bool {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
|
|
result := true
|
|
|
|
deployment := op.DeploymentOneInterface(cmiiEnv, appName)
|
|
if deployment == nil {
|
|
log.ErrorF("[DeploymentRestart] - [%s] [%s] not exists !", cmiiEnv, appName)
|
|
return false
|
|
}
|
|
|
|
result = op.DeploymentScale(deployment.Namespace, deployment.Name, 0)
|
|
if !result {
|
|
return result
|
|
}
|
|
time.Sleep(time.Millisecond * 200)
|
|
result = op.DeploymentScale(deployment.Namespace, deployment.Name, deployment.Replicas)
|
|
if !result {
|
|
return result
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentRestartByKill(cmiiEnv, appName string) bool {
|
|
|
|
deployment := op.DeploymentOneInterface(cmiiEnv, appName)
|
|
if deployment == nil {
|
|
log.ErrorF("[DeploymentRestart] - [%s] [%s] not exists !", cmiiEnv, appName)
|
|
return false
|
|
}
|
|
|
|
podList := op.PodByAppName(deployment.Namespace, deployment.Name)
|
|
if podList == nil {
|
|
log.ErrorF("[DeploymentRestart] - [%s] [%s] no pod success !", deployment.Namespace, deployment.Name)
|
|
return true
|
|
}
|
|
|
|
for _, podInterface := range podList {
|
|
if !op.PodDelete(cmiiEnv, podInterface.Name) {
|
|
log.ErrorF("[DeploymentRestart] - [%s] [%s] delete pod failed !", podInterface.Namespace, podInterface.Name)
|
|
} else {
|
|
log.DebugF("[DeploymentRestart] - [%s] [%s] delete pod success !", podInterface.Namespace, podInterface.Name)
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentNew(cmiiEnv, appName string, waitTimeOut int) bool {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
//op.CurrentClient.AppsV1().Deployments(op.CurrentNamespace).Apply()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) DeploymentStatusCheck(cmiiEnv, appName string, waitTimeOut int) bool {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
|
|
// 设置超时时间和时间间隔
|
|
timeout := time.After(time.Duration(waitTimeOut) * time.Second)
|
|
tick := time.Tick(time.Second)
|
|
|
|
// 监控Pod状态
|
|
for {
|
|
select {
|
|
case <-timeout:
|
|
log.ErrorF("[DeploymentStatusCheck] - [%s] [%s] 状态: 失败!", cmiiEnv, appName)
|
|
return false
|
|
case <-tick:
|
|
// check deployment exists
|
|
deployment := op.DeploymentOneInterface(cmiiEnv, appName)
|
|
if deployment == nil {
|
|
log.ErrorF("[DeploymentStatusCheck] - [%s] [%s] not exists !", cmiiEnv, appName)
|
|
return false
|
|
}
|
|
if deployment.AvailableReplicas == deployment.Replicas {
|
|
log.InfoF("[DeploymentStatusCheck] - [%s] [%s] Available: %d, Total: %d success !", deployment.Namespace, deployment.Name, deployment.AvailableReplicas, deployment.Replicas)
|
|
return true
|
|
}
|
|
|
|
log.DebugF("[DeploymentStatusCheck] - [%s] [%s] Available: %d, Total: %d waiting !", deployment.Namespace, deployment.Name, deployment.AvailableReplicas, deployment.Replicas)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) ReplicaSetExists(cmiiEnv, replicaSetName string) *v1.ReplicaSet {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
replicaSet, err := client.AppsV1().ReplicaSets(op.CurrentNamespace).Get(context.TODO(), replicaSetName, metav1.GetOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[ReplicaSetExists] - [%s] [%s] not exists !", cmiiEnv, replicaSetName)
|
|
return nil
|
|
}
|
|
|
|
return replicaSet
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) ReplicaSetByAppName(cmiiEnv, appName string) (replicaList []v1.ReplicaSet) {
|
|
deploy := op.DeploymentExist(cmiiEnv, appName)
|
|
if deploy == nil {
|
|
log.ErrorF("[ReplicaSetByAppName] - [%s] [%s] app not exists !", cmiiEnv, appName)
|
|
return nil
|
|
}
|
|
|
|
labelSelector := metav1.FormatLabelSelector(deploy.Spec.Selector)
|
|
//Get the replica sets that belong to the deployment.
|
|
replicaSets, err := op.CurrentClient.AppsV1().ReplicaSets(op.CurrentNamespace).List(context.TODO(), metav1.ListOptions{
|
|
LabelSelector: labelSelector,
|
|
})
|
|
if err != nil {
|
|
log.ErrorF("[ReplicaSetByAppName] - [%s] [%s] list replicaset error %s", cmiiEnv, appName, err.Error())
|
|
return nil
|
|
}
|
|
|
|
for _, replicaSet := range replicaSets.Items {
|
|
replicaSet.SetManagedFields(nil)
|
|
replicaList = append(replicaList, replicaSet)
|
|
}
|
|
|
|
return replicaList
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodAll(cmiiEnv string) []corev1.Pod {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
|
|
client := op.CurrentClient
|
|
|
|
podList, err := client.CoreV1().Pods(op.CurrentNamespace).List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[PodAll] - list c in [%s] [%s] error => %s", cmiiEnv, op.CurrentNamespace, err.Error())
|
|
return nil
|
|
}
|
|
pods := podList.Items
|
|
|
|
length := len(pods)
|
|
results := make([]corev1.Pod, length)
|
|
ccc := make(chan corev1.Pod, length)
|
|
var wg sync.WaitGroup
|
|
|
|
worker := workerThread
|
|
if length <= worker {
|
|
for i, pod := range pods {
|
|
objectMeta := pod.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
pod.ObjectMeta = objectMeta
|
|
|
|
results[i] = pod
|
|
}
|
|
return results
|
|
}
|
|
|
|
pinch := length / worker
|
|
wg.Add(worker)
|
|
for splice := 0; splice < worker; splice++ {
|
|
go func(podList []corev1.Pod) {
|
|
defer wg.Done()
|
|
for _, pod := range podList {
|
|
objectMeta := pod.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
pod.ObjectMeta = objectMeta
|
|
|
|
ccc <- pod
|
|
}
|
|
|
|
}(pods[splice*pinch : utils.MinInt((splice+1)*pinch, length)])
|
|
}
|
|
|
|
go func() {
|
|
wg.Wait()
|
|
close(ccc)
|
|
}()
|
|
|
|
index := 0
|
|
for c := range ccc {
|
|
results[index] = c
|
|
index++
|
|
}
|
|
|
|
return results[:index]
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodAllInterface(cmiiEnv string) []CmiiPodInterface {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
podList, err := client.CoreV1().Pods(op.CurrentNamespace).List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[PodAll] - list c in [%s] [%s] error => %s", cmiiEnv, op.CurrentNamespace, err.Error())
|
|
return nil
|
|
}
|
|
pods := podList.Items
|
|
|
|
length := len(pods)
|
|
results := make([]CmiiPodInterface, length)
|
|
ccc := make(chan CmiiPodInterface, length)
|
|
var wg sync.WaitGroup
|
|
podInterface := CmiiPodInterface{}
|
|
|
|
worker := workerThread
|
|
if length <= worker {
|
|
for i, pod := range pods {
|
|
objectMeta := pod.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
pod.ObjectMeta = objectMeta
|
|
|
|
results[i] = podInterface.Convert(pod)
|
|
}
|
|
return results
|
|
}
|
|
|
|
pinch := length / worker
|
|
wg.Add(worker)
|
|
|
|
for splice := 0; splice < worker; splice++ {
|
|
go func(podList []corev1.Pod) {
|
|
defer wg.Done()
|
|
for _, pod := range podList {
|
|
objectMeta := pod.ObjectMeta
|
|
objectMeta.SetAnnotations(nil)
|
|
objectMeta.SetManagedFields(nil)
|
|
pod.ObjectMeta = objectMeta
|
|
|
|
ccc <- podInterface.Convert(pod)
|
|
}
|
|
|
|
}(pods[splice*pinch : utils.MinInt((splice+1)*pinch, length)])
|
|
}
|
|
|
|
go func() {
|
|
wg.Wait()
|
|
close(ccc)
|
|
}()
|
|
|
|
index := 0
|
|
for c := range ccc {
|
|
results[index] = c
|
|
index++
|
|
}
|
|
|
|
return results[:index]
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodByAppName(cmiiEnv, appName string) (podList []CmiiPodInterface) {
|
|
|
|
deploy := op.DeploymentExist(cmiiEnv, appName)
|
|
if deploy == nil {
|
|
log.ErrorF("[PodByAppName] - [%s] [%s] app not exists !", cmiiEnv, appName)
|
|
return nil
|
|
}
|
|
|
|
labelSelector := metav1.FormatLabelSelector(deploy.Spec.Selector)
|
|
//Get the replica sets that belong to the deployment.
|
|
pods, err := op.CurrentClient.CoreV1().Pods(op.CurrentNamespace).List(context.TODO(), metav1.ListOptions{
|
|
LabelSelector: labelSelector,
|
|
})
|
|
if err != nil {
|
|
log.ErrorF("[PodByAppName] - [%s] [%s] list pods error %s", cmiiEnv, appName, err.Error())
|
|
return nil
|
|
}
|
|
|
|
cmiiPodInterface := CmiiPodInterface{}
|
|
for _, pod := range pods.Items {
|
|
pod.SetManagedFields(nil)
|
|
podInterface := cmiiPodInterface.Convert(pod)
|
|
podList = append(podList, podInterface)
|
|
}
|
|
|
|
return podList
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodByNodeName(cmiiEnv, nodeName string) (podList []CmiiPodInterface) {
|
|
|
|
node := op.NodeExists(cmiiEnv, nodeName)
|
|
if node == nil {
|
|
return nil
|
|
}
|
|
|
|
list, err := op.CurrentClient.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{
|
|
FieldSelector: "spec.nodeName=" + nodeName,
|
|
})
|
|
if err != nil {
|
|
log.ErrorF("[PodByNodeName] - [%s] [%s] list pod error %s !", cmiiEnv, nodeName, err.Error())
|
|
return nil
|
|
}
|
|
|
|
podInterface := CmiiPodInterface{}
|
|
for _, pod := range list.Items {
|
|
cmiiPodInterface := podInterface.Convert(pod)
|
|
|
|
podList = append(podList, cmiiPodInterface)
|
|
}
|
|
|
|
return podList
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodFizz(cmiiEnv, appFizz string) (fizzPod []corev1.Pod) {
|
|
|
|
podAll := op.PodAll(cmiiEnv)
|
|
|
|
if podAll == nil {
|
|
log.ErrorF("[DeploymentFizz] - no app find in [%s] !", cmiiEnv)
|
|
return nil
|
|
}
|
|
|
|
for _, pod := range podAll {
|
|
if strings.Contains(pod.Name, appFizz) {
|
|
fizzPod = append(fizzPod, pod)
|
|
}
|
|
}
|
|
|
|
return fizzPod
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodDelete(cmiiEnv, podName string) bool {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
pod, err := client.CoreV1().Pods(op.CurrentNamespace).Get(context.TODO(), podName, metav1.GetOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[PodDelete] - [%s] [%s] not exists", cmiiEnv, podName)
|
|
return false
|
|
}
|
|
|
|
// pod exists
|
|
err = client.CoreV1().Pods(op.CurrentNamespace).Delete(context.TODO(), pod.Name, metav1.DeleteOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[PodDelete] - [%s] [%s] delete error ! %s", cmiiEnv, podName, err.Error())
|
|
return false
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) PodExec(cmiiEnv string, podInterface CmiiPodInterface, commandList []string) (stdout, stderr *bytes.Buffer) {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
execRequest := client.CoreV1().RESTClient().
|
|
Post().
|
|
Resource("pods").
|
|
Name(podInterface.Name).
|
|
Namespace(op.CurrentNamespace).
|
|
SubResource("exec").
|
|
VersionedParams(&corev1.PodExecOptions{
|
|
Stdin: false,
|
|
Stdout: true,
|
|
Stderr: true,
|
|
TTY: false,
|
|
Container: podInterface.ContainerName,
|
|
Command: commandList,
|
|
}, scheme.ParameterCodec)
|
|
|
|
stdout = &bytes.Buffer{}
|
|
stderr = &bytes.Buffer{}
|
|
//log.DebugF("PodExec] - [%s] [%s] exec %s, url %s", cmiiEnv, podInterface.Name, commandList, execRequest.URL())
|
|
exec, err := remotecommand.NewSPDYExecutor(op.CurrentConfig, "POST", execRequest.URL())
|
|
|
|
if err != nil {
|
|
log.ErrorF("[PodExec] - NewSPDYExecutor error => %s", err.Error())
|
|
return stdout, stderr
|
|
}
|
|
|
|
err = exec.Stream(remotecommand.StreamOptions{
|
|
Stdin: nil,
|
|
Stdout: stdout,
|
|
Stderr: stderr,
|
|
Tty: false,
|
|
TerminalSizeQueue: nil,
|
|
})
|
|
if err != nil {
|
|
log.ErrorF("[PodExec] - exec.Stream error => %s", err.Error())
|
|
}
|
|
|
|
return stdout, stderr
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) NodeAll(cmiiEnv string) (nodeListR []corev1.Node) {
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
nodeList, err := client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[NodeAll] - [%s] list all node failed %s", cmiiEnv, err.Error())
|
|
return nil
|
|
}
|
|
|
|
for _, node := range nodeList.Items {
|
|
node.SetManagedFields(nil)
|
|
nodeListR = append(nodeListR, node)
|
|
}
|
|
|
|
return nodeListR
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) NodeAllInterface(cmiiEnv string) (nodeList []CmiiNodeInterface) {
|
|
|
|
nodeListR := op.NodeAll(cmiiEnv)
|
|
|
|
nodeInterface := CmiiNodeInterface{}
|
|
|
|
for _, node := range nodeListR {
|
|
nodeList = append(nodeList, nodeInterface.Convert(node))
|
|
}
|
|
|
|
return nodeList
|
|
}
|
|
|
|
func (op *CmiiK8sOperator) NodeExists(cmiiEnv, nodeName string) (node *CmiiNodeInterface) {
|
|
|
|
op.changeOperatorEnv(cmiiEnv)
|
|
client := op.CurrentClient
|
|
|
|
nodeInterface := CmiiNodeInterface{}
|
|
|
|
nodeList, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
|
|
if err != nil {
|
|
log.ErrorF("[NodeExists] - [%s] [%s] not exists !", cmiiEnv, nodeName)
|
|
return nil
|
|
}
|
|
|
|
convert := nodeInterface.Convert(*nodeList)
|
|
|
|
return &convert
|
|
}
|