From 314b6054d311cd5bc9bf74256612ebb42c288f48 Mon Sep 17 00:00:00 2001 From: zeaslity Date: Thu, 18 Apr 2024 15:20:19 +0800 Subject: [PATCH] [agent-go] [Bastion] - basic accomplished ! --- agent-go/a_executor/BaseFunction.go | 136 ++++++++++-- agent-go/a_executor/BasicFunction.go | 203 +++++++++++++----- agent-go/a_executor/BasicFunction_test.go | 6 + .../a_executor/beans/DockerDaemonConfig.go | 9 + agent-go/a_executor/beans/SshKeyConfig.go | 58 +++++ agent-go/a_init/AgentInitialization.go | 53 +++++ agent-go/a_init/BastionInitializaion.go | 10 +- agent-go/a_init/bastion_init/123.txt | 49 +++++ agent-go/a_init/bastion_init/BastionHelp.go | 14 ++ agent-go/a_init/bastion_init/BastionTest.go | 1 - agent-go/a_init/bastion_init/DPSearch.go | 91 -------- agent-go/a_init/bastion_init/TrieSearch.go | 3 + .../a_init/bastion_init/TrieSearch_test.go | 33 --- agent-go/a_init/bastion_init/config.go | 5 - 14 files changed, 467 insertions(+), 204 deletions(-) create mode 100644 agent-go/a_init/bastion_init/123.txt create mode 100644 agent-go/a_init/bastion_init/BastionHelp.go delete mode 100644 agent-go/a_init/bastion_init/BastionTest.go delete mode 100644 agent-go/a_init/bastion_init/DPSearch.go delete mode 100644 agent-go/a_init/bastion_init/config.go diff --git a/agent-go/a_executor/BaseFunction.go b/agent-go/a_executor/BaseFunction.go index 98598a2..ad658ed 100644 --- a/agent-go/a_executor/BaseFunction.go +++ b/agent-go/a_executor/BaseFunction.go @@ -233,11 +233,13 @@ func (op *AgentOsOperator) shutdownFirewallExec() (bool, []string) { {"iptables", "-F"}, } // 忽略错误 - _, resultLog := AllCompleteExecutor(shutdownFunc) + AllCompleteExecutor(shutdownFunc) // centos - return true, resultLog + return true, []string{ + "[shutdownFirewallExec] - 关闭防火墙成功!", + } } func (op *AgentOsOperator) modifyHostname(args []string) [][]string { @@ -258,15 +260,45 @@ func (op *AgentOsOperator) modifyHostnameExec(args []string) (bool, []string) { } func (op *AgentOsOperator) modifySystemConfigExec() (bool, []string) { + sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf" // ssh config // system redirection + if !BasicFileExistAndNotNull(sysctlConfigFile) { + ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"systemctl-config-template.txt", "", "", "", sysctlConfigFile) + if !ok { + return false, resultLog + } + } + + AllCommandExecutor([]string{ + "sysctl", + "-p", + sysctlConfigFile, + }) return true, nil } func (op *AgentOsOperator) ModifySysConfigBastion() (bool, []string) { - return op.modifySystemConfigExec() + + sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf" + + if !BasicAppendOverwriteContentToFile(beans.SysctlConfig, sysctlConfigFile) { + return false, []string{ + "[ModifySysConfigBastion] - error appending sysctl config to sysctl.d !", + } + } + + AllCommandExecutor([]string{ + "sysctl", + "-p", + sysctlConfigFile, + }) + + return true, []string{ + "[ModifySysConfigBastion] - success !", + } } func (op *AgentOsOperator) enableSwap() [][]string { @@ -370,7 +402,9 @@ func (op *AgentOsOperator) disableSELinuxExec() (bool, []string) { "0", }) - return true, []string{} + return true, []string{ + "[disableSELinuxExec] - success", + } } func (op *AgentOsOperator) DisableSelinuxBastion() (bool, []string) { @@ -417,7 +451,9 @@ func (op *AgentOsOperator) installDefaultSSHKeyExec(funcArgs []string) (bool, [] // check if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") { - return true, nil + return true, []string{ + "[installDefaultSSHKeyExec] - authorized_keys contain the ssh-pub key !", + } } return false, []string{ @@ -444,7 +480,7 @@ func (op *AgentOsOperator) InstallDefaultSshBastion() (bool, []string) { "[installDefaultSSHKeyExec] - error appending private ssh key to authorized_keys !", } } - if !BasicAppendOverwriteContentToFile(beans.Ed25519PublicKey, "/root/.ssh/id_ed25519.pu") { + if !BasicAppendOverwriteContentToFile(beans.Ed25519PublicKey, "/root/.ssh/id_ed25519.pub") { return false, []string{ "[installDefaultSSHKeyExec] - error appending public ssh key to authorized_keys !", } @@ -466,7 +502,9 @@ func (op *AgentOsOperator) InstallDefaultSshBastion() (bool, []string) { // check if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") { log.Info("installDefaultSSHKeyExec - authorized_keys contain the ssh-pub key !") - return true, nil + return true, []string{ + "[InstallDefaultSshBastion] - install success !", + } } return false, []string{ @@ -504,6 +542,12 @@ func (op *AgentOsOperator) removeDocker() [][]string { func (op *AgentOsOperator) removeDockerExec() (bool, []string) { + if !BasicCommandExistByPath("docker") { + return true, []string{ + "[removeDockerExec] - docker is not installed !", + } + } + dockerServiceStopCommand := [][]string{ { "systemctl", @@ -1236,13 +1280,13 @@ func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) { var DockerComposeFile string if strings.HasPrefix(op.AgentArch, "amd") { - DockerComposeFile = op.OssOfflinePrefix + "docker-compose-linux-x86_64-v2.18.0" + DockerComposeFile = OctopusAgentInstallPrefix + "docker-compose-linux-x86_64-v2.18.0" } else if strings.HasPrefix(op.AgentArch, "arm64") { - DockerComposeFile = op.OssOfflinePrefix + "docker-compose-linux-aarch64-v2.18.0" + DockerComposeFile = OctopusAgentInstallPrefix + "docker-compose-linux-aarch64-v2.18.0" } // check file exits - if !BasicFileExistInFolder(DockerComposeFile) { + if !BasicFileExistAndNotNull(DockerComposeFile) { sprintf := fmt.Sprintf("docker-compose 离线安装文件不存在! => %s", DockerComposeFile) return false, []string{ sprintf, @@ -1250,6 +1294,11 @@ func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) { } AllCompleteExecutor([][]string{ + { + "mv", + DockerComposeFile, + "/usr/local/bin/docker-compose", + }, { "chmod", "+x", "/usr/local/bin/docker-compose", }, @@ -1259,6 +1308,12 @@ func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) { }) log.Info("docker-compose安装成功!") + if !BasicCommandExistByPath("docker-compose") { + return false, []string{ + "[InstallDockerComposeBastion] - docker-compose 安装失败!", + } + } + return true, []string{ "[InstallDockerComposeBastion] - docker-compose offline installation from local success!", } @@ -1378,12 +1433,46 @@ func (op *AgentOsOperator) modifyDockerConfig(args []string) [][]string { } func (op *AgentOsOperator) ModifyDockerConfigBastion() (bool, []string) { - argList := []string{ - "127.0.0.1", + dockerDaemonFile := "/etc/docker/daemon.json" + // check docker daemon json exist + if BasicFileExistAndNotNull(dockerDaemonFile) { + AllCommandExecutor([]string{ + "mv", + dockerDaemonFile, + "/etc/docker/daemon-json.backup", + }) } - return op.modifyDockerConfigExec(argList) -} + // download new + if !BasicAppendOverwriteContentToFile(beans.DockerDeamonConfig, dockerDaemonFile) { + return false, []string{ + "[ModifyDockerConfigBastion] - modify docker daemon config error !", + } + } + + if !BasicReplace(dockerDaemonFile, "DockerRegisterDomain", op.AgentServerInfo.ServerIPInV4) { + return false, []string{ + "[ModifyDockerConfigBastion] - modify docker daemon config error !", + } + } + log.InfoF("[ModifyDockerConfigBastion] - 修改docker配置成功! => %s", op.AgentServerInfo.ServerIPInV4) + + // restart docker + if !PureResultSingleExecute([]string{ + "systemctl", + "restart", + "docker.service", + }) { + return false, []string{ + "[ModifyDockerConfigBastion] - restart docker.service error !", + } + } + + return true, []string{ + "[ModifyDockerConfigBastion] - 修改docker配置成功!", + } + +} func (op *AgentOsOperator) modifyDockerConfigExec(args []string) (bool, []string) { dockerDaemonFile := "/etc/docker/daemon.json" @@ -1438,7 +1527,7 @@ func (op *AgentOsOperator) installNfsOnlineExec() (bool, []string) { if op.IsOsTypeUbuntu { // ubuntu - installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, false, + installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, false, "nfs-common", "nfs-client", "nfs") if !installOk { return false, installLog @@ -1451,7 +1540,7 @@ func (op *AgentOsOperator) installNfsOnlineExec() (bool, []string) { } else if op.IsOsTypeCentOS { // centos - installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, false, + installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, false, "nfs-utils") if !installOk { return false, installLog @@ -1547,7 +1636,7 @@ func (op *AgentOsOperator) installNfsServerOnlineExec() (bool, []string) { // os if op.IsOsTypeUbuntu { // ubuntu - installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, true, "nfs-kernel-server", + installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, true, "nfs-kernel-server", "nfs-common") if !installOk { return false, installLog @@ -1563,7 +1652,7 @@ func (op *AgentOsOperator) installNfsServerOnlineExec() (bool, []string) { } else if op.IsOsTypeCentOS { // ubuntu - installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, true, "nfs-utils") + installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, true, "nfs-utils") if !installOk { return false, installLog } @@ -1762,7 +1851,7 @@ func (op *AgentOsOperator) installHarbor() [][]string { } func (op *AgentOsOperator) checkHarborInstallExec() (bool, []string) { // check docker-compose - if !BasicCommandExistByPath("/usr/local/bin/docker-compose") { + if !BasicCommandExistByPath("docker-compose") { return false, []string{ "[install harbor] - docker-compose uninstalled ! can't install harbor!", } @@ -1809,7 +1898,9 @@ func (op *AgentOsOperator) checkHarborInstallExec() (bool, []string) { } } - return true, nil + return true, []string{ + "[install harbor] - check harbor installation environment success !", + } } // installHarborExec install harbor offline @@ -1912,7 +2003,8 @@ func (op *AgentOsOperator) InstallHarborBastion() (bool, []string) { // local file check exists if !BasicFileExistAndNotNull("/root/wdd/harbor-offline-installer-v2.9.0.tgz") { - return false, []string{"[InstallHarborBastion] - harbor offline installer not exists !"} + sprintf := fmt.Sprintf("[InstallHarborBastion] - harbor offline installer not exists ! => %s", "/root/wdd/harbor-offline-installer-v2.9.0.tgz") + return false, []string{sprintf} } // unzip @@ -2350,7 +2442,7 @@ func (op *AgentOsOperator) chronyToMasterExec(args []string) (bool, []string) { } // install ntp - installSoftwares, i := BasicInstallSoftwares(op.InstallCommandPrefix, true, "ntp") + installSoftwares, i := BasicInstallSoftware(op.InstallCommandPrefix, true, "ntp") if !installSoftwares { msg := "[chronyToMasterExec] - centos install ntp error!" log.ErrorF(msg) diff --git a/agent-go/a_executor/BasicFunction.go b/agent-go/a_executor/BasicFunction.go index bd5b75e..08c3000 100644 --- a/agent-go/a_executor/BasicFunction.go +++ b/agent-go/a_executor/BasicFunction.go @@ -3,6 +3,7 @@ package a_executor import ( "bufio" "bytes" + "errors" "fmt" "golang.org/x/net/proxy" "io" @@ -10,6 +11,8 @@ import ( "net/url" "os" "os/exec" + "path/filepath" + "regexp" "strings" ) @@ -26,6 +29,7 @@ func BasicCommandExists(commandName string) bool { } else { return true } + } // BasicCommandExistsBatch 判定批量命令是否存在 @@ -43,7 +47,7 @@ func BasicCommandExistsBatch(commandNameList []string) (bool, string) { // BasicCommandExistByPath 根据路径判定 命令是否存在 func BasicCommandExistByPath(commandName string) bool { - if BasicFileExistInFolder(commandName, "/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "bin", "/snap/bin") { + if BasicFileExistInFolder(commandName, "/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "/bin", "/snap/bin") { return true } @@ -53,7 +57,14 @@ func BasicCommandExistByPath(commandName string) bool { // BasicFileExistInFolder 查询fileName是否存在于目录folderList中,如果存在返回true,不存在返回false func BasicFileExistInFolder(fileName string, folderList ...string) bool { + if fileName == "" { + return false // If the file name is empty, we cannot check for existence. + } + for _, folder := range folderList { + if folder == "" { + continue // Skip empty folders. + } if BasicFolderExists(folder) { // is folder ok, _ := PipelineCommandExecutor([][]string{ @@ -71,22 +82,6 @@ func BasicFileExistInFolder(fileName string, folderList ...string) bool { return true } - } else { - // it's a file - ok, _ := PipelineCommandExecutor([][]string{ - { - "echo", - folder, - }, - { - "grep", - "-c", - fileName, - }, - }) - if ok { - return true - } } } @@ -261,16 +256,16 @@ func BasicDockerImageExists(imageName, imageVersion string) bool { return true } -func BasicInstallSoftwares(installPrefix []string, isStrict bool, softwares ...string) (bool, []string) { +func BasicInstallSoftware(installPrefix []string, isStrict bool, softwares ...string) (bool, []string) { var installLog []string for _, software := range softwares { - log.DebugF("[BasicInstallSoftwares] - going to install [ %s ]", software) + log.DebugF("[BasicInstallSoftware] - going to install [ %s ]", software) if !PureResultSingleExecute(append(installPrefix, software)) { - failedInstall := fmt.Sprintf("[BasicInstallSoftwares] - software of [ %s ] install failed !", software) + failedInstall := fmt.Sprintf("[BasicInstallSoftware] - software of [ %s ] install failed !", software) installLog = append(installLog, failedInstall) if isStrict { @@ -278,16 +273,90 @@ func BasicInstallSoftwares(installPrefix []string, isStrict bool, softwares ...s } } - successInstall := fmt.Sprintf("[BasicInstallSoftwares] - software of [ %s ] install success !", software) + successInstall := fmt.Sprintf("[BasicInstallSoftware] - software of [ %s ] install success !", software) installLog = append(installLog, successInstall) } return true, installLog } -// BasicReplace 基础替换命令 +// BasicReplace 将文件中origin字段全部替换为replace func BasicReplace(filename string, origin string, replace string) bool { + if !BasicFileExistAndNotNull(filename) { + log.WarnF("文件替换 文件不存在 %s", filename) + return false + } + + // 打开文件 + file, err := os.OpenFile(filename, os.O_RDWR, 0644) + if err != nil { + fmt.Printf("error opening file: %v\n", err) + return false + } + + // 创建一个临时文件用于存储替换后的内容 + tempFilename := filename + ".tmp" + tempFile, err := os.Create(tempFilename) + if err != nil { + fmt.Printf("error creating temp file: %v\n", err) + return false + } + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + + // 使用正则表达式替换,以支持多种替换场景(如部分词、多行等) + re := regexp.MustCompile(fmt.Sprintf("(\\b%s\\b)|(^%s)|(%s$)", origin, origin, replace)) + newLine := re.ReplaceAllString(line, replace) + + // 写入替换后的内容到临时文件 + _, err := tempFile.WriteString(newLine + "\n") + if err != nil { + fmt.Printf("error writing to temp file: %v\n", err) + return false + } + } + + // 检查是否有错误发生 + if err := scanner.Err(); err != nil { + fmt.Printf("error reading from file: %v\n", err) + return false + } + + err = file.Close() + if err != nil { + log.ErrorF("error closing file: %v\n", err) + return false + } + err = tempFile.Close() + if err != nil { + log.ErrorF("error closing file: %v\n", err) + return false + } + + // 移动文件名,指向新的替换后的文件 + err = os.Remove(filename) + if err != nil { + log.ErrorF("error removing file: %v\n", err) + return false + } + + err = os.Rename(tempFilename, filename) + if err != nil { + fmt.Printf("error renaming file: %v\n", err) + return false + } + + // 返回成功标志 + return true + +} + +// BasicReplaceBySed 基础替换命令 +func BasicReplaceBySed(filename string, origin string, replace string) bool { + // 暂不添加 //if !BasicFileExistAndNotNull(filename) { // log.DebugF("文件替换") @@ -305,57 +374,91 @@ func BasicReplace(filename string, origin string, replace string) bool { func BasicRemoveFolderComplete(folderName string) bool { - if !BasicFileExists(folderName) || !BasicFolderExists(folderName) { - log.DebugF("[BasicRemoveFolderComplete] - file or folder of [%s] not exists !", folderName) - return true - } - - cmd := exec.Command("rm", "-rf", folderName) - err := cmd.Run() + err := filepath.Walk(folderName, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + return os.Remove(path) + } + return nil + }) if err != nil { - log.DebugF("删除 %s 失败!", folderName) return false - } else { - return true } + err = os.RemoveAll(folderName) + if err != nil { + return false + } + return true } // BasicFileExists 检测文件是否存在 func BasicFileExists(filename string) bool { - cmd := exec.Command("test", "-f", filename) - err := cmd.Run() - if err != nil { - log.DebugF("文件 %s 不存在!", filename) - return false - } else { - return true + if filename == "" { + return false // An empty string does not correspond to a valid file. } + _, err := os.Stat(filename) + if err != nil { + switch err.(type) { + case *os.PathError: + // If the error is because the path doesn't exist, return false. + if errors.Is(err.(*os.PathError).Err, os.ErrNotExist) { + log.DebugF("文件 %s 不存在!", filename) + return false + } + case nil: + return true + default: + // Handle other types of errors as appropriate for your use case. + return false + } + } + return true } // BasicFileExistAndNotNull 文件不为空返回true 文件为空返回false func BasicFileExistAndNotNull(filename string) bool { - cmd := exec.Command("test", "-s", filename) - err := cmd.Run() - if err != nil { - log.DebugF("文件 %s 为空!", filename) + // Check if the file exists + if _, err := os.Stat(filename); os.IsNotExist(err) { + log.DebugF("文件 %s 不存在!", filename) return false - } else { - return true } + + // Open the file for reading + file, err := os.Open(filename) + defer file.Close() + if err != nil { + log.DebugF("文件 %s 打开有误!", filename) + return false // Handle error according to your needs + } + + // Get the file size + info, _ := file.Stat() + size := info.Size() + + // Check if the file is not empty + return size > 0 } func BasicFolderExists(folderName string) bool { - cmd := exec.Command("test", "-d", folderName) - err := cmd.Run() + fi, err := os.Stat(folderName) if err != nil { - log.DebugF("目录 %s 不存在!", folderName) + if os.IsNotExist(err) { + // 目标路径不存在 + log.WarnF("[BasicFolderExists] - 目录 %s 不存在!", folderName) + return false + } + // 其他错误 return false - } else { - return true } + + // 判断是否为目录 + return fi.IsDir() } func BasicCreateFolder(folderName string) bool { diff --git a/agent-go/a_executor/BasicFunction_test.go b/agent-go/a_executor/BasicFunction_test.go index a8f6b80..4ec0962 100644 --- a/agent-go/a_executor/BasicFunction_test.go +++ b/agent-go/a_executor/BasicFunction_test.go @@ -17,6 +17,12 @@ func TestBasicFileExistAndNotNull(t *testing.T) { } +func TestBasicReplace(t *testing.T) { + replace := BasicReplace("C:\\Users\\wddsh\\Documents\\IdeaProjects\\ProjectOctopus\\agent-go\\a_init\\bastion_init\\123.txt", "HarborHostPort", "8033") + + assert.Equal(t, replace, true, "判定为空文件返回false!") +} + func TestBasicReplaceFileNotExists(t *testing.T) { replace := BasicReplace(noExistFilePath, "123", "123") diff --git a/agent-go/a_executor/beans/DockerDaemonConfig.go b/agent-go/a_executor/beans/DockerDaemonConfig.go index b8d78eb..ae778d9 100644 --- a/agent-go/a_executor/beans/DockerDaemonConfig.go +++ b/agent-go/a_executor/beans/DockerDaemonConfig.go @@ -110,3 +110,12 @@ OOMScoreAdjust=-500 [Install] WantedBy=multi-user.target ` + +var DockerDeamonConfig = ` +{ + "insecure-registries": [ + "DockerRegisterDomain:8033", + "harbor.wdd.io:8033" + ] +} +` diff --git a/agent-go/a_executor/beans/SshKeyConfig.go b/agent-go/a_executor/beans/SshKeyConfig.go index 2fd95a7..f286877 100644 --- a/agent-go/a_executor/beans/SshKeyConfig.go +++ b/agent-go/a_executor/beans/SshKeyConfig.go @@ -13,3 +13,61 @@ KGhIhJXbSwuJdk9k994vAAAADHdkZEBjbWlpLmNvbQE= var Ed25519PublicKey = ` ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOTxHgpcaANrkfavweupbWSVKGhIhJXbSwuJdk9k994v wdd@cmii.com ` + +var SysctlConfig = ` +# 开启 IPv4 路由转发 +net.ipv4.ip_forward = 1 + +# 禁用 IPv6 +net.ipv6.conf.all.disable_ipv6 = 1 +net.ipv6.conf.default.disable_ipv6 = 1 + +# 开启 IPv4 转发 +net.ipv4.conf.all.forwarding = 1 +net.ipv4.conf.default.forwarding = 1 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_syncookies = 1 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_tw_recycle = 1 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_tw_reuse = 1 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_fin_timeout = 30 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_keepalive_time = 1200 + +# 开启 IPv4 连接跟踪 +net.ipv4.ip_local_port_range = 1024 65535 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_max_syn_backlog = 8192 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_max_tw_buckets = 5000 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_max_orphans = 32768 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_synack_retries = 2 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_syn_retries = 2 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_synflood_protect = 1000 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_timestamps = 1 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_window_scaling = 1 + +# 开启 IPv4 连接跟踪 +net.ipv4.tcp_rmem = 4096 87380 4194304 +` diff --git a/agent-go/a_init/AgentInitialization.go b/agent-go/a_init/AgentInitialization.go index fe9ae25..286aba2 100644 --- a/agent-go/a_init/AgentInitialization.go +++ b/agent-go/a_init/AgentInitialization.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "math/rand" "reflect" + "regexp" "strings" "time" "wdd.io/agent-common/logger" @@ -233,15 +234,67 @@ func buildOctopusTCPConnect(agentConfig *viper.Viper) *rabbitmq.RabbitTCPConnect func refreshAgentInfoByStatusInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) { + // host info agentServerInfo.Platform = agentInfo.HostInfo.Platform agentServerInfo.PlatformFamily = agentInfo.HostInfo.PlatformFamily agentServerInfo.PlatformVersion = agentInfo.HostInfo.PlatformVersion agentServerInfo.KernelVersion = agentInfo.HostInfo.KernelVersion agentServerInfo.KernelArch = agentInfo.HostInfo.KernelArch + // network part + refreshAgentNetworkInfo(agentInfo, agentServerInfo) + log.DebugF("[refreshAgentInfoByStatusInfo] - ok !") } +func refreshAgentNetworkInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) { + + // 测试网卡名称 + //testCases := []string{"ens33", "eno1", "enp0s3", "enp1s2", "eth0", "enp2s5", "enx1234567890ab", "ens1234567890ab", "enp1234567890ab", "enp1234567890ab", "enp1", "lo","","docker0", "virbr0", "veth0",} + //for _, tc := range testCases { + // fmt.Printf("Network interface '%s' is %s\n", tc, fmt.Sprintf("%v", isNetworkInterface(tc))) + //} + + // inner ip v4 v6 + for _, networkInfo := range agentInfo.NetworkInfo { + if isNetworkInterface(networkInfo.Name) { + log.InfoF("refreshAgentNetworkInfo - network interface is %v", networkInfo) + if networkInfo.InternalIPv4 == nil || len(networkInfo.InternalIPv4) == 0 { + continue + } + // 通配到对应的网卡 + s := networkInfo.InternalIPv4[0] + if strings.Contains(s, "/") { + s = strings.Split(s, "/")[0] + } + agentServerInfo.ServerIPInV4 = s + + if networkInfo.InternalIPv6 == nil || len(networkInfo.InternalIPv6) == 0 { + continue + } + s2 := networkInfo.InternalIPv6[0] + if strings.Contains(s2, "/") { + s2 = strings.Split(s2, "/")[0] + } + agentServerInfo.ServerIPInV6 = s2 + + if agentServerInfo.ServerIPInV4 != "" { + break + } + } + } + +} + +// isNetworkInterface 检查网卡名称是否符合给定的模式(ens, eno或enp开头,或者像enp1s2这样的格式)。 +func isNetworkInterface(networkInterface string) bool { + // 正则表达式匹配 ens 或 eno 开头的字符串 + // 或者以 enp 开头,后面跟着至少一个数字,一个连字符,再是一个数字,最后可以有一个可选的连字符和数字组合(如enp0s3或enp1s2) + pattern := `^(ens|eno|eth|enp)[0-9]+$|enp+[0-9]s+[0-9]$` + re := regexp.MustCompile(pattern) + return re.MatchString(networkInterface) +} + // handleInitMsgFromServer 处理从Server接收的 注册信息 func handleInitMsgFromServer(initFromServerMsg *rabbitmq.OctopusMessage, initToServerQueue *rabbitmq.RabbitQueue, agentServerInfo *a_agent.AgentServerInfo) bool { diff --git a/agent-go/a_init/BastionInitializaion.go b/agent-go/a_init/BastionInitializaion.go index fec3815..0b77ac1 100644 --- a/agent-go/a_init/BastionInitializaion.go +++ b/agent-go/a_init/BastionInitializaion.go @@ -51,8 +51,8 @@ func BastionModeInit() { // Build For Operator bastionAgentServerInfo := &a_agent.AgentServerInfo{ ServerName: "BastionSingle", - ServerIPPbV4: "127.0.0.1", - ServerIPInV4: "127.0.0.1", + ServerIPPbV4: "", + ServerIPInV4: "", ServerIPPbV6: "", ServerIPInV6: "", Location: "Bastion", @@ -167,6 +167,12 @@ func buildBastionModeFunction() { tcc.Insert(InstallDocker) tcc.Insert(InstallDockerCompose) tcc.Insert(InstallMinio) + tcc.Insert(InstallDefaultSsh) + tcc.Insert(DisableSwap) + tcc.Insert(DisableSelinux) + tcc.Insert(DisableFirewall) + tcc.Insert(ModifySysConfig) + tcc.Insert(ModifyDockerConfig) tcc.Insert(InstallHarbor) tcc.Insert(RemoveDocker) tcc.Insert(Help) diff --git a/agent-go/a_init/bastion_init/123.txt b/agent-go/a_init/bastion_init/123.txt new file mode 100644 index 0000000..9cb3115 --- /dev/null +++ b/agent-go/a_init/bastion_init/123.txt @@ -0,0 +1,49 @@ +hostname: HarborHostName + +http: + port: 8033 + +harbor_admin_password: HarborAdminPas + +database: + password: HarborAdminPas + max_idle_conns: 50 + max_open_conns: 1000 + conn_max_lifetime: 3600 + conn_max_idle_time: 3600 + +data_volume: /var/lib/docker/harbor-data + +jobservice: + max_job_workers: 10 + job_loggers: + - STD_OUTPUT + - FILE + logger_sweeper_duration: 3 + +notification: + webhook_job_max_retry: 10 + webhook_job_http_client_timeout: 10 + + +log: + level: warning + local: + rotate_count: 50 + rotate_size: 200M + location: /var/log/harbor + +cache: + enabled: false + expire_hours: 24 + +_version: 2.9.0 + +proxy: + http_proxy: + https_proxy: + no_proxy: + components: + - core + - jobservice + - trivy diff --git a/agent-go/a_init/bastion_init/BastionHelp.go b/agent-go/a_init/bastion_init/BastionHelp.go new file mode 100644 index 0000000..3c67e7d --- /dev/null +++ b/agent-go/a_init/bastion_init/BastionHelp.go @@ -0,0 +1,14 @@ +package bastion_init + +import "fmt" + +var BastionFunctionList []string + +func PrintBastionHelp() { + fmt.Println() + fmt.Println("Bastion Mode Supported Commands:") + for i, s := range BastionFunctionList { + fmt.Printf("\t%d. %s\n", i+1, s) + } + fmt.Println() +} diff --git a/agent-go/a_init/bastion_init/BastionTest.go b/agent-go/a_init/bastion_init/BastionTest.go deleted file mode 100644 index 09931d7..0000000 --- a/agent-go/a_init/bastion_init/BastionTest.go +++ /dev/null @@ -1 +0,0 @@ -package bastion_init diff --git a/agent-go/a_init/bastion_init/DPSearch.go b/agent-go/a_init/bastion_init/DPSearch.go deleted file mode 100644 index 0feede1..0000000 --- a/agent-go/a_init/bastion_init/DPSearch.go +++ /dev/null @@ -1,91 +0,0 @@ -package bastion_init - -import "strings" - -// 假设我们的预定义字符串列表存储在这个map中,键为字符串索引,值为字符串本身 -var dictionary = map[string]struct{}{ - "apple": {}, - "apply": {}, - "apron": {}, - "docker": {}, - "docker-compose": {}, - "harbor": {}, - // ...其他词汇 -} - -// normalize 将字符串转换为小写并去除特殊符号 -func normalize(s string) string { - return strings.ToLower(strings.ReplaceAll(s, "\\W", "")) -} - -// findBestMatch 在字典中找到最合适的单词 -func findBestMatch(query string) string { - normQuery := normalize(query) - - // 将查询字符串排序,以便二分查找 - sortedQuery := []rune(normQuery) - - var bestMatch string - minDistance := len(dictionary) + 1 // 最初假设没有匹配项 - - // 遍历字典中的所有单词 - for word, _ := range dictionary { - normWord := normalize(word) - distance := levenshteinDistance(sortedQuery, []rune(normWord)) // 计算编辑距离 - - // 如果当前单词的编辑距离小于等于最佳匹配的距离,并且它是第一个匹配项(或者距离相同但字典序更低) - if distance <= minDistance || (distance == minDistance && strings.ToLower(word) < normQuery) { - minDistance = distance - bestMatch = word - } - } - - return bestMatch -} - -// levenshteinDistance 计算两个字符串之间的编辑距离(插入、删除或替换一个字符的次数) -func levenshteinDistance(a, b []rune) int { - lenA := len(a) - lenB := len(b) - - dist := make([][]int, lenA+1) - for i := range dist { - dist[i] = make([]int, lenB+1) - } - - for i := 0; i <= lenA; i++ { - dist[i][0] = i - } - for j := 0; j <= lenB; j++ { - dist[0][j] = j - } - - for i := 1; i <= lenA; i++ { - for j := 1; j <= lenB; j++ { - cost := int(a[i-1] - b[j-1]) - dist[i][j] = minInt(dist[i-1][j]+1, dist[i][j-1]+1, dist[i-1][j-1]+cost) - } - } - - return dist[lenA][lenB] -} - -// minInt 找到三个整数中的最小值 -func minInt(a, b, c int) int { - if a < b { - if a < c { - return a - } - return c - } - if b < c { - return b - } - return c -} - -func main() { - query := "app!" - bestMatch := findBestMatch(query) - println("The best match for", query, "is:", bestMatch) -} diff --git a/agent-go/a_init/bastion_init/TrieSearch.go b/agent-go/a_init/bastion_init/TrieSearch.go index 9151e76..7d48c33 100644 --- a/agent-go/a_init/bastion_init/TrieSearch.go +++ b/agent-go/a_init/bastion_init/TrieSearch.go @@ -33,7 +33,10 @@ func (tn *TrieNode) Insert(word string) { } func (t *Trie) Insert(word string) { + // insert word into trie t.root.Insert(word) + // insert to AllFunction List + BastionFunctionList = append(BastionFunctionList, word) } func (t *Trie) InsertAll(words []string) { for _, word := range words { diff --git a/agent-go/a_init/bastion_init/TrieSearch_test.go b/agent-go/a_init/bastion_init/TrieSearch_test.go index 7eeea37..60f09e4 100644 --- a/agent-go/a_init/bastion_init/TrieSearch_test.go +++ b/agent-go/a_init/bastion_init/TrieSearch_test.go @@ -2,7 +2,6 @@ package bastion_init import ( "fmt" - "syscall" "testing" ) @@ -22,37 +21,5 @@ func TestNewTrie(t *testing.T) { } func TestDp(t *testing.T) { - // 获取netlink接口(用于网络控制的内核机制) - nl := syscall.NewLk(syscall.AT_FDCWD, "netlink") - if nl == nil { - fmt.Println("Unable to open netlink") - return - } - defer nl.Close() - // 设置对netlink的访问权限 - if err := syscall.Setpgid(0, syscall.Getpid()); err != nil { - fmt.Println("Unable to set pgid", err) - return - } - - // 设置netlink接口为非阻塞模式 - if err := nl.Control(syscall.SET_NONBLOCK, 1); err != nil { - fmt.Println("Unable to set netlink nonblocking", err) - return - } - - // 获取IPv4路由转发设置的值 - var value syscall.SysctlValInt - if err := syscall.Sysctl(nl, "net/ipv4/ip_forward", &value); err != nil { - fmt.Println("Unable to get ip_forward value:", err) - return - } - - // 打印IPv4路由转发的状态 - if value == 1 { - fmt.Println("IPv4 routing forwarding is enabled") - } else { - fmt.Println("IPv4 routing forwarding is disabled") - } } diff --git a/agent-go/a_init/bastion_init/config.go b/agent-go/a_init/bastion_init/config.go deleted file mode 100644 index fad48cf..0000000 --- a/agent-go/a_init/bastion_init/config.go +++ /dev/null @@ -1,5 +0,0 @@ -package bastion_init - -func PrintBastionHelp() { - -}