github.com/nbering/terraform@v0.8.5-0.20170113232247-453f670684b5/builtin/providers/archive/data_source_archive_file.go (about)

     1  package archive
     2  
     3  import (
     4  	"crypto/md5"
     5  	"crypto/sha1"
     6  	"crypto/sha256"
     7  	"encoding/base64"
     8  	"encoding/hex"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"path"
    13  
    14  	"github.com/hashicorp/terraform/helper/schema"
    15  )
    16  
    17  func dataSourceFile() *schema.Resource {
    18  	return &schema.Resource{
    19  		Read: dataSourceFileRead,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"type": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  				ForceNew: true,
    26  			},
    27  			"source_content": &schema.Schema{
    28  				Type:          schema.TypeString,
    29  				Optional:      true,
    30  				ForceNew:      true,
    31  				ConflictsWith: []string{"source_file", "source_dir"},
    32  			},
    33  			"source_content_filename": &schema.Schema{
    34  				Type:          schema.TypeString,
    35  				Optional:      true,
    36  				ForceNew:      true,
    37  				ConflictsWith: []string{"source_file", "source_dir"},
    38  			},
    39  			"source_file": &schema.Schema{
    40  				Type:          schema.TypeString,
    41  				Optional:      true,
    42  				ForceNew:      true,
    43  				ConflictsWith: []string{"source_content", "source_content_filename", "source_dir"},
    44  			},
    45  			"source_dir": &schema.Schema{
    46  				Type:          schema.TypeString,
    47  				Optional:      true,
    48  				ForceNew:      true,
    49  				ConflictsWith: []string{"source_content", "source_content_filename", "source_file"},
    50  			},
    51  			"output_path": &schema.Schema{
    52  				Type:     schema.TypeString,
    53  				Required: true,
    54  			},
    55  			"output_size": &schema.Schema{
    56  				Type:     schema.TypeInt,
    57  				Computed: true,
    58  				ForceNew: true,
    59  			},
    60  			"output_sha": &schema.Schema{
    61  				Type:        schema.TypeString,
    62  				Computed:    true,
    63  				ForceNew:    true,
    64  				Description: "SHA1 checksum of output file",
    65  			},
    66  			"output_base64sha256": &schema.Schema{
    67  				Type:        schema.TypeString,
    68  				Computed:    true,
    69  				ForceNew:    true,
    70  				Description: "Base64 Encoded SHA256 checksum of output file",
    71  			},
    72  			"output_md5": &schema.Schema{
    73  				Type:        schema.TypeString,
    74  				Computed:    true,
    75  				ForceNew:    true,
    76  				Description: "MD5 of output file",
    77  			},
    78  		},
    79  	}
    80  }
    81  
    82  func dataSourceFileRead(d *schema.ResourceData, meta interface{}) error {
    83  	outputPath := d.Get("output_path").(string)
    84  
    85  	outputDirectory := path.Dir(outputPath)
    86  	if outputDirectory != "" {
    87  		if _, err := os.Stat(outputDirectory); err != nil {
    88  			if err := os.MkdirAll(outputDirectory, 0755); err != nil {
    89  				return err
    90  			}
    91  		}
    92  	}
    93  
    94  	if err := archive(d); err != nil {
    95  		return err
    96  	}
    97  
    98  	// Generate archived file stats
    99  	fi, err := os.Stat(outputPath)
   100  	if err != nil {
   101  		return err
   102  	}
   103  
   104  	sha1, base64sha256, md5, err := genFileShas(outputPath)
   105  	if err != nil {
   106  
   107  		return fmt.Errorf("could not generate file checksum sha256: %s", err)
   108  	}
   109  	d.Set("output_sha", sha1)
   110  	d.Set("output_base64sha256", base64sha256)
   111  	d.Set("output_md5", md5)
   112  
   113  	d.Set("output_size", fi.Size())
   114  	d.SetId(d.Get("output_sha").(string))
   115  
   116  	return nil
   117  }
   118  
   119  func archive(d *schema.ResourceData) error {
   120  	archiveType := d.Get("type").(string)
   121  	outputPath := d.Get("output_path").(string)
   122  
   123  	archiver := getArchiver(archiveType, outputPath)
   124  	if archiver == nil {
   125  		return fmt.Errorf("archive type not supported: %s", archiveType)
   126  	}
   127  
   128  	if dir, ok := d.GetOk("source_dir"); ok {
   129  		if err := archiver.ArchiveDir(dir.(string)); err != nil {
   130  			return fmt.Errorf("error archiving directory: %s", err)
   131  		}
   132  	} else if file, ok := d.GetOk("source_file"); ok {
   133  		if err := archiver.ArchiveFile(file.(string)); err != nil {
   134  			return fmt.Errorf("error archiving file: %s", err)
   135  		}
   136  	} else if filename, ok := d.GetOk("source_content_filename"); ok {
   137  		content := d.Get("source_content").(string)
   138  		if err := archiver.ArchiveContent([]byte(content), filename.(string)); err != nil {
   139  			return fmt.Errorf("error archiving content: %s", err)
   140  		}
   141  	} else {
   142  		return fmt.Errorf("one of 'source_dir', 'source_file', 'source_content_filename' must be specified")
   143  	}
   144  	return nil
   145  }
   146  
   147  func genFileShas(filename string) (string, string, string, error) {
   148  	data, err := ioutil.ReadFile(filename)
   149  	if err != nil {
   150  		return "", "", "", fmt.Errorf("could not compute file '%s' checksum: %s", filename, err)
   151  	}
   152  	h := sha1.New()
   153  	h.Write([]byte(data))
   154  	sha1 := hex.EncodeToString(h.Sum(nil))
   155  
   156  	h256 := sha256.New()
   157  	h256.Write([]byte(data))
   158  	shaSum := h256.Sum(nil)
   159  	sha256base64 := base64.StdEncoding.EncodeToString(shaSum[:])
   160  
   161  	md5 := md5.New()
   162  	md5.Write([]byte(data))
   163  	md5Sum := hex.EncodeToString(md5.Sum(nil))
   164  
   165  	return sha1, sha256base64, md5Sum, nil
   166  }