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

new datasource azurerm_elastic_san_volume_snapshot #26439

Merged
merged 6 commits into from
Jul 9, 2024

Conversation

teowa
Copy link
Contributor

@teowa teowa commented Jun 24, 2024

Community Note

  • Please vote on this PR by adding a 👍 reaction to the original PR to help the community and maintainers prioritize for review
  • Please do not leave comments along the lines of "+1", "me too" or "any updates", they generate extra noise for PR followers and do not help prioritize for review

Description

As discussed in #25372 (comment), the Elastic SAN Volume Snapshot should be onboarded as a data source instead of a resource. The acctest relys on Azure CLI to create/delete the snapshot, and an envrionment variable ARM_TEST_ELASTIC_SAN_VOLUME_SNAPSHOT_RUN is used to control whether to run the test.

PR Checklist

  • I have followed the guidelines in our Contributing Documentation.
  • I have checked to ensure there aren't other open Pull Requests for the same update/change.
  • I have checked if my changes close any open issues. If so please include appropriate closing keywords below.
  • I have updated/added Documentation as required written in a helpful and kind way to assist users that may be unfamiliar with the resource / data source.
  • I have used a meaningful PR title to help maintainers and other users understand this change and help prevent duplicate work.
    For example: “resource_name_here - description of change e.g. adding property new_property_name_here

Changes to existing Resource / Data Source

  • I have added an explanation of what my changes do and why I'd like you to include them (This may be covered by linking to an issue above, but may benefit from additional explanation).
  • I have written new tests for my resource or datasource changes & updated any relevent documentation.
  • I have successfully run tests with my changes locally. If not, please provide details on testing challenges that prevented you running the tests.
  • (For changes that include a state migration only). I have manually tested the migration path between relevant versions of the provider.

Testing

  • My submission includes Test coverage as described in the Contribution Guide and the tests pass. (if this is not possible for any reason, please include details of why you did or could not add test coverage)
% ARM_TEST_ELASTIC_SAN_VOLUME_SNAPSHOT_RUN=1 make acctests SERVICE="elasticsan" TESTARGS="-parallel 5 -run TestAccElasticSANVolumeSnapshotData" TESTTIMEOUT='2h'                                                                                         ==> Checking that code complies with gofmt requirements...
==> Checking that Custom Timeouts are used...
==> Checking that acceptance test packages are used...
TF_ACC=1 go test -v ./internal/services/elasticsan -parallel 5 -run TestAccElasticSANVolumeSnapshotData -timeout 2h -ldflags="-X=github.com/hashicorp/terraform-provider-azurerm/version.ProviderVersion=acc"
=== RUN   TestAccElasticSANVolumeSnapshotDataSource_basic
--- PASS: TestAccElasticSANVolumeSnapshotDataSource_basic (336.60s)
PASS
ok      github.com/hashicorp/terraform-provider-azurerm/internal/services/elasticsan    336.633s

Change Log

Below please provide what should go into the changelog (if anything) conforming to the Changelog Format documented here.

  • new datasource azurerm_elastic_san_volume_snapshot [GH-00000]

This is a (please select all that apply):

  • Bug Fix
  • New Feature (ie adding a service, resource, or data source)
  • Enhancement
  • Breaking Change

Related Issue(s)

Fixes #0000

Note

If this PR changes meaningfully during the course of review please update the title and description as required.

Copy link
Member

@stephybun stephybun left a comment

Choose a reason for hiding this comment

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

Thanks @teowa. Could you take a look at the comments left in-line? Once that's done we can take another look through.


type ElasticSANVolumeSnapshotDataSourceModel struct {
Name string `tfschema:"name"`
SourceVolumeSizeGiB int64 `tfschema:"source_volume_size_gib"`
Copy link
Member

Choose a reason for hiding this comment

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

In the other elastic san resources we're using something_in_gib, can we rename this to follow that pattern as well

Suggested change
SourceVolumeSizeGiB int64 `tfschema:"source_volume_size_gib"`
SourceVolumeSizeGiB int64 `tfschema:"source_volume_size_in_gib"`

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

}
}

func FlattenElasticSANVolumeSnapshotCreateSource(input snapshots.SnapshotCreationData) (*[]ElasticSANVolumeSnapshotCreateSource, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be a public function?

Suggested change
func FlattenElasticSANVolumeSnapshotCreateSource(input snapshots.SnapshotCreationData) (*[]ElasticSANVolumeSnapshotCreateSource, error) {
func flattenElasticSANVolumeSnapshotCreateSource(input snapshots.SnapshotCreationData) (*[]ElasticSANVolumeSnapshotCreateSource, error) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the block is flattened, so this function is removed.

Comment on lines 135 to 146
var sourceId string
parsedSourceId, err := volumes.ParseVolumeIDInsensitively(input.SourceId)
if err != nil {
return nil, fmt.Errorf("parsing source ID as ElasticSAN Volume ID: %+v", err)
}
sourceId = parsedSourceId.ID()

return &[]ElasticSANVolumeSnapshotCreateSource{
{
SourceId: sourceId,
},
}, nil
Copy link
Member

Choose a reason for hiding this comment

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

Since only ElasticSAN Volumes are supported for now can we simplify this for the time being

Suggested change
var sourceId string
parsedSourceId, err := volumes.ParseVolumeIDInsensitively(input.SourceId)
if err != nil {
return nil, fmt.Errorf("parsing source ID as ElasticSAN Volume ID: %+v", err)
}
sourceId = parsedSourceId.ID()
return &[]ElasticSANVolumeSnapshotCreateSource{
{
SourceId: sourceId,
},
}, nil
volumeId, err := volumes.ParseVolumeIDInsensitively(input.SourceId)
if err != nil {
return nil, err
}
return &[]ElasticSANVolumeSnapshotCreateSource{
{
SourceId: volumeId.ID(),
},
}, nil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

Comment on lines 59 to 70
"creation_source": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"source_id": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
},
},
Copy link
Member

Choose a reason for hiding this comment

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

Can we flatten this to

Suggested change
"creation_source": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"source_id": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
},
},
"source_id": {
Type: pluginsdk.TypeString,
Computed: true,
},

Copy link
Contributor Author

Choose a reason for hiding this comment

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

make sense, changed


* `volume_group_id` - The Elastic SAN Volume Group ID within which the Elastic SAN Volume Snapshot exists.

## Attributes Reference
Copy link
Member

@stephybun stephybun Jun 24, 2024

Choose a reason for hiding this comment

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

The volume_name and source_volume_size_in_gib seem to be missing here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

Comment on lines 17 to 25
func TestAccElasticSANVolumeSnapshotDataSource_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_elastic_san_volume_snapshot", "test")
d := ElasticSANVolumeSnapshotDataSource{}

const SnapshotTestRunEnv = "ARM_TEST_ELASTIC_SAN_VOLUME_SNAPSHOT_RUN"

if os.Getenv(SnapshotTestRunEnv) == "" {
t.Skipf("skip the test as one or more of below environment variables are not specified: %q", SnapshotTestRunEnv)
}
Copy link
Member

Choose a reason for hiding this comment

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

We should add the creation of the Snapshot as a test step in here instead of using the local-exec provisioner to run az cli. That way we don't need to set an environment variable to run this test. Here's an example of where we provision resources "outside" of Terraform in tests:

func TestAccDataSourceKubernetesNodePoolSnapshot_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_kubernetes_node_pool_snapshot", "test")
r := KubernetesNodePoolSnapshotDataSource{}
data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.snapshotSource(data),
Check: acceptance.ComposeTestCheckFunc(
data.CheckWithClientForResource(func(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) error {
if _, ok := ctx.Deadline(); !ok {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, 30*time.Minute)
defer cancel()
}
client := clients.Containers.SnapshotClient
poolId, err := agentpools.ParseAgentPoolID(state.ID)
if err != nil {
return err
}
id := snapshots.NewSnapshotID(poolId.SubscriptionId, poolId.ResourceGroupName, data.RandomString)
snapshot := snapshots.Snapshot{
Location: data.Locations.Primary,
Properties: &snapshots.SnapshotProperties{
CreationData: &snapshots.CreationData{
SourceResourceId: utils.String(poolId.ID()),
},
},
}
_, err = client.CreateOrUpdate(ctx, id, snapshot)
if err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}
return nil
}, "azurerm_kubernetes_cluster_node_pool.source"),
),
},

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

ValidateFunc: validate.ElasticSanSnapshotName,
},

"volume_group_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 we add some validation here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

@teowa
Copy link
Contributor Author

teowa commented Jun 26, 2024

Thanks for reviewing this, I have changed the code.
image

Copy link
Member

@stephybun stephybun left a comment

Choose a reason for hiding this comment

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

Thanks @teowa. I made another pass through and there are still a few things that need to be fixed up. Once that's done though this should be good to go!

// only ElasticSAN Volumes are supported for now
volumeId, err := volumes.ParseVolumeIDInsensitively(model.Properties.CreationData.SourceId)
if err != nil {
return fmt.Errorf("parsing source ID as ElasticSAN Volume ID: %+v", err)
Copy link
Member

Choose a reason for hiding this comment

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

The parser functions return a lot of information already, including the string that the function is attempting to parse as well as the ID type that it's trying to parse it to, so this is redundant information that we would be printing in the error message, please try and avoid wrapping the error messages returned by the resource ID functions with redundant information

Suggested change
return fmt.Errorf("parsing source ID as ElasticSAN Volume ID: %+v", err)
return err

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed


* `source_id` - The Resource ID from which the Snapshot is created.

* `source_volume_size_gib` - Size of Source Volume.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* `source_volume_size_gib` - Size of Source Volume.
* `source_volume_size_in_gib` - The size of Source Volume.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed


* `source_volume_size_gib` - Size of Source Volume.

* `volume_name` - Source Volume Name of the Snapshot.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* `volume_name` - Source Volume Name of the Snapshot.
* `volume_name` - The source Volume Name of the Snapshot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

Comment on lines 100 to 108
variable "primary_location" {
default = %q
}
variable "random_integer" {
default = %d
}
variable "random_string" {
default = %q
}
Copy link
Member

Choose a reason for hiding this comment

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

This looks like a remnant from a resource/data source generated with Pandora, please remove these

Suggested change
variable "primary_location" {
default = %q
}
variable "random_integer" {
default = %d
}
variable "random_string" {
default = %q
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed

Comment on lines 115 to 137
name = "acctestrg-esvg-${var.random_integer}"
location = var.primary_location
}

resource "azurerm_elastic_san" "test" {
name = "acctestes-${var.random_string}"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
base_size_in_tib = 1
sku {
name = "Premium_LRS"
}
}

resource "azurerm_elastic_san_volume_group" "test" {
name = "acctestesvg-${var.random_string}"
elastic_san_id = azurerm_elastic_san.test.id
}

resource "azurerm_elastic_san_volume" "test" {
name = "acctestesv-${var.random_string}"
volume_group_id = azurerm_elastic_san_volume_group.test.id
size_in_gib = 1
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
name = "acctestrg-esvg-${var.random_integer}"
location = var.primary_location
}
resource "azurerm_elastic_san" "test" {
name = "acctestes-${var.random_string}"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
base_size_in_tib = 1
sku {
name = "Premium_LRS"
}
}
resource "azurerm_elastic_san_volume_group" "test" {
name = "acctestesvg-${var.random_string}"
elastic_san_id = azurerm_elastic_san.test.id
}
resource "azurerm_elastic_san_volume" "test" {
name = "acctestesv-${var.random_string}"
volume_group_id = azurerm_elastic_san_volume_group.test.id
size_in_gib = 1
name = "acctestrg-esvg-%[2]d"
location = %[1]s
}
resource "azurerm_elastic_san" "test" {
name = "acctestes-%[3]s"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
base_size_in_tib = 1
sku {
name = "Premium_LRS"
}
}
resource "azurerm_elastic_san_volume_group" "test" {
name = "acctestesvg-%[3]s"
elastic_san_id = azurerm_elastic_san.test.id
}
resource "azurerm_elastic_san_volume" "test" {
name = "acctestesv-%[3]s"
volume_group_id = azurerm_elastic_san_volume_group.test.id
size_in_gib = 1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

Comment on lines 144 to 152
variable "primary_location" {
default = %q
}
variable "random_integer" {
default = %d
}
variable "random_string" {
default = %q
}
Copy link
Member

Choose a reason for hiding this comment

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

Same for this test config, remove the variables and refer to them using the indexed verbs notation like we do for other hand written data sources/resources in the provider.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed

@teowa
Copy link
Contributor Author

teowa commented Jul 9, 2024

Hi @stephybun , thanks for reviewing this. I have changed the code, please kindly take another look.

TF_ACC=1 go test -v ./internal/services/elasticsan -parallel 5 -run TestAccElasticSANVolumeSnapshotData -timeout 2h -ldflags="-X=github.com/hashicorp/terraform-provider-azurerm/version.ProviderVersion=acc"
=== RUN   TestAccElasticSANVolumeSnapshotDataSource_basic
--- PASS: TestAccElasticSANVolumeSnapshotDataSource_basic (394.37s)
PASS
ok      github.com/hashicorp/terraform-provider-azurerm/internal/services/elasticsan    394.399s

Copy link
Member

@stephybun stephybun left a comment

Choose a reason for hiding this comment

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

Thanks @teowa LGTM 👍

@stephybun stephybun merged commit b298acc into hashicorp:main Jul 9, 2024
40 checks passed
@github-actions github-actions bot added this to the v3.112.0 milestone Jul 9, 2024
stephybun added a commit that referenced this pull request Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants