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 workload #10107

Merged
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8816596
Add data source for Apphub discovered workload
praseedhaPK Mar 4, 2024
37713b3
Add data source for Apphub discovered workload
praseedhaPK Mar 4, 2024
26539d0
Add data source for Apphub Discovered Workload
praseedhaPK Mar 5, 2024
49c9ded
Resolved comments
praseedhaPK Mar 6, 2024
8255dfa
Resolved comments
praseedhaPK Mar 6, 2024
7782050
Resolved comments
praseedhaPK Mar 6, 2024
ab05c4c
Resolved comments
praseedhaPK Mar 6, 2024
b84b99b
Add tests and documentation for data source discovered workload
praseedhaPK Mar 7, 2024
af74301
Resolved comments and added tests
praseedhaPK Mar 7, 2024
4f2b563
Resolved comments
praseedhaPK Mar 7, 2024
395f953
Merge branch 'GoogleCloudPlatform:main' into DataSourceDiscoveredWork…
praseedhaPK Mar 8, 2024
5c7cf1e
Added modifications in tests, data source and documentation
praseedhaPK Mar 8, 2024
32a9f7a
Added modifications in tests, data source and documentation
praseedhaPK Mar 8, 2024
a8bcf05
Added modifications in tests, data source and documentation
praseedhaPK Mar 8, 2024
43b660e
Verified tests
praseedhaPK Mar 8, 2024
cecf207
Tests Verification
praseedhaPK Mar 10, 2024
29214e7
Tests Verification
praseedhaPK Mar 10, 2024
c07bd65
Updated logic to obtain workload_uri
praseedhaPK Mar 11, 2024
fe95787
Updated logic to obtain workload_uri
praseedhaPK Mar 11, 2024
184f5ed
Resolved comments
praseedhaPK Mar 11, 2024
b2ad74e
Resolved comments
praseedhaPK Mar 11, 2024
3b2ffbc
Add billing account and shorten service project name
praseedhaPK Mar 11, 2024
fc5ae10
Add header
praseedhaPK Mar 11, 2024
b9c6ded
Change the project name to start with tf-test
praseedhaPK Mar 11, 2024
ceb46ff
Resolved comments
praseedhaPK Mar 11, 2024
80782ef
Lint changes
praseedhaPK Mar 11, 2024
403a0ce
Removing two sleeps
praseedhaPK Mar 11, 2024
9dd0ac9
Removing two sleeps
praseedhaPK Mar 11, 2024
809a921
Modifying documentation
praseedhaPK Mar 11, 2024
68c0a54
Resolved tests
praseedhaPK Mar 11, 2024
e34a264
Resolved comments
praseedhaPK Mar 11, 2024
e62a150
Resolved comments
praseedhaPK Mar 11, 2024
f831528
logic modification
praseedhaPK Mar 12, 2024
269e7fd
Update Retry logic
praseedhaPK Mar 12, 2024
10e4371
Update Retry logic
praseedhaPK Mar 12, 2024
55b51ab
Resolved tests
praseedhaPK Mar 12, 2024
4cbbe1f
Adding workload_uri description
praseedhaPK Mar 12, 2024
8cfd3d9
Adding workload_uri description
praseedhaPK Mar 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var handwrittenDatasources = map[string]*schema.Resource{
"google_alloydb_locations": alloydb.DataSourceAlloydbLocations(),
"google_alloydb_supported_database_flags": alloydb.DataSourceAlloydbSupportedDatabaseFlags(),
"google_artifact_registry_repository": artifactregistry.DataSourceArtifactRegistryRepository(),
"google_apphub_discovered_workload": apphub.DataSourceApphubDiscoveredWorkload(),
"google_app_engine_default_service_account": appengine.DataSourceGoogleAppEngineDefaultServiceAccount(),
<% unless version == 'ga' -%>
"google_backup_dr_management_server": backupdr.DataSourceGoogleCloudBackupDRService(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package apphub

import (
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
"google.golang.org/api/googleapi"
)

func DataSourceApphubDiscoveredWorkload() *schema.Resource {
return &schema.Resource{
Read: dataSourceApphubDiscoveredWorkloadRead,
Schema: map[string]*schema.Schema{
"project":{
Type: schema.TypeString,
Optional: true,
},
"location":{
Type: schema.TypeString,
Required: true,
},
"workload_uri": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"workload_reference": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"workload_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 dataSourceApphubDiscoveredWorkloadRead(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, fmt.Sprintf("{{ApphubBasePath}}projects/{{project}}/locations/{{location}}/discoveredWorkloads:lookup?uri={{workload_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
}

var res map[string]interface{}

err = transport_tpg.Retry(transport_tpg.RetryOptions{
RetryFunc: func() (rerr error) {
res, rerr = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
})
return rerr
},
Timeout: d.Timeout(schema.TimeoutRead),
ErrorRetryPredicates: []transport_tpg.RetryErrorPredicateFunc{
func(err error) (bool, string) {
gerr, ok := err.(*googleapi.Error)
if !ok {
return false, ""
}

if gerr.Code == 404 {
log.Printf("[DEBUG] Dismissed an error as retryable based on error code: %s", err)
return true, fmt.Sprintf("Retryable error code %d", gerr.Code)
}
return false, ""
},
},
})

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

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

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

if err := d.Set("workload_properties", flattenApphubDiscoveredWorkloadProperties(res["discoveredWorkload"].(map[string]interface{})["workloadProperties"], d, config)); err != nil {
return fmt.Errorf("Error setting workload properties: %s", err)
}

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

return nil

}

func flattenApphubDiscoveredWorkloadReference(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"] = flattenApphubDiscoveredWorkloadDataUri(original["uri"], d, config)
return []interface{}{transformed}
}

func flattenApphubDiscoveredWorkloadProperties(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"] = flattenApphubDiscoveredWorkloadDataGcpProject(original["gcpProject"], d, config)
transformed["location"] = flattenApphubDiscoveredWorkloadDataLocation(original["location"], d, config)
transformed["zone"] = flattenApphubDiscoveredWorkloadDataZone(original["zone"], d, config)
return []interface{}{transformed}
}

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

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

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

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

func flattenApphubDiscoveredWorkloadDataZone(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,147 @@
package apphub_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-google/google/acctest"
zli82016 marked this conversation as resolved.
Show resolved Hide resolved
)

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

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

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testDataSourceApphubDiscoveredWorkload_basic(context),
},
},
})
}

func testDataSourceApphubDiscoveredWorkload_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_project" "service_project" {
project_id ="apphub-service-project-%{random_suffix}"
name = "Service Project"
org_id = "%{org_id}"
}

resource "time_sleep" "wait_120s_for_service_project" {
depends_on = [google_project.service_project]
create_duration = "120s"
}

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

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

resource "google_apphub_service_project_attachment" "service_project_attachment" {
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
service_project_attachment_id = google_project.service_project.project_id
depends_on = [time_sleep.wait_120s_for_service_project]
}

data "google_apphub_discovered_workload" "catalog-workload" {
provider = google
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
location = "us-central1"
count=0
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

@zli82016 zli82016 Mar 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this line? This could be the reason for the failed test. It means getting 0 datasource.

https://developer.hashicorp.com/terraform/language/meta-arguments/count

workload_uri = "//compute.googleapis.com/${data.google_compute_region_instance_group.ig.instances[count.index].attributes.id}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you try the following line?

workload_uri = "//compute.googleapis.com/${data.google_compute_region_instance_group.ig.instances[0].attributes.id}"

depends_on = [google_apphub_service_project_attachment.service_project_attachment]
}

data "google_compute_region_instance_group" "ig" {
self_link = google_compute_region_instance_group_manager.mig.instance_group
}

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

# backend subnet
resource "google_compute_subnetwork" "ilb_subnet" {
name = "l7-ilb-subnetwork-%{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
depends_on = [google_compute_network.ilb_network]
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
}

# instance template
resource "google_compute_instance_template" "instance_template" {
name = "l7-ilb-mig-template-%{random_suffix}"
project = google_project.service_project.project_id
machine_type = "e2-small"
tags = ["http-server"]
network_interface {
network = google_compute_network.ilb_network.id
subnetwork = google_compute_subnetwork.ilb_subnet.id
access_config {
# add external ip to fetch packages
}
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
}
disk {
source_image = "debian-cloud/debian-10"
auto_delete = true
boot = true
}
# install nginx and serve a simple web page
metadata = {
startup-script = <<-EOF1
#! /bin/bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y nginx-light jq
NAME=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/hostname")
IP=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip")
METADATA=$(curl -f -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=True" | jq 'del(.["startup-script"])')
cat <<EOF > /var/www/html/index.html
<pre>
Name: $NAME
IP: $IP
Metadata: $METADATA
</pre>
EOF
EOF1
}
lifecycle {
create_before_destroy = true
}
depends_on = [google_compute_subnetwork.ilb_subnet, google_compute_network.ilb_network]
}

resource "google_compute_region_instance_group_manager" "mig" {
name = "l7-ilb-mig1-%{random_suffix}"
project = google_project.service_project.project_id
region = "us-central1"
version {
instance_template = google_compute_instance_template.instance_template.id
name = "primary"
}
base_instance_name = "vm"
target_size = 2
depends_on = [google_compute_instance_template.instance_template]
}
`, context)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
subcategory: "Apphub"
description: |-
Get information about a discovered workload.
---

# google\_apphub\_discovered_workload

Get information about a discovered workload from its uri.


## Example Usage


```hcl
data "google_apphub_discovered_workload" "my-workload" {
location = "my-location"
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
workload_uri = "my-workload-uri"
}
```

## Argument Reference

The following arguments are supported:

* `project` - The host project of the discovered workload.
* `workload_uri` - (Required) The uri of the workload.
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved
* `location` - (Required) The location of the discovered workload.

## Attributes Reference

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

* `discovered_workload` - Represents a network/api interface that exposes some functionality to clients for consumption over the network. Structure is [documented below](#nested_discovered_workloads)

<a name="nested_discovered_workloads"></a>A `discovered_workload` object would contain the following fields:-
zli82016 marked this conversation as resolved.
Show resolved Hide resolved

* `name` - Resource name of a Workload. Format: "projects/{host-project-id}/locations/{location}/applications/{application-id}/workloads/{workload-id}".
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved

* `workload_reference` - Reference to an underlying networking resource that can comprise a Workload. Structure is [documented below](#nested_workload_reference)

<a name="nested_workload_reference"></a>A `workload_reference` object would contain the following fields:-
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved

* uri - The underlying resource URI.
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved

* `workload_properties` - Properties of an underlying compute resource that can comprise a Workload. Structure is [documented below](#nested_workload_properties)

<a name="nested_workload_properties"></a>A `workload_properties` object would contain the following fields:-
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved

* 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.
praseedhaPK marked this conversation as resolved.
Show resolved Hide resolved