Repository: chanzuckerberg/terraform-provider-snowflake
Pull request #589 (2021-06-24 13:44:03)

feat: Snowflake Platform Info Datasource
Added Snowflake Platform Info Datasource

## Test Plan
* [x] unit tests
* [x] acceptance tests


## References
https://docs.snowflake.com/en/sql-reference/functions/system_get_snowflake_platform_info.html

* 

alldoami: /ok-to-test sha=10323b1
github-actions[bot]: Integration tests success for [10323b1](https://github.com/chanzuckerberg/terraform-provider-snowflake/actions/runs/969095621)

Patch:
diff --git a/examples/data-sources/system_get_snowflake_platform_info/data-source.tf b/examples/data-sources/system_get_snowflake_platform_info/data-source.tf
new file mode 100644
index 00000000..22687d0b
--- /dev/null
+++ b/examples/data-sources/system_get_snowflake_platform_info/data-source.tf
@@ -0,0 +1,1 @@
+data "snowflake_system_get_snowflake_platform_info" "current" {}
\ No newline at end of file
diff --git a/pkg/datasources/system_get_snowflake_platform_info.go b/pkg/datasources/system_get_snowflake_platform_info.go
new file mode 100644
index 00000000..88658243
--- /dev/null
+++ b/pkg/datasources/system_get_snowflake_platform_info.go
@@ -0,0 +1,74 @@
+package datasources
+
+import (
+	"database/sql"
+	"fmt"
+	"log"
+
+	"github.com/chanzuckerberg/terraform-provider-snowflake/pkg/snowflake"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	"github.com/pkg/errors"
+)
+
+var systemGetSnowflakePlatformInfoSchema = map[string]*schema.Schema{
+	"azure_vnet_subnet_ids": {
+		Type:        schema.TypeList,
+		Elem:        &schema.Schema{Type: schema.TypeString},
+		Computed:    true,
+		Description: "Snowflake Azure Virtual Network Subnet IDs",
+	},
+	"aws_vpc_ids": {
+		Type:        schema.TypeList,
+		Elem:        &schema.Schema{Type: schema.TypeString},
+		Computed:    true,
+		Description: "Snowflake AWS Virtual Private Cloud IDs",
+	},
+}
+
+func SystemGetSnowflakePlatformInfo() *schema.Resource {
+	return &schema.Resource{
+		Read:   ReadSystemGetSnowflakePlatformInfo,
+		Schema: systemGetSnowflakePlatformInfoSchema,
+	}
+}
+
+// ReadSystemGetSnowflakePlatformInfo implements schema.ReadFunc
+func ReadSystemGetSnowflakePlatformInfo(d *schema.ResourceData, meta interface{}) error {
+	db := meta.(*sql.DB)
+	sel := snowflake.SystemGetSnowflakePlatformInfoQuery()
+	row := snowflake.QueryRow(db, sel)
+
+	acc, err := snowflake.ReadCurrentAccount(db)
+	if err != nil {
+		// If not found, mark resource to be removed from statefile during apply or refresh
+		d.SetId("")
+		log.Printf("[DEBUG] current_account failed to decode")
+		return errors.Wrap(err, "error current_account")
+	}
+
+	d.SetId(fmt.Sprintf("%s.%s", acc.Account, acc.Region))
+
+	rawInfo, err := snowflake.ScanSnowflakePlatformInfo(row)
+	if err == sql.ErrNoRows {
+		// If not found, mark resource to be removed from statefile during apply or refresh
+		log.Print("[DEBUG] system_get_snowflake_platform_info not found")
+		return errors.Wrap(err, "error system_get_snowflake_platform_info")
+	}
+
+	info, err := rawInfo.GetStructuredConfig()
+	if err != nil {
+		log.Printf("[DEBUG] system_get_snowflake_platform_info failed to decode")
+		d.SetId("")
+		return errors.Wrap(err, "error system_get_snowflake_platform_info")
+	}
+
+	if err = d.Set("azure_vnet_subnet_ids", info.AzureVnetSubnetIds); err != nil {
+		return errors.Wrap(err, "error system_get_snowflake_platform_info")
+	}
+
+	if err = d.Set("aws_vpc_ids", info.AwsVpcIds); err != nil {
+		return errors.Wrap(err, "error system_get_snowflake_platform_info")
+	}
+
+	return nil
+}
diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go
index 5cca7479..2673bf94 100644
--- a/pkg/provider/provider.go
+++ b/pkg/provider/provider.go
@@ -192,10 +192,11 @@ func getResources() map[string]*schema.Resource {
 
 func getDataSources() map[string]*schema.Resource {
 	dataSources := map[string]*schema.Resource{
-		"snowflake_current_account":                   datasources.CurrentAccount(),
-		"snowflake_system_generate_scim_access_token": datasources.SystemGenerateSCIMAccessToken(),
-		"snowflake_system_get_aws_sns_iam_policy":     datasources.SystemGetAWSSNSIAMPolicy(),
-		"snowflake_system_get_privatelink_config":     datasources.SystemGetPrivateLinkConfig(),
+		"snowflake_current_account":                    datasources.CurrentAccount(),
+		"snowflake_system_generate_scim_access_token":  datasources.SystemGenerateSCIMAccessToken(),
+		"snowflake_system_get_aws_sns_iam_policy":      datasources.SystemGetAWSSNSIAMPolicy(),
+		"snowflake_system_get_privatelink_config":      datasources.SystemGetPrivateLinkConfig(),
+		"snowflake_system_get_snowflake_platform_info": datasources.SystemGetSnowflakePlatformInfo(),
 	}
 
 	return dataSources
diff --git a/pkg/snowflake/system_get_snowflake_platform_info.go b/pkg/snowflake/system_get_snowflake_platform_info.go
new file mode 100644
index 00000000..dd204ab5
--- /dev/null
+++ b/pkg/snowflake/system_get_snowflake_platform_info.go
@@ -0,0 +1,50 @@
+package snowflake
+
+import (
+	"encoding/json"
+
+	"github.com/jmoiron/sqlx"
+)
+
+func SystemGetSnowflakePlatformInfoQuery() string {
+	return `SELECT SYSTEM$GET_SNOWFLAKE_PLATFORM_INFO() AS "info"`
+}
+
+type RawSnowflakePlatformInfo struct {
+	Info string `db:"info"`
+}
+
+type snowflakePlatformInfoInternal struct {
+	AzureVnetSubnetIds []string `json:"snowflake-vnet-subnet-id,omitempty"`
+	AwsVpcIds          []string `json:"snowflake-vpc-id,omitempty"`
+}
+
+type SnowflakePlatformInfo struct {
+	AzureVnetSubnetIds []string
+	AwsVpcIds          []string
+}
+
+func ScanSnowflakePlatformInfo(row *sqlx.Row) (*RawSnowflakePlatformInfo, error) {
+	info := &RawSnowflakePlatformInfo{}
+	err := row.StructScan(info)
+	return info, err
+}
+
+func (r *RawSnowflakePlatformInfo) GetStructuredConfig() (*SnowflakePlatformInfo, error) {
+	info := &snowflakePlatformInfoInternal{}
+	err := json.Unmarshal([]byte(r.Info), info)
+	if err != nil {
+		return nil, err
+	}
+
+	return info.getSnowflakePlatformInfo()
+}
+
+func (i *snowflakePlatformInfoInternal) getSnowflakePlatformInfo() (*SnowflakePlatformInfo, error) {
+	config := &SnowflakePlatformInfo{
+		i.AzureVnetSubnetIds,
+		i.AwsVpcIds,
+	}
+
+	return config, nil
+}


Test patch:
diff --git a/pkg/datasources/system_get_snowflake_platform_info_acceptance_test.go b/pkg/datasources/system_get_snowflake_platform_info_acceptance_test.go
new file mode 100644
index 00000000..dc196d8a
--- /dev/null
+++ b/pkg/datasources/system_get_snowflake_platform_info_acceptance_test.go
@@ -0,0 +1,29 @@
+package datasources_test
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+)
+
+func TestAccSystemGetSnowflakePlatformInfo(t *testing.T) {
+	resource.ParallelTest(t, resource.TestCase{
+		Providers: providers(),
+		Steps: []resource.TestStep{
+			{
+				Config: snowflakePlatformInfo(),
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrSet("data.snowflake_system_get_snowflake_platform_info.p", "aws_vpc_ids.#"),
+					resource.TestCheckResourceAttrSet("data.snowflake_system_get_snowflake_platform_info.p", "azure_vnet_subnet_ids.#"),
+				),
+			},
+		},
+	})
+}
+
+func snowflakePlatformInfo() string {
+	s := `
+	data snowflake_system_get_snowflake_platform_info "p" {}
+	`
+	return s
+}
diff --git a/pkg/snowflake/system_get_snowflake_platform_info_test.go b/pkg/snowflake/system_get_snowflake_platform_info_test.go
new file mode 100644
index 00000000..cad7240e
--- /dev/null
+++ b/pkg/snowflake/system_get_snowflake_platform_info_test.go
@@ -0,0 +1,42 @@
+package snowflake
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestSystemGetSnowflakePlatformInfoQuery(t *testing.T) {
+	r := require.New(t)
+	sb := SystemGetSnowflakePlatformInfoQuery()
+
+	r.Equal(sb, `SELECT SYSTEM$GET_SNOWFLAKE_PLATFORM_INFO() AS "info"`)
+}
+
+func TestSystemGetSnowflakePlatformInfoGetStructuredConfigAws(t *testing.T) {
+	r := require.New(t)
+
+	raw := &RawSnowflakePlatformInfo{
+		Info: `{"snowflake-vpc-id": ["vpc-1", "vpc-2"]}`,
+	}
+
+	c, e := raw.GetStructuredConfig()
+	r.Nil(e)
+
+	r.Equal([]string{"vpc-1", "vpc-2"}, c.AwsVpcIds)
+	r.Equal([]string(nil), c.AzureVnetSubnetIds)
+}
+
+func TestSystemGetSnowflakePlatformInfoGetStructuredConfigAzure(t *testing.T) {
+	r := require.New(t)
+
+	raw := &RawSnowflakePlatformInfo{
+		Info: `{"snowflake-vnet-subnet-id": ["/subscription/1/1", "/subscription/1/2"]}`,
+	}
+
+	c, e := raw.GetStructuredConfig()
+	r.Nil(e)
+
+	r.Equal([]string{"/subscription/1/1", "/subscription/1/2"}, c.AzureVnetSubnetIds)
+	r.Equal([]string(nil), c.AwsVpcIds)
+}