github.com/atsaki/terraform@v0.4.3-0.20150919165407-25bba5967654/builtin/providers/google/resource_storage_bucket.go (about)

     1  package google
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  
    10  	"google.golang.org/api/storage/v1"
    11  )
    12  
    13  func resourceStorageBucket() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceStorageBucketCreate,
    16  		Read:   resourceStorageBucketRead,
    17  		Update: resourceStorageBucketUpdate,
    18  		Delete: resourceStorageBucketDelete,
    19  
    20  		Schema: map[string]*schema.Schema{
    21  			"name": &schema.Schema{
    22  				Type:     schema.TypeString,
    23  				Required: true,
    24  				ForceNew: true,
    25  			},
    26  			"predefined_acl": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Default:  "projectPrivate",
    29  				Optional: true,
    30  				ForceNew: true,
    31  			},
    32  			"location": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Default:  "US",
    35  				Optional: true,
    36  				ForceNew: true,
    37  			},
    38  			"force_destroy": &schema.Schema{
    39  				Type:     schema.TypeBool,
    40  				Optional: true,
    41  				Default:  false,
    42  			},
    43  			"website": &schema.Schema{
    44  				Type:     schema.TypeList,
    45  				Optional: true,
    46  				Elem: &schema.Resource{
    47  					Schema: map[string]*schema.Schema{
    48  						"main_page_suffix": &schema.Schema{
    49  							Type:     schema.TypeString,
    50  							Optional: true,
    51  						},
    52  						"not_found_page": &schema.Schema{
    53  							Type:     schema.TypeString,
    54  							Optional: true,
    55  						},
    56  					},
    57  				},
    58  			},
    59  			"self_link": &schema.Schema{
    60  				Type:     schema.TypeString,
    61  				Computed: true,
    62  			},
    63  		},
    64  	}
    65  }
    66  
    67  func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error {
    68  	config := meta.(*Config)
    69  
    70  	// Get the bucket and acl
    71  	bucket := d.Get("name").(string)
    72  	acl := d.Get("predefined_acl").(string)
    73  	location := d.Get("location").(string)
    74  
    75  	// Create a bucket, setting the acl, location and name.
    76  	sb := &storage.Bucket{Name: bucket, Location: location}
    77  
    78  	if v, ok := d.GetOk("website"); ok {
    79  		websites := v.([]interface{})
    80  
    81  		if len(websites) > 1 {
    82  			return fmt.Errorf("At most one website block is allowed")
    83  		}
    84  
    85  		sb.Website = &storage.BucketWebsite{}
    86  
    87  		website := websites[0].(map[string]interface{})
    88  
    89  		if v, ok := website["not_found_page"]; ok {
    90  			sb.Website.NotFoundPage = v.(string)
    91  		}
    92  
    93  		if v, ok := website["main_page_suffix"]; ok {
    94  			sb.Website.MainPageSuffix = v.(string)
    95  		}
    96  	}
    97  
    98  	res, err := config.clientStorage.Buckets.Insert(config.Project, sb).PredefinedAcl(acl).Do()
    99  
   100  	if err != nil {
   101  		fmt.Printf("Error creating bucket %s: %v", bucket, err)
   102  		return err
   103  	}
   104  
   105  	log.Printf("[DEBUG] Created bucket %v at location %v\n\n", res.Name, res.SelfLink)
   106  
   107  	// Assign the bucket ID as the resource ID
   108  	d.Set("self_link", res.SelfLink)
   109  	d.SetId(res.Id)
   110  
   111  	return nil
   112  }
   113  
   114  func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error {
   115  	config := meta.(*Config)
   116  
   117  	sb := &storage.Bucket{}
   118  
   119  	if d.HasChange("website") {
   120  		if v, ok := d.GetOk("website"); ok {
   121  			websites := v.([]interface{})
   122  
   123  			if len(websites) > 1 {
   124  				return fmt.Errorf("At most one website block is allowed")
   125  			}
   126  
   127  			// Setting fields to "" to be explicit that the PATCH call will 
   128  			// delete this field. 
   129  			if len(websites) == 0 {
   130  				sb.Website.NotFoundPage = ""
   131  				sb.Website.MainPageSuffix = ""
   132  			} else {
   133  				website := websites[0].(map[string]interface{})
   134  				sb.Website = &storage.BucketWebsite{}
   135  				if v, ok := website["not_found_page"]; ok {
   136  					sb.Website.NotFoundPage = v.(string)
   137  				} else {
   138  					sb.Website.NotFoundPage = ""
   139  				}
   140  
   141  				if v, ok := website["main_page_suffix"]; ok {
   142  					sb.Website.MainPageSuffix = v.(string)
   143  				} else {
   144  					sb.Website.MainPageSuffix = ""
   145  				}
   146  			}
   147  		}
   148  	}
   149  
   150  	res, err := config.clientStorage.Buckets.Patch(d.Get("name").(string), sb).Do()
   151  
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	log.Printf("[DEBUG] Patched bucket %v at location %v\n\n", res.Name, res.SelfLink)
   157  
   158  	// Assign the bucket ID as the resource ID
   159  	d.Set("self_link", res.SelfLink)
   160  	d.SetId(res.Id)
   161  
   162  	return nil
   163  }
   164  
   165  func resourceStorageBucketRead(d *schema.ResourceData, meta interface{}) error {
   166  	config := meta.(*Config)
   167  
   168  	// Get the bucket and acl
   169  	bucket := d.Get("name").(string)
   170  	res, err := config.clientStorage.Buckets.Get(bucket).Do()
   171  
   172  	if err != nil {
   173  		fmt.Printf("Error reading bucket %s: %v", bucket, err)
   174  		return err
   175  	}
   176  
   177  	log.Printf("[DEBUG] Read bucket %v at location %v\n\n", res.Name, res.SelfLink)
   178  
   179  	// Update the bucket ID according to the resource ID
   180  	d.Set("self_link", res.SelfLink)
   181  	d.SetId(res.Id)
   182  
   183  	return nil
   184  }
   185  
   186  func resourceStorageBucketDelete(d *schema.ResourceData, meta interface{}) error {
   187  	config := meta.(*Config)
   188  
   189  	// Get the bucket
   190  	bucket := d.Get("name").(string)
   191  
   192  	for {
   193  		res, err := config.clientStorage.Objects.List(bucket).Do()
   194  		if err != nil {
   195  			fmt.Printf("Error Objects.List failed: %v", err)
   196  			return err
   197  		}
   198  
   199  		if len(res.Items) != 0 {
   200  			if d.Get("force_destroy").(bool) {
   201  				// purge the bucket...
   202  				log.Printf("[DEBUG] GCS Bucket attempting to forceDestroy\n\n")
   203  
   204  				for _, object := range res.Items {
   205  					log.Printf("[DEBUG] Found %s", object.Name)
   206  					if err := config.clientStorage.Objects.Delete(bucket, object.Name).Do(); err != nil {
   207  						log.Fatalf("Error trying to delete object: %s %s\n\n", object.Name, err)
   208  					} else {
   209  						log.Printf("Object deleted: %s \n\n", object.Name)
   210  					}
   211  				}
   212  
   213  			} else {
   214  				delete_err := errors.New("Error trying to delete a bucket containing objects without `force_destroy` set to true")
   215  				log.Printf("Error! %s : %s\n\n", bucket, delete_err)
   216  				return delete_err
   217  			}
   218  		} else {
   219  			break // 0 items, bucket empty
   220  		}
   221  	}
   222  
   223  	// remove empty bucket
   224  	err := config.clientStorage.Buckets.Delete(bucket).Do()
   225  	if err != nil {
   226  		fmt.Printf("Error deleting bucket %s: %v\n\n", bucket, err)
   227  		return err
   228  	}
   229  	log.Printf("[DEBUG] Deleted bucket %v\n\n", bucket)
   230  
   231  	return nil
   232  }