Files
ProjectOctopus/agent-go/executor/AppFunction.go
2023-11-21 16:17:13 +08:00

852 lines
20 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package executor
import (
"fmt"
"net"
"time"
)
type OctopusFunc interface {
Command(baseFuncName string, funcArgs ...string) []string
Exec(baseFuncName string, funcArgs ...string) (bool, []string)
Deploy(appFuncName string, funcArgs ...string) (bool, []string)
}
type AppFunc interface {
Deploy(appFuncName string, funcArgs ...string) (bool, []string)
}
var AppExecuteErrorLogPrefix = []string{"App指令执行错误 => "}
var nfsDataPath = "/var/lib/docker/nfs_data"
func (op *AgentOsOperator) Deploy(appFuncName string, funcArgs ...string) (bool, []string) {
var resultOK bool
var result []string
switch appFuncName {
case "DEPLOY_RKE":
resultOK, result = op.deployRke(funcArgs)
break
case "DEPLOY_K8S_DASHBOARD":
resultOK, result = op.deployK8sDashboard(funcArgs)
break
case "DEPLOY_K8S_NAMESPACE":
resultOK, result = op.deployK8sNamespace(funcArgs)
break
case "DEPLOY_MINIO":
resultOK, result = op.deployMinio(funcArgs)
break
case "DEPLOY_NFS":
resultOK, result = op.deployNFS(funcArgs)
break
case "DEPLOY_TEST_NFS":
resultOK, result = op.deployTestNFS(funcArgs)
break
case "deployPVC":
resultOK, result = op.deployPVC(funcArgs)
break
case "DEPLOY_STORAGE_CLASS":
break
case "DEPLOY_K8S_MYSQL":
resultOK, result = op.deployMySQL(funcArgs)
break
case "LOAD_MYSQL_INIT_SCRIPT":
resultOK, result = op.loadMysqlInitScript(funcArgs)
break
case "checkMySQL":
resultOK, result = op.checkMySQL(funcArgs)
break
case "DEPLOY_K8S_MIDDLEWARES":
resultOK, result = op.deployMiddlewares(funcArgs)
break
case "DEPLOY_K8S_REDIS":
resultOK, result = op.deployRedis(funcArgs)
break
case "DEPLOY_INGRESS":
resultOK, result = op.deployIngress(funcArgs)
break
case "DEPLOY_FRONTEND":
resultOK, result = op.deployFront(funcArgs)
break
case "INIT_MINIO":
resultOK, result = op.initMinio(funcArgs)
break
case "DEPLOY_K8S_SRS":
resultOK, result = op.deploySRS(funcArgs)
break
case "deployGDR":
resultOK, result = op.deployGDR(funcArgs)
break
case "MODIFY_NACOS":
resultOK, result = op.modifyNacos(funcArgs)
break
case "DEPLOY_BACKEND":
resultOK, result = op.deployBackend(funcArgs)
break
default:
op.ok(funcArgs)
}
// debug
log.DebugF("app deploy of %s result is %v", appFuncName, result)
return resultOK, result
}
func CheckAppInstallFolder() (bool, []string) {
if !BasicCreateFolder("/root/wdd/install") {
return false, []string{
"[CheckAppInstallFolder] - install folder create failed !",
}
}
return true, nil
}
func (op *AgentOsOperator) deployRke(funcArgs []string) (bool, []string) {
var ok bool
var resultLog []string
// download rke
// download kubectl
// download rke-cluster.yml
ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"rke", "/usr/local/bin/rke")
if !ok {
return false, resultLog
}
ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"kubectl", "/usr/local/bin/kubectl")
if !ok {
return false, resultLog
}
ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"rke-cluster-template.yaml", "/root/wdd/cluster.yml")
if !ok {
return false, resultLog
}
AllCompleteExecutor([][]string{
{
"chmod",
"+x",
"/usr/local/bin/rke",
},
{
"chmod",
"+x",
"/usr/local/bin/kubectl",
},
})
if !BasicCreateFolder("/root/.kube") {
return false, []string{
"[deployRke] - folder [/root/.kube] create error!",
}
}
// replace ip addr
parseIP := net.ParseIP(funcArgs[0])
if parseIP == nil {
return false, []string{
"[deployRke] - ip args error !",
}
}
if !BasicReplace("/root/wdd/rke-cluster.yml", "A1C2IP", funcArgs[1]) {
log.ErrorF("[deployRke] - rke config replace error !")
}
return true, []string{
"[deployRke] - rke dependency download success !",
}
}
func (op *AgentOsOperator) deployK8sDashboard(funcArgs []string) (bool, []string) {
restartHarborExec, strings := op.restartHarborExec()
if !restartHarborExec {
return false, strings
}
// check folder
folder, i := CheckAppInstallFolder()
if !folder {
return false, i
}
// download template file
k8sDashBoardYamlFile := "/root/wdd/install/k8s-dashboard.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"k8s-dashboard-template.yaml", k8sDashBoardYamlFile)
if !ok {
return false, resultLog
}
// kubectl
// replace
parseIP := net.ParseIP(funcArgs[0])
if parseIP == nil {
return false, []string{
"[deployK8sDashboard] - ip args error !",
}
}
BasicReplace(k8sDashBoardYamlFile, "A1C2IP", funcArgs[0])
// up
applyExec, resultLog := KubectlApplyExec(k8sDashBoardYamlFile)
if !applyExec {
return false, resultLog
}
// check deployment ok
if !CheckDeploymentStatusTimeout("kubernetes-dashboard", "kube-system", 120) {
return false, []string{
"[deployK8sDashboard] - deployment run error !",
}
}
return true, nil
}
func (op *AgentOsOperator) deployK8sNamespace(funcArgs []string) (bool, []string) {
if !CreateK8sNamespace(funcArgs[1]) {
return false, []string{
fmt.Sprintf("Namespace of %s create error!", funcArgs[1]),
}
}
return true, []string{
fmt.Sprintf("Namespace of %s create success !", funcArgs[1]),
}
}
func (op *AgentOsOperator) deployMinio(funcArgs []string) (bool, []string) {
minioTemplateFileName := "minio-docker-compose.yaml"
result := append(AppExecuteErrorLogPrefix, "部署MINIO")
// 逻辑为接收执行,但是会报错
// 环境判定
commandExist, commandName := BasicCommandExistsBatch([]string{
"docker-compose",
})
if !commandExist {
result = append(result, "命令不存在", commandName)
return false, result
}
// 磁盘空间足够
// 目录存在
// 下载模板文件
if !PureResultSingleExecute([]string{
"wget",
"-q",
op.OssOfflinePrefix + "/" + minioTemplateFileName,
}) {
result = append(result, "下载模板文件")
return false, result
}
// 根据参数 A1C2IP 替换
if !BasicReplace(minioTemplateFileName, "A1C2IP", funcArgs[0]) {
result = append(result, "替换IP信息")
return false, result
}
// 启动服务
if !PureResultSingleExecute([]string{
"docker-compose",
"-f",
minioTemplateFileName,
"up",
"-d",
}) {
result = append(result, "启动minio失败!")
return false, result
}
// 成功启动
return true, []string{
"MINIO安装成功!",
"输入如下命令查看启动情况: ",
"docker-compose logs minio1",
}
}
func (op *AgentOsOperator) deployNFS(funcArgs []string) (bool, []string) {
nfsTemplateFile := "k8s-nfs-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署NFS")
// 环境判定
if !BasicCommandExistByPath("kubectl") {
result = append(result, "命令不存在", "kubectl")
return false, result
}
// 创建目录修改权限
if !PureResultSingleExecuteBatch([][]string{
{"mkdir", "-p", nfsDataPath},
{"chmod", "777", nfsDataPath},
}) {
result = append(result, "目录不存在", nfsDataPath)
return false, result
}
// 下载模板文件
k8sNFSYamlFile := "/root/wdd/install/k8s-nfs.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+nfsTemplateFile, k8sNFSYamlFile)
if !ok {
return false, resultLog
}
// 根据参数 A1C2IP 替换
ip := net.ParseIP(funcArgs[0])
if ip == nil {
return false, append(result,
"ip args error !")
}
if !BasicReplace(k8sNFSYamlFile, "N1C2IP", funcArgs[0]) {
result = append(result, "替换IP信息")
return false, result
}
// 启动服务
exec, strings := KubectlApplyExec(k8sNFSYamlFile)
if !exec {
return false, strings
}
// 成功启动
return true, []string{
"NFS部署成功!",
}
}
func (op *AgentOsOperator) deployTestNFS(funcArgs []string) (bool, []string) {
nfsTemplateFile := "k8s-nfs-test-template.yaml"
result := append(AppExecuteErrorLogPrefix, "测试NFS部署")
// 环境判定
if !BasicCommandExistByPath("kubectl") {
result = append(result, "命令不存在", "kubectl")
return false, result
}
// 下载模板文件
k8sNFSYamlFile := "/root/wdd/install/k8s-nfs-test.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+nfsTemplateFile, k8sNFSYamlFile)
if !ok {
return false, resultLog
}
// 根据参数 A1C2IP 替换
ip := net.ParseIP(funcArgs[0])
if ip == nil {
return false, append(result,
"ip args error !")
}
if !BasicReplace(k8sNFSYamlFile, "N1C2IP", funcArgs[0]) {
result = append(result, "替换IP信息")
return false, result
}
// 启动服务
// 启动服务
exec, strings := KubectlApplyExec(k8sNFSYamlFile)
if !exec {
return false, strings
}
// 测试文件是否存在
if !BasicFileExists(nfsDataPath + "/test-pod*/NFS-CREATE-SUCCESS") {
result = append(result, "NFS 测试功能 异常!!")
return false, result
}
// 成功启动
return true, []string{
"NFS 测试功能正常!",
}
}
func (op *AgentOsOperator) deployPVC(funcArgs []string) (bool, []string) {
pvcTemplateFile := "k8s-pvc-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署PVC")
// 环境判定
if !BasicCommandExistByPath("kubectl") {
result = append(result, "命令不存在", "kubectl")
return false, result
}
// 下载模板文件
k8sNFSYamlFile := "/root/wdd/install/k8s-pvc.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+pvcTemplateFile, k8sNFSYamlFile)
if !ok {
return false, resultLog
}
// 根据参数 A1C2IP 替换
if !BasicReplace(k8sNFSYamlFile, "SUPREME", funcArgs[1]) {
result = append(result, "替换SUPREME信息")
return false, result
}
// 启动服务
exec, strings := KubectlApplyExec(k8sNFSYamlFile)
if !exec {
return false, strings
}
// 成功启动
return true, []string{
"PVC部署成功",
}
}
func (op *AgentOsOperator) deployMySQL(funcArgs []string) (bool, []string) {
mysqlTemplate := "k8s-mysql-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署 MySQL !")
// 环境判定
if !BasicCommandExistByPath("kubectl") {
result = append(result, "命令不存在", "kubectl")
return false, result
}
// 下载模板文件
k8sMysqlYamlFile := "/root/wdd/install/k8s-mysql.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+mysqlTemplate, k8sMysqlYamlFile)
if !ok {
return false, resultLog
}
// 根据参数 A1C2IP 替换
ip := net.ParseIP(funcArgs[0])
if ip == nil {
return false, append(result,
"ip args error !")
}
if !BasicReplace(k8sMysqlYamlFile, "A1C2IP", funcArgs[0]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
// 替换SUPREME信
if !BasicReplace(k8sMysqlYamlFile, "SUPREME", funcArgs[1]) {
result = append(result, "替换SUPREME信息")
return false, result
}
// 启动服务
exec, strings := KubectlApplyExec(k8sMysqlYamlFile)
if !exec {
return false, append(result, strings...)
}
// 成功启动
return true, []string{
"MySQL部署成功",
}
}
func (op *AgentOsOperator) loadMysqlInitScript(funcArgs []string) (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) checkMySQL(funcArgs []string) (bool, []string) {
if !CheckPodStatusTimeout("helm-mysql-0", funcArgs[0], 180) {
return false, []string{
"helm-mysql 启动失败!",
}
}
return true, nil
}
func (op *AgentOsOperator) deployMiddlewares(funcArgs []string) (bool, []string) {
middlewaresTemplate := "k8s-middleware-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署 所有的中间件 !")
// 环境判定
if !BasicCommandExistByPath("kubectl") {
result = append(result, "命令不存在", "kubectl")
return false, result
}
// 下载模板文件
k8sMiddlewaresYamlFile := "/root/wdd/install/k8s-middlewares.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+middlewaresTemplate, k8sMiddlewaresYamlFile)
if !ok {
return false, resultLog
}
// 根据参数 A1C2IP 替换
ip := net.ParseIP(funcArgs[0])
if ip == nil {
return false, append(result,
"ip args error !")
}
if !BasicReplace(k8sMiddlewaresYamlFile, "A1C2IP", funcArgs[0]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
if !BasicReplace(k8sMiddlewaresYamlFile, "SUPREME", funcArgs[1]) {
result = append(result, "替换SUPREME信息")
return false, result
}
// 启动服务
exec, strings := KubectlApplyExec(k8sMiddlewaresYamlFile)
if !exec {
return false, append(result, strings...)
}
// 成功启动
return true, []string{
"中间件部署成功!",
}
}
func (op *AgentOsOperator) deployRedis(funcArgs []string) (bool, []string) {
redisTemplate := "k8s-redis-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署 redis !")
// 环境判定
if !BasicCommandExistByPath("kubectl") {
result = append(result, "命令不存在", "kubectl")
return false, result
}
// 下载模板文件
k8sRedisYamlFile := "/root/wdd/install/k8s-redis.yaml"
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+redisTemplate, k8sRedisYamlFile)
if !ok {
return false, resultLog
}
// 根据参数 A1C2IP 替换
ip := net.ParseIP(funcArgs[0])
if ip == nil {
return false, append(result,
"ip args error !")
}
if !BasicReplace(k8sRedisYamlFile, "A1C2IP", funcArgs[0]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
if !BasicReplace(k8sRedisYamlFile, "SUPREME", funcArgs[1]) {
result = append(result, "替换SUPREME信息")
return false, result
}
// 启动服务
exec, strings := KubectlApplyExec(k8sRedisYamlFile)
if !exec {
return false, append(result, strings...)
}
// 成功启动
return true, []string{
"Redis 部署成功!",
}
}
func (op *AgentOsOperator) deployIngress(funcArgs []string) (bool, []string) {
ingressTemplate := "ingress-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署 Ingress !")
// 环境判定
commandExist, commandName := BasicCommandExistsBatch([]string{
"kubectl",
})
if !commandExist {
result = append(result, "命令不存在", commandName)
return false, result
}
// 下载模板文件
if !PureResultSingleExecute([]string{
"wget",
"-q",
op.OssOfflinePrefix + "/" + ingressTemplate,
}) {
result = append(result, "下载模板文件")
return false, result
}
// 根据参数 A1C2IP 替换
if !BasicReplace(ingressTemplate, "SUPREME", funcArgs[0]) {
result = append(result, "替换SUPREME信息")
return false, result
}
if !BasicReplace(ingressTemplate, "A1C2IP", funcArgs[1]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
if !BasicReplace(ingressTemplate, "A1C1JS", funcArgs[1]) {
result = append(result, "替换A1C1JS信息")
return false, result
}
// 启动服务
if !PureResultSingleExecute([]string{
"kubectl",
"apply",
"-f",
ingressTemplate,
}) {
result = append(result, "创建 Ingress 失败!")
return false, result
}
// 成功启动
return true, []string{
"Ingress 部署成功!",
}
}
func (op *AgentOsOperator) deployFront(funcArgs []string) (bool, []string) {
fontTemplate := "front-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署 前端服务 !")
// 环境判定
commandExist, commandName := BasicCommandExistsBatch([]string{
"kubectl",
})
if !commandExist {
result = append(result, "命令不存在", commandName)
return false, result
}
// 下载模板文件
if !PureResultSingleExecute([]string{
"wget",
"-q",
op.OssOfflinePrefix + "/" + fontTemplate,
}) {
result = append(result, "下载模板文件")
return false, result
}
// 根据参数 A1C2IP 替换
if !BasicReplace(fontTemplate, "SUPREME", funcArgs[0]) {
result = append(result, "替换SUPREME信息")
return false, result
}
if !BasicReplace(fontTemplate, "A1C2IP", funcArgs[1]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
// 启动服务
if !PureResultSingleExecute([]string{
"kubectl",
"apply",
"-f",
fontTemplate,
}) {
result = append(result, "创建 前端服务 失败!")
return false, result
}
// 成功启动
return true, []string{
"前端服务 部署成功!",
}
}
func (op *AgentOsOperator) initMinio(funcArgs []string) (bool, []string) {
initMinioTemplate := "minio-init.sh"
result := append(AppExecuteErrorLogPrefix, "进行MINIO初始化服务 !")
// 环境判定
commandExist, commandName := BasicCommandExistsBatch([]string{
"kubectl",
})
if !commandExist {
result = append(result, "命令不存在", commandName)
return false, result
}
// 下载模板文件
if !PureResultSingleExecute([]string{
"wget",
"-q",
op.OssOfflinePrefix + "/" + initMinioTemplate,
}) {
result = append(result, "下载模板文件")
return false, result
}
// 根据参数 A1C2IP 替换
if !BasicReplace(initMinioTemplate, "SUPREME", funcArgs[0]) {
result = append(result, "替换SUPREME信息")
return false, result
}
if !BasicReplace(initMinioTemplate, "A1C2IP", funcArgs[1]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
if !BasicReplace(initMinioTemplate, "M2D2IP", funcArgs[1]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
// 启动服务
if !PureResultSingleExecute([]string{
"kubectl",
"apply",
"-f",
initMinioTemplate,
}) {
result = append(result, "MINIO 初始化 失败!")
return false, result
}
// 成功启动
return true, []string{
"MINIO 初始化 成功!",
}
}
func (op *AgentOsOperator) deploySRS(funcArgs []string) (bool, []string) {
srsTemplate := "srs-template.yaml"
result := append(AppExecuteErrorLogPrefix, "开始部署SRS服务")
// 环境判定
commandExist, commandName := BasicCommandExistsBatch([]string{
"kubectl",
})
if !commandExist {
result = append(result, "命令不存在", commandName)
return false, result
}
// 下载模板文件
if !PureResultSingleExecute([]string{
"wget",
"-q",
op.OssOfflinePrefix + "/" + srsTemplate,
}) {
result = append(result, "下载模板文件")
return false, result
}
// 根据参数 A1C2IP 替换
if !BasicReplace(srsTemplate, "SUPREME", funcArgs[0]) {
result = append(result, "替换SUPREME信息")
return false, result
}
if !BasicReplace(srsTemplate, "A1C2IP", funcArgs[1]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
if !BasicReplace(srsTemplate, "A1C1JS", funcArgs[1]) {
result = append(result, "替换A1C1JS信息")
return false, result
}
if !BasicReplace(srsTemplate, "M2D2IP", funcArgs[1]) {
result = append(result, "替换M2D2IP信息")
return false, result
}
// 启动服务
if !PureResultSingleExecute([]string{
"kubectl",
"apply",
"-f",
srsTemplate,
}) {
result = append(result, "部署 SRS 失败!")
return false, result
}
// 成功启动
return true, []string{
"部署 SRS 成功!",
}
}
func (op *AgentOsOperator) deployGDR(funcArgs []string) (bool, []string) {
return true, []string{
"请手动进行GDR的部署工作",
}
}
func (op *AgentOsOperator) modifyNacos(funcArgs []string) (bool, []string) {
log.Info("请开始进行Nacos的配置修改工作")
log.Info("请开始进行Nacos的配置修改工作")
after := time.After(120 * time.Second)
<-after
msg := "等待Nacos的配置结束"
log.Info(msg)
return true, []string{msg}
}
func (op *AgentOsOperator) deployBackend(funcArgs []string) (bool, []string) {
backendTemplate := "backend-template.yaml"
result := append(AppExecuteErrorLogPrefix, "部署 后端 服务 !")
// 环境判定
commandExist, commandName := BasicCommandExistsBatch([]string{
"kubectl",
})
if !commandExist {
result = append(result, "命令不存在", commandName)
return false, result
}
// 下载模板文件
if !PureResultSingleExecute([]string{
"wget",
"-q",
op.OssOfflinePrefix + "/" + backendTemplate,
}) {
result = append(result, "下载模板文件")
return false, result
}
// 根据参数 A1C2IP 替换
if !BasicReplace(backendTemplate, "SUPREME", funcArgs[0]) {
result = append(result, "替换SUPREME信息")
return false, result
}
if !BasicReplace(backendTemplate, "A1C2IP", funcArgs[1]) {
result = append(result, "替换A1C2IP信息")
return false, result
}
// 启动服务
if !PureResultSingleExecute([]string{
"kubectl",
"apply",
"-f",
backendTemplate,
}) {
result = append(result, "创建 后端服务 失败!")
return false, result
}
// 成功启动
return true, []string{
"后端服务 部署成功!",
}
}