问题描述
我正在尝试同时通过Vault服务器。我可以递归搜索,但是无法并行化它。
下面是我想出的代码示例。我正在研究如何通过使用并发来使其更快。是否可以同时遍历保险柜路径?
package main
import (
"flag"
"fmt"
"github.com/hashicorp/vault/api"
"log"
"net/http"
"strings"
"sync"
"time"
)
var vault_path string
var vault_addr string
var dev_vault_addr = ""
var pie_vault_addr = ""
var prod_vault_addr = ""
var dev_vault_path string = ""
var pie_vault_path string = ""
var prod_vault_path string = ""
//flags
var env = flag.String("ENV","","vault environment - dev,pie,prod")
var okta_user = flag.String("USER","okta username")
var okta_pw = flag.String("PW","okta pw")
var searchValue= flag.String("VALUE","value to search for")
var searchKey = flag.String("KEY","key to search for")
func main() {
flag.Parse()
switch *env {
case "dev":
fmt.Println("dev vault ")
vault_path = dev_vault_path
vault_addr = dev_vault_addr
case "pie":
fmt.Println("pie")
vault_path = pie_vault_path
vault_addr = pie_vault_addr
case "prod":
fmt.Println("prod")
vault_path = prod_vault_path
vault_addr = prod_vault_addr
}
workerCount := 1
jobs := make(chan workerJob,workerCount)
results := make(chan workerResult)
readDone := make(chan bool)
wg := &sync.WaitGroup{}
// start N workers
for i := 0; i < workerCount; i++ {
go worker(jobs,results,wg)
}
// One initial job
wg.Add(1)
go func() {
jobs <- workerJob{
Path: vault_path,}
}()
// When all jobs finished,shutdown the system.
go func() {
wg.Wait()
readDone <- true
}()
readloop:
for {
select {
case res := <-results:
log.Printf(`result=%#v`,res.secret)
case <-readDone:
log.Printf(`got stop`)
close(jobs)
break readloop
}
}
}
func setupClient(vault_addr string) *api.Client {
httpClient := &http.Client{
Timeout: 10 * time.Second,}
client,err := api.NewClient(&api.Config{Address: vault_addr,HttpClient: httpClient})
if err != nil {
fmt.Println(err)
}
// to pass the password
options := map[string]interface{}{
"password": okta_pw,}
// the login path
// this is configurable,change userpass to ldap etc
path := fmt.Sprintf("auth/okta/login/%s",*okta_user)
// PUT call to get a token
secret,err := client.Logical().Write(path,options)
client.SetToken(secret.Auth.ClientToken)
return client
}
func walkDir(client *api.Client,path string) {
var value *api.Secret
var err error
if path != "" {
value,err = client.Logical().List(path)
} else {
path = vault_path
value,err = client.Logical().List(path)
}
if err != nil {
fmt.Println(err)
}
var datamap map[string]interface{}
datamap = value.Data
data := datamap["keys"].([]interface{})
for _,item := range data {
itemString := item.(string)
if strings.HasSuffix(itemString,"/") {
walkDir(client,path+itemString)
} else {
//its a secret
data := read(client,path+itemString)
if *searchKey!="" && searchForKey(data,*searchKey){
fmt.Println(path + itemString)
}
if *searchValue!="" && searchForValue(data,*searchValue){
fmt.Println(path + itemString)
}
}
}
}
func read(client *api.Client,path string) map[string]interface{} {
value,err := client.Logical().Read(path)
if err != nil {
fmt.Println(err)
}
values := value.Data
return values
}
func searchForValue(mapp map[string]interface{},searchValue string) bool {
for _,value := range mapp {
if searchValue == value {
return true
}
}
return false
}
func searchForKey(mapp map[string]interface{},searchKey string) bool {
for key := range mapp {
if searchKey == key {
return true
}
}
return false
}
// Job for worker
type workerJob struct {
Address string
Path string
}
// Result of a worker
type workerResult struct {
secret map[string]interface{}
}
func worker(jobs chan workerJob,results chan<- workerResult,wg *sync.WaitGroup) {
for j := range jobs {
client := setupClient(vault_addr)
log.Printf(`Vault Path: %#v`,j.Path)
var value *api.Secret
if j.Path != "" {
value,_ = client.Logical().List(j.Path)
} else {
j.Path = vault_path
value,_ = client.Logical().List(j.Path)
}
var datamap map[string]interface{}
datamap = value.Data
data := datamap["keys"].([]interface{})
for _,item := range data {
itemString := item.(string)
if strings.HasSuffix(itemString,"/") {
nj := workerJob{Path: itemString}
log.Printf(`sent new vault dir job: %#v`,nj.Path)
//one more job add to wg
wg.Add(1)
// Do not block when sending jobs
go func() {
jobs <- nj
}()
} else {
//its a secret
data := read(client,j.Path+itemString)
if *searchKey!="" && searchForKey(data,*searchKey){
log.Printf(vault_path+itemString)
r := workerResult{
secret: data,}
results<-r
}
if *searchValue!="" && searchForValue(data,*searchValue){
log.Printf(vault_path+itemString)
r := workerResult{
secret: data,}
results<-r
}
}
}
// Done one job,let wg kNow.
wg.Done()
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)