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