[Agent][Bastion] - Bastion mode - 2

This commit is contained in:
zeaslity
2024-04-17 16:42:02 +08:00
parent c0712b7325
commit dacdb6588e
12 changed files with 383 additions and 203 deletions

View File

@@ -214,6 +214,23 @@ func (op *AgentOsOperator) shutdownFirewall() [][]string {
return shutdownFunc
}
func (op *AgentOsOperator) shutdownFirewallBastion() (bool, []string) {
shutdownFunc := [][]string{
{"systemctl", "stop", "firewalld"},
{"systemctl", "disable", "firewalld"},
{"systemctl", "stop", "ufw"},
{"systemctl", "disable", "ufw"},
{"iptables", "-F"},
}
// 忽略错误
_, resultLog := AllCompleteExecutor(shutdownFunc)
// centos
return true, resultLog
}
func (op *AgentOsOperator) shutdownFirewallExec() (bool, []string) {
shutdownFunc := [][]string{
@@ -838,7 +855,7 @@ func (op *AgentOsOperator) installDockerOfflineExec(args []string) (bool, []stri
dockerOfflineFileName = "docker-arm64-20.10.15.tgz"
}
ok, resultLog := BasicDownloadFileByCurl(op.OssOfflinePrefix+dockerOfflineFileName, "/root/wdd/"+dockerOfflineFileName)
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+dockerOfflineFileName, "", "", "", "/root/wdd/"+dockerOfflineFileName)
if !ok {
return false, resultLog
}
@@ -932,10 +949,48 @@ func (op *AgentOsOperator) installDockerOfflineExec(args []string) (bool, []stri
"[installDockerOfflineExec] - docker offline installation success!",
}
}
func (op *AgentOsOperator) InstallDockerFromLocalExec(args []string) (bool, []string) {
func (op *AgentOsOperator) InstallDockerBastion() (bool, []string) {
// check offline file exits
log.InfoF("[InstallDockerBastion] - install docker 20.10.15 by local file method !")
BasicCreateFolder("/root/wdd")
// install docker
var dockerOfflineFileName string
if strings.HasPrefix(op.AgentArch, "amd") {
dockerOfflineFileName = "docker-amd64-20.10.15.tgz"
} else if strings.HasPrefix(op.AgentArch, "arm64") {
dockerOfflineFileName = "docker-arm64-20.10.15.tgz"
}
BasicRemoveFolderComplete("/root/wdd/docker")
dockerLocalFile := "/root/wdd/" + dockerOfflineFileName
if !BasicFileExistAndNotNull(dockerLocalFile) {
sprintf := fmt.Sprintf("docker offline file not exists ! => %s", dockerLocalFile)
log.Error(sprintf)
return false, []string{sprintf}
}
PureResultSingleExecute([]string{
"tar",
"-vxf",
dockerLocalFile,
"-C",
"/root/wdd",
})
HardCodeCommandExecutor("chmod 777 -R /root/wdd/docker/*")
resultOk, l := HardCodeCommandExecutor("mv /root/wdd/docker/* /usr/bin")
if !resultOk {
return false, append(l, "[InstallDockerBastion] - cp docker executable file error!")
}
// daemon docker
return true, []string{
"[installDockerFromLocalExec] - docker offline installation from local success!",
"[InstallDockerBastion] - docker offline installation from local success!",
}
}
@@ -1025,7 +1080,7 @@ func (op *AgentOsOperator) installDockerComposeExec() (bool, []string) {
return true, []string{"docker-compose安装成功"}
}
func (op *AgentOsOperator) InstallDockerComposeFromLocalExec() (bool, []string) {
func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) {
return true, []string{
"[installDockerComposeFromLocalExec] - docker-compose offline installation from local success!",
}
@@ -2126,6 +2181,11 @@ func (op *AgentOsOperator) chronyToMasterExec(args []string) (bool, []string) {
}
}
func (op *AgentOsOperator) InstallMinioBastion() (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) chronyToMasterByDocker(args []string) (bool, []string) {
return true, nil

View File

@@ -27,6 +27,7 @@ type ExecutionMessage struct {
var log = logger.Log
// AgentOsOperatorCache global agent operator cache
var AgentOsOperatorCache = &AgentOsOperator{}
func Activate() {

View File

@@ -6,7 +6,9 @@ import (
"os"
"strings"
"wdd.io/agent-go/a_agent"
"wdd.io/agent-go/a_executor"
"wdd.io/agent-go/a_init/bastion_init"
"wdd.io/agent-go/a_status"
)
/*
@@ -25,11 +27,22 @@ import (
3.5 安装kubernetes
*/
var AllFunctionCache = &bastion_init.Trie{}
const (
InstallDocker = "docker"
InstallDockerCompose = "dockercompose"
InstallMinio = "minio"
InstallRabbitmq = "rabbitmq"
Exit = "exit"
Help = "help"
)
// BastionModeInit 堡垒机模式 完全离线模式
func BastionModeInit() {
// Build For Operator
_ = &a_agent.AgentServerInfo{
bastionAgentServerInfo := &a_agent.AgentServerInfo{
ServerName: "BastionSingle",
ServerIPPbV4: "127.0.0.1",
ServerIPInV4: "127.0.0.1",
@@ -59,53 +72,78 @@ func BastionModeInit() {
TopicName: "BastionNode",
}
// build for bastion mode operator
// re-get agentInfo from status module
//agentInfo := a_status.ReportAgentInfo()
//refreshAgentInfoByStatusInfo(agentInfo, agentServerInfo)
//buildAgentOsOperator(agentInfo, agentServerInfo)
agentInfo := a_status.ReportAgentInfo()
refreshAgentInfoByStatusInfo(agentInfo, bastionAgentServerInfo)
// install docker
//agentOsOperator := a_executor.AgentOsOperatorCache
// boot up minio & rabbitmq
//agentOsOperator.InstallDockerFromLocalExec(nil)
//agentOsOperator.InstallDockerComposeFromLocalExec()
// build operator cache
buildAgentOsOperator(agentInfo, bastionAgentServerInfo)
// build for socks server
// 缓存此内容
a_agent.AgentServerInfoCache = bastionAgentServerInfo
agentOperator := a_executor.AgentOsOperatorCache
words := []string{"apple", "apricot", "apprentice", "application"}
t := bastion_init.NewTrie()
t.InsertAll(words)
// build for all functions
buildBastionModeFunction()
prefix := "ap"
closest, err := bastion_init.FindClosestWord(t, prefix)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("The closest word to '%s' is '%s'\n", prefix, closest)
}
// build for function arguments list
//var funcArgsList []string
reader := bufio.NewReader(os.Stdin)
bastion_init.PrintBastionHelp()
for {
bastion_init.PrintBastionHelp()
fmt.Println()
fmt.Print("enter ==> ")
text, _ := reader.ReadString('\n')
text = strings.TrimSpace(text)
inputCommand := uniformInputCommand(text)
fmt.Println("inputCommand: ", inputCommand)
if text == "quit" {
break
} else if text == "help" {
// execute the function
switch inputCommand {
case InstallDocker:
agentOperator.InstallDockerBastion()
case InstallDockerCompose:
agentOperator.InstallDockerComposeBastion()
case InstallMinio:
agentOperator.InstallMinioBastion()
case Exit:
os.Exit(0)
case Help:
bastion_init.PrintBastionHelp()
} else {
// Execute the command
fmt.Println("Executing command:", text)
default:
fmt.Println("inputCommand is not exist ! Please input again")
}
}
}
// uniformInputCommand 归一化输入的命令
func uniformInputCommand(inputString string) {
func buildBastionModeFunction() {
// build the tree search node
log.Info("build the tree search node")
tcc := bastion_init.NewTrie()
tcc.Insert(InstallDocker)
tcc.Insert(InstallDockerCompose)
tcc.Insert(InstallMinio)
tcc.Insert(InstallRabbitmq)
tcc.Insert(Help)
tcc.Insert(Exit)
AllFunctionCache = tcc
}
// uniformInputCommand 归一化输入的命令
func uniformInputCommand(inputString string) string {
findClosestWord, err := bastion_init.FindClosestWord(AllFunctionCache, inputString)
if err != nil {
log.ErrorF("inputString error: %s", err.Error())
}
return findClosestWord
}

View File

@@ -1,140 +1 @@
package bastion_init
import (
"fmt"
"sort"
)
type TrieNode struct {
children [26]*TrieNode
isEnd bool
word string
}
type Trie struct {
root *TrieNode
}
func NewTrie() *Trie {
return &Trie{root: &TrieNode{}}
}
func (tn *TrieNode) Insert(word string) {
node := tn
for _, c := range word {
c -= 'a' // Convert char to int index
if node.children[c] == nil {
node.children[c] = &TrieNode{}
}
node = node.children[c]
}
node.isEnd = true
node.word = word
}
func (t *Trie) InsertAll(words []string) {
for _, word := range words {
t.root.Insert(word)
}
}
func (tn *TrieNode) Find(prefix string) []string {
node := tn
result := make([]string, 0)
for _, c := range prefix {
c -= 'a' // Convert char to int index
if node.children[c] != nil {
node = node.children[c]
} else {
return result // No more matching nodes
}
}
trieWalk(node, &result)
return result
}
func trieWalk(node *TrieNode, result *[]string) {
if node.isEnd {
*result = append(*result, node.word)
}
for _, child := range node.children {
if child != nil {
trieWalk(child, result)
}
}
}
type Word struct {
Word string
Rank int
}
func SortWords(words []string) []Word {
sortedWords := make([]Word, len(words))
for i, word := range words {
sortedWords[i] = Word{Word: word, Rank: i}
}
sort.Slice(sortedWords, func(i, j int) bool {
return sortedWords[i].Word < sortedWords[j].Word
})
return sortedWords
}
func FindClosestWord(trie *Trie, prefix string) (string, error) {
words := trie.root.Find(prefix)
if len(words) == 0 {
return "", fmt.Errorf("no words found for prefix: %s", prefix)
}
sortedWords := SortWords(words)
minDistance := len(prefix) // Initialize with the maximum possible distance
closestWord := sortedWords[0].Word
for _, word := range sortedWords {
distance := levDist(prefix, word.Word)
if distance < minDistance {
minDistance = distance
closestWord = word.Word
}
}
return closestWord, nil
}
func levDist(s1, s2 string) int {
m, n := len(s1), len(s2)
if m == 0 {
return n
}
if n == 0 {
return m
}
dp := make([][]int, m+1)
for i := range dp {
dp[i] = make([]int, n+1)
}
for i := 1; i <= m; i++ {
for j := 1; j <= n; j++ {
cost := 0
if s1[i-1] != s2[j-1] {
cost = 1
}
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + cost
}
}
return dp[m][n]
}
func min(a, b, c int) int {
if a < b && a < c {
return a
} else if b < a && b < c {
return b
} else {
return c
}
}

View File

@@ -0,0 +1,143 @@
package bastion_init
import (
"fmt"
"sort"
)
type TrieNode struct {
children [26]*TrieNode
isEnd bool
word string
}
type Trie struct {
root *TrieNode
}
func NewTrie() *Trie {
return &Trie{root: &TrieNode{}}
}
func (tn *TrieNode) Insert(word string) {
node := tn
for _, c := range word {
c -= 'a' // Convert char to int index
if node.children[c] == nil {
node.children[c] = &TrieNode{}
}
node = node.children[c]
}
node.isEnd = true
node.word = word
}
func (t *Trie) Insert(word string) {
t.root.Insert(word)
}
func (t *Trie) InsertAll(words []string) {
for _, word := range words {
t.root.Insert(word)
}
}
func (tn *TrieNode) Find(prefix string) []string {
node := tn
result := make([]string, 0)
for _, c := range prefix {
c -= 'a' // Convert char to int index
if node.children[c] != nil {
node = node.children[c]
} else {
return result // No more matching nodes
}
}
trieWalk(node, &result)
return result
}
func trieWalk(node *TrieNode, result *[]string) {
if node.isEnd {
*result = append(*result, node.word)
}
for _, child := range node.children {
if child != nil {
trieWalk(child, result)
}
}
}
type Word struct {
Word string
Rank int
}
func SortWords(words []string) []Word {
sortedWords := make([]Word, len(words))
for i, word := range words {
sortedWords[i] = Word{Word: word, Rank: i}
}
sort.Slice(sortedWords, func(i, j int) bool {
return sortedWords[i].Word < sortedWords[j].Word
})
return sortedWords
}
func FindClosestWord(trie *Trie, prefix string) (string, error) {
words := trie.root.Find(prefix)
if len(words) == 0 {
return "", fmt.Errorf("no words found for prefix: %s", prefix)
}
sortedWords := SortWords(words)
minDistance := len(prefix) // Initialize with the maximum possible distance
closestWord := sortedWords[0].Word
for _, word := range sortedWords {
distance := levDist(prefix, word.Word)
if distance < minDistance {
minDistance = distance
closestWord = word.Word
}
}
return closestWord, nil
}
func levDist(s1, s2 string) int {
m, n := len(s1), len(s2)
if m == 0 {
return n
}
if n == 0 {
return m
}
dp := make([][]int, m+1)
for i := range dp {
dp[i] = make([]int, n+1)
}
for i := 1; i <= m; i++ {
for j := 1; j <= n; j++ {
cost := 0
if s1[i-1] != s2[j-1] {
cost = 1
}
dp[i][j] = minThree(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + cost
}
}
return dp[m][n]
}
func minThree(a, b, c int) int {
if a < b && a < c {
return a
} else if b < a && b < c {
return b
} else {
return c
}
}

View File

@@ -0,0 +1,21 @@
package bastion_init
import (
"fmt"
"testing"
)
func TestNewTrie(t *testing.T) {
words := []string{"apple", "apricot", "apprentice", "application"}
tcc := NewTrie()
tcc.InsertAll(words)
prefix := "ap"
closest, err := FindClosestWord(tcc, prefix)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("The closest word to '%s' is '%s'\n", prefix, closest)
}
}

View File

@@ -1,27 +1,5 @@
package bastion_init
import (
"fmt"
"io"
"os"
)
// getStandardOutPutLength 获取到标准输出终端的长度
func getStandardOutPutLength() (int, error) {
buffer := make([]byte, 0)
_, err := io.ReadFull(os.Stdout, buffer)
if err != nil {
return 0, err
}
return len(buffer), nil
}
func PrintBastionHelp() {
length, err := getStandardOutPutLength()
if err == nil {
fmt.Printf("标准输出终端的长度: %d 字节\n", length)
} else {
fmt.Println("获取标准输出终端长度时发生错误:", err)
}
}