From d863e79eee17600f2c4050aede3578ac3dcc7428 Mon Sep 17 00:00:00 2001 From: Christoph Tavan Date: Wed, 14 Jun 2017 14:55:51 +0200 Subject: [PATCH] Add google_appengine_app resource --- google/config.go | 9 ++ google/provider.go | 1 + google/resource_appengine_app.go | 116 +++++++++++++++++++++ website/docs/r/appengine_app.html.markdown | 38 +++++++ 4 files changed, 164 insertions(+) create mode 100644 google/resource_appengine_app.go create mode 100644 website/docs/r/appengine_app.html.markdown diff --git a/google/config.go b/google/config.go index ccdf4d22b9d..acd60746a6b 100644 --- a/google/config.go +++ b/google/config.go @@ -16,6 +16,7 @@ import ( "golang.org/x/oauth2" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" + "google.golang.org/api/appengine/v1" "google.golang.org/api/bigquery/v2" "google.golang.org/api/cloudbilling/v1" "google.golang.org/api/cloudresourcemanager/v1" @@ -42,6 +43,7 @@ type Config struct { Project string Region string + clientAppengine *appengine.APIService clientBilling *cloudbilling.Service clientCompute *compute.Service clientComputeBeta *computeBeta.Service @@ -127,6 +129,13 @@ func (c *Config) loadAndValidate() error { var err error + log.Printf("[INFO] Instantiating Google App Engine Client...") + c.clientAppengine, err = appengine.New(client) + if err != nil { + return err + } + c.clientAppengine.UserAgent = userAgent + log.Printf("[INFO] Instantiating GCE client...") c.clientCompute, err = compute.New(client) if err != nil { diff --git a/google/provider.go b/google/provider.go index 24ba686f001..848a71b2e7f 100644 --- a/google/provider.go +++ b/google/provider.go @@ -61,6 +61,7 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ + "google_appengine_app": resourceAppengineApp(), "google_bigquery_dataset": resourceBigQueryDataset(), "google_bigquery_table": resourceBigQueryTable(), "google_bigtable_instance": resourceBigtableInstance(), diff --git a/google/resource_appengine_app.go b/google/resource_appengine_app.go new file mode 100644 index 00000000000..3e5d9adc6fb --- /dev/null +++ b/google/resource_appengine_app.go @@ -0,0 +1,116 @@ +package google + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + + "google.golang.org/api/appengine/v1" + "google.golang.org/api/googleapi" +) + +func resourceAppengineApp() *schema.Resource { + return &schema.Resource{ + Create: resourceAppengineAppCreate, + Read: resourceAppengineAppRead, + Delete: resourceAppengineAppDelete, + + Schema: map[string]*schema.Schema{ + "region": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "project": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceAppengineAppCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + region := d.Get("region").(string) + + app := &appengine.Application{Id: project, LocationId: region} + + var res *appengine.Operation + + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + call := config.clientAppengine.Apps.Create(app) + + res, err = call.Do() + if err == nil { + return nil + } + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 429 { + return resource.RetryableError(gerr) + } + return resource.NonRetryableError(err) + }) + + if err != nil { + fmt.Printf("Error creating app engine app %s: %v", project, err) + return err + } + + log.Printf("[DEBUG] Created App Engine app %v at location %v\n\n", project, region) + + d.SetId(project) + + return nil +} + +func resourceAppengineAppRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + res, err := config.clientAppengine.Apps.Get(project).Do() + + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing App Engine app %q because it's gone", project) + // The resource doesn't exist anymore + d.SetId("") + + return nil + } + + return fmt.Errorf("Error reading App Engine app %s: %v", project, err) + } + + log.Printf("[DEBUG] Read App Engine app %v at location %v\n\n", res.Id, res.LocationId) + + d.SetId(res.Id) + + return nil +} + +func resourceAppengineAppDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + log.Printf("[DEBUG] Deleting App Engine app not supported %v\n\n", project) + + return nil +} diff --git a/website/docs/r/appengine_app.html.markdown b/website/docs/r/appengine_app.html.markdown new file mode 100644 index 00000000000..75ca0333073 --- /dev/null +++ b/website/docs/r/appengine_app.html.markdown @@ -0,0 +1,38 @@ +--- +layout: "google" +page_title: "Google: google_appengine_app" +sidebar_current: "docs-google-appengine-app" +description: |- + Creates an App Engine app +--- + +# google\_appengine\_app + +Creates a Google App Engine app. For more information see +[the official documentation](https://cloud.google.com/appengine/docs/) and +[API](https://cloud.google.com/appengine/docs/admin-api/reference/rest/). + + +## Example Usage + +```hcl +resource "google_appengine_app" "default" { + project = "my-google-project" + region = "us-central" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `project` - (Optional) The project in which the resource belongs. If it + is not provided, the provider project is used. + +* `region` - (Optional) The region where the App Engine app will be deployed. + This is bound to the project and cannot be changed for the lifetime of the + project. + +## Attributes Reference + +Only the arguments listed above are exposed as attributes.