[agent-go] [Bastion] - basic accomplished !
This commit is contained in:
@@ -233,11 +233,13 @@ func (op *AgentOsOperator) shutdownFirewallExec() (bool, []string) {
|
|||||||
{"iptables", "-F"},
|
{"iptables", "-F"},
|
||||||
}
|
}
|
||||||
// 忽略错误
|
// 忽略错误
|
||||||
_, resultLog := AllCompleteExecutor(shutdownFunc)
|
AllCompleteExecutor(shutdownFunc)
|
||||||
|
|
||||||
// centos
|
// centos
|
||||||
|
|
||||||
return true, resultLog
|
return true, []string{
|
||||||
|
"[shutdownFirewallExec] - 关闭防火墙成功!",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *AgentOsOperator) modifyHostname(args []string) [][]string {
|
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) {
|
func (op *AgentOsOperator) modifySystemConfigExec() (bool, []string) {
|
||||||
|
sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf"
|
||||||
|
|
||||||
// ssh config
|
// ssh config
|
||||||
// system redirection
|
// 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
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *AgentOsOperator) ModifySysConfigBastion() (bool, []string) {
|
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 {
|
func (op *AgentOsOperator) enableSwap() [][]string {
|
||||||
@@ -370,7 +402,9 @@ func (op *AgentOsOperator) disableSELinuxExec() (bool, []string) {
|
|||||||
"0",
|
"0",
|
||||||
})
|
})
|
||||||
|
|
||||||
return true, []string{}
|
return true, []string{
|
||||||
|
"[disableSELinuxExec] - success",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *AgentOsOperator) DisableSelinuxBastion() (bool, []string) {
|
func (op *AgentOsOperator) DisableSelinuxBastion() (bool, []string) {
|
||||||
@@ -417,7 +451,9 @@ func (op *AgentOsOperator) installDefaultSSHKeyExec(funcArgs []string) (bool, []
|
|||||||
|
|
||||||
// check
|
// check
|
||||||
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
|
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{
|
return false, []string{
|
||||||
@@ -444,7 +480,7 @@ func (op *AgentOsOperator) InstallDefaultSshBastion() (bool, []string) {
|
|||||||
"[installDefaultSSHKeyExec] - error appending private ssh key to authorized_keys !",
|
"[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{
|
return false, []string{
|
||||||
"[installDefaultSSHKeyExec] - error appending public ssh key to authorized_keys !",
|
"[installDefaultSSHKeyExec] - error appending public ssh key to authorized_keys !",
|
||||||
}
|
}
|
||||||
@@ -466,7 +502,9 @@ func (op *AgentOsOperator) InstallDefaultSshBastion() (bool, []string) {
|
|||||||
// check
|
// check
|
||||||
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
|
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
|
||||||
log.Info("installDefaultSSHKeyExec - authorized_keys contain the ssh-pub key !")
|
log.Info("installDefaultSSHKeyExec - authorized_keys contain the ssh-pub key !")
|
||||||
return true, nil
|
return true, []string{
|
||||||
|
"[InstallDefaultSshBastion] - install success !",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, []string{
|
return false, []string{
|
||||||
@@ -504,6 +542,12 @@ func (op *AgentOsOperator) removeDocker() [][]string {
|
|||||||
|
|
||||||
func (op *AgentOsOperator) removeDockerExec() (bool, []string) {
|
func (op *AgentOsOperator) removeDockerExec() (bool, []string) {
|
||||||
|
|
||||||
|
if !BasicCommandExistByPath("docker") {
|
||||||
|
return true, []string{
|
||||||
|
"[removeDockerExec] - docker is not installed !",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dockerServiceStopCommand := [][]string{
|
dockerServiceStopCommand := [][]string{
|
||||||
{
|
{
|
||||||
"systemctl",
|
"systemctl",
|
||||||
@@ -1236,13 +1280,13 @@ func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) {
|
|||||||
|
|
||||||
var DockerComposeFile string
|
var DockerComposeFile string
|
||||||
if strings.HasPrefix(op.AgentArch, "amd") {
|
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") {
|
} 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
|
// check file exits
|
||||||
if !BasicFileExistInFolder(DockerComposeFile) {
|
if !BasicFileExistAndNotNull(DockerComposeFile) {
|
||||||
sprintf := fmt.Sprintf("docker-compose 离线安装文件不存在! => %s", DockerComposeFile)
|
sprintf := fmt.Sprintf("docker-compose 离线安装文件不存在! => %s", DockerComposeFile)
|
||||||
return false, []string{
|
return false, []string{
|
||||||
sprintf,
|
sprintf,
|
||||||
@@ -1250,6 +1294,11 @@ func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AllCompleteExecutor([][]string{
|
AllCompleteExecutor([][]string{
|
||||||
|
{
|
||||||
|
"mv",
|
||||||
|
DockerComposeFile,
|
||||||
|
"/usr/local/bin/docker-compose",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"chmod", "+x", "/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安装成功!")
|
log.Info("docker-compose安装成功!")
|
||||||
|
|
||||||
|
if !BasicCommandExistByPath("docker-compose") {
|
||||||
|
return false, []string{
|
||||||
|
"[InstallDockerComposeBastion] - docker-compose 安装失败!",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true, []string{
|
return true, []string{
|
||||||
"[InstallDockerComposeBastion] - docker-compose offline installation from local success!",
|
"[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) {
|
func (op *AgentOsOperator) ModifyDockerConfigBastion() (bool, []string) {
|
||||||
|
|
||||||
argList := []string{
|
dockerDaemonFile := "/etc/docker/daemon.json"
|
||||||
"127.0.0.1",
|
// check docker daemon json exist
|
||||||
}
|
if BasicFileExistAndNotNull(dockerDaemonFile) {
|
||||||
return op.modifyDockerConfigExec(argList)
|
AllCommandExecutor([]string{
|
||||||
|
"mv",
|
||||||
|
dockerDaemonFile,
|
||||||
|
"/etc/docker/daemon-json.backup",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
func (op *AgentOsOperator) modifyDockerConfigExec(args []string) (bool, []string) {
|
||||||
|
|
||||||
dockerDaemonFile := "/etc/docker/daemon.json"
|
dockerDaemonFile := "/etc/docker/daemon.json"
|
||||||
@@ -1438,7 +1527,7 @@ func (op *AgentOsOperator) installNfsOnlineExec() (bool, []string) {
|
|||||||
if op.IsOsTypeUbuntu {
|
if op.IsOsTypeUbuntu {
|
||||||
|
|
||||||
// ubuntu
|
// ubuntu
|
||||||
installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, false,
|
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, false,
|
||||||
"nfs-common", "nfs-client", "nfs")
|
"nfs-common", "nfs-client", "nfs")
|
||||||
if !installOk {
|
if !installOk {
|
||||||
return false, installLog
|
return false, installLog
|
||||||
@@ -1451,7 +1540,7 @@ func (op *AgentOsOperator) installNfsOnlineExec() (bool, []string) {
|
|||||||
} else if op.IsOsTypeCentOS {
|
} else if op.IsOsTypeCentOS {
|
||||||
|
|
||||||
// centos
|
// centos
|
||||||
installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, false,
|
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, false,
|
||||||
"nfs-utils")
|
"nfs-utils")
|
||||||
if !installOk {
|
if !installOk {
|
||||||
return false, installLog
|
return false, installLog
|
||||||
@@ -1547,7 +1636,7 @@ func (op *AgentOsOperator) installNfsServerOnlineExec() (bool, []string) {
|
|||||||
// os
|
// os
|
||||||
if op.IsOsTypeUbuntu {
|
if op.IsOsTypeUbuntu {
|
||||||
// ubuntu
|
// ubuntu
|
||||||
installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, true, "nfs-kernel-server",
|
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, true, "nfs-kernel-server",
|
||||||
"nfs-common")
|
"nfs-common")
|
||||||
if !installOk {
|
if !installOk {
|
||||||
return false, installLog
|
return false, installLog
|
||||||
@@ -1563,7 +1652,7 @@ func (op *AgentOsOperator) installNfsServerOnlineExec() (bool, []string) {
|
|||||||
|
|
||||||
} else if op.IsOsTypeCentOS {
|
} else if op.IsOsTypeCentOS {
|
||||||
// ubuntu
|
// ubuntu
|
||||||
installOk, installLog := BasicInstallSoftwares(op.InstallCommandPrefix, true, "nfs-utils")
|
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, true, "nfs-utils")
|
||||||
if !installOk {
|
if !installOk {
|
||||||
return false, installLog
|
return false, installLog
|
||||||
}
|
}
|
||||||
@@ -1762,7 +1851,7 @@ func (op *AgentOsOperator) installHarbor() [][]string {
|
|||||||
}
|
}
|
||||||
func (op *AgentOsOperator) checkHarborInstallExec() (bool, []string) {
|
func (op *AgentOsOperator) checkHarborInstallExec() (bool, []string) {
|
||||||
// check docker-compose
|
// check docker-compose
|
||||||
if !BasicCommandExistByPath("/usr/local/bin/docker-compose") {
|
if !BasicCommandExistByPath("docker-compose") {
|
||||||
return false, []string{
|
return false, []string{
|
||||||
"[install harbor] - docker-compose uninstalled ! can't install harbor!",
|
"[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
|
// installHarborExec install harbor offline
|
||||||
@@ -1912,7 +2003,8 @@ func (op *AgentOsOperator) InstallHarborBastion() (bool, []string) {
|
|||||||
|
|
||||||
// local file check exists
|
// local file check exists
|
||||||
if !BasicFileExistAndNotNull("/root/wdd/harbor-offline-installer-v2.9.0.tgz") {
|
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
|
// unzip
|
||||||
@@ -2350,7 +2442,7 @@ func (op *AgentOsOperator) chronyToMasterExec(args []string) (bool, []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// install ntp
|
// install ntp
|
||||||
installSoftwares, i := BasicInstallSoftwares(op.InstallCommandPrefix, true, "ntp")
|
installSoftwares, i := BasicInstallSoftware(op.InstallCommandPrefix, true, "ntp")
|
||||||
if !installSoftwares {
|
if !installSoftwares {
|
||||||
msg := "[chronyToMasterExec] - centos install ntp error!"
|
msg := "[chronyToMasterExec] - centos install ntp error!"
|
||||||
log.ErrorF(msg)
|
log.ErrorF(msg)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package a_executor
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
"io"
|
"io"
|
||||||
@@ -10,6 +11,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,6 +29,7 @@ func BasicCommandExists(commandName string) bool {
|
|||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicCommandExistsBatch 判定批量命令是否存在
|
// BasicCommandExistsBatch 判定批量命令是否存在
|
||||||
@@ -43,7 +47,7 @@ func BasicCommandExistsBatch(commandNameList []string) (bool, string) {
|
|||||||
// BasicCommandExistByPath 根据路径判定 命令是否存在
|
// BasicCommandExistByPath 根据路径判定 命令是否存在
|
||||||
func BasicCommandExistByPath(commandName string) bool {
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +57,14 @@ func BasicCommandExistByPath(commandName string) bool {
|
|||||||
// BasicFileExistInFolder 查询fileName是否存在于目录folderList中,如果存在返回true,不存在返回false
|
// BasicFileExistInFolder 查询fileName是否存在于目录folderList中,如果存在返回true,不存在返回false
|
||||||
func BasicFileExistInFolder(fileName string, folderList ...string) bool {
|
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 {
|
for _, folder := range folderList {
|
||||||
|
if folder == "" {
|
||||||
|
continue // Skip empty folders.
|
||||||
|
}
|
||||||
if BasicFolderExists(folder) {
|
if BasicFolderExists(folder) {
|
||||||
// is folder
|
// is folder
|
||||||
ok, _ := PipelineCommandExecutor([][]string{
|
ok, _ := PipelineCommandExecutor([][]string{
|
||||||
@@ -71,22 +82,6 @@ func BasicFileExistInFolder(fileName string, folderList ...string) bool {
|
|||||||
return true
|
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
|
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
|
var installLog []string
|
||||||
|
|
||||||
for _, software := range softwares {
|
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)) {
|
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)
|
installLog = append(installLog, failedInstall)
|
||||||
|
|
||||||
if isStrict {
|
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)
|
installLog = append(installLog, successInstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, installLog
|
return true, installLog
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicReplace 基础替换命令
|
// BasicReplace 将文件中origin字段全部替换为replace
|
||||||
func BasicReplace(filename string, origin string, replace string) bool {
|
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) {
|
//if !BasicFileExistAndNotNull(filename) {
|
||||||
// log.DebugF("文件替换")
|
// log.DebugF("文件替换")
|
||||||
@@ -305,57 +374,91 @@ func BasicReplace(filename string, origin string, replace string) bool {
|
|||||||
|
|
||||||
func BasicRemoveFolderComplete(folderName string) bool {
|
func BasicRemoveFolderComplete(folderName string) bool {
|
||||||
|
|
||||||
if !BasicFileExists(folderName) || !BasicFolderExists(folderName) {
|
err := filepath.Walk(folderName,
|
||||||
log.DebugF("[BasicRemoveFolderComplete] - file or folder of [%s] not exists !", folderName)
|
func(path string, info os.FileInfo, err error) error {
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command("rm", "-rf", folderName)
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.DebugF("删除 %s 失败!", folderName)
|
return err
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return os.Remove(path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
err = os.RemoveAll(folderName)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicFileExists 检测文件是否存在
|
// BasicFileExists 检测文件是否存在
|
||||||
func BasicFileExists(filename string) bool {
|
func BasicFileExists(filename string) bool {
|
||||||
|
|
||||||
cmd := exec.Command("test", "-f", filename)
|
if filename == "" {
|
||||||
err := cmd.Run()
|
return false // An empty string does not correspond to a valid file.
|
||||||
|
}
|
||||||
|
_, err := os.Stat(filename)
|
||||||
if err != nil {
|
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)
|
log.DebugF("文件 %s 不存在!", filename)
|
||||||
return false
|
return false
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
case nil:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
// Handle other types of errors as appropriate for your use case.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicFileExistAndNotNull 文件不为空返回true 文件为空返回false
|
// BasicFileExistAndNotNull 文件不为空返回true 文件为空返回false
|
||||||
func BasicFileExistAndNotNull(filename string) bool {
|
func BasicFileExistAndNotNull(filename string) bool {
|
||||||
|
|
||||||
cmd := exec.Command("test", "-s", filename)
|
// Check if the file exists
|
||||||
err := cmd.Run()
|
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||||
if err != nil {
|
log.DebugF("文件 %s 不存在!", filename)
|
||||||
log.DebugF("文件 %s 为空!", filename)
|
|
||||||
return false
|
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 {
|
func BasicFolderExists(folderName string) bool {
|
||||||
|
|
||||||
cmd := exec.Command("test", "-d", folderName)
|
fi, err := os.Stat(folderName)
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.DebugF("目录 %s 不存在!", folderName)
|
if os.IsNotExist(err) {
|
||||||
|
// 目标路径不存在
|
||||||
|
log.WarnF("[BasicFolderExists] - 目录 %s 不存在!", folderName)
|
||||||
return false
|
return false
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
// 其他错误
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否为目录
|
||||||
|
return fi.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
func BasicCreateFolder(folderName string) bool {
|
func BasicCreateFolder(folderName string) bool {
|
||||||
|
|||||||
@@ -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) {
|
func TestBasicReplaceFileNotExists(t *testing.T) {
|
||||||
|
|
||||||
replace := BasicReplace(noExistFilePath, "123", "123")
|
replace := BasicReplace(noExistFilePath, "123", "123")
|
||||||
|
|||||||
@@ -110,3 +110,12 @@ OOMScoreAdjust=-500
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var DockerDeamonConfig = `
|
||||||
|
{
|
||||||
|
"insecure-registries": [
|
||||||
|
"DockerRegisterDomain:8033",
|
||||||
|
"harbor.wdd.io:8033"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|||||||
@@ -13,3 +13,61 @@ KGhIhJXbSwuJdk9k994vAAAADHdkZEBjbWlpLmNvbQE=
|
|||||||
var Ed25519PublicKey = `
|
var Ed25519PublicKey = `
|
||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOTxHgpcaANrkfavweupbWSVKGhIhJXbSwuJdk9k994v wdd@cmii.com
|
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
|
||||||
|
`
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"wdd.io/agent-common/logger"
|
"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) {
|
func refreshAgentInfoByStatusInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) {
|
||||||
|
|
||||||
|
// host info
|
||||||
agentServerInfo.Platform = agentInfo.HostInfo.Platform
|
agentServerInfo.Platform = agentInfo.HostInfo.Platform
|
||||||
agentServerInfo.PlatformFamily = agentInfo.HostInfo.PlatformFamily
|
agentServerInfo.PlatformFamily = agentInfo.HostInfo.PlatformFamily
|
||||||
agentServerInfo.PlatformVersion = agentInfo.HostInfo.PlatformVersion
|
agentServerInfo.PlatformVersion = agentInfo.HostInfo.PlatformVersion
|
||||||
agentServerInfo.KernelVersion = agentInfo.HostInfo.KernelVersion
|
agentServerInfo.KernelVersion = agentInfo.HostInfo.KernelVersion
|
||||||
agentServerInfo.KernelArch = agentInfo.HostInfo.KernelArch
|
agentServerInfo.KernelArch = agentInfo.HostInfo.KernelArch
|
||||||
|
|
||||||
|
// network part
|
||||||
|
refreshAgentNetworkInfo(agentInfo, agentServerInfo)
|
||||||
|
|
||||||
log.DebugF("[refreshAgentInfoByStatusInfo] - ok !")
|
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接收的 注册信息
|
// handleInitMsgFromServer 处理从Server接收的 注册信息
|
||||||
func handleInitMsgFromServer(initFromServerMsg *rabbitmq.OctopusMessage, initToServerQueue *rabbitmq.RabbitQueue, agentServerInfo *a_agent.AgentServerInfo) bool {
|
func handleInitMsgFromServer(initFromServerMsg *rabbitmq.OctopusMessage, initToServerQueue *rabbitmq.RabbitQueue, agentServerInfo *a_agent.AgentServerInfo) bool {
|
||||||
|
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ func BastionModeInit() {
|
|||||||
// Build For Operator
|
// Build For Operator
|
||||||
bastionAgentServerInfo := &a_agent.AgentServerInfo{
|
bastionAgentServerInfo := &a_agent.AgentServerInfo{
|
||||||
ServerName: "BastionSingle",
|
ServerName: "BastionSingle",
|
||||||
ServerIPPbV4: "127.0.0.1",
|
ServerIPPbV4: "",
|
||||||
ServerIPInV4: "127.0.0.1",
|
ServerIPInV4: "",
|
||||||
ServerIPPbV6: "",
|
ServerIPPbV6: "",
|
||||||
ServerIPInV6: "",
|
ServerIPInV6: "",
|
||||||
Location: "Bastion",
|
Location: "Bastion",
|
||||||
@@ -167,6 +167,12 @@ func buildBastionModeFunction() {
|
|||||||
tcc.Insert(InstallDocker)
|
tcc.Insert(InstallDocker)
|
||||||
tcc.Insert(InstallDockerCompose)
|
tcc.Insert(InstallDockerCompose)
|
||||||
tcc.Insert(InstallMinio)
|
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(InstallHarbor)
|
||||||
tcc.Insert(RemoveDocker)
|
tcc.Insert(RemoveDocker)
|
||||||
tcc.Insert(Help)
|
tcc.Insert(Help)
|
||||||
|
|||||||
49
agent-go/a_init/bastion_init/123.txt
Normal file
49
agent-go/a_init/bastion_init/123.txt
Normal file
@@ -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
|
||||||
14
agent-go/a_init/bastion_init/BastionHelp.go
Normal file
14
agent-go/a_init/bastion_init/BastionHelp.go
Normal file
@@ -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()
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
package bastion_init
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -33,7 +33,10 @@ func (tn *TrieNode) Insert(word string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trie) Insert(word string) {
|
func (t *Trie) Insert(word string) {
|
||||||
|
// insert word into trie
|
||||||
t.root.Insert(word)
|
t.root.Insert(word)
|
||||||
|
// insert to AllFunction List
|
||||||
|
BastionFunctionList = append(BastionFunctionList, word)
|
||||||
}
|
}
|
||||||
func (t *Trie) InsertAll(words []string) {
|
func (t *Trie) InsertAll(words []string) {
|
||||||
for _, word := range words {
|
for _, word := range words {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package bastion_init
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,37 +21,5 @@ func TestNewTrie(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDp(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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package bastion_init
|
|
||||||
|
|
||||||
func PrintBastionHelp() {
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user