Skip to content

Commit b9d711c

Browse files
author
Marton Sereg
authored
Merge pull request #6 from sequenceiq/chgpass
Ability to setup saltuser with pass
2 parents aedd344 + ca605b2 commit b9d711c

File tree

6 files changed

+126
-66
lines changed

6 files changed

+126
-66
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BINARY=salt-bootstrap
22

3-
VERSION=0.1.2
3+
VERSION=0.2.0
44
BUILD_TIME=$(shell date +%FT%T)
55
LDFLAGS=-ldflags "-X github.com/sequenceiq/salt-bootstrap/saltboot.Version=${VERSION} -X github.com/sequenceiq/salt-bootstrap/saltboot.BuildTime=${BUILD_TIME}"
66

main.go

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
package main
22

33
import (
4-
"fmt"
5-
"log"
6-
"os"
7-
"strings"
8-
"github.com/sequenceiq/salt-bootstrap/saltboot"
4+
"fmt"
5+
"log"
6+
"os"
7+
"strings"
8+
"github.com/sequenceiq/salt-bootstrap/saltboot"
9+
"io"
910
)
1011

1112
func main() {
12-
if len(os.Args) > 1 && strings.HasSuffix(os.Args[1], "version") {
13-
fmt.Printf("Version: %s-%s", saltboot.Version, saltboot.BuildTime)
14-
return
15-
}
16-
log.Println("[main] Launch salt-bootstrap application")
17-
saltboot.NewCloudbreakBootstrapWeb()
13+
14+
if len(os.Args) > 1 && strings.HasSuffix(os.Args[1], "version") {
15+
fmt.Printf("Version: %s-%s", saltboot.Version, saltboot.BuildTime)
16+
return
17+
}
18+
19+
logFile, err := os.OpenFile("/var/log/saltboot.log", os.O_APPEND | os.O_CREATE | os.O_RDWR, 0666)
20+
if err != nil {
21+
log.Printf("Error opening log file: %v", err)
22+
}
23+
defer logFile.Close()
24+
log.SetOutput(io.MultiWriter(os.Stdout, logFile))
25+
26+
log.Println("[main] Launch salt-bootstrap application")
27+
saltboot.NewCloudbreakBootstrapWeb()
1828
}

saltboot/netutil.go

-27
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,12 @@
11
package saltboot
22

33
import (
4-
"io/ioutil"
54
"log"
65
"os"
7-
"regexp"
86
"strconv"
97
"strings"
108
)
119

12-
func DetermineDNSRecursors(fallbackDNSRecursors []string) []string {
13-
var dnsRecursors []string
14-
if dat, err := ioutil.ReadFile("/etc/resolv.conf"); err == nil {
15-
resolvContent := string(dat)
16-
log.Printf("[determineDNSRecursors] Loaded /etc/resolv.conf file: %s.", resolvContent)
17-
r, _ := regexp.Compile("nameserver .*")
18-
if nameserverLines := r.FindAllString(resolvContent, -1); nameserverLines != nil {
19-
for _, nameserverLine := range nameserverLines {
20-
log.Printf("[determineDNSRecursors] Found nameserverline: %s.", nameserverLine)
21-
dnsRecursor := strings.TrimSpace(strings.Split(nameserverLine, " ")[1])
22-
log.Printf("[determineDNSRecursors] Parsed DNS recursor: %s.", dnsRecursor)
23-
if !strings.Contains(dnsRecursor, "127.0.0.1") {
24-
dnsRecursors = append(dnsRecursors, dnsRecursor)
25-
}
26-
}
27-
}
28-
} else {
29-
log.Printf("[containerhandler] Failed to load /etc/resolv.conf")
30-
}
31-
if fallbackDNSRecursors != nil {
32-
dnsRecursors = append(dnsRecursors, fallbackDNSRecursors...)
33-
}
34-
return dnsRecursors
35-
}
36-
3710
func DetermineBootstrapPort() int {
3811

3912
portStr := os.Getenv("SALTBOOT_PORT")

saltboot/salt.go

+41-16
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,21 @@ import (
1313
"gopkg.in/yaml.v2"
1414
)
1515

16-
type SaltServerSetupRequest struct {
17-
Password string `json:"password,omitempty"`
18-
}
19-
2016
type SaltActionRequest struct {
17+
Master SaltMaster `json:"master,omitempty"`
2118
Minions []SaltMinion `json:"minions,omitempty"`
22-
Server string `json:"server,omitempty"`
2319
Action string `json:"action"`
2420
}
2521

22+
type SaltAuth struct {
23+
Password string `json:"password,omitempty"`
24+
}
25+
26+
type SaltMaster struct {
27+
Address string `json:"address"`
28+
Auth SaltAuth `json:"auth,omitempty"`
29+
}
30+
2631
type SaltMinion struct {
2732
Address string `json:"address"`
2833
Roles []string `json:"roles,omitempty"`
@@ -40,6 +45,11 @@ func (saltMinion SaltMinion) AsByteArray() []byte {
4045
return b
4146
}
4247

48+
func (saltMaster SaltMaster) AsByteArray() []byte {
49+
b, _ := json.Marshal(saltMaster)
50+
return b
51+
}
52+
4353
type GrainConfig struct {
4454
HostGroup string `json:"hostgroup" yaml:"hostgroup"`
4555
Roles []string `json:"roles" yaml:"roles"`
@@ -52,21 +62,22 @@ func (r SaltActionRequest) String() string {
5262

5363
func (r SaltActionRequest) distributeAction(user string, pass string) (result []model.Response) {
5464
log.Printf("[distributeAction] distribute salt state command to targets: %s", r.String())
65+
5566
var targets []string
56-
var payloads []Payload
67+
var minionPayload []Payload
5768
for _, minion := range r.Minions {
5869
targets = append(targets, minion.Address)
5970
if minion.Server == "" {
60-
minion.Server = r.Server
71+
minion.Server = r.Master.Address
6172
}
62-
payloads = append(payloads, minion)
73+
minionPayload = append(minionPayload, minion)
6374
}
6475

65-
for res := range DistributePayload(targets, payloads, SaltMinionEp+"/"+r.Action, user, pass) {
76+
for res := range DistributePayload(targets, minionPayload, SaltMinionEp + "/" + r.Action, user, pass) {
6677
result = append(result, res)
6778
}
68-
if len(r.Server) > 0 {
69-
result = append(result, <-Distribute([]string{r.Server}, nil, SaltServerEp+"/"+r.Action, user, pass))
79+
if len(r.Master.Address) > 0 {
80+
result = append(result, <-DistributePayload([]string{r.Master.Address}, []Payload{r.Master}, SaltServerEp + "/" + r.Action, user, pass))
7081
}
7182
return result
7283
}
@@ -135,11 +146,29 @@ func SaltMinionStopRequestHandler(w http.ResponseWriter, req *http.Request) {
135146

136147
func SaltServerRunRequestHandler(w http.ResponseWriter, req *http.Request) {
137148
log.Printf("[SaltServerRunRequestHandler] execute salt run request")
138-
resp, err := LaunchService("salt-master")
149+
150+
decoder := json.NewDecoder(req.Body)
151+
var saltMaster SaltMaster
152+
err := decoder.Decode(&saltMaster)
153+
if err != nil {
154+
log.Printf("[SaltServerRunRequestHandler] [ERROR] couldn't decode json: %s", err)
155+
model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
156+
return
157+
}
158+
159+
resp, err := CreateUser(saltMaster)
160+
resp.WriteHttp(w)
161+
if err != nil {
162+
return
163+
}
164+
165+
resp, err = LaunchService("salt-master")
139166
resp.WriteHttp(w)
167+
140168
if err != nil {
141169
return
142170
}
171+
143172
resp, _ = LaunchService("salt-api")
144173
resp.WriteHttp(w)
145174
}
@@ -155,10 +184,6 @@ func SaltServerStopRequestHandler(w http.ResponseWriter, req *http.Request) {
155184
resp.WriteHttp(w)
156185
}
157186

158-
func SaltServerSetupRequestHandler(w http.ResponseWriter, req *http.Request) {
159-
160-
}
161-
162187
func (pillar SaltPillar) WritePillar() (outStr string, err error) {
163188
file := "/srv/pillar" + pillar.Path
164189
dir := file[0:strings.LastIndex(file, "/")]

saltboot/user.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package saltboot
2+
3+
import (
4+
"log"
5+
"github.com/sequenceiq/salt-bootstrap/saltboot/model"
6+
"github.com/kless/osutil/user/crypt/sha512_crypt"
7+
"net/http"
8+
"time"
9+
"math/rand"
10+
)
11+
12+
const SALT_USER = "saltuser"
13+
14+
func init() {
15+
rand.Seed(time.Now().UnixNano())
16+
}
17+
18+
func randStringRunes(n int) string {
19+
LETTER_RUNES := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
20+
b := make([]rune, n)
21+
for i := range b {
22+
b[i] = LETTER_RUNES[rand.Intn(len(LETTER_RUNES))]
23+
}
24+
return string(b)
25+
}
26+
27+
func CreateUser(saltMaster SaltMaster) (resp model.Response, err error) {
28+
log.Printf("[CreateUser] execute salt run request")
29+
30+
result := "OK"
31+
32+
//saltUser, _ := user.Lookup(SALT_USER) //requires cgo
33+
_, err = ExecCmd("grep", SALT_USER, "/etc/passwd")
34+
35+
if err != nil {
36+
log.Printf("[CreateUser] user: %s does not exsist and will be created", SALT_USER)
37+
38+
c := sha512_crypt.New()
39+
40+
// Password needs to be "salted" and must start with a magic prefix
41+
salt := "$6$" + randStringRunes(20)
42+
43+
hash, err := c.Generate([]byte(saltMaster.Auth.Password), []byte(salt))
44+
if err != nil {
45+
return model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}, err
46+
}
47+
result, err = ExecCmd("adduser", "--password", hash, SALT_USER)
48+
49+
if err != nil {
50+
return model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}, err
51+
}
52+
result, err = ExecCmd("usermod", "-G", "wheel", SALT_USER)
53+
if err != nil {
54+
return model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}, err
55+
}
56+
} else {
57+
log.Printf("[CreateUser] user: %s exsist", SALT_USER)
58+
}
59+
60+
resp = model.Response{Status: result, StatusCode: http.StatusOK}
61+
return resp, nil
62+
63+
}

saltboot/web.go

-11
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package saltboot
22

33
import (
44
"fmt"
5-
"io"
65
"log"
76
"net/http"
8-
"os"
97

108
"github.com/gorilla/mux"
119
)
@@ -22,7 +20,6 @@ const (
2220
SaltMinionStopEP = SaltMinionEp + "/stop"
2321
SaltServerRunEP = SaltServerEp + "/run"
2422
SaltServerStopEP = SaltServerEp + "/stop"
25-
SaltServerSetupEP = RootPath + "/salt/server/setup"
2623
SaltPillarEP = RootPath + "/salt/server/pillar"
2724
HostnameDistributeEP = RootPath + "/hostname/distribute"
2825
HostnameEP = RootPath + "/hostname"
@@ -31,13 +28,6 @@ const (
3128

3229
func NewCloudbreakBootstrapWeb() {
3330

34-
logFile, err := os.OpenFile("/var/log/saltboot.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
35-
if err != nil {
36-
log.Printf("Error opening log file: %v", err)
37-
}
38-
defer logFile.Close()
39-
log.SetOutput(io.MultiWriter(os.Stdout, logFile))
40-
4131
address := fmt.Sprintf(":%d", DetermineBootstrapPort())
4232
username, password := DetermineAuthCredentials()
4333

@@ -55,7 +45,6 @@ func NewCloudbreakBootstrapWeb() {
5545
r.Handle(SaltMinionStopEP, authenticator.Wrap(SaltMinionStopRequestHandler)).Methods("POST")
5646
r.Handle(SaltServerRunEP, authenticator.Wrap(SaltServerRunRequestHandler)).Methods("POST")
5747
r.Handle(SaltServerStopEP, authenticator.Wrap(SaltServerStopRequestHandler)).Methods("POST")
58-
r.Handle(SaltServerSetupEP, authenticator.Wrap(SaltServerSetupRequestHandler)).Methods("POST")
5948
r.Handle(SaltPillarEP, authenticator.Wrap(SaltPillarRequestHandler)).Methods("POST")
6049

6150
r.Handle(HostnameDistributeEP, authenticator.Wrap(ClientHostnameDistributionHandler)).Methods("POST")

0 commit comments

Comments
 (0)