0
0
mirror of https://github.com/thegeeklab/wp-opentofu.git synced 2024-11-09 18:00:40 +00:00

Merge pull request #46 from jmccann/secrets

Remove secrets
This commit is contained in:
Jacob McCann 2017-09-06 10:54:04 -05:00 committed by GitHub
commit 4423c336c5
16 changed files with 811 additions and 52 deletions

64
DOCS.md
View File

@ -29,8 +29,11 @@ pipeline:
+ app_version: 1.0.0
```
Example configuration passing secrets to terraform via `vars`. The following
example will call `terraform apply -var my_secret=${TERRAFORM_SECRET}`:
Example configuration passing secrets to terraform. Please read
https://www.terraform.io/docs/configuration/variables.html#environment-variables
for more details.
**Drone 0.6+**:
```diff
pipeline:
@ -38,7 +41,26 @@ pipeline:
image: jmccann/drone-terraform:1
plan: false
+ secrets:
+ my_secret: TERRAFORM_SECRET
+ - source: terraform_secret
+ target: tf_var_my_secret
```
**Drone 0.5**:
```diff
pipeline:
terraform_1:
image: jmccann/drone-terraform:1
plan: false
+ environment:
+ TF_VAR_MY_SECRET: ${TERRAFORM_SECRET}
terraform_2:
image: jmccann/drone-terraform:1
plan: false
+ sensitive: true
+ vars:
+ my_secret: ${TERRAFORM_SECRET}
```
You may be passing sensitive vars to your terraform commands. If you do not want
@ -138,36 +160,6 @@ pipeline:
+ parallelism: 2
```
If you need to set different ENV secrets for multiple `terraform` steps you can utilize `secrets`.
The following example shows using different remotes secrets each step.
```yaml
pipeline:
dev_terraform:
image: jmccann/drone-terraform:1
plan: false
init_options:
backend_config:
- "bucket=my-terraform-config-bucket"
- "key=tf-states/my-project"
- "region=us-east-1"
+ secrets:
+ AWS_ACCESS_KEY_ID: DEV_AWS_ACCESS_KEY_ID
+ AWS_SECRET_ACCESS_KEY: DEV_AWS_SECRET_ACCESS_KEY
prod_terraform:
image: jmccann/drone-terraform:1
plan: false
init_options:
backend_config:
- "bucket=my-terraform-config-bucket"
- "key=tf-states/my-project"
- "region=us-east-1"
+ secrets:
+ AWS_ACCESS_KEY_ID: PROD_AWS_ACCESS_KEY_ID
+ AWS_SECRET_ACCESS_KEY: PROD_AWS_SECRET_ACCESS_KEY
```
Destroying the service can be done using the boolean `destory` option. Keep in mind that Fastly won't allow a service with active version be destoryed. Use `force_destroy` option in the service definition for terraform to handle it.
```yaml
@ -205,12 +197,6 @@ var_files
: a list of variable files to pass to the Terraform `plan` and `apply` commands.
Each value is passed as a `-var-file <value>` option.
secrets
: a map of variables to pass to the Terraform `plan` and `apply` commands as well as setting envvars.
The `key` is the var and ENV to set. The `value` is the ENV to read the value from.
* Each entry generate a terraform var as follows: `-var <key>=$<value>`
* Additionally each entry generate sets and envvar as follows: `key=$value`
ca_cert
: ca cert to add to your environment to allow terraform to use internal/private resources

View File

@ -1,6 +1,6 @@
# Docker image for the Drone Terraform plugin
#
# docker build --rm=true -t jmccann/drone-terraform:latest .
# docker build -t jmccann/drone-terraform:latest .
FROM golang:1.8-alpine AS builder
COPY ./*.go ./src/
COPY ./vendor/ ./src/

View File

@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"os/exec"
"regexp"
"strings"
"time"
@ -53,9 +54,7 @@ func (p Plugin) Exec() error {
var commands []*exec.Cmd
if len(p.Config.Secrets) != 0 {
exportSecrets(p.Config.Secrets)
}
CopyTfEnv()
if p.Config.Cacert != "" {
commands = append(commands, installCaCert(p.Config.Cacert))
@ -108,9 +107,14 @@ func installCaCert(cacert string) *exec.Cmd {
)
}
func exportSecrets(secrets map[string]string) {
for k, v := range secrets {
os.Setenv(fmt.Sprintf("%s", k), fmt.Sprintf("%s", os.Getenv(v)))
func CopyTfEnv() {
tfVar := regexp.MustCompile(`^TF_VAR_.*$`)
for _, e := range os.Environ() {
pair := strings.SplitN(e, "=", 2)
if tfVar.MatchString(pair[0]) {
name := strings.Split(pair[0], "TF_VAR_")
os.Setenv(fmt.Sprintf("TF_VAR_%s", strings.ToLower(name[1])), pair[1])
}
}
}
@ -187,10 +191,6 @@ func planCommand(config Config) *exec.Cmd {
args = append(args, "-var")
args = append(args, fmt.Sprintf("%s=%s", k, v))
}
for k, v := range config.Secrets {
args = append(args, "-var")
args = append(args, fmt.Sprintf("%s=%s", k, os.Getenv(v)))
}
if config.Parallelism > 0 {
args = append(args, fmt.Sprintf("-parallelism=%d", config.Parallelism))
}

View File

@ -1,9 +1,12 @@
package main
import (
"os"
"os/exec"
"reflect"
"testing"
. "github.com/franela/goblin"
)
func Test_destroyCommand(t *testing.T) {
@ -131,3 +134,23 @@ func Test_planCommand(t *testing.T) {
})
}
}
func TestPlugin(t *testing.T) {
g := Goblin(t)
g.Describe("CopyTfEnv", func() {
g.It("Should create copies of TF_VAR_ to lowercase", func() {
// Set some initial TF_VAR_ that are uppercase
os.Setenv("TF_VAR_SOMETHING", "some value")
os.Setenv("TF_VAR_SOMETHING_ELSE", "some other value")
os.Setenv("TF_VAR_BASE64", "dGVzdA==")
CopyTfEnv()
// Make sure new env vars exist with proper values
g.Assert(os.Getenv("TF_VAR_something")).Equal("some value")
g.Assert(os.Getenv("TF_VAR_something_else")).Equal("some other value")
g.Assert(os.Getenv("TF_VAR_base64")).Equal("dGVzdA==")
})
})
}

19
vendor/github.com/franela/goblin/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2013 Marcos Lilljedahl and Jonathan Leibiusky
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

3
vendor/github.com/franela/goblin/Makefile generated vendored Normal file
View File

@ -0,0 +1,3 @@
export GOPATH=$(shell pwd)
test:
go test -v

141
vendor/github.com/franela/goblin/README.md generated vendored Normal file
View File

@ -0,0 +1,141 @@
[![Build Status](https://travis-ci.org/franela/goblin.png?branch=master)](https://travis-ci.org/franela/goblin)
Goblin
======
![](https://github.com/marcosnils/goblin/blob/master/goblin_logo.jpg?raw=true)
A [Mocha](http://mochajs.org/) like BDD testing framework for Go
No extensive documentation nor complicated steps to get it running
Run tests as usual with `go test`
Colorful reports and beautiful syntax
Why Goblin?
-----------
Inspired by the flexibility and simplicity of Node BDD and frustrated by the
rigorousness of Go way of testing, we wanted to bring a new tool to
write self-describing and comprehensive code.
What do I get with it?
----------------------
- Preserve the exact same syntax and behaviour as Node's Mocha
- Nest as many `Describe` and `It` blocks as you want
- Use `Before`, `BeforeEach`, `After` and `AfterEach` for setup and teardown your tests
- No need to remember confusing parameters in `Describe` and `It` blocks
- Use a declarative and expressive language to write your tests
- Plug different assertion libraries ([Gomega](https://github.com/onsi/gomega) supported so far)
- Skip your tests the same way as you would do in Mocha
- Automatic terminal support for colored outputs
- Two line setup is all you need to get up running
How do I use it?
----------------
Since ```go test``` is not currently extensive, you will have to hook Goblin to it. You do that by
adding a single test method in your test file. All your goblin tests will be implemented inside this function.
```go
package foobar
import (
"testing"
. "github.com/franela/goblin"
)
func Test(t *testing.T) {
g := Goblin(t)
g.Describe("Numbers", func() {
g.It("Should add two numbers ", func() {
g.Assert(1+1).Equal(2)
})
g.It("Should match equal numbers", func() {
g.Assert(2).Equal(4)
})
g.It("Should substract two numbers")
})
}
```
Ouput will be something like:
![](https://github.com/marcosnils/goblin/blob/master/goblin_output.png?raw=true)
Nice and easy, right?
Can I do asynchronous tests?
----------------------------
Yes! Goblin will help you to test asynchronous things, like goroutines, etc. You just need to add a ```done``` parameter to the handler function of your ```It```. This handler function should be called when your test passes.
```go
...
g.Describe("Numbers", func() {
g.It("Should add two numbers asynchronously", func(done Done) {
go func() {
g.Assert(1+1).Equal(2)
done()
}()
})
})
...
```
Goblin will wait for the ```done``` call, a ```Fail``` call or any false assertion.
How do I use it with Gomega?
----------------------------
Gomega is a nice assertion framework. But it doesn't provide a nice way to hook it to testing frameworks. It should just panic instead of requiring a fail function. There is an issue about that [here](https://github.com/onsi/gomega/issues/5).
While this is being discussed and hopefully fixed, the way to use Gomega with Goblin is:
```go
package foobar
import (
"testing"
. "github.com/franela/goblin"
. "github.com/onsi/gomega"
)
func Test(t *testing.T) {
g := Goblin(t)
//special hook for gomega
RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })
g.Describe("lala", func() {
g.It("lslslslsls", func() {
Expect(1).To(Equal(10))
})
})
}
```
FAQ:
----
### How do I run specific tests?
If `-goblin.run=$REGES` is supplied to the `go test` command then only tests that match the supplied regex will run
TODO:
-----
We do have a couple of [issues](https://github.com/franela/goblin/issues) pending we'll be addressing soon. But feel free to
contribute and send us PRs (with tests please :smile:).
Contributions:
------------
Special thanks to [Leandro Reox](https://github.com/leandroreox) (Leitan) for the goblin logo.

59
vendor/github.com/franela/goblin/assertions.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
package goblin
import (
"fmt"
"reflect"
"strings"
)
type Assertion struct {
src interface{}
fail func(interface{})
}
func objectsAreEqual(a, b interface{}) bool {
if reflect.TypeOf(a) != reflect.TypeOf(b) {
return false
}
if reflect.DeepEqual(a, b) {
return true
}
if fmt.Sprintf("%#v", a) == fmt.Sprintf("%#v", b) {
return true
}
return false
}
func formatMessages(messages ...string) string {
if len(messages) > 0 {
return ", " + strings.Join(messages, " ")
}
return ""
}
func (a *Assertion) Eql(dst interface{}) {
a.Equal(dst)
}
func (a *Assertion) Equal(dst interface{}) {
if !objectsAreEqual(a.src, dst) {
a.fail(fmt.Sprintf("%#v %s %#v", a.src, "does not equal", dst))
}
}
func (a *Assertion) IsTrue(messages ...string) {
if !objectsAreEqual(a.src, true) {
message := fmt.Sprintf("%v %s%s", a.src, "expected false to be truthy", formatMessages(messages...))
a.fail(message)
}
}
func (a *Assertion) IsFalse(messages ...string) {
if !objectsAreEqual(a.src, false) {
message := fmt.Sprintf("%v %s%s", a.src, "expected true to be falsey", formatMessages(messages...))
a.fail(message)
}
}

36
vendor/github.com/franela/goblin/go.snippets generated vendored Normal file
View File

@ -0,0 +1,36 @@
snippet gd
g.Describe("${1:name}", func() {
${2}
})
${0}
snippet git
g.It("${1:name}", func() {
${2}
})
${0}
snippet gait
g.It("${1:name}", func(done Done) {
done()
${2}
})
${0}
snippet gb
g.Before(func() {
${1}
})
${0}
snippet gbe
g.BeforeEach(func() {
${1}
})
${0}
snippet ga
g.After(func() {
${1}
})
${0}
snippet gae
g.AfterEach(func() {
${1}
})
${0}

302
vendor/github.com/franela/goblin/goblin.go generated vendored Normal file
View File

@ -0,0 +1,302 @@
package goblin
import (
"flag"
"fmt"
"regexp"
"runtime"
"sync"
"testing"
"time"
)
type Done func(error ...interface{})
type Runnable interface {
run(*G) bool
}
func (g *G) Describe(name string, h func()) {
d := &Describe{name: name, h: h, parent: g.parent}
if d.parent != nil {
d.parent.children = append(d.parent.children, Runnable(d))
}
g.parent = d
h()
g.parent = d.parent
if g.parent == nil && d.hasTests {
g.reporter.begin()
if d.run(g) {
g.t.Fail()
}
g.reporter.end()
}
}
func (g *G) Timeout(time time.Duration) {
g.timeout = time
g.timer.Reset(time)
}
type Describe struct {
name string
h func()
children []Runnable
befores []func()
afters []func()
afterEach []func()
beforeEach []func()
hasTests bool
parent *Describe
}
func (d *Describe) runBeforeEach() {
if d.parent != nil {
d.parent.runBeforeEach()
}
for _, b := range d.beforeEach {
b()
}
}
func (d *Describe) runAfterEach() {
if d.parent != nil {
d.parent.runAfterEach()
}
for _, a := range d.afterEach {
a()
}
}
func (d *Describe) run(g *G) bool {
failed := false
if d.hasTests {
g.reporter.beginDescribe(d.name)
for _, b := range d.befores {
b()
}
for _, r := range d.children {
if r.run(g) {
failed = true
}
}
for _, a := range d.afters {
a()
}
g.reporter.endDescribe()
}
return failed
}
type Failure struct {
stack []string
testName string
message string
}
type It struct {
h interface{}
name string
parent *Describe
failure *Failure
reporter Reporter
isAsync bool
}
func (it *It) run(g *G) bool {
g.currentIt = it
if it.h == nil {
g.reporter.itIsPending(it.name)
return false
}
//TODO: should handle errors for beforeEach
it.parent.runBeforeEach()
runIt(g, it.h)
it.parent.runAfterEach()
failed := false
if it.failure != nil {
failed = true
}
if failed {
g.reporter.itFailed(it.name)
g.reporter.failure(it.failure)
} else {
g.reporter.itPassed(it.name)
}
return failed
}
func (it *It) failed(msg string, stack []string) {
it.failure = &Failure{stack: stack, message: msg, testName: it.parent.name + " " + it.name}
}
func parseFlags() {
//Flag parsing
flag.Parse()
if *regexParam != "" {
runRegex = regexp.MustCompile(*regexParam)
} else {
runRegex = nil
}
}
var timeout = flag.Duration("goblin.timeout", 5*time.Second, "Sets default timeouts for all tests")
var isTty = flag.Bool("goblin.tty", true, "Sets the default output format (color / monochrome)")
var regexParam = flag.String("goblin.run", "", "Runs only tests which match the supplied regex")
var runRegex *regexp.Regexp
func init() {
parseFlags()
}
func Goblin(t *testing.T, arguments ...string) *G {
g := &G{t: t, timeout: *timeout}
var fancy TextFancier
if *isTty {
fancy = &TerminalFancier{}
} else {
fancy = &Monochrome{}
}
g.reporter = Reporter(&DetailedReporter{fancy: fancy})
return g
}
func runIt(g *G, h interface{}) {
defer timeTrack(time.Now(), g)
g.mutex.Lock()
g.timedOut = false
g.mutex.Unlock()
g.timer = time.NewTimer(g.timeout)
g.shouldContinue = make(chan bool)
if call, ok := h.(func()); ok {
// the test is synchronous
go func(c chan bool) { call(); c <- true }(g.shouldContinue)
} else if call, ok := h.(func(Done)); ok {
doneCalled := 0
go func(c chan bool) {
call(func(msg ...interface{}) {
if len(msg) > 0 {
g.Fail(msg)
} else {
doneCalled++
if doneCalled > 1 {
g.Fail("Done called multiple times")
}
c <- true
}
})
}(g.shouldContinue)
} else {
panic("Not implemented.")
}
select {
case <-g.shouldContinue:
case <-g.timer.C:
//Set to nil as it shouldn't continue
g.shouldContinue = nil
g.timedOut = true
g.Fail("Test exceeded " + fmt.Sprintf("%s", g.timeout))
}
// Reset timeout value
g.timeout = *timeout
}
type G struct {
t *testing.T
parent *Describe
currentIt *It
timeout time.Duration
reporter Reporter
timedOut bool
shouldContinue chan bool
mutex sync.Mutex
timer *time.Timer
}
func (g *G) SetReporter(r Reporter) {
g.reporter = r
}
func (g *G) It(name string, h ...interface{}) {
if matchesRegex(name) {
it := &It{name: name, parent: g.parent, reporter: g.reporter}
notifyParents(g.parent)
if len(h) > 0 {
it.h = h[0]
}
g.parent.children = append(g.parent.children, Runnable(it))
}
}
func matchesRegex(value string) bool {
if runRegex != nil {
return runRegex.MatchString(value)
}
return true
}
func notifyParents(d *Describe) {
d.hasTests = true
if d.parent != nil {
notifyParents(d.parent)
}
}
func (g *G) Before(h func()) {
g.parent.befores = append(g.parent.befores, h)
}
func (g *G) BeforeEach(h func()) {
g.parent.beforeEach = append(g.parent.beforeEach, h)
}
func (g *G) After(h func()) {
g.parent.afters = append(g.parent.afters, h)
}
func (g *G) AfterEach(h func()) {
g.parent.afterEach = append(g.parent.afterEach, h)
}
func (g *G) Assert(src interface{}) *Assertion {
return &Assertion{src: src, fail: g.Fail}
}
func timeTrack(start time.Time, g *G) {
g.reporter.itTook(time.Since(start))
}
func (g *G) Fail(error interface{}) {
//Skips 7 stacks due to the functions between the stack and the test
stack := ResolveStack(7)
message := fmt.Sprintf("%v", error)
g.currentIt.failed(message, stack)
if g.shouldContinue != nil {
g.shouldContinue <- true
}
g.mutex.Lock()
defer g.mutex.Unlock()
if !g.timedOut {
//Stop test function execution
runtime.Goexit()
}
}

BIN
vendor/github.com/franela/goblin/goblin_logo.jpg generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
vendor/github.com/franela/goblin/goblin_output.png generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

26
vendor/github.com/franela/goblin/mono_reporter.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
package goblin
import ()
type Monochrome struct {
}
func (self *Monochrome) Red(text string) string {
return "!" + text
}
func (self *Monochrome) Gray(text string) string {
return text
}
func (self *Monochrome) Cyan(text string) string {
return text
}
func (self *Monochrome) WithCheck(text string) string {
return ">>>" + text
}
func (self *Monochrome) Green(text string) string {
return text
}

137
vendor/github.com/franela/goblin/reporting.go generated vendored Normal file
View File

@ -0,0 +1,137 @@
package goblin
import (
"fmt"
"strconv"
"strings"
"time"
)
type Reporter interface {
beginDescribe(string)
endDescribe()
begin()
end()
failure(*Failure)
itTook(time.Duration)
itFailed(string)
itPassed(string)
itIsPending(string)
}
type TextFancier interface {
Red(text string) string
Gray(text string) string
Cyan(text string) string
Green(text string) string
WithCheck(text string) string
}
type DetailedReporter struct {
level, failed, passed, pending int
failures []*Failure
executionTime, totalExecutionTime time.Duration
fancy TextFancier
}
func (r *DetailedReporter) SetTextFancier(f TextFancier) {
r.fancy = f
}
type TerminalFancier struct {
}
func (self *TerminalFancier) Red(text string) string {
return "\033[31m" + text + "\033[0m"
}
func (self *TerminalFancier) Gray(text string) string {
return "\033[90m" + text + "\033[0m"
}
func (self *TerminalFancier) Cyan(text string) string {
return "\033[36m" + text + "\033[0m"
}
func (self *TerminalFancier) Green(text string) string {
return "\033[32m" + text + "\033[0m"
}
func (self *TerminalFancier) WithCheck(text string) string {
return "\033[32m\u2713\033[0m " + text
}
func (r *DetailedReporter) getSpace() string {
return strings.Repeat(" ", (r.level+1)*2)
}
func (r *DetailedReporter) failure(failure *Failure) {
r.failures = append(r.failures, failure)
}
func (r *DetailedReporter) print(text string) {
fmt.Printf("%v%v\n", r.getSpace(), text)
}
func (r *DetailedReporter) printWithCheck(text string) {
fmt.Printf("%v%v\n", r.getSpace(), r.fancy.WithCheck(text))
}
func (r *DetailedReporter) beginDescribe(name string) {
fmt.Println("")
r.print(name)
r.level++
}
func (r *DetailedReporter) endDescribe() {
r.level--
}
func (r *DetailedReporter) itTook(duration time.Duration) {
r.executionTime = duration
r.totalExecutionTime += duration
}
func (r *DetailedReporter) itFailed(name string) {
r.failed++
r.print(r.fancy.Red(strconv.Itoa(r.failed) + ") " + name))
}
func (r *DetailedReporter) itPassed(name string) {
r.passed++
r.printWithCheck(r.fancy.Gray(name))
}
func (r *DetailedReporter) itIsPending(name string) {
r.pending++
r.print(r.fancy.Cyan("- " + name))
}
func (r *DetailedReporter) begin() {
}
func (r *DetailedReporter) end() {
comp := fmt.Sprintf("%d tests complete", r.passed)
t := fmt.Sprintf("(%d ms)", r.totalExecutionTime/time.Millisecond)
//fmt.Printf("\n\n \033[32m%d tests complete\033[0m \033[90m(%d ms)\033[0m\n", r.passed, r.totalExecutionTime/time.Millisecond)
fmt.Printf("\n\n %v %v\n", r.fancy.Green(comp), r.fancy.Gray(t))
if r.pending > 0 {
pend := fmt.Sprintf("%d test(s) pending", r.pending)
fmt.Printf(" %v\n\n", r.fancy.Cyan(pend))
}
if len(r.failures) > 0 {
fmt.Printf("%s \n\n", r.fancy.Red(fmt.Sprintf(" %d tests failed:", len(r.failures))))
}
for i, failure := range r.failures {
fmt.Printf(" %d) %s:\n\n", i+1, failure.testName)
fmt.Printf(" %s\n", r.fancy.Red(failure.message))
for _, stackItem := range failure.stack {
fmt.Printf(" %s\n", r.fancy.Gray(stackItem))
}
}
}

21
vendor/github.com/franela/goblin/resolver.go generated vendored Normal file
View File

@ -0,0 +1,21 @@
package goblin
import (
"runtime/debug"
"strings"
)
func ResolveStack(skip int) []string {
return cleanStack(debug.Stack(), skip)
}
func cleanStack(stack []byte, skip int) []string {
arrayStack := strings.Split(string(stack), "\n")
var finalStack []string
for i := skip; i < len(arrayStack); i++ {
if strings.Contains(arrayStack[i], ".go") {
finalStack = append(finalStack, arrayStack[i])
}
}
return finalStack
}

8
vendor/vendor.json vendored
View File

@ -144,6 +144,12 @@
"revision": "c0d7d3282e4c14991a4814de7eae4774e388de61",
"revisionTime": "2016-10-07T22:43:33Z"
},
{
"checksumSHA1": "ip3Xz/dILw2RMM6Z0MzAj5TUZ/c=",
"path": "github.com/franela/goblin",
"revision": "2fa789fd0c6b7975acbfb89a04830b4081a7b0e9",
"revisionTime": "2017-01-11T05:10:28Z"
},
{
"checksumSHA1": "cVyhKIRI2gQrgpn5qrBeAqErmWM=",
"path": "github.com/go-ini/ini",
@ -175,5 +181,5 @@
"revisionTime": "2016-10-06T02:47:49Z"
}
],
"rootPath": "github.com/drone-plugins/drone-terraform"
"rootPath": "github.com/jmccann/drone-terraform"
}