Skip to content

Commit

Permalink
adding (backwards compatible) support for providing multiple source f…
Browse files Browse the repository at this point in the history
…ilename and content (#11271)
  • Loading branch information
nevins-b authored and stack72 committed Jan 23, 2017
1 parent 87d98b1 commit 03b6dfd
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions builtin/providers/archive/archiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Archiver interface {
ArchiveContent(content []byte, infilename string) error
ArchiveFile(infilename string) error
ArchiveDir(indirname string) error
ArchiveMultiple(content map[string][]byte) error
}

type ArchiverBuilder func(filepath string) Archiver
Expand Down
39 changes: 39 additions & 0 deletions builtin/providers/archive/data_source_archive_file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package archive

import (
"bytes"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
Expand All @@ -11,6 +12,7 @@ import (
"os"
"path"

"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
)

Expand All @@ -24,6 +26,33 @@ func dataSourceFile() *schema.Resource {
Required: true,
ForceNew: true,
},
"source": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"content": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"filename": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
},
ConflictsWith: []string{"source_file", "source_dir", "source_content", "source_content_filename"},
Set: func(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["filename"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["content"].(string)))
return hashcode.String(buf.String())
},
},
"source_content": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -138,6 +167,16 @@ func archive(d *schema.ResourceData) error {
if err := archiver.ArchiveContent([]byte(content), filename.(string)); err != nil {
return fmt.Errorf("error archiving content: %s", err)
}
} else if v, ok := d.GetOk("source"); ok {
vL := v.(*schema.Set).List()
content := make(map[string][]byte)
for _, v := range vL {
src := v.(map[string]interface{})
content[src["filename"].(string)] = []byte(src["content"].(string))
}
if err := archiver.ArchiveMultiple(content); err != nil {
return fmt.Errorf("error archiving content: %s", err)
}
} else {
return fmt.Errorf("one of 'source_dir', 'source_file', 'source_content_filename' must be specified")
}
Expand Down
18 changes: 18 additions & 0 deletions builtin/providers/archive/data_source_archive_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ func TestAccArchiveFile_Basic(t *testing.T) {
r.TestCheckResourceAttrPtr("data.archive_file.foo", "output_size", &fileSize),
),
},
r.TestStep{
Config: testAccArchiveFileMultiConfig,
Check: r.ComposeTestCheckFunc(
testAccArchiveFileExists("zip_file_acc_test.zip", &fileSize),
r.TestCheckResourceAttrPtr("data.archive_file.foo", "output_size", &fileSize),
),
},
r.TestStep{
Config: testAccArchiveFileOutputPath,
Check: r.ComposeTestCheckFunc(
Expand Down Expand Up @@ -107,3 +114,14 @@ data "archive_file" "foo" {
output_path = "zip_file_acc_test.zip"
}
`

var testAccArchiveFileMultiConfig = `
data "archive_file" "foo" {
type = "zip"
source {
filename = "content.txt"
content = "This is some content"
}
output_path = "zip_file_acc_test.zip"
}
`
29 changes: 29 additions & 0 deletions builtin/providers/archive/zip_archiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"sort"
)

type ZipArchiver struct {
Expand Down Expand Up @@ -85,6 +86,34 @@ func (a *ZipArchiver) ArchiveDir(indirname string) error {

}

func (a *ZipArchiver) ArchiveMultiple(content map[string][]byte) error {
if err := a.open(); err != nil {
return err
}
defer a.close()

// Ensure files are processed in the same order so hashes don't change
keys := make([]string, len(content))
i := 0
for k := range content {
keys[i] = k
i++
}
sort.Strings(keys)

for _, filename := range keys {
f, err := a.writer.Create(filename)
if err != nil {
return err
}
_, err = f.Write(content[filename])
if err != nil {
return err
}
}
return nil
}

func (a *ZipArchiver) open() error {
f, err := os.Create(a.filepath)
if err != nil {
Expand Down
17 changes: 17 additions & 0 deletions builtin/providers/archive/zip_archiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ func TestZipArchiver_Dir(t *testing.T) {
})
}

func TestZipArchiver_Multiple(t *testing.T) {
zipfilepath := "archive-content.zip"
content := map[string][]byte{
"file1.txt": []byte("This is file 1"),
"file2.txt": []byte("This is file 2"),
"file3.txt": []byte("This is file 3"),
}

archiver := NewZipArchiver(zipfilepath)
if err := archiver.ArchiveMultiple(content); err != nil {
t.Fatalf("unexpected error: %s", err)
}

ensureContents(t, zipfilepath, content)

}

func ensureContents(t *testing.T, zipfilepath string, wants map[string][]byte) {
r, err := zip.OpenReader(zipfilepath)
if err != nil {
Expand Down

0 comments on commit 03b6dfd

Please sign in to comment.