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  }