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