Add base system configuration commands for agent-wdd
- Implemented new base commands for system configuration: * swap: Disable system swap * selinux: Disable SELinux * firewall: Stop and disable firewalld and ufw * sysconfig: Modify system sysctl configuration * ssh: Add SSH-related subcommands (key, port, config) - Updated Config.go to initialize ConfigCache with default values - Added new utility functions in FileUtils.go for file content manipulation - Extended Excutor.go with HardCodeCommandExecutor method
This commit is contained in:
@@ -52,6 +52,124 @@ func addBaseSubcommands(cmd *cobra.Command) {
|
|||||||
addDockerComposeSubcommands(dockerComposeCmd)
|
addDockerComposeSubcommands(dockerComposeCmd)
|
||||||
|
|
||||||
// 其他base子命令...
|
// 其他base子命令...
|
||||||
|
swapCmd := &cobra.Command{
|
||||||
|
Use: "swap",
|
||||||
|
Short: "关闭系统的Swap",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("Swap 关闭!")
|
||||||
|
// 实现这个函数,能够关闭centos或者ubuntu系统的swap
|
||||||
|
|
||||||
|
// 备份文件存在,pass
|
||||||
|
if !utils.FileExistAndNotNull("/etc/fstab_back_wdd_swap") {
|
||||||
|
utils.AppendOverwriteContentToFile(
|
||||||
|
"/etc/fstab",
|
||||||
|
"/etc/fstab_back_wdd_swap",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// 执行关闭操作
|
||||||
|
op.SingleLineCommandExecutor([]string{
|
||||||
|
"swapoff",
|
||||||
|
"-a",
|
||||||
|
})
|
||||||
|
|
||||||
|
op.SingleLineCommandExecutor([]string{
|
||||||
|
"sed",
|
||||||
|
"-i",
|
||||||
|
"/swap/d",
|
||||||
|
"/etc/fstab",
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Info("Swap 关闭成功!")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
selinuxCmd := &cobra.Command{
|
||||||
|
Use: "selinux",
|
||||||
|
Short: "关闭selinux",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("Selinux 关闭!")
|
||||||
|
|
||||||
|
// 如果configCache的OS为空,则收集OS信息
|
||||||
|
if config.ConfigCache.Agent.OS.Hostname == "" {
|
||||||
|
log.Warning("ConfigCache OS is nil")
|
||||||
|
config.ConfigCache.Agent.OS.Gather()
|
||||||
|
config.ConfigCache.Agent.OS.SaveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
os := config.ConfigCache.Agent.OS
|
||||||
|
if os.IsUbuntuType {
|
||||||
|
log.Info("Ubuntu 系统,跳过关闭selinux!")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
op.SingleLineCommandExecutor([]string{
|
||||||
|
"setenforce",
|
||||||
|
"0",
|
||||||
|
})
|
||||||
|
|
||||||
|
// 备份一下/etc/selinux/config
|
||||||
|
if !utils.FileExistAndNotNull("/etc/selinux/config_back_wdd_selinux") {
|
||||||
|
utils.AppendOverwriteContentToFile(
|
||||||
|
"/etc/selinux/config",
|
||||||
|
"/etc/selinux/config_back_wdd_selinux",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 持久化关闭selinux
|
||||||
|
utils.FindAndDeleteContentInFile("SELINUX=enforcing", "/etc/selinux/config")
|
||||||
|
utils.FindAndDeleteContentInFile("SELINUX=permissive", "/etc/selinux/config")
|
||||||
|
utils.FindAndDeleteContentInFile("SELINUX=disabled", "/etc/selinux/config")
|
||||||
|
utils.AppendContentToFile("SELINUX=disabled", "/etc/selinux/config")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Selinux 关闭成功!")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
firewallCmd := &cobra.Command{
|
||||||
|
Use: "firewall",
|
||||||
|
Short: "关闭防火墙",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("Firewall 关闭!")
|
||||||
|
|
||||||
|
// 调用systemd关闭firewalld
|
||||||
|
op.SystemdDown("firewalld")
|
||||||
|
op.SystemdDisable("firewalld")
|
||||||
|
// 调用systemd关闭ufw
|
||||||
|
op.SystemdDown("ufw")
|
||||||
|
op.SystemdDisable("ufw")
|
||||||
|
|
||||||
|
// 清空路由表
|
||||||
|
log.Info("清空路由表...")
|
||||||
|
op.HardCodeCommandExecutor("iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -t raw -F")
|
||||||
|
op.HardCodeCommandExecutor("ip6tables -F && ip6tables -t nat -F && ip6tables -t mangle -F && ip6tables -t raw -F")
|
||||||
|
|
||||||
|
log.Info("Firewall 关闭成功!")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sysconfigCmd := &cobra.Command{
|
||||||
|
Use: "sysconfig",
|
||||||
|
Short: "修改系统的sysconfig",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("Sysconfig 修改!")
|
||||||
|
|
||||||
|
// 修改系统的sysconfig
|
||||||
|
sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf"
|
||||||
|
|
||||||
|
if !utils.AppendOverwriteContentToFile(beans.SysctlConfig, sysctlConfigFile) {
|
||||||
|
log.Error("[ModifySysConfigBastion] - error appending sysctl config to sysctl.d !")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
op.SingleLineCommandExecutor([]string{
|
||||||
|
"sysctl",
|
||||||
|
"-p",
|
||||||
|
sysctlConfigFile,
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Info("Sysconfig 修改成功!")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// 通用工具安装
|
// 通用工具安装
|
||||||
commonToolsInstall := &cobra.Command{
|
commonToolsInstall := &cobra.Command{
|
||||||
@@ -80,14 +198,134 @@ func addBaseSubcommands(cmd *cobra.Command) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sshCmd := &cobra.Command{
|
||||||
|
Use: "ssh",
|
||||||
|
Short: "修改ssh配置",
|
||||||
|
}
|
||||||
|
addSSHSubcommands(sshCmd)
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
dockerCmd,
|
dockerCmd,
|
||||||
dockerComposeCmd,
|
dockerComposeCmd,
|
||||||
|
swapCmd,
|
||||||
commonToolsInstall,
|
commonToolsInstall,
|
||||||
|
selinuxCmd,
|
||||||
|
firewallCmd,
|
||||||
|
sysconfigCmd,
|
||||||
|
sshCmd,
|
||||||
// 其他命令...
|
// 其他命令...
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addSSHSubcommands(sshCmd *cobra.Command) {
|
||||||
|
keyCmd := &cobra.Command{
|
||||||
|
Use: "key",
|
||||||
|
Short: "安装默认的ssh-key",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("安装默认的ssh-key!")
|
||||||
|
|
||||||
|
// 创建.ssh目录
|
||||||
|
utils.CreateFolder("/root/.ssh")
|
||||||
|
|
||||||
|
// 检查密钥是否存在
|
||||||
|
if utils.FileExistAndNotNull("/root/.ssh/id_ed25519") &&
|
||||||
|
utils.FileExistAndNotNull("/root/.ssh/id_ed25519.pub") &&
|
||||||
|
utils.FindContentInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
|
||||||
|
log.Info("SSH密钥已存在,无需重新安装。")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载标准的私钥和公钥
|
||||||
|
if !utils.AppendOverwriteContentToFile(beans.Ed25519PrivateKey, "/root/.ssh/id_ed25519") {
|
||||||
|
log.Error("[InstallDefaultSSHKey] - error appending private ssh key to authorized_keys !")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !utils.AppendOverwriteContentToFile(beans.Ed25519PublicKey, "/root/.ssh/id_ed25519.pub") {
|
||||||
|
log.Error("[InstallDefaultSSHKey] - error appending public ssh key to authorized_keys !")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入到authorized_keys
|
||||||
|
if !utils.AppendFileToFile("/root/.ssh/id_ed25519.pub", "/root/.ssh/authorized_keys") {
|
||||||
|
log.Error("[InstallDefaultSSHKey] - error appending ssh key to authorized_keys !")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置权限
|
||||||
|
op.SingleLineCommandExecutor([]string{
|
||||||
|
"chmod",
|
||||||
|
"600",
|
||||||
|
"/root/.ssh/id_ed25519",
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检查
|
||||||
|
if utils.FindContentInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
|
||||||
|
log.Info("[InstallDefaultSSHKey] - install success !")
|
||||||
|
} else {
|
||||||
|
log.Error("[InstallDefaultSSHKey] - authorized_keys don't contain the ssh-pub key !")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
portCmd := &cobra.Command{
|
||||||
|
Use: "port",
|
||||||
|
Short: "修改ssh端口",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("修改ssh端口!")
|
||||||
|
|
||||||
|
// 检查参数
|
||||||
|
if len(args) > 0 {
|
||||||
|
fmt.Printf("modify ssh port to: %s\n", args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有传递参数,使用默认参数
|
||||||
|
port := "22333"
|
||||||
|
log.Info("[ModifySSHPort] modify ssh port to: %s", port)
|
||||||
|
|
||||||
|
// 修改ssh端口
|
||||||
|
utils.AppendContentToFile(fmt.Sprintf("Port %s", port), "/etc/ssh/sshd_config")
|
||||||
|
|
||||||
|
// 重启ssh服务
|
||||||
|
ok, resultLog := op.SystemdRestart("sshd")
|
||||||
|
if !ok {
|
||||||
|
log.Error("[ModifySSHPort] restart sshd error: %s", resultLog)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("[ModifySSHPort] modify ssh port to: %s success!", port)
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
configCmd := &cobra.Command{
|
||||||
|
Use: "config",
|
||||||
|
Short: "修改ssh配置 为wdd默认配置!",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
log.Info("修改ssh配置 为wdd默认配置!")
|
||||||
|
|
||||||
|
// 备份文件
|
||||||
|
if !utils.FileExistAndNotNull("/etc/ssh/sshd_config_back_wdd_ssh") {
|
||||||
|
utils.AppendOverwriteContentToFile("/etc/ssh/sshd_config", "/etc/ssh/sshd_config_back_wdd_ssh")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改ssh配置
|
||||||
|
utils.AppendContentToFile(beans.DefaultSshdConfig, "/etc/ssh/sshd_config")
|
||||||
|
|
||||||
|
// 重启ssh服务
|
||||||
|
ok, resultLog := op.SystemdRestart("sshd")
|
||||||
|
if !ok {
|
||||||
|
log.Error("sshd 重启失败: %s", resultLog)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("[sshd配置修改] 成功!")
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sshCmd.AddCommand(keyCmd, portCmd, configCmd)
|
||||||
|
}
|
||||||
|
|
||||||
// 添加docker子命令
|
// 添加docker子命令
|
||||||
func addDockerSubcommands(cmd *cobra.Command) {
|
func addDockerSubcommands(cmd *cobra.Command) {
|
||||||
onlineCmd := &cobra.Command{
|
onlineCmd := &cobra.Command{
|
||||||
|
|||||||
203
agent-wdd/cmd/beans/SshSysConfig.go
Normal file
203
agent-wdd/cmd/beans/SshSysConfig.go
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
package beans
|
||||||
|
|
||||||
|
var Ed25519PrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||||
|
QyNTUxOQAAACDk8R4KXGgDa5H2r8HrqW1klShoSISV20sLiXZPZPfeLwAAAJCIan+LiGp/
|
||||||
|
iwAAAAtzc2gtZWQyNTUxOQAAACDk8R4KXGgDa5H2r8HrqW1klShoSISV20sLiXZPZPfeLw
|
||||||
|
AAAEDhnul+q0TNTgrO9kfmGsFhtn/rGRIrmhFostjem/QlZuTxHgpcaANrkfavweupbWSV
|
||||||
|
KGhIhJXbSwuJdk9k994vAAAADHdkZEBjbWlpLmNvbQE=
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
|
||||||
|
var Ed25519PublicKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOTxHgpcaANrkfavweupbWSVKGhIhJXbSwuJdk9k994v wdd@cmii.com
|
||||||
|
`
|
||||||
|
|
||||||
|
var DefaultSshdConfig = `
|
||||||
|
# OCTOPUS AGENT DEFAULT SSHD CONFIG - WDD
|
||||||
|
|
||||||
|
# This is the sshd server system-wide configuration file. See
|
||||||
|
# sshd_config(5) for more information.
|
||||||
|
|
||||||
|
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
# The strategy used for options in the default sshd_config shipped with
|
||||||
|
# OpenSSH is to specify options with their default value where
|
||||||
|
# possible, but leave them commented. Uncommented options override the
|
||||||
|
# default value.
|
||||||
|
|
||||||
|
#Include /etc/ssh/sshd_config.d/*.conf
|
||||||
|
|
||||||
|
Port 22
|
||||||
|
Port 22333
|
||||||
|
AddressFamily any
|
||||||
|
ListenAddress 0.0.0.0
|
||||||
|
ListenAddress ::
|
||||||
|
|
||||||
|
#HostKey /etc/ssh/ssh_host_rsa_key
|
||||||
|
#HostKey /etc/ssh/ssh_host_ecdsa_key
|
||||||
|
#HostKey /etc/ssh/ssh_host_ed25519_key
|
||||||
|
|
||||||
|
# Ciphers and keying
|
||||||
|
#RekeyLimit default none
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
#SyslogFacility AUTH
|
||||||
|
#LogLevel INFO
|
||||||
|
|
||||||
|
# Authentication:
|
||||||
|
|
||||||
|
#LoginGraceTime 2m
|
||||||
|
#PermitRootLogin prohibit-password
|
||||||
|
#StrictModes yes
|
||||||
|
#MaxAuthTries 6
|
||||||
|
#MaxSessions 10
|
||||||
|
|
||||||
|
#PubkeyAuthentication yes
|
||||||
|
|
||||||
|
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
|
||||||
|
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
|
||||||
|
|
||||||
|
#AuthorizedPrincipalsFile none
|
||||||
|
|
||||||
|
#AuthorizedKeysCommand none
|
||||||
|
#AuthorizedKeysCommandUser nobody
|
||||||
|
|
||||||
|
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
||||||
|
#HostbasedAuthentication no
|
||||||
|
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
||||||
|
# HostbasedAuthentication
|
||||||
|
#IgnoreUserKnownHosts no
|
||||||
|
# Don't read the user's ~/.rhosts and ~/.shosts files
|
||||||
|
#IgnoreRhosts yes
|
||||||
|
|
||||||
|
# To disable tunneled clear text passwords, change to no here!
|
||||||
|
#PasswordAuthentication yes
|
||||||
|
PermitEmptyPasswords no
|
||||||
|
|
||||||
|
# Change to yes to enable challenge-response passwords (beware issues with
|
||||||
|
# some PAM modules and threads)
|
||||||
|
ChallengeResponseAuthentication no
|
||||||
|
|
||||||
|
# Kerberos options
|
||||||
|
#KerberosAuthentication no
|
||||||
|
#KerberosOrLocalPasswd yes
|
||||||
|
#KerberosTicketCleanup yes
|
||||||
|
#KerberosGetAFSToken no
|
||||||
|
|
||||||
|
# GSSAPI options
|
||||||
|
#GSSAPIAuthentication no
|
||||||
|
#GSSAPICleanupCredentials yes
|
||||||
|
#GSSAPIStrictAcceptorCheck yes
|
||||||
|
#GSSAPIKeyExchange no
|
||||||
|
|
||||||
|
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||||
|
# and session processing. If this is enabled, PAM authentication will
|
||||||
|
# be allowed through the ChallengeResponseAuthentication and
|
||||||
|
# PasswordAuthentication. Depending on your PAM configuration,
|
||||||
|
# PAM authentication via ChallengeResponseAuthentication may bypass
|
||||||
|
# the setting of "PermitRootLogin without-password".
|
||||||
|
# If you just want the PAM account and session checks to run without
|
||||||
|
# PAM authentication, then enable this but set PasswordAuthentication
|
||||||
|
# and ChallengeResponseAuthentication to 'no'.
|
||||||
|
UsePAM yes
|
||||||
|
|
||||||
|
AllowAgentForwarding yes
|
||||||
|
AllowTcpForwarding yes
|
||||||
|
#GatewayPorts no
|
||||||
|
X11Forwarding yes
|
||||||
|
#X11DisplayOffset 10
|
||||||
|
#X11UseLocalhost yes
|
||||||
|
#PermitTTY yes
|
||||||
|
PrintMotd no
|
||||||
|
#PrintLastLog yes
|
||||||
|
TCPKeepAlive yes
|
||||||
|
#PermitUserEnvironment no
|
||||||
|
#Compression delayed
|
||||||
|
#ClientAliveInterval 0
|
||||||
|
#ClientAliveCountMax 3
|
||||||
|
#UseDNS no
|
||||||
|
#PidFile /var/run/sshd.pid
|
||||||
|
#MaxStartups 10:30:100
|
||||||
|
#PermitTunnel no
|
||||||
|
#ChrootDirectory none
|
||||||
|
#VersionAddendum none
|
||||||
|
|
||||||
|
# no default banner path
|
||||||
|
#Banner none
|
||||||
|
|
||||||
|
# Allow client to pass locale environment variables
|
||||||
|
AcceptEnv LANG LC_*
|
||||||
|
|
||||||
|
# override default of no subsystems
|
||||||
|
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||||
|
|
||||||
|
# Example of overriding settings on a per-user basis
|
||||||
|
#Match User anoncvs
|
||||||
|
# X11Forwarding no
|
||||||
|
# AllowTcpForwarding no
|
||||||
|
# PermitTTY no
|
||||||
|
# ForceCommand cvs server
|
||||||
|
PasswordAuthentication yes
|
||||||
|
PermitRootLogin yes
|
||||||
|
StrictModes no
|
||||||
|
ClientAliveInterval 30
|
||||||
|
ClientAliveCountMax 60
|
||||||
|
`
|
||||||
|
|
||||||
|
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
|
||||||
|
`
|
||||||
@@ -12,7 +12,19 @@ import (
|
|||||||
|
|
||||||
var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml"
|
var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml"
|
||||||
|
|
||||||
var ConfigCache *Config
|
// ConfigCache 配置缓存
|
||||||
|
var ConfigCache = &Config{
|
||||||
|
TimeStamp: "",
|
||||||
|
ModifiedTimes: 0,
|
||||||
|
Agent: Agent{
|
||||||
|
OS: OS{},
|
||||||
|
Network: Network{},
|
||||||
|
CPU: CPU{},
|
||||||
|
Mem: Memory{},
|
||||||
|
Swap: Swap{},
|
||||||
|
Disks: []Disk{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置
|
// 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置
|
||||||
|
|||||||
@@ -161,6 +161,37 @@ func PipeLineCommandExecutor(pipeLineCommand [][]string) (ok bool, resultLog []s
|
|||||||
return success, output
|
return success, output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HardCodeCommandExecutor 执行硬编码命令,返回执行结果和输出内容
|
||||||
|
// hardCodeCommand: 硬编码命令,如 []string{"echo", "hello"}
|
||||||
|
// 返回值:
|
||||||
|
//
|
||||||
|
// bool - 命令是否执行成功(true为成功,false为失败)
|
||||||
|
// []string - 合并后的标准输出和标准错误内容(按行分割)
|
||||||
|
func HardCodeCommandExecutor(hardCodeCommand string) (ok bool, resultLog []string) {
|
||||||
|
|
||||||
|
log.Info("[Excutor] - start => %v", hardCodeCommand)
|
||||||
|
|
||||||
|
if hardCodeCommand == "" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
cmd := exec.Command(hardCodeCommand)
|
||||||
|
|
||||||
|
// 执行命令并获取错误信息
|
||||||
|
err := cmd.Run()
|
||||||
|
|
||||||
|
// 合并输出结果
|
||||||
|
stdoutBuf := bytes.Buffer{}
|
||||||
|
stderrBuf := bytes.Buffer{}
|
||||||
|
cmd.Stdout = &stdoutBuf
|
||||||
|
cmd.Stderr = &stderrBuf
|
||||||
|
|
||||||
|
output := mergeOutput(&stdoutBuf, &stderrBuf)
|
||||||
|
|
||||||
|
return err == nil, output
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// 成功案例
|
// 成功案例
|
||||||
success, output := SingleLineCommandExecutor([]string{"ls", "-l"})
|
success, output := SingleLineCommandExecutor([]string{"ls", "-l"})
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AppendFileToFile 将源文件的内容添加到目标文件
|
// AppendFileToFile 将源文件的内容添加到目标文件
|
||||||
@@ -178,6 +179,15 @@ func FileExists(fileFullPath string) bool {
|
|||||||
return !info.IsDir()
|
return !info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateFolder 创建文件夹,如果文件夹存在,则返回true,否则返回false
|
||||||
|
func CreateFolder(folderName string) bool {
|
||||||
|
// 递归创建 类似于 mkdir -p folderName
|
||||||
|
if _, err := os.Stat(folderName); os.IsNotExist(err) {
|
||||||
|
return os.MkdirAll(folderName, 0755) == nil
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// FileOrFolderExists 文件或者目录是否返回true,不存在返回false
|
// FileOrFolderExists 文件或者目录是否返回true,不存在返回false
|
||||||
func FileOrFolderExists(fileFullPath string) bool {
|
func FileOrFolderExists(fileFullPath string) bool {
|
||||||
_, err := os.Stat(fileFullPath)
|
_, err := os.Stat(fileFullPath)
|
||||||
@@ -298,6 +308,89 @@ func ReadAllContentFromFile(fileFullPath string) (result []string) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindContentInFile 在文件中查找内容,如果存在,则返回true,否则返回false 类似于grep -q content targetFile
|
||||||
|
func FindContentInFile(content string, targetFile string) bool {
|
||||||
|
|
||||||
|
// 读取文件内容
|
||||||
|
fileContent, err := os.ReadFile(targetFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[FindContentInFile] - Error reading file: %s , error is %s", targetFile, err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将文件内容按行分割
|
||||||
|
lines := strings.Split(string(fileContent), "\n")
|
||||||
|
|
||||||
|
// 遍历每一行
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.Contains(line, content) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAndReplaceContentInFile 在文件中查找内容,如果存在,则替换,如果存在多个,则替换全部 类似于sed -i 's/oldContent/newContent/g' targetFile
|
||||||
|
func FindAndReplaceContentInFile(oldContent string, newContent string, targetFile string) bool {
|
||||||
|
|
||||||
|
// 读取文件内容
|
||||||
|
fileContent, err := os.ReadFile(targetFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[FindAndReplaceContentInFile] - Error reading file: %s , error is %s", targetFile, err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将文件内容按行分割
|
||||||
|
lines := strings.Split(string(fileContent), "\n")
|
||||||
|
|
||||||
|
// 遍历每一行
|
||||||
|
for i, line := range lines {
|
||||||
|
if strings.Contains(line, oldContent) {
|
||||||
|
lines[i] = strings.Replace(line, oldContent, newContent, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将修改后的内容写回文件
|
||||||
|
err = os.WriteFile(targetFile, []byte(strings.Join(lines, "\n")), 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[FindAndReplaceContentInFile] - Error writing file: %s , error is %s", targetFile, err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAndDeleteContentInFile 在文件中查找内容,如果存在,则删除,如果存在多个,则删除全部 类似于sed -i '/content/d' targetFile
|
||||||
|
func FindAndDeleteContentInFile(content string, targetFile string) bool {
|
||||||
|
|
||||||
|
// 读取文件内容
|
||||||
|
fileContent, err := os.ReadFile(targetFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[FindAndDeleteContentInFile] - Error reading file: %s , error is %s", targetFile, err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将文件内容按行分割
|
||||||
|
lines := strings.Split(string(fileContent), "\n")
|
||||||
|
|
||||||
|
// 过滤掉包含指定内容的行
|
||||||
|
var newLines []string
|
||||||
|
for _, line := range lines {
|
||||||
|
if !strings.Contains(line, content) {
|
||||||
|
newLines = append(newLines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将过滤后的内容写回文件
|
||||||
|
err = os.WriteFile(targetFile, []byte(strings.Join(newLines, "\n")), 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[FindAndDeleteContentInFile] - Error writing file: %s , error is %s", targetFile, err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// MoveFolerToAnother 将源文件夹的所有文件递归移动到目标文件夹
|
// MoveFolerToAnother 将源文件夹的所有文件递归移动到目标文件夹
|
||||||
func MoveFolerToAnother(srcDir, dstDir string) error {
|
func MoveFolerToAnother(srcDir, dstDir string) error {
|
||||||
// 读取源文件夹中的所有条目
|
// 读取源文件夹中的所有条目
|
||||||
|
|||||||
Reference in New Issue
Block a user