github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/oneandone/resource_oneandone_vpn.go (about) 1 package oneandone 2 3 import ( 4 "crypto/md5" 5 "encoding/base64" 6 "fmt" 7 "github.com/1and1/oneandone-cloudserver-sdk-go" 8 "github.com/hashicorp/terraform/helper/schema" 9 "io" 10 "os" 11 fp "path/filepath" 12 "strings" 13 ) 14 15 func resourceOneandOneVPN() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceOneandOneVPNCreate, 18 Read: resourceOneandOneVPNRead, 19 Update: resourceOneandOneVPNUpdate, 20 Delete: resourceOneandOneVPNDelete, 21 Schema: map[string]*schema.Schema{ 22 23 "name": { 24 Type: schema.TypeString, 25 Required: true, 26 }, 27 "description": { 28 Type: schema.TypeString, 29 Optional: true, 30 }, 31 "download_path": { 32 Type: schema.TypeString, 33 Computed: true, 34 }, 35 "datacenter": { 36 Type: schema.TypeString, 37 Optional: true, 38 }, 39 "file_name": { 40 Type: schema.TypeString, 41 Computed: true, 42 }, 43 }, 44 } 45 } 46 47 func resourceOneandOneVPNCreate(d *schema.ResourceData, meta interface{}) error { 48 config := meta.(*Config) 49 50 var datacenter string 51 52 if raw, ok := d.GetOk("datacenter"); ok { 53 dcs, err := config.API.ListDatacenters() 54 if err != nil { 55 return fmt.Errorf("An error occured while fetching list of datacenters %s", err) 56 } 57 58 decenter := raw.(string) 59 for _, dc := range dcs { 60 if strings.ToLower(dc.CountryCode) == strings.ToLower(decenter) { 61 datacenter = dc.Id 62 break 63 } 64 } 65 } 66 67 var description string 68 if raw, ok := d.GetOk("description"); ok { 69 description = raw.(string) 70 } 71 72 vpn_id, vpn, err := config.API.CreateVPN(d.Get("name").(string), description, datacenter) 73 if err != nil { 74 return err 75 } 76 77 err = config.API.WaitForState(vpn, "ACTIVE", 10, config.Retries) 78 if err != nil { 79 return err 80 } 81 82 d.SetId(vpn_id) 83 84 return resourceOneandOneVPNRead(d, meta) 85 } 86 87 func resourceOneandOneVPNUpdate(d *schema.ResourceData, meta interface{}) error { 88 config := meta.(*Config) 89 90 if d.HasChange("name") || d.HasChange("description") { 91 92 vpn, err := config.API.ModifyVPN(d.Id(), d.Get("name").(string), d.Get("description").(string)) 93 if err != nil { 94 return err 95 } 96 97 err = config.API.WaitForState(vpn, "ACTIVE", 10, config.Retries) 98 if err != nil { 99 return err 100 } 101 } 102 103 return resourceOneandOneVPNRead(d, meta) 104 } 105 106 func resourceOneandOneVPNRead(d *schema.ResourceData, meta interface{}) error { 107 config := meta.(*Config) 108 109 vpn, err := config.API.GetVPN(d.Id()) 110 111 base64_str, err := config.API.GetVPNConfigFile(d.Id()) 112 if err != nil { 113 if strings.Contains(err.Error(), "404") { 114 d.SetId("") 115 return nil 116 } 117 return err 118 } 119 120 var download_path string 121 if raw, ok := d.GetOk("download_path"); ok { 122 download_path = raw.(string) 123 } 124 125 path, fileName, err := writeCofnig(vpn, download_path, base64_str) 126 if err != nil { 127 return err 128 } 129 130 d.Set("name", vpn.Name) 131 d.Set("description", vpn.Description) 132 d.Set("download_path", path) 133 d.Set("file_name", fileName) 134 d.Set("datacenter", vpn.Datacenter.CountryCode) 135 136 return nil 137 } 138 139 func writeCofnig(vpn *oneandone.VPN, path, base64config string) (string, string, error) { 140 data, err := base64.StdEncoding.DecodeString(base64config) 141 if err != nil { 142 return "", "", err 143 } 144 145 var fileName string 146 if vpn.CloudPanelId != "" { 147 fileName = vpn.CloudPanelId + ".zip" 148 } else { 149 fileName = "vpn_" + fmt.Sprintf("%x", md5.Sum(data)) + ".zip" 150 } 151 152 if path == "" { 153 path, err = os.Getwd() 154 if err != nil { 155 return "", "", err 156 } 157 } 158 159 if !fp.IsAbs(path) { 160 path, err = fp.Abs(path) 161 if err != nil { 162 return "", "", err 163 } 164 } 165 166 _, err = os.Stat(path) 167 if err != nil { 168 if os.IsNotExist(err) { 169 // make all dirs 170 os.MkdirAll(path, 0666) 171 } else { 172 return "", "", err 173 } 174 } 175 176 fpath := fp.Join(path, fileName) 177 178 f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY, 0666) 179 defer f.Close() 180 181 if err != nil { 182 return "", "", err 183 } 184 185 n, err := f.Write(data) 186 if err == nil && n < len(data) { 187 err = io.ErrShortWrite 188 } 189 190 if err != nil { 191 return "", "", err 192 } 193 194 return path, fileName, nil 195 196 } 197 198 func resourceOneandOneVPNDelete(d *schema.ResourceData, meta interface{}) error { 199 config := meta.(*Config) 200 201 vpn, err := config.API.DeleteVPN(d.Id()) 202 if err != nil { 203 return err 204 } 205 206 err = config.API.WaitUntilDeleted(vpn) 207 if err != nil { 208 return err 209 } 210 211 fullPath := fp.Join(d.Get("download_path").(string), d.Get("file_name").(string)) 212 if _, err := os.Stat(fullPath); !os.IsNotExist(err) { 213 os.Remove(fullPath) 214 } 215 216 return nil 217 }