[agent-go] [Bastion] - basic accomplished !

This commit is contained in:
zeaslity
2024-04-18 15:20:19 +08:00
parent 8e43f1f90f
commit 314b6054d3
14 changed files with 467 additions and 204 deletions

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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")

View File

@@ -110,3 +110,12 @@ OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target
`
var DockerDeamonConfig = `
{
"insecure-registries": [
"DockerRegisterDomain:8033",
"harbor.wdd.io:8033"
]
}
`

View File

@@ -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
`