github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/archive/data_source_archive_file.go (about)

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