mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-28 22:16:04 +00:00
Add basic test and fix bugs.
Add a test case that exercises the obvious path, and fix the some of the bugs it exposed.
This commit is contained in:
parent
765d9af0a3
commit
02a4259c39
@ -3,6 +3,7 @@ package google
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@ -11,6 +12,10 @@ import (
|
||||
"google.golang.org/api/appengine/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
appEngineOperationIdRE = regexp.MustCompile(fmt.Sprintf("apps/%s/operations/(.*)", ProjectRegex))
|
||||
)
|
||||
|
||||
type AppEngineOperationWaiter struct {
|
||||
Service *appengine.APIService
|
||||
Op *appengine.Operation
|
||||
@ -19,7 +24,11 @@ type AppEngineOperationWaiter struct {
|
||||
|
||||
func (w *AppEngineOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
op, err := w.Service.Apps.Operations.Get(w.AppId, w.Op.Name).Do()
|
||||
matches := appEngineOperationIdRE.FindStringSubmatch(w.Op.Name)
|
||||
if len(matches) != 2 {
|
||||
return nil, "", fmt.Errorf("Expected %d results of parsing operation name, got %d from %s", 2, len(matches), w.Op.Name)
|
||||
}
|
||||
op, err := w.Service.Apps.Operations.Get(w.AppId, matches[1]).Do()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
@ -140,11 +140,35 @@ func appEngineResource() *schema.Resource {
|
||||
Computed: true,
|
||||
},
|
||||
"default_cookie_expiration_seconds": &schema.Schema{
|
||||
Type: schema.TypeFloat,
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
// There's an undocumented requirement that this field be set to 1 day, 1 week, or 2 weeks in seconds
|
||||
// that's 86400, 604800, and 1209600, respectively. This doesn't appear anywhere in the docs, as far
|
||||
// as I can tell, but if you try to create with another value, the API is clear in its response that
|
||||
// these are the only supported values:
|
||||
//
|
||||
// "This field must be either 1 day, 1 week, or 2 weeks in seconds. Valid values are 86400s, 604800s,
|
||||
// or 1209600s."
|
||||
ValidateFunc: func(i interface{}, k string) ([]string, []error) {
|
||||
v, ok := i.(int)
|
||||
if !ok {
|
||||
return nil, []error{fmt.Errorf("expected type of %q to be int, was %T", k, i)}
|
||||
}
|
||||
if v != 86400 && v != 604800 && v != 1209600 {
|
||||
return nil, []error{fmt.Errorf("only possible values for %q are %d, %d, and %d", k, 86400, 604800, 1209600)}
|
||||
}
|
||||
return nil, nil
|
||||
},
|
||||
},
|
||||
"serving_status": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{
|
||||
"UNSPECIFIED",
|
||||
"SERVING",
|
||||
"USER_DISABLED",
|
||||
"SYSTEM_DISABLED",
|
||||
}, false),
|
||||
Computed: true,
|
||||
},
|
||||
"default_hostname": &schema.Schema{
|
||||
@ -163,7 +187,7 @@ func appEngineResource() *schema.Resource {
|
||||
},
|
||||
"gcr_domain": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"feature_settings": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
@ -233,7 +257,7 @@ func appEngineFeatureSettingsResource() *schema.Resource {
|
||||
|
||||
func resourceGoogleProjectCustomizeDiff(diff *schema.ResourceDiff, meta interface{}) error {
|
||||
// don't need to check if changed, the call is a no-op/error if there's no change
|
||||
diff.ForceNew("app_engine.#")
|
||||
diff.ForceNew("app_engine")
|
||||
|
||||
// force a change to client secret if it doesn't match its sha
|
||||
if !diff.HasChange("app_engine.0.iap.0.oauth2_client_secret") {
|
||||
@ -289,6 +313,34 @@ func resourceGoogleProjectCreate(d *schema.ResourceData, meta interface{}) error
|
||||
}
|
||||
}
|
||||
|
||||
// set up App Engine, too
|
||||
app, err := expandAppEngineApp(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] Creating App Engine if %v is true", app != nil)
|
||||
if app != nil {
|
||||
log.Printf("[DEBUG] Enabling App Engine")
|
||||
// enable the app engine APIs so we can create stuff
|
||||
if err = enableService("appengine.googleapis.com", project.ProjectId, config); err != nil {
|
||||
return fmt.Errorf("Error enabling the App Engine Admin API required to configure App Engine applications: %s", err)
|
||||
}
|
||||
log.Printf("[DEBUG] Enabled App Engine")
|
||||
app.Id = pid
|
||||
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())
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
waitErr := appEngineOperationWait(config.clientAppEngine, op, pid, "App Engine app to create")
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
log.Printf("[DEBUG] Created App Engine App")
|
||||
}
|
||||
|
||||
err = resourceGoogleProjectRead(d, meta)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -308,30 +360,6 @@ func resourceGoogleProjectCreate(d *schema.ResourceData, meta interface{}) error
|
||||
return fmt.Errorf("Error deleting default network in project %s: %s", project.ProjectId, err)
|
||||
}
|
||||
}
|
||||
|
||||
// set up App Engine, too
|
||||
if len(d.Get("app_engine").([]interface{})) > 0 {
|
||||
// enable the app engine APIs so we can create stuff
|
||||
if err = enableService("appengine.googleapis.com", project.ProjectId, config); err != nil {
|
||||
return fmt.Errorf("Error enabling the App Engine Admin API required to configure App Engine applications: %s", err)
|
||||
}
|
||||
app, err := expandAppEngineApp(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if app != nil {
|
||||
op, err := config.clientAppEngine.Apps.Create(app).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating App Engine application: %s", err.Error())
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
waitErr := appEngineOperationWait(config.clientAppEngine, op, app.Id, "App Engine app to create")
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -399,7 +427,7 @@ func resourceGoogleProjectRead(d *schema.ResourceData, meta interface{}) error {
|
||||
}
|
||||
err = d.Set("app_engine", appBlocks)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting App Engine application in state. This is a bug, please report it at https://github.com/terraform-providers/terraform-provider-google/issues")
|
||||
return fmt.Errorf("Error setting App Engine application 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
|
||||
@ -623,13 +651,14 @@ func expandAppEngineApp(d *schema.ResourceData) (*appengine.Application, error)
|
||||
return nil, fmt.Errorf("only one app_engine block may be defined per project")
|
||||
}
|
||||
result := &appengine.Application{
|
||||
AuthDomain: d.Get("app_engine.0.auth_domain").(string),
|
||||
LocationId: d.Get("app_engine.0.location_id").(string),
|
||||
Id: d.Get("project_id").(string),
|
||||
GcrDomain: d.Get("gcr_domain").(string),
|
||||
AuthDomain: d.Get("app_engine.0.auth_domain").(string),
|
||||
LocationId: d.Get("app_engine.0.location_id").(string),
|
||||
Id: d.Get("project_id").(string),
|
||||
GcrDomain: d.Get("app_engine.0.gcr_domain").(string),
|
||||
ServingStatus: d.Get("app_engine.0.serving_status").(string),
|
||||
}
|
||||
if v, ok := d.GetOkExists("app_engine.0.default_cookie_expiration_seconds"); ok {
|
||||
result.DefaultCookieExpiration = strconv.FormatFloat(v.(float64), 'f', 9, 64) + "s"
|
||||
result.DefaultCookieExpiration = strconv.FormatInt(int64(v.(int)), 10) + "s"
|
||||
}
|
||||
iap, err := expandAppEngineIAP(d, "app_engine.0.")
|
||||
if err != nil {
|
||||
@ -666,7 +695,7 @@ func flattenAppEngineApp(app *appengine.Application) ([]map[string]interface{},
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result["dispatch_rule"] = dispatchRules
|
||||
result["url_dispatch_rule"] = dispatchRules
|
||||
featureSettings, err := flattenAppEngineFeatureSettings(app.FeatureSettings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -187,6 +187,25 @@ func TestAccProject_parentFolder(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccProject_appEngineBasic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
pid := acctest.RandomWithPrefix("tf-test")
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccProject_appEngineBasic(pid, org),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleProjectExists("google_project.acceptance", pid),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckGoogleProjectExists(r, pid string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[r]
|
||||
@ -349,6 +368,22 @@ resource "google_folder" "folder1" {
|
||||
`, pid, projectName, folderName, org)
|
||||
}
|
||||
|
||||
func testAccProject_appEngineBasic(pid, org string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_project" "acceptance" {
|
||||
project_id = "%s"
|
||||
name = "%s"
|
||||
org_id = "%s"
|
||||
|
||||
app_engine {
|
||||
auth_domain = "hashicorptest.com"
|
||||
location_id = "us-central"
|
||||
default_cookie_expiration_seconds = 86400
|
||||
serving_status = "SERVING"
|
||||
}
|
||||
}`, pid, pid, org)
|
||||
}
|
||||
|
||||
func skipIfEnvNotSet(t *testing.T, envs ...string) {
|
||||
for _, k := range envs {
|
||||
if os.Getenv(k) == "" {
|
||||
|
Loading…
Reference in New Issue
Block a user