diff --git a/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl b/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl
index 4d4cf2f26fdd..8db763e20b34 100644
--- a/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl
+++ b/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl
@@ -168,6 +168,7 @@ var handwrittenDatasources = map[string]*schema.Resource{
"google_monitoring_app_engine_service": monitoring.DataSourceMonitoringServiceAppEngine(),
"google_monitoring_uptime_check_ips": monitoring.DataSourceGoogleMonitoringUptimeCheckIps(),
"google_netblock_ip_ranges": resourcemanager.DataSourceGoogleNetblockIpRanges(),
+ "google_oracle_database_db_nodes": oracledatabase.DataSourceOracleDatabaseDbNodes(),
"google_oracle_database_db_servers": oracledatabase.DataSourceOracleDatabaseDbServers(),
"google_oracle_database_cloud_vm_cluster": oracledatabase.DataSourceOracleDatabaseCloudVmCluster(),
"google_oracle_database_cloud_exadata_infrastructure":oracledatabase.DataSourceOracleDatabaseCloudExadataInfrastructure(),
diff --git a/mmv1/third_party/terraform/services/oracledatabase/data_source_oracle_database_db_nodes.go b/mmv1/third_party/terraform/services/oracledatabase/data_source_oracle_database_db_nodes.go
new file mode 100644
index 000000000000..77a450ce4a22
--- /dev/null
+++ b/mmv1/third_party/terraform/services/oracledatabase/data_source_oracle_database_db_nodes.go
@@ -0,0 +1,214 @@
+package oracledatabase
+
+import (
+ "fmt"
+
+ "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"
+)
+
+func DataSourceOracleDatabaseDbNodes() *schema.Resource {
+ dsSchema := map[string]*schema.Schema{
+ "project": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The ID of the project in which the dataset is located. If it is not provided, the provider project is used.",
+ },
+ "location": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "location",
+ },
+ "cloud_vm_cluster": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "vmcluster",
+ },
+ "db_nodes": {
+ Type: schema.TypeList,
+ Computed: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The dbnode name",
+ },
+ "properties": {
+ Type: schema.TypeList,
+ Computed: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "ocid": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Output only",
+ },
+ "ocpu_count": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "Output only",
+ },
+ "memory_size_gb": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "Output only",
+ },
+ "db_node_storage_size_gb": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "Output only",
+ },
+ "db_server_ocid": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Output only",
+ },
+ "hostname": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Output only",
+ },
+ "state": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Output only",
+ },
+ "total_cpu_core_count": {
+ Type: schema.TypeInt,
+ Computed: true,
+ Description: "Output only",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ return &schema.Resource{
+ Read: DataSourceOracleDatabaseDbNodesRead,
+ Schema: dsSchema,
+ }
+}
+
+func DataSourceOracleDatabaseDbNodesRead(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, "{{OracleDatabaseBasePath}}projects/{{project}}/locations/{{location}}/cloudVmClusters/{{cloud_vm_cluster}}/dbNodes")
+ if err != nil {
+ return err
+ }
+ billingProject := ""
+ project, err := tpgresource.GetProject(d, config)
+ if err != nil {
+ return fmt.Errorf("Error fetching project for DbNode: %s", err)
+ }
+ billingProject = project
+ // 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 fmt.Errorf("Error reading DbNode: %s", err)
+ }
+
+ if err := d.Set("project", project); err != nil {
+ return fmt.Errorf("Error reading DbNode: %s", err)
+ }
+ if err := d.Set("db_nodes", flattenOracleDatabaseDbNodes(res["dbNodes"], d, config)); err != nil {
+ return fmt.Errorf("Error reading DbNode: %s", err)
+ }
+ id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/cloudVmClusters/{{cloud_vm_cluster}}/dbNodes")
+ if err != nil {
+ return fmt.Errorf("Error constructing id: %s", err)
+ }
+ d.SetId(id)
+ return nil
+}
+
+func flattenOracleDatabaseDbNodes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) []map[string]interface{} {
+ if v == nil {
+ return nil
+ }
+ l := v.([]interface{})
+ transformed := make([]map[string]interface{}, 0)
+ for _, raw := range l {
+ original := raw.(map[string]interface{})
+ transformed = append(transformed, map[string]interface{}{
+ "name": flattenOracleDatabaseDbNodeName(original["name"], d, config),
+ "properties": flattenOracleDatabaseDbNodeProperties(original["properties"], d, config),
+ })
+ }
+
+ return transformed
+}
+
+func flattenOracleDatabaseDbNodeName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodeProperties(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["ocid"] = flattenOracleDatabaseDbNodePropertiesOcid(original["ocid"], d, config)
+ transformed["ocpu_count"] = flattenOracleDatabaseDbNodePropertiesOcpuCount(original["ocpuCount"], d, config)
+ transformed["memory_size_gb"] = flattenOracleDatabaseDbNodePropertiesMemorySizeGb(original["memorySizeGb"], d, config)
+ transformed["db_node_storage_size_gb"] = flattenOracleDatabaseDbNodePropertiesDbNodeStorageSizeGb(original["dbNodeStorageSizeGb"], d, config)
+ transformed["db_server_ocid"] = flattenOracleDatabaseDbNodePropertiesDbServerOcid(original["dbServerOcid"], d, config)
+ transformed["hostname"] = flattenOracleDatabaseDbNodePropertiesHostname(original["hostname"], d, config)
+ transformed["state"] = flattenOracleDatabaseDbNodePropertiesState(original["state"], d, config)
+ transformed["total_cpu_core_count"] = flattenOracleDatabaseDbNodePropertiesTotalCpuCoreCount(original["totalCpuCoreCount"], d, config)
+
+ return []interface{}{transformed}
+}
+
+func flattenOracleDatabaseDbNodePropertiesOcid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesOcpuCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesMemorySizeGb(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesDbNodeStorageSizeGb(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesDbServerOcid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesHostname(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenOracleDatabaseDbNodePropertiesTotalCpuCoreCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
diff --git a/mmv1/third_party/terraform/services/oracledatabase/data_source_oracle_database_db_nodes_test.go b/mmv1/third_party/terraform/services/oracledatabase/data_source_oracle_database_db_nodes_test.go
new file mode 100644
index 000000000000..fce3340670aa
--- /dev/null
+++ b/mmv1/third_party/terraform/services/oracledatabase/data_source_oracle_database_db_nodes_test.go
@@ -0,0 +1,41 @@
+package oracledatabase_test
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "github.com/hashicorp/terraform-provider-google/google/acctest"
+)
+
+func TestAccOracleDatabaseDbNodes_basic(t *testing.T) {
+ t.Parallel()
+ acctest.VcrTest(t, resource.TestCase{
+ PreCheck: func() { acctest.AccTestPreCheck(t) },
+ ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
+ Steps: []resource.TestStep{
+ {
+ Config: testAccOracleDatabaseDbNodesConfig(),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttrSet("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.#"),
+ resource.TestCheckResourceAttrSet("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.0.name"),
+ resource.TestCheckResourceAttrSet("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.0.properties.#"),
+ resource.TestCheckResourceAttrSet("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.1.name"),
+ resource.TestCheckResourceAttrSet("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.1.properties.#"),
+ resource.TestCheckResourceAttr("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.0.properties.0.state", "AVAILABLE"),
+ resource.TestCheckResourceAttr("data.google_oracle_database_db_nodes.my_db_nodes", "db_nodes.1.properties.0.state", "AVAILABLE"),
+ ),
+ },
+ },
+ })
+}
+
+func testAccOracleDatabaseDbNodesConfig() string {
+ return fmt.Sprintf(`
+data "google_oracle_database_db_nodes" "my_db_nodes"{
+ location = "us-east4"
+ project = "oci-terraform-testing"
+ cloud_vm_cluster = "ofake-do-not-delete-tf-vmcluster"
+}
+`)
+}
diff --git a/mmv1/third_party/terraform/website/docs/d/oracle_database_db_nodes.html.markdown b/mmv1/third_party/terraform/website/docs/d/oracle_database_db_nodes.html.markdown
new file mode 100644
index 000000000000..ab5c99eaa58b
--- /dev/null
+++ b/mmv1/third_party/terraform/website/docs/d/oracle_database_db_nodes.html.markdown
@@ -0,0 +1,72 @@
+---
+subcategory: "Oracle Database"
+description: |-
+ List all database nodes of a Cloud VmCluster.
+---
+
+# google_oracle_database_db_nodes
+
+List all DbNodes of a Cloud VmCluster.
+
+For more information see the
+[API](https://cloud.google.com/oracle/database/docs/reference/rest/v1/projects.locations.cloudVmClusters.dbNodes).
+
+## Example Usage
+
+```hcl
+data "google_oracle_database_db_nodes" "my_db_nodes"{
+ location = "us-east4"
+ cloud_vm_cluster = "vmcluster-id"
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `cloud_vm_cluster` - (Required) The ID of the VM Cluster.
+
+* `location` - (Required) The location of the resource.
+
+* `project` - (Optional) The project in which the resource belongs. If it
+ is not provided, the provider project is used.
+
+## Attributes reference
+
+The following attributes are exported:
+
+* `db_nodes` - List of dbNodes. Structure is [documented below](#nested_dbnodes).
+
+ The `db_nodes` block supports:
+
+* `name` - The name of the database node resource in the following format: projects/{project}/locations/{location}/cloudVmClusters/{cloudVmCluster}/dbNodes/{db_node}
+
+* `properties` - Various properties of the database node. Structure is [documented below](#nested_properties).
+
+ The `properties` block supports:
+
+* `ocid`- OCID of database node.
+
+* `ocpu_count` - OCPU count per database node.
+
+* `memory_size_gb` - The allocated memory in GBs on the database node.
+
+* `db_node_storage_size_gb` - The allocated local node storage in GBs on the database node.
+
+* `db_server_ocid` - The OCID of the Database server associated with the database node.
+
+* `hostname` - The host name for the database node.
+
+* `state` - State of the database node.
+Possible values for `state` are:
+`PROVISIONING` - Indicates that the resource is being provisioned.
+`AVAILABLE` - Indicates that the resource is available.
+`UPDATING` - Indicates that the resource is being updated.
+`STOPPING` - Indicates that the resource is being stopped.
+`STOPPED` - Indicates that the resource is stopped.
+`STARTING` - Indicates that the resource is being started.
+`TERMINATING` - Indicates that the resource is being terminated.
+`TERMINATED` - Indicates that the resource is terminated.
+`FAILED` - Indicates that the resource has failed.
+
+* `total_cpu_core_count` - The total number of CPU cores reserved on the database node.
\ No newline at end of file