diff --git a/cloudfoundry/data_source_cf_app.go b/cloudfoundry/data_source_cf_app.go index 3f31cf0ef..5746233c0 100644 --- a/cloudfoundry/data_source_cf_app.go +++ b/cloudfoundry/data_source_cf_app.go @@ -3,7 +3,9 @@ package cloudfoundry import ( "context" - "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" + "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" + "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" + "code.cloudfoundry.org/cli/resources" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" uuid "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-cloudfoundry/cloudfoundry/managers" @@ -51,6 +53,12 @@ func dataSourceApp() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "buildpacks": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + ConflictsWith: []string{"buildpack"}, + }, "command": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -96,7 +104,7 @@ func dataSourceAppRead(ctx context.Context, d *schema.ResourceData, meta interfa var ( nameOrId string space string - app ccv2.Application + app resources.Application err error ) @@ -104,37 +112,99 @@ func dataSourceAppRead(ctx context.Context, d *schema.ResourceData, meta interfa space = d.Get("space").(string) isUUID := uuid.FromStringOrNil(nameOrId) + + var query []ccv3.Query + if uuid.Equal(isUUID, uuid.Nil) { - apps, _, err := session.ClientV2.GetApplications(ccv2.FilterByName(nameOrId), ccv2.FilterBySpace(space)) - if err != nil { - return diag.FromErr(err) - } - if len(apps) == 0 { - return diag.FromErr(NotFound) + query = []ccv3.Query{ + { + Key: ccv3.NameFilter, + Values: []string{nameOrId}, + }, + { + Key: ccv3.SpaceGUIDFilter, + Values: []string{space}, + }, } - app = apps[0] } else { - app, _, err = session.ClientV2.GetApplication(nameOrId) - if err != nil { - return diag.FromErr(err) + query = []ccv3.Query{ + { + Key: ccv3.GUIDFilter, + Values: []string{nameOrId}, + }, + { + Key: ccv3.SpaceGUIDFilter, + Values: []string{space}, + }, } } + apps, _, err := session.ClientV3.GetApplications(query...) + + if err != nil { + return diag.FromErr(err) + } + + if len(apps) == 0 { + return diag.FromErr(NotFound) + } + app = apps[0] + d.SetId(app.GUID) d.Set("name", app.Name) d.Set("space", app.SpaceGUID) - d.Set("instances", app.Instances.Value) - d.Set("memory", app.Memory.Value) - d.Set("disk_quota", app.DiskQuota.Value) - d.Set("stack", app.StackGUID) - d.Set("buildpack", app.Buildpack.Value) - d.Set("command", app.Command.Value) - d.Set("enable_ssh", app.EnableSSH.Value) - d.Set("environment", app.EnvironmentVariables) + + proc, _, err := session.ClientV3.GetApplicationProcessByType(d.Id(), constant.ProcessTypeWeb) + + if err != nil { + return diag.FromErr(err) + } + + if proc.Instances.IsSet { + d.Set("instances", proc.Instances.Value) + } + + if proc.MemoryInMB.IsSet { + d.Set("memory", proc.MemoryInMB.Value) + } + if proc.DiskInMB.IsSet { + d.Set("disk_quota", proc.DiskInMB.Value) + } + + d.Set("stack", app.StackName) + if bpkg := app.LifecycleBuildpacks; len(bpkg) > 0 { + d.Set("buildpacks", bpkg) + d.Set("buildpack", bpkg[0]) + } + + if proc.Command.IsSet { + d.Set("command", proc.Command.Value) + } + + enableSSH, _, err := session.ClientV3.GetAppFeature(d.Id(), "ssh") + if err != nil { + return diag.FromErr(err) + } + d.Set("enable_ssh", enableSSH.Enabled) + + env, err := session.BitsManager.GetAppEnvironmentVariables(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + d.Set("environment", env) + d.Set("state", app.State) - d.Set("health_check_http_endpoint", app.HealthCheckHTTPEndpoint) - d.Set("health_check_type", app.HealthCheckType) - d.Set("health_check_timeout", app.HealthCheckTimeout) + + if proc.HealthCheckEndpoint != "" { + d.Set("health_check_http_endpoint", proc.HealthCheckEndpoint) + } + if proc.HealthCheckTimeout != 0 { + d.Set("health_check_timeout", proc.HealthCheckTimeout) + } + if proc.HealthCheckType != "" { + d.Set("health_check_type", proc.HealthCheckType) + } err = metadataRead(appMetadata, d, meta, true) if err != nil { diff --git a/cloudfoundry/data_source_cf_app_test.go b/cloudfoundry/data_source_cf_app_test.go new file mode 100644 index 000000000..bbde36b1e --- /dev/null +++ b/cloudfoundry/data_source_cf_app_test.go @@ -0,0 +1,128 @@ +package cloudfoundry + +import ( + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +const appDataSource = ` + +data "cloudfoundry_org" "org" { + name = "%s" +} +data "cloudfoundry_space" "space" { + name = "%s" + org = "${data.cloudfoundry_org.org.id}" +} + +resource "cloudfoundry_app" "dummy-app" { + name = "%s" + space = "${data.cloudfoundry_space.space.id}" + + instances = 1 + health_check_type = "port" + health_check_timeout = 180 + + stack = "cflinuxfs4" + + buildpacks = [ + "staticfile_buildpack", + "binary_buildpack" + + ] + + enable_ssh = true + + environment = { + "UPDATED" = "true" + "APPNAME" = "cloudfoundry_app_test" + } + + path = "%s" +} + +data "cloudfoundry_app" "dummy-app-by-id" { + name_or_id = cloudfoundry_app.dummy-app.id + space = "${data.cloudfoundry_space.space.id}" + depends_on = [ cloudfoundry_app.dummy-app ] +} + +data "cloudfoundry_app" "dummy-app-by-name" { + name_or_id = cloudfoundry_app.dummy-app.name + space = "${data.cloudfoundry_space.space.id}" + depends_on = [ cloudfoundry_app.dummy-app ] +} + +output "dummy"{ + value = [data.cloudfoundry_app.dummy-app-by-id.id, data.cloudfoundry_app.dummy-app-by-name.id] +} +` + +func TestAccDataSourceApp_normal(t *testing.T) { + _, orgName := defaultTestOrg(t) + _, spaceName := defaultTestSpace(t) + + refs := []string{"data.cloudfoundry_app.dummy-app-by-id", "data.cloudfoundry_app.dummy-app-by-name"} + + appName := "BindAppName-%s" + appName = fmt.Sprintf(appName, uuid.New()) + + resource.ParallelTest(t, + resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProvidersFactories, + Steps: []resource.TestStep{ + + resource.TestStep{ + Config: fmt.Sprintf(appDataSource, orgName, spaceName, appName, "https://raw.githubusercontent.com/cloudfoundry-community/terraform-provider-cloudfoundry/main/tests/cf-acceptance-tests/assets/dummy-app.zip"), + Check: resource.ComposeTestCheckFunc( + func(s *terraform.State) error { + for _, ref := range refs { + _, ok := s.RootModule().Resources[ref] + if !ok { + return fmt.Errorf("app '%s' not found in terraform state", ref) + } + } + return nil + }, + resource.TestCheckResourceAttr(refs[0], "name", appName), + resource.TestCheckResourceAttr(refs[0], "instances", "1"), + resource.TestCheckResourceAttr(refs[0], "memory", "1024"), + resource.TestCheckResourceAttr(refs[0], "disk_quota", "1024"), + resource.TestCheckResourceAttr(refs[0], "stack", "cflinuxfs4"), + resource.TestCheckResourceAttr(refs[0], "buildpack", "staticfile_buildpack"), + resource.TestCheckResourceAttr(refs[0], "command", "./app"), + resource.TestCheckResourceAttr(refs[0], "enable_ssh", "true"), + resource.TestCheckResourceAttr(refs[0], "state", "STARTED"), + resource.TestCheckResourceAttr(refs[0], "health_check_type", "port"), + resource.TestCheckResourceAttr(refs[0], "health_check_timeout", "180"), + resource.TestCheckResourceAttr(refs[0], "buildpacks.0", "staticfile_buildpack"), + resource.TestCheckResourceAttr(refs[0], "buildpacks.1", "binary_buildpack"), + resource.TestCheckResourceAttr(refs[0], "environment.%", "2"), + resource.TestCheckResourceAttr(refs[0], "environment.UPDATED", "true"), + resource.TestCheckResourceAttr(refs[0], "environment.APPNAME", "cloudfoundry_app_test"), + resource.TestCheckResourceAttr(refs[1], "name", appName), + resource.TestCheckResourceAttr(refs[1], "instances", "1"), + resource.TestCheckResourceAttr(refs[1], "memory", "1024"), + resource.TestCheckResourceAttr(refs[1], "disk_quota", "1024"), + resource.TestCheckResourceAttr(refs[1], "stack", "cflinuxfs4"), + resource.TestCheckResourceAttr(refs[1], "buildpack", "staticfile_buildpack"), + resource.TestCheckResourceAttr(refs[1], "command", "./app"), + resource.TestCheckResourceAttr(refs[1], "enable_ssh", "true"), + resource.TestCheckResourceAttr(refs[1], "state", "STARTED"), + resource.TestCheckResourceAttr(refs[1], "health_check_type", "port"), + resource.TestCheckResourceAttr(refs[1], "health_check_timeout", "180"), + resource.TestCheckResourceAttr(refs[1], "buildpacks.0", "staticfile_buildpack"), + resource.TestCheckResourceAttr(refs[1], "buildpacks.1", "binary_buildpack"), + resource.TestCheckResourceAttr(refs[1], "environment.%", "2"), + resource.TestCheckResourceAttr(refs[1], "environment.UPDATED", "true"), + resource.TestCheckResourceAttr(refs[1], "environment.APPNAME", "cloudfoundry_app_test"), + ), + }, + }, + }) +}