Skip to content
This repository was archived by the owner on Mar 8, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/keylockerbv/secrethub-clientd

require (
github.com/gorilla/mux v1.7.0
github.com/keylockerbv/secrethub-go v0.0.0-20190225132925-244d98858e9d
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b // indirect
)
38 changes: 38 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
bitbucket.org/zombiezen/cardcpx v0.0.0-20150417151802-902f68ff43ef h1:Y5Zf3CYdrdGE7GOuK/MNN98GS1V8mOfeiJlISrKUcEo=
bitbucket.org/zombiezen/cardcpx v0.0.0-20150417151802-902f68ff43ef/go.mod h1:ZJR5FpaQx7Bt2bzIV3gBaCInI1+kG949WhNYYlRr8eA=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448 h1:8tNk6SPXzLDnATTrWoI5Bgw9s/x4uf0kmBpk21NZgI4=
github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/go-chi/chi v4.0.1+incompatible h1:RSRC5qmFPtO90t7pTL0DBMNpZFsb/sHF3RXVlDgFisA=
github.com/go-chi/chi v4.0.1+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/keylockerbv/secrethub-go v0.0.0-20190225132925-244d98858e9d h1:NxCFGfkmBF9RaloxF5c/J5knS3FE/g+uWOZ9ENucc1M=
github.com/keylockerbv/secrethub-go v0.0.0-20190225132925-244d98858e9d/go.mod h1:U086plZMagUfy92G4DgCsRAns20Q5j+Rf8bYDXiDxMw=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
134 changes: 134 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package main

import (
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"

"github.com/gorilla/mux"
"github.com/keylockerbv/secrethub-go/pkg/api"
"github.com/keylockerbv/secrethub-go/pkg/errio"
"github.com/keylockerbv/secrethub-go/pkg/secrethub"
)

var (
credential string
credentialPassphrase string
port int
client secrethub.Client
)

func init() {
flag.StringVar(&credential, "C", "", "(Required) SecretHub credential")
flag.StringVar(&credentialPassphrase, "P", "", "Passphrase to unlock SecretHub credential")
flag.IntVar(&port, "p", 8080, "HTTP port to listen on")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SecretHub CLI has a --credential-passphrase flag with a shortcut -p. Not sure what we want to do here

flag.Parse()

if credential == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see these flags either sourced from:

  1. The default ~/.secrethub/credential file
  2. The SECRETHUB_CREDENTIAL envar
  3. The --credential flag

It's not entirely necessary for the MVP, but it would be very nice to make it consistent with current CLI behavior.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if the same DRY function could be used there. What do you think @SimonBarendse?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that would be the preferred end-state.

However, I think for now it’s better to duplicate it in an internal package, so that the cli open-source release doesnt become a blocker for the terrraform open-source release. If we use the same signature, we can replace it (deduplicate) with the cli package when that is open-source.

flag.Usage()
exit(fmt.Errorf("credential is required"))
}

cred, err := secrethub.NewCredential(credential, credentialPassphrase)
if err != nil {
exit(err)
}

client = secrethub.NewClient(cred, nil)
}

func main() {
err := startHTTPServer()
if err != nil {
exit(err)
}
}

func startHTTPServer() error {
mux := mux.NewRouter()
v1 := mux.PathPrefix("/v1/").Subrouter()

v1.PathPrefix("/secrets/").Handler(
http.StripPrefix("/v1/secrets/", http.HandlerFunc(handleSecret)),
)

fmt.Println("SecretHub Clientd started, press ^C to exit")
return http.ListenAndServe(fmt.Sprintf(":%v", port), mux)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think %v works here, but to be 'correct' it should be %d. If it works, fine.

}

func handleSecret(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
err := api.ValidateSecretPath(path)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, err.Error())
return
}

switch r.Method {
case "GET":
secret, err := client.Secrets().Versions().GetWithData(path)
if err != nil {
var errCode int

if err, ok := err.(errio.PublicStatusError); ok {
errCode = err.StatusCode
}

if errCode == 0 {
errCode = http.StatusInternalServerError
}

w.WriteHeader(errCode)
io.WriteString(w, err.Error())
return
}

w.WriteHeader(http.StatusOK)
w.Write(secret.Data)
case "POST":
secret, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, err.Error())
return
}

_, err = client.Secrets().Write(path, secret)
if err != nil {
var errCode int

if err, ok := err.(errio.PublicStatusError); ok {
errCode = err.StatusCode
}

switch err {
case secrethub.ErrCannotWriteToVersion,
secrethub.ErrEmptySecret,
secrethub.ErrSecretTooBig:
errCode = http.StatusBadRequest
}

if errCode == 0 {
errCode = http.StatusInternalServerError
}

w.WriteHeader(errCode)
io.WriteString(w, err.Error())
return
}

w.WriteHeader(http.StatusCreated)
default:
w.Header().Add("Allow", "GET, POST")
w.WriteHeader(http.StatusMethodNotAllowed)
}
}

func exit(err error) {
fmt.Printf("secrethub-clientd: error: %v\n", err)
os.Exit(1)
}