Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add data source for apphub discovered service #7080

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/10105.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-datasource
`google_apphub_discovered_service`
```
1 change: 1 addition & 0 deletions google-beta/provider/provider_mmv1_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ var handwrittenDatasources = map[string]*schema.Resource{
"google_alloydb_supported_database_flags": alloydb.DataSourceAlloydbSupportedDatabaseFlags(),
"google_artifact_registry_repository": artifactregistry.DataSourceArtifactRegistryRepository(),
"google_app_engine_default_service_account": appengine.DataSourceGoogleAppEngineDefaultServiceAccount(),
"google_apphub_discovered_service": apphub.DataSourceApphubDiscoveredService(),
"google_backup_dr_management_server": backupdr.DataSourceGoogleCloudBackupDRService(),
"google_beyondcorp_app_connection": beyondcorp.DataSourceGoogleBeyondcorpAppConnection(),
"google_beyondcorp_app_connector": beyondcorp.DataSourceGoogleBeyondcorpAppConnector(),
Expand Down
173 changes: 173 additions & 0 deletions google-beta/services/apphub/data_source_apphub_discovered_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package apphub

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
)

func DataSourceApphubDiscoveredService() *schema.Resource {
return &schema.Resource{
Read: dataSourceApphubDiscoveredServiceRead,
Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Optional: true,
},
"location": {
Type: schema.TypeString,
Required: true,
},
"service_uri": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"service_reference": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"uri": {
Type: schema.TypeString,
Computed: true,
},
"path": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"service_properties": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"gcp_project": {
Type: schema.TypeString,
Computed: true,
},
"location": {
Type: schema.TypeString,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

func dataSourceApphubDiscoveredServiceRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

url, err := tpgresource.ReplaceVars(d, config, "{{ApphubBasePath}}projects/{{project}}/locations/{{location}}/discoveredServices:lookup?uri={{service_uri}}")
if err != nil {
return err
}

billingProject := ""

// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
})

if err != nil {
return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("ApphubDiscoveredService %q", d.Id()), url)
}

if err := d.Set("name", flattenApphubDiscoveredServiceName(res["discoveredService"].(map[string]interface{})["name"], d, config)); err != nil {
return fmt.Errorf("Error setting service name: %s", err)
}

if err := d.Set("service_reference", flattenApphubDiscoveredServiceReference(res["discoveredService"].(map[string]interface{})["serviceReference"], d, config)); err != nil {
return fmt.Errorf("Error setting service reference: %s", err)
}

if err := d.Set("service_properties", flattenApphubDiscoveredServiceProperties(res["discoveredService"].(map[string]interface{})["serviceProperties"], d, config)); err != nil {
return fmt.Errorf("Error setting service properties: %s", err)
}

d.SetId(res["discoveredService"].(map[string]interface{})["name"].(string))

return nil

}

func flattenApphubDiscoveredServiceReference(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["uri"] = flattenApphubDiscoveredServiceDataUri(original["uri"], d, config)
transformed["path"] = flattenApphubDiscoveredServiceDataPath(original["path"], d, config)
return []interface{}{transformed}
}

func flattenApphubDiscoveredServiceProperties(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["gcp_project"] = flattenApphubDiscoveredServiceDataGcpProject(original["gcpProject"], d, config)
transformed["location"] = flattenApphubDiscoveredServiceDataLocation(original["location"], d, config)
transformed["zone"] = flattenApphubDiscoveredServiceDataZone(original["zone"], d, config)
return []interface{}{transformed}
}

func flattenApphubDiscoveredServiceName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenApphubDiscoveredServiceDataUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenApphubDiscoveredServiceDataPath(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenApphubDiscoveredServiceDataGcpProject(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenApphubDiscoveredServiceDataLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenApphubDiscoveredServiceDataZone(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package apphub_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
)

func TestAccDataSourceApphubDiscoveredService_basic(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"org_id": envvar.GetTestOrgFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"time": {},
},
Steps: []resource.TestStep{
{
Config: testDataSourceApphubDiscoveredService_basic(context),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.google_apphub_discovered_service.catalog-service", "name"),
),
},
},
})
}

func testDataSourceApphubDiscoveredService_basic(context map[string]interface{}) string {
return acctest.Nprintf(
`
resource "google_project" "service_project" {
project_id ="tf-test-ah-%{random_suffix}"
name = "Service Project"
org_id = "%{org_id}"
billing_account = "%{billing_account}"
}

# Enable Compute API
resource "google_project_service" "compute_service_project" {
project = google_project.service_project.project_id
service = "compute.googleapis.com"
}

resource "time_sleep" "wait_120s" {
depends_on = [google_project_service.compute_service_project]
create_duration = "120s"
}

resource "google_apphub_service_project_attachment" "service_project_attachment" {
service_project_attachment_id = google_project.service_project.project_id
depends_on = [time_sleep.wait_120s]
}

# discovered service block
data "google_apphub_discovered_service" "catalog-service" {
location = "us-central1"
# ServiceReference | Application Hub | Google Cloud
# Using this reference means that this resource will not be provisioned until the forwarding rule is fully created
service_uri = "//compute.googleapis.com/${google_compute_forwarding_rule.forwarding_rule.id}"
depends_on = [time_sleep.wait_120s_for_resource_ingestion]
}

# VPC network
resource "google_compute_network" "ilb_network" {
name = "ilb-network-%{random_suffix}"
project = google_project.service_project.project_id
auto_create_subnetworks = false
depends_on = [time_sleep.wait_120s]
}

# backend subnet
resource "google_compute_subnetwork" "ilb_subnet" {
name = "ilb-subnet-%{random_suffix}"
project = google_project.service_project.project_id
ip_cidr_range = "10.0.1.0/24"
region = "us-central1"
network = google_compute_network.ilb_network.id
}

# forwarding rule
resource "google_compute_forwarding_rule" "forwarding_rule" {
name = "forwarding-rule-%{random_suffix}"
project = google_project.service_project.project_id
region = "us-central1"
ip_version = "IPV4"
load_balancing_scheme = "INTERNAL"
all_ports = true
backend_service = google_compute_region_backend_service.backend.id
network = google_compute_network.ilb_network.id
subnetwork = google_compute_subnetwork.ilb_subnet.id
}

resource "time_sleep" "wait_120s_for_resource_ingestion" {
depends_on = [google_compute_forwarding_rule.forwarding_rule]
create_duration = "120s"
}

# backend service
resource "google_compute_region_backend_service" "backend" {
name = "backend-service-%{random_suffix}"
project = google_project.service_project.project_id
region = "us-central1"
health_checks = [google_compute_health_check.default.id]
}

# health check
resource "google_compute_health_check" "default" {
name = "health-check-%{random_suffix}"
project = google_project.service_project.project_id
check_interval_sec = 1
timeout_sec = 1

tcp_health_check {
port = "80"
}
depends_on = [time_sleep.wait_120s]
}
`, context)
}
52 changes: 52 additions & 0 deletions website/docs/d/apphub_discovered_service.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
subcategory: "Apphub"
description: |-
Get information about a discovered service.
---

# google\_apphub\_discovered_service

Get information about a discovered service from its uri.


## Example Usage


```hcl
data "google_apphub_discovered_service" "my-service" {
location = "my-location"
service_uri = "my-service-uri"
}
```

## Argument Reference

The following arguments are supported:

* `project` - The host project of the discovered service.
* `service_uri` - (Required) The uri of the service.
* `location` - (Required) The location of the discovered service.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:

* `name` - Resource name of a Service. Format: "projects/{host-project-id}/locations/{location}/applications/{application-id}/services/{service-id}".

* `service_reference` - Reference to an underlying networking resource that can comprise a Service. Structure is [documented below](#nested_service_reference)

<a name="nested_service_reference"></a>A `service_reference` object would contain the following fields:

* `uri` - The underlying resource URI.

* `path` - Additional path under the resource URI.

* `service_properties` - Properties of an underlying compute resource that can comprise a Service. Structure is [documented below](#nested_service_properties)

<a name="nested_service_properties"></a>A `service_properties` object would contain the following fields:

* `gcp_project` - The service project identifier that the underlying cloud resource resides in.

* `location` - The location that the underlying resource resides in.

* `zone` - The location that the underlying resource resides in if it is zonal.