Skip to content

Commit ff4e448

Browse files
committed
Larger file can be sent to credhub
1 parent feff669 commit ff4e448

File tree

20 files changed

+1194
-262
lines changed

20 files changed

+1194
-262
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
An [http backend](https://www.terraform.io/docs/backends/types/http.html) which stores and retrieves tfstates files in a secure and encrypted way through [credhub](https://github.com/cloudfoundry-incubator/credhub).
44

5+
When file is too large for database use in credhub, file will be split in part and gzipped to be sent to credhub and rebuild final file when retrieving from credhub.
6+
57
This backend supports [state locking](https://www.terraform.io/docs/state/locking.html).
68

79
## Boshrelease
@@ -67,7 +69,8 @@ There is two different ways to run the server:
6769
```yaml
6870
host: 0.0.0.0 # an be 127.0.0.1 too
6971
port: 8080 # port to listen
70-
name: terraform-secure # this name inside credhub to create an unique path for your tfstate
72+
chunk_size: ~ # Chunk size in number of bytes to split your tfstate inside credhub to leverage database limit (Default: 60000)
73+
base_path: /terraform-secure-backend/tfstate/pouet # Create an unique path for your tfstate on credhub
7174
cert: ~ # Set a path or pem cert string certificate to run your senver in tls (ignored if lets_encrypt_domains is set)
7275
key: ~ # Set a path or pem key string certificate to run your senver in tls (ignored if lets_encrypt_domains is set)
7376
log_level: ~ # Verbosity, can be info, debug, warning, error

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,8 @@ require (
3232
github.com/urfave/cli v1.20.0
3333
github.com/zclconf/go-cty v0.0.0-20190201220620-4ca19710f056 // indirect
3434
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613
35+
golang.org/x/net v0.0.0-20190225153610-fe579d43d832 // indirect
36+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
37+
golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12 // indirect
3538
gopkg.in/yaml.v2 v2.2.2
3639
)

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,22 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r
174174
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
175175
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76 h1:xx5MUFyRQRbPk6VjWjIE1epE/K5AoDD8QUN116NCy8k=
176176
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
177+
golang.org/x/net v0.0.0-20190225153610-fe579d43d832 h1:2IdId8zoI92l1bUzjAOygcAOkmCe13HY1j0rqPPPzB8=
178+
golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
177179
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
178180
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
179181
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
182+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
183+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
180184
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
181185
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
182186
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
183187
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
184188
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
185189
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 h1:0oC8rFnE+74kEmuHZ46F6KHsMr5Gx2gUQPuNz28iQZM=
186190
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
191+
golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12 h1:Zw7eRv6INHGfu15LVRN1vrrwusJbnfJjAZn3D1VkQIE=
192+
golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
187193
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
188194
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
189195
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=

server/api.go

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
package server
22

33
import (
4-
"code.cloudfoundry.org/credhub-cli/credhub/credentials/values"
54
"encoding/json"
65
"fmt"
76
"github.com/gorilla/mux"
87
"github.com/hashicorp/terraform/state"
8+
"github.com/orange-cloudfoundry/terraform-secure-backend/server/credhub"
9+
"github.com/orange-cloudfoundry/terraform-secure-backend/server/storer"
910
"github.com/sirupsen/logrus"
11+
"io"
1012
"io/ioutil"
1113
"net/http"
1214
"strings"
1315
)
1416

1517
type ApiController struct {
16-
name string
17-
credhubClient CredhubClient
18+
basePath string
19+
storer storer.Storer
1820
store *LockStore
21+
credhubClient credhub.CredhubClient
1922
}
2023

21-
func NewApiController(name string, credhubClient CredhubClient, store *LockStore) *ApiController {
22-
return &ApiController{name, credhubClient, store}
24+
func NewApiController(basePath string, credhubClient credhub.CredhubClient, storer storer.Storer, store *LockStore) *ApiController {
25+
return &ApiController{basePath, storer, store, credhubClient}
2326
}
2427

2528
type CredModel struct {
@@ -34,18 +37,7 @@ func (c ApiController) Store(w http.ResponseWriter, req *http.Request) {
3437
defer req.Body.Close()
3538
entry := logrus.WithField("action", "store").WithField("name", c.RequestName(req))
3639
entry.Debug("Storing tfstate")
37-
var dataJson map[string]interface{}
38-
b, err := ioutil.ReadAll(req.Body)
39-
if err != nil {
40-
entry.Error(err)
41-
panic(err)
42-
}
43-
err = json.Unmarshal(b, &dataJson)
44-
if err != nil {
45-
entry.Error(err)
46-
panic(err)
47-
}
48-
_, err = c.credhubClient.SetJSON(c.CredhubName(req), values.JSON(dataJson))
40+
err := c.storer.Store(c.CredhubName(req), req.Body)
4941
if err != nil {
5042
entry.Error(err)
5143
panic(err)
@@ -56,7 +48,7 @@ func (c ApiController) Retrieve(w http.ResponseWriter, req *http.Request) {
5648
defer req.Body.Close()
5749
entry := logrus.WithField("action", "retrieve").WithField("name", c.RequestName(req))
5850
entry.Debug("Retrieving tfstate")
59-
cred, err := c.credhubClient.GetLatestJSON(c.CredhubName(req))
51+
r, err := c.storer.Retrieve(c.CredhubName(req))
6052
if err != nil && strings.Contains(err.Error(), "does not exist") {
6153
w.WriteHeader(http.StatusNoContent)
6254
return
@@ -65,22 +57,22 @@ func (c ApiController) Retrieve(w http.ResponseWriter, req *http.Request) {
6557
entry.Error(err)
6658
panic(err)
6759
}
60+
defer r.Close()
6861
w.Header().Set("Content-Type", "application/json")
69-
b, _ := json.Marshal(cred.Value)
70-
w.Write(b)
62+
io.Copy(w, r)
7163
}
7264

7365
func (c ApiController) Delete(w http.ResponseWriter, req *http.Request) {
7466
defer req.Body.Close()
75-
name := c.CredhubName(req)
67+
path := c.CredhubName(req)
7668
entry := logrus.WithField("action", "delete").WithField("name", c.RequestName(req))
7769
entry.Debug("Deleting tfstate")
78-
err := c.credhubClient.Delete(name)
70+
err := c.storer.Delete(path)
7971
if err != nil {
8072
entry.Error(err)
8173
panic(err)
8274
}
83-
err = c.store.DeleteLock(name)
75+
err = c.store.DeleteLock(path)
8476
if err != nil {
8577
entry.Error(err)
8678
panic(err)
@@ -119,12 +111,8 @@ func (c ApiController) Lock(w http.ResponseWriter, req *http.Request) {
119111
}
120112
}
121113

122-
func (c ApiController) Path() string {
123-
return fmt.Sprintf("%s/%s", CREDHUB_PREFIX, c.name)
124-
}
125-
126114
func (c ApiController) CredhubName(req *http.Request) string {
127-
return fmt.Sprintf("%s/%s", c.Path(), c.RequestName(req))
115+
return fmt.Sprintf("%s/%s", c.basePath, c.RequestName(req))
128116
}
129117

130118
func (c ApiController) RequestName(req *http.Request) string {
@@ -165,7 +153,7 @@ func (c ApiController) UnLock(w http.ResponseWriter, req *http.Request) {
165153

166154
func (c ApiController) List(w http.ResponseWriter, req *http.Request) {
167155
entry := logrus.WithField("action", "list")
168-
result, err := c.credhubClient.FindByPath(c.Path())
156+
result, err := c.credhubClient.FindByPath(c.basePath)
169157
if err != nil {
170158
entry.Error(err)
171159
panic(err)

server/api_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package server_test
22

33
import (
4-
. "github.com/orange-cloudfoundry/terraform-secure-backend/server"
5-
64
"bytes"
75
"code.cloudfoundry.org/credhub-cli/credhub/credentials"
86
"code.cloudfoundry.org/credhub-cli/credhub/credentials/values"
@@ -11,7 +9,9 @@ import (
119
"github.com/hashicorp/terraform/state"
1210
. "github.com/onsi/ginkgo"
1311
. "github.com/onsi/gomega"
14-
"github.com/orange-cloudfoundry/terraform-secure-backend/server/serverfakes"
12+
. "github.com/orange-cloudfoundry/terraform-secure-backend/server"
13+
"github.com/orange-cloudfoundry/terraform-secure-backend/server/credhub/credhubfakes"
14+
"github.com/orange-cloudfoundry/terraform-secure-backend/server/storer"
1515
log "github.com/sirupsen/logrus"
1616
"io/ioutil"
1717
"net/http"
@@ -20,15 +20,17 @@ import (
2020

2121
var _ = Describe("Api", func() {
2222
log.SetOutput(ioutil.Discard)
23-
var fakeClient *serverfakes.FakeCredhubClient
23+
var fakeClient *credhubfakes.FakeCredhubClient
24+
var cStorer *storer.Credhub
2425
var apiController *ApiController
2526
var lockStore *LockStore
2627
var responseRecorder *httptest.ResponseRecorder
2728
BeforeEach(func() {
2829
responseRecorder = httptest.NewRecorder()
29-
fakeClient = new(serverfakes.FakeCredhubClient)
30+
fakeClient = new(credhubfakes.FakeCredhubClient)
31+
cStorer = storer.NewCredhub(fakeClient)
3032
lockStore = NewLockStore(fakeClient)
31-
apiController = NewApiController("test", fakeClient, lockStore)
33+
apiController = NewApiController("test", fakeClient, cStorer, lockStore)
3234
})
3335
Context("Store", func() {
3436
It("should store data when giving state", func() {

0 commit comments

Comments
 (0)