github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/builtin/providers/ignition/resource_ignition_file.go (about)

     1  package ignition
     2  
     3  import (
     4  	"encoding/base64"
     5  	"fmt"
     6  
     7  	"github.com/coreos/ignition/config/types"
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  )
    10  
    11  func resourceFile() *schema.Resource {
    12  	return &schema.Resource{
    13  		Create: resourceFileCreate,
    14  		Delete: resourceFileDelete,
    15  		Exists: resourceFileExists,
    16  		Read:   resourceFileRead,
    17  		Schema: map[string]*schema.Schema{
    18  			"filesystem": &schema.Schema{
    19  				Type:     schema.TypeString,
    20  				Required: true,
    21  				ForceNew: true,
    22  			},
    23  			"path": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  			"content": &schema.Schema{
    29  				Type:     schema.TypeList,
    30  				Optional: true,
    31  				ForceNew: true,
    32  				MaxItems: 1,
    33  				Elem: &schema.Resource{
    34  					Schema: map[string]*schema.Schema{
    35  						"mime": &schema.Schema{
    36  							Type:     schema.TypeString,
    37  							Optional: true,
    38  							ForceNew: true,
    39  							Default:  "text/plain",
    40  						},
    41  
    42  						"content": &schema.Schema{
    43  							Type:     schema.TypeString,
    44  							Required: true,
    45  							ForceNew: true,
    46  						},
    47  					},
    48  				},
    49  			},
    50  			"source": &schema.Schema{
    51  				Type:     schema.TypeList,
    52  				Optional: true,
    53  				ForceNew: true,
    54  				MaxItems: 1,
    55  				Elem: &schema.Resource{
    56  					Schema: map[string]*schema.Schema{
    57  						"source": &schema.Schema{
    58  							Type:     schema.TypeString,
    59  							Optional: true,
    60  							ForceNew: true,
    61  						},
    62  						"compression": &schema.Schema{
    63  							Type:     schema.TypeString,
    64  							Optional: true,
    65  							ForceNew: true,
    66  						},
    67  						"verification": &schema.Schema{
    68  							Type:     schema.TypeString,
    69  							Optional: true,
    70  							ForceNew: true,
    71  						},
    72  					},
    73  				},
    74  			},
    75  			"mode": &schema.Schema{
    76  				Type:     schema.TypeInt,
    77  				Optional: true,
    78  				ForceNew: true,
    79  			},
    80  			"uid": &schema.Schema{
    81  				Type:     schema.TypeInt,
    82  				Optional: true,
    83  				ForceNew: true,
    84  			},
    85  			"gid": &schema.Schema{
    86  				Type:     schema.TypeInt,
    87  				Optional: true,
    88  				ForceNew: true,
    89  			},
    90  		},
    91  	}
    92  }
    93  
    94  func resourceFileCreate(d *schema.ResourceData, meta interface{}) error {
    95  	id, err := buildFile(d, meta.(*cache))
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	d.SetId(id)
   101  	return nil
   102  }
   103  
   104  func resourceFileDelete(d *schema.ResourceData, meta interface{}) error {
   105  	d.SetId("")
   106  	return nil
   107  }
   108  
   109  func resourceFileExists(d *schema.ResourceData, meta interface{}) (bool, error) {
   110  	id, err := buildFile(d, meta.(*cache))
   111  	if err != nil {
   112  		return false, err
   113  	}
   114  
   115  	return id == d.Id(), nil
   116  }
   117  
   118  func resourceFileRead(d *schema.ResourceData, metacontent interface{}) error {
   119  	return nil
   120  }
   121  
   122  func buildFile(d *schema.ResourceData, c *cache) (string, error) {
   123  	_, hasContent := d.GetOk("content")
   124  	_, hasSource := d.GetOk("source")
   125  	if hasContent && hasSource {
   126  		return "", fmt.Errorf("content and source options are incompatible")
   127  	}
   128  
   129  	if !hasContent && !hasSource {
   130  		return "", fmt.Errorf("content or source options must be present")
   131  	}
   132  
   133  	var compression types.Compression
   134  	var source types.Url
   135  	var hash *types.Hash
   136  	var err error
   137  
   138  	if hasContent {
   139  		source, err = encodeDataURL(
   140  			d.Get("content.0.mime").(string),
   141  			d.Get("content.0.content").(string),
   142  		)
   143  
   144  		if err != nil {
   145  			return "", err
   146  		}
   147  	}
   148  
   149  	if hasSource {
   150  		source, err = buildURL(d.Get("source.0.source").(string))
   151  		if err != nil {
   152  			return "", err
   153  		}
   154  
   155  		compression = types.Compression(d.Get("source.0.compression").(string))
   156  		h, err := buildHash(d.Get("source.0.verification").(string))
   157  		if err != nil {
   158  			return "", err
   159  		}
   160  
   161  		hash = &h
   162  	}
   163  
   164  	return c.addFile(&types.File{
   165  		Filesystem: d.Get("filesystem").(string),
   166  		Path:       types.Path(d.Get("path").(string)),
   167  		Contents: types.FileContents{
   168  			Compression: compression,
   169  			Source:      source,
   170  			Verification: types.Verification{
   171  				Hash: hash,
   172  			},
   173  		},
   174  		User: types.FileUser{
   175  			Id: d.Get("uid").(int),
   176  		},
   177  		Group: types.FileGroup{
   178  			Id: d.Get("gid").(int),
   179  		},
   180  		Mode: types.FileMode(d.Get("mode").(int)),
   181  	}), nil
   182  }
   183  
   184  func encodeDataURL(mime, content string) (types.Url, error) {
   185  	base64 := base64.StdEncoding.EncodeToString([]byte(content))
   186  	return buildURL(
   187  		fmt.Sprintf("data:%s;charset=utf-8;base64,%s", mime, base64),
   188  	)
   189  }