179 lines
3.8 KiB
Go
179 lines
3.8 KiB
Go
package ignition
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
|
|
"github.com/coreos/ignition/config/types"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
)
|
|
|
|
func resourceFile() *schema.Resource {
|
|
return &schema.Resource{
|
|
Exists: resourceFileExists,
|
|
Read: resourceFileRead,
|
|
Schema: map[string]*schema.Schema{
|
|
"filesystem": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
"path": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
"content": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
MaxItems: 1,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"mime": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
Default: "text/plain",
|
|
},
|
|
|
|
"content": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"source": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
MaxItems: 1,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"source": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
},
|
|
"compression": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
},
|
|
"verification": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"mode": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
},
|
|
"uid": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
},
|
|
"gid": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func resourceFileRead(d *schema.ResourceData, meta interface{}) error {
|
|
id, err := buildFile(d, meta.(*cache))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
d.SetId(id)
|
|
return nil
|
|
}
|
|
|
|
func resourceFileExists(d *schema.ResourceData, meta interface{}) (bool, error) {
|
|
id, err := buildFile(d, meta.(*cache))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return id == d.Id(), nil
|
|
}
|
|
|
|
func buildFile(d *schema.ResourceData, c *cache) (string, error) {
|
|
_, hasContent := d.GetOk("content")
|
|
_, hasSource := d.GetOk("source")
|
|
if hasContent && hasSource {
|
|
return "", fmt.Errorf("content and source options are incompatible")
|
|
}
|
|
|
|
if !hasContent && !hasSource {
|
|
return "", fmt.Errorf("content or source options must be present")
|
|
}
|
|
|
|
var compression types.Compression
|
|
var source types.Url
|
|
var hash *types.Hash
|
|
var err error
|
|
|
|
if hasContent {
|
|
source, err = encodeDataURL(
|
|
d.Get("content.0.mime").(string),
|
|
d.Get("content.0.content").(string),
|
|
)
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
if hasSource {
|
|
source, err = buildURL(d.Get("source.0.source").(string))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
compression = types.Compression(d.Get("source.0.compression").(string))
|
|
h, err := buildHash(d.Get("source.0.verification").(string))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
hash = &h
|
|
}
|
|
|
|
return c.addFile(&types.File{
|
|
Filesystem: d.Get("filesystem").(string),
|
|
Path: types.Path(d.Get("path").(string)),
|
|
Contents: types.FileContents{
|
|
Compression: compression,
|
|
Source: source,
|
|
Verification: types.Verification{
|
|
Hash: hash,
|
|
},
|
|
},
|
|
User: types.FileUser{
|
|
Id: d.Get("uid").(int),
|
|
},
|
|
Group: types.FileGroup{
|
|
Id: d.Get("gid").(int),
|
|
},
|
|
Mode: types.FileMode(d.Get("mode").(int)),
|
|
}), nil
|
|
}
|
|
|
|
func encodeDataURL(mime, content string) (types.Url, error) {
|
|
base64 := base64.StdEncoding.EncodeToString([]byte(content))
|
|
return buildURL(
|
|
fmt.Sprintf("data:%s;charset=utf-8;base64,%s", mime, base64),
|
|
)
|
|
}
|