Skip to content

Commit

Permalink
Merge branch 'v2.x' of github.com:distribworks/dkron into v2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Castell committed Oct 22, 2019
2 parents 09dd765 + 300fd0d commit 82dcfc7
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 20 deletions.
89 changes: 69 additions & 20 deletions builtin/bins/dkron-executor-http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -70,26 +71,6 @@ func (s *HTTP) ExecuteImpl(args *dkron.ExecuteRequest) ([]byte, error) {
return output.Bytes(), errors.New("method is empty")
}

_timeout := timeout
if args.Config["timeout"] != "" {
_timeout, _ = strconv.Atoi(args.Config["timeout"])
}

tlsconf := &tls.Config{}
tlsconf.InsecureSkipVerify, _ = strconv.ParseBool(args.Config["tlsNoVerifyPeer"])
if args.Config["tlsCertificateFile"] != "" {
cert, err := tls.LoadX509KeyPair(args.Config["tlsCertificateFile"], args.Config["tlsCertificateKeyFile"])
if err == nil {
tlsconf.Certificates = append(tlsconf.Certificates, cert)
} else {
output.Write([]byte(fmt.Sprintf("Warning: failed to read certificate file(s): %s. Continuing without certificate.\n", err.Error())))
}
}

client := &http.Client{
Transport: &http.Transport{TLSClientConfig: tlsconf},
Timeout: time.Duration(_timeout) * time.Second,
}
req, err := http.NewRequest(args.Config["method"], args.Config["url"], bytes.NewBuffer([]byte(args.Config["body"])))
if err != nil {
return output.Bytes(), err
Expand All @@ -112,6 +93,11 @@ func (s *HTTP) ExecuteImpl(args *dkron.ExecuteRequest) ([]byte, error) {
log.Printf("request %#v\n\n", req)
}

client, warns := createClient(args.Config)
for _, warn := range warns {
output.Write([]byte(fmt.Sprintf("Warning: %s.\n", warn.Error())))
}

resp, err := client.Do(req)
if err != nil {
return output.Bytes(), err
Expand Down Expand Up @@ -155,3 +141,66 @@ func (s *HTTP) ExecuteImpl(args *dkron.ExecuteRequest) ([]byte, error) {

return output.Bytes(), nil
}

// createClient always returns a new http client. Any errors returned are
// errors in the configuration.
func createClient(config map[string]string) (http.Client, []error) {
var errs []error

_timeout, err := atoiOrDefault(config["timeout"], timeout)
if config["timeout"] != "" && err != nil {
errs = append(errs, fmt.Errorf("invalid timeout value: %s", err.Error()))
}

tlsconf := &tls.Config{}
tlsconf.InsecureSkipVerify, err = strconv.ParseBool(config["tlsNoVerifyPeer"])
if config["tlsNoVerifyPeer"] != "" && err != nil {
errs = append(errs, fmt.Errorf("not disabling certificate validation: %s", err.Error()))
}

if config["tlsCertificateFile"] != "" {
cert, err := tls.LoadX509KeyPair(config["tlsCertificateFile"], config["tlsCertificateKeyFile"])
if err == nil {
tlsconf.Certificates = append(tlsconf.Certificates, cert)
} else {
errs = append(errs, fmt.Errorf("not using client certificate: %s", err.Error()))
}
}

if config["tlsRootCAsFile"] != "" {
tlsconf.RootCAs, err = loadCertPool(config["tlsRootCAsFile"])
if err != nil {
errs = append(errs, fmt.Errorf("using system root CAs instead of configured CAs: %s", err.Error()))
}
}

return http.Client{
Transport: &http.Transport{TLSClientConfig: tlsconf},
Timeout: time.Duration(_timeout) * time.Second,
}, errs
}

// loadCertPool creates a CertPool using the given file
func loadCertPool(filename string) (*x509.CertPool, error) {
certsFile, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}

roots := x509.NewCertPool()
if !roots.AppendCertsFromPEM(certsFile) {
return nil, fmt.Errorf("no certificates in file")
}

return roots, nil
}

// atoiOrDefault returns the integer value of s, or a default value
// if s could not be converted, along with an error.
func atoiOrDefault(s string, _default int) (int, error) {
i, err := strconv.Atoi(s)
if err == nil {
return i, nil
}
return _default, fmt.Errorf("\"%s\" not understood (%s), using default value of %d", s, err, _default)
}
18 changes: 18 additions & 0 deletions builtin/bins/dkron-executor-http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,21 @@ func TestClientSSLCert(t *testing.T) {
fmt.Println(output.Error)
assert.Equal(t, output.Error, "")
}

func TestRootCA(t *testing.T) {
pa := &dkron.ExecuteRequest{
JobName: "testJob",
Config: map[string]string{
"method": "GET",
"url": "https://untrusted-root.badssl.com/",
"expectCode": "200",
"debug": "true",
"tlsRootCAsFile": "testdata/badssl-ca-untrusted-root.crt",
},
}
http := &HTTP{}
output, _ := http.Execute(pa)
fmt.Println(string(output.Output))
fmt.Println(output.Error)
assert.Equal(t, output.Error, "")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
-----BEGIN CERTIFICATE-----
MIIGfjCCBGagAwIBAgIJAJeg/PrX5Sj9MA0GCSqGSIb3DQEBCwUAMIGBMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j
aXNjbzEPMA0GA1UECgwGQmFkU1NMMTQwMgYDVQQDDCtCYWRTU0wgVW50cnVzdGVk
IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE2MDcwNzA2MzEzNVoXDTM2
MDcwMjA2MzEzNVowgYExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
MRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wxNDAyBgNV
BAMMK0JhZFNTTCBVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKQtPMhEH073gis/HISWAi
bOEpCtOsatA3JmeVbaWal8O/5ZO5GAn9dFVsGn0CXAHR6eUKYDAFJLa/3AhjBvWa
tnQLoXaYlCvBjodjLEaFi8ckcJHrAYG9qZqioRQ16Yr8wUTkbgZf+er/Z55zi1yn
CnhWth7kekvrwVDGP1rApeLqbhYCSLeZf5W/zsjLlvJni9OrU7U3a9msvz8mcCOX
fJX9e3VbkD/uonIbK2SvmAGMaOj/1k0dASkZtMws0Bk7m1pTQL+qXDM/h3BQZJa5
DwTcATaa/Qnk6YHbj/MaS5nzCSmR0Xmvs/3CulQYiZJ3kypns1KdqlGuwkfiCCgD
yWJy7NE9qdj6xxLdqzne2DCyuPrjFPS0mmYimpykgbPnirEPBF1LW3GJc9yfhVXE
Cc8OY8lWzxazDNNbeSRDpAGbBeGSQXGjAbliFJxwLyGzZ+cG+G8lc+zSvWjQu4Xp
GJ+dOREhQhl+9U8oyPX34gfKo63muSgo539hGylqgQyzj+SX8OgK1FXXb2LS1gxt
VIR5Qc4MmiEG2LKwPwfU8Yi+t5TYjGh8gaFv6NnksoX4hU42gP5KvjYggDpR+NSN
CGQSWHfZASAYDpxjrOo+rk4xnO+sbuuMk7gORsrl+jgRT8F2VqoR9Z3CEdQxcCjR
5FsfTymZCk3GfIbWKkaeLQIDAQABo4H2MIHzMB0GA1UdDgQWBBRvx4NzSbWnY/91
3m1u/u37l6MsADCBtgYDVR0jBIGuMIGrgBRvx4NzSbWnY/913m1u/u37l6MsAKGB
h6SBhDCBgTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV
BAcMDVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDE0MDIGA1UEAwwrQmFk
U1NMIFVudHJ1c3RlZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eYIJAJeg/PrX
5Sj9MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IC
AQBQU9U8+jTRT6H9AIFm6y50tXTg/ySxRNmeP1Ey9Zf4jUE6yr3Q8xBv9gTFLiY1
qW2qfkDSmXVdBkl/OU3+xb5QOG5hW7wVolWQyKREV5EvUZXZxoH7LVEMdkCsRJDK
wYEKnEErFls5WPXY3bOglBOQqAIiuLQ0f77a2HXULDdQTn5SueW/vrA4RJEKuWxU
iD9XPnVZ9tPtky2Du7wcL9qhgTddpS/NgAuLO4PXh2TQ0EMCll5reZ5AEr0NSLDF
c/koDv/EZqB7VYhcPzr1bhQgbv1dl9NZU0dWKIMkRE/T7vZ97I3aPZqIapC2ulrf
KrlqjXidwrGFg8xbiGYQHPx3tHPZxoM5WG2voI6G3s1/iD+B4V6lUEvivd3f6tq7
d1V/3q1sL5DNv7TvaKGsq8g5un0TAkqaewJQ5fXLigF/yYu5a24/GUD783MdAPFv
gWz8F81evOyRfpf9CAqIswMF+T6Dwv3aw5L9hSniMrblkg+ai0K22JfoBcGOzMtB
Ke/Ps2Za56dTRoY/a4r62hrcGxufXd0mTdPaJLw3sJeHYjLxVAYWQq4QKJQWDgTS
dAEWyN2WXaBFPx5c8KIW95Eu8ShWE00VVC3oA4emoZ2nrzBXLrUScifY6VaYYkkR
2O2tSqU8Ri3XRdgpNPDWp8ZL49KhYGYo3R/k98gnMHiY5g==
-----END CERTIFICATE-----
1 change: 1 addition & 0 deletions website/content/usage/executors/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ debug: Debug option, will log everything when this option is not empty
tlsNoVerifyPeer: false (default) or true. If true, disables verification of the remote SSL certificate's validity.
tlsCertificateFile: Path to the PEM file containing the client certificate. Optional.
tlsCertificateKeyFile: Path to the PEM file containing the client certificate private key. Optional.
tlsRootCAsFile: Path to the PEM file containing certificates to use as root CAs. Optional.
```

Example
Expand Down

0 comments on commit 82dcfc7

Please sign in to comment.