mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-07 03:01:06 +00:00
286 lines
8.1 KiB
Go
286 lines
8.1 KiB
Go
package google
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/hashicorp/terraform/helper/customdiff"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
"github.com/hashicorp/terraform/helper/validation"
|
|
appengine "google.golang.org/api/appengine/v1"
|
|
)
|
|
|
|
func resourceAppEngineApplication() *schema.Resource {
|
|
return &schema.Resource{
|
|
Create: resourceAppEngineApplicationCreate,
|
|
Read: resourceAppEngineApplicationRead,
|
|
Update: resourceAppEngineApplicationUpdate,
|
|
Delete: resourceAppEngineApplicationDelete,
|
|
|
|
Importer: &schema.ResourceImporter{
|
|
State: schema.ImportStatePassthrough,
|
|
},
|
|
|
|
CustomizeDiff: customdiff.All(
|
|
appEngineApplicationLocationIDCustomizeDiff,
|
|
),
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
"project": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Computed: true,
|
|
ForceNew: true,
|
|
ValidateFunc: validateProjectID(),
|
|
},
|
|
"auth_domain": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Computed: true,
|
|
},
|
|
"location_id": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ValidateFunc: validation.StringInSlice([]string{
|
|
"northamerica-northeast1",
|
|
"us-central",
|
|
"us-west2",
|
|
"us-east1",
|
|
"us-east4",
|
|
"southamerica-east1",
|
|
"europe-west",
|
|
"europe-west2",
|
|
"europe-west3",
|
|
"asia-northeast1",
|
|
"asia-south1",
|
|
"australia-southeast1",
|
|
}, false),
|
|
},
|
|
"serving_status": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ValidateFunc: validation.StringInSlice([]string{
|
|
"UNSPECIFIED",
|
|
"SERVING",
|
|
"USER_DISABLED",
|
|
"SYSTEM_DISABLED",
|
|
}, false),
|
|
Computed: true,
|
|
},
|
|
"feature_settings": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
Computed: true,
|
|
MaxItems: 1,
|
|
Elem: appEngineApplicationFeatureSettingsResource(),
|
|
},
|
|
"name": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"url_dispatch_rule": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Computed: true,
|
|
Elem: appEngineApplicationURLDispatchRuleResource(),
|
|
},
|
|
"code_bucket": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"default_hostname": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"default_bucket": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"gcr_domain": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func appEngineApplicationURLDispatchRuleResource() *schema.Resource {
|
|
return &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"domain": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"path": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"service": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func appEngineApplicationFeatureSettingsResource() *schema.Resource {
|
|
return &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"split_health_checks": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func appEngineApplicationLocationIDCustomizeDiff(d *schema.ResourceDiff, meta interface{}) error {
|
|
old, new := d.GetChange("location_id")
|
|
if old != "" && old != new {
|
|
return fmt.Errorf("Cannot change location_id once the resource is created.")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func resourceAppEngineApplicationCreate(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
|
|
project, err := getProject(d, config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
app, err := expandAppEngineApplication(d, project)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Printf("[DEBUG] Creating App Engine App")
|
|
op, err := config.clientAppEngine.Apps.Create(app).Do()
|
|
if err != nil {
|
|
return fmt.Errorf("Error creating App Engine application: %s", err.Error())
|
|
}
|
|
|
|
d.SetId(project)
|
|
|
|
// Wait for the operation to complete
|
|
waitErr := appEngineOperationWait(config.clientAppEngine, op, project, "App Engine app to create")
|
|
if waitErr != nil {
|
|
d.SetId("")
|
|
return waitErr
|
|
}
|
|
log.Printf("[DEBUG] Created App Engine App")
|
|
|
|
return resourceAppEngineApplicationRead(d, meta)
|
|
}
|
|
|
|
func resourceAppEngineApplicationRead(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
pid := d.Id()
|
|
|
|
app, err := config.clientAppEngine.Apps.Get(pid).Do()
|
|
if err != nil {
|
|
return handleNotFoundError(err, d, fmt.Sprintf("App Engine Application %q", pid))
|
|
}
|
|
d.Set("auth_domain", app.AuthDomain)
|
|
d.Set("code_bucket", app.CodeBucket)
|
|
d.Set("default_bucket", app.DefaultBucket)
|
|
d.Set("default_hostname", app.DefaultHostname)
|
|
d.Set("location_id", app.LocationId)
|
|
d.Set("name", app.Name)
|
|
d.Set("serving_status", app.ServingStatus)
|
|
d.Set("project", pid)
|
|
dispatchRules, err := flattenAppEngineApplicationDispatchRules(app.DispatchRules)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = d.Set("url_dispatch_rule", dispatchRules)
|
|
if err != nil {
|
|
return fmt.Errorf("Error setting dispatch rules in state. This is a bug, please report it at https://github.com/terraform-providers/terraform-provider-google/issues. Error is:\n%s", err.Error())
|
|
}
|
|
featureSettings, err := flattenAppEngineApplicationFeatureSettings(app.FeatureSettings)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = d.Set("feature_settings", featureSettings)
|
|
if err != nil {
|
|
return fmt.Errorf("Error setting feature settings in state. This is a bug, please report it at https://github.com/terraform-providers/terraform-provider-google/issues. Error is:\n%s", err.Error())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func resourceAppEngineApplicationUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
pid := d.Id()
|
|
app, err := expandAppEngineApplication(d, pid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Printf("[DEBUG] Updating App Engine App")
|
|
op, err := config.clientAppEngine.Apps.Patch(pid, app).UpdateMask("authDomain,servingStatus,featureSettings.splitHealthChecks").Do()
|
|
if err != nil {
|
|
return fmt.Errorf("Error updating App Engine application: %s", err.Error())
|
|
}
|
|
|
|
// Wait for the operation to complete
|
|
waitErr := appEngineOperationWait(config.clientAppEngine, op, pid, "App Engine app to update")
|
|
if waitErr != nil {
|
|
return waitErr
|
|
}
|
|
log.Printf("[DEBUG] Updated App Engine App")
|
|
|
|
return resourceAppEngineApplicationRead(d, meta)
|
|
}
|
|
|
|
func resourceAppEngineApplicationDelete(d *schema.ResourceData, meta interface{}) error {
|
|
log.Println("[WARN] App Engine applications cannot be destroyed once created. The project must be deleted to delete the application.")
|
|
return nil
|
|
}
|
|
|
|
func expandAppEngineApplication(d *schema.ResourceData, project string) (*appengine.Application, error) {
|
|
result := &appengine.Application{
|
|
AuthDomain: d.Get("auth_domain").(string),
|
|
LocationId: d.Get("location_id").(string),
|
|
Id: project,
|
|
GcrDomain: d.Get("gcr_domain").(string),
|
|
ServingStatus: d.Get("serving_status").(string),
|
|
}
|
|
featureSettings, err := expandAppEngineApplicationFeatureSettings(d)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.FeatureSettings = featureSettings
|
|
return result, nil
|
|
}
|
|
|
|
func expandAppEngineApplicationFeatureSettings(d *schema.ResourceData) (*appengine.FeatureSettings, error) {
|
|
blocks := d.Get("feature_settings").([]interface{})
|
|
if len(blocks) < 1 {
|
|
return nil, nil
|
|
}
|
|
return &appengine.FeatureSettings{
|
|
SplitHealthChecks: d.Get("feature_settings.0.split_health_checks").(bool),
|
|
// force send SplitHealthChecks, so if it's set to false it still gets disabled
|
|
ForceSendFields: []string{"SplitHealthChecks"},
|
|
}, nil
|
|
}
|
|
|
|
func flattenAppEngineApplicationFeatureSettings(settings *appengine.FeatureSettings) ([]map[string]interface{}, error) {
|
|
if settings == nil {
|
|
return []map[string]interface{}{}, nil
|
|
}
|
|
result := map[string]interface{}{
|
|
"split_health_checks": settings.SplitHealthChecks,
|
|
}
|
|
return []map[string]interface{}{result}, nil
|
|
}
|
|
|
|
func flattenAppEngineApplicationDispatchRules(rules []*appengine.UrlDispatchRule) ([]map[string]interface{}, error) {
|
|
results := make([]map[string]interface{}, 0, len(rules))
|
|
for _, rule := range rules {
|
|
results = append(results, map[string]interface{}{
|
|
"domain": rule.Domain,
|
|
"path": rule.Path,
|
|
"service": rule.Service,
|
|
})
|
|
}
|
|
return results, nil
|
|
}
|