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

feat: Add Resource for External Volumes #3106

Merged
merged 19 commits into from
Oct 25, 2024

Conversation

jdoldis
Copy link
Contributor

@jdoldis jdoldis commented Sep 27, 2024

This PR adds the resource for External Volumes. This is part of a series of PRs aimed at adding provider support for Iceberg tables.

References

return diag.FromErr(err)
}

if withExternalChangesMarking {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed on Slack, I’m not exactly sure how this works. It seems to be used for all Boolean values so I’ve copied it over and the tests are passing, would be good if you could check it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

it looks good, I don't know every detail, but this magic is mostly done to detect changes based on show_output field and seeing how it's changing and comparing it to the config/state you're currently having. It's a bit complicated, but Terraform SDKv2 is very limited when it comes to change detection. We tried a few solutions, and we ended up with this one (actually, we have a different approach for handling parameters, e.g. in the database, that utilizes Optional + Computed combo, you'll probably use it when implementing Iceberg Tables). Maybe @sfc-gh-asawicki would give more insight here.

Optional: true,
Description: "Specifies the case-sensitive Amazon Resource Name (ARN) of the AWS identity and access management (IAM) role that grants privileges on the S3 bucket containing your data files.",
},
"storage_aws_external_id": {
Copy link
Contributor Author

@jdoldis jdoldis Sep 27, 2024

Choose a reason for hiding this comment

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

I’ve followed the example of Storage Integration, which leaves this as a read only parameter. However, for both the Storage Integration and the External Volume I can see use cases in the future where users would want to set it. We should keep that in mind for the next iteration.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, I'm not sure if that parameter was settable when we were working on storage integration. If it's possible in Snowflake, then it should be possible here. But maybe as you say, we can leave it for the next iteration. cc: @sfc-gh-asawicki

@jdoldis
Copy link
Contributor Author

jdoldis commented Sep 27, 2024

Hey @sfc-gh-asawicki / @sfc-gh-jcieslak / @sfc-gh-jmichalak 🙂

I’ll be on holidays for the next two weeks so won’t be able to respond to the review until I’m back. If you have the time you are welcome to take the PR over yourself to make changes / get it merged, otherwise I’ll take a look once I’m back. I’ve checked Allow edits by maintainers, so you should be able to push here if you like.

Cheers,
James

}
}

temp_storage_location, err := CopyStorageLocationWithTempName(removedLocations[0])
Copy link
Contributor Author

@jdoldis jdoldis Sep 29, 2024

Choose a reason for hiding this comment

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

It shouldn’t happen often but if deleting the temp resources fails in one apply, adding them on the next apply could fail due to duplicate names. If we want to avoid this, we could first run a check to see if the temp storage location already exists and run a remove operation.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, that's annoying. cc: @sfc-gh-asawicki is d.Partial essential in this case ?

@sfc-gh-fbudzynski sfc-gh-fbudzynski marked this pull request as ready for review October 4, 2024 10:27
@sfc-gh-fbudzynski sfc-gh-fbudzynski marked this pull request as draft October 4, 2024 10:30
description: |-
Resource used to manage external volume objects. For more information, check external volume documentation https://docs.snowflake.com/en/sql-reference/commands-data-loading#external-volume.
---

Copy link
Collaborator

Choose a reason for hiding this comment

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

V1 candidate note is missing, a new template has to be created in the templates/resources directory for external volume (you can copy-paste the schema.md.tmpl one, but change the migration guide link header to the correct one).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have added that without a migration guide link for now as I'm not sure when we'll get it released, will leave the comment as unresolved so we don't forget.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, we don't want this note here. This object is not officially supported and requires a follow-up on our side. After this follow-up (also with an entry in the migration guide), we can add a note about the release candidate.

We can merge it now, but this note shouldn't be present in the next release.

pkg/helpers/helpers.go Outdated Show resolved Hide resolved
pkg/helpers/helpers.go Outdated Show resolved Hide resolved
pkg/resources/external_volume_acceptance_test.go Outdated Show resolved Hide resolved
pkg/resources/external_volume.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@sfc-gh-jmichalak sfc-gh-jmichalak left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution 🚀

pkg/sdk/external_volumes_def.go Show resolved Hide resolved
pkg/schemas/gen/sdk_show_result_structs.go Outdated Show resolved Hide resolved
pkg/helpers/helpers.go Show resolved Hide resolved
pkg/helpers/helpers.go Outdated Show resolved Hide resolved
pkg/helpers/helpers.go Outdated Show resolved Hide resolved
),
parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(props)
require.NoError(t, err)
expectedParsedExternalVolumeDescribed := helpers.ParsedExternalVolumeDescribed{
Copy link
Collaborator

Choose a reason for hiding this comment

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

We now have such assertions in the objectassert package, but I think we can move this on our side.

"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

var (
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure which functions you mean here. If you mean getS3StorageLocation et al., then they can be left for now. I'd just change the names to sth like getS3StorageLocationConfigVariables.

pkg/resources/external_volume_acceptance_test.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@sfc-gh-jmichalak sfc-gh-jmichalak left a comment

Choose a reason for hiding this comment

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

Thanks for the follow-up! Please mark this PR as a ready for review, instead of a draft.

@@ -10,3 +11,23 @@ func (e *ExternalVolumeResourceAssert) HasStorageLocationLength(len int) *Extern
e.AddAssertion(assert.ValueSet("storage_location.#", strconv.FormatInt(int64(len), 10)))
return e
}

func (e *ExternalVolumeResourceAssert) HasStorageLocationAtIndex(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: we can pass here a slice of a custom struct with these fields. But it's okay like this.

pkg/resources/external_volume.go Outdated Show resolved Hide resolved
}
}
}

temp_storage_location, err := CopyStorageLocationWithTempName(removedLocations[0])
if err != nil {
return diag.FromErr(err)
Copy link
Collaborator

@sfc-gh-jmichalak sfc-gh-jmichalak Oct 22, 2024

Choose a reason for hiding this comment

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

I think that CopyStorageLocationWithTempName is not suitable here - we can create an arbitrary storage location with our special name. We can leave it as is, but rename the function to copySentinelStorageLocation or something similar.

Copy link
Contributor Author

@jdoldis jdoldis Oct 22, 2024

Choose a reason for hiding this comment

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

That's also an option - we could have a storage location with placeholder values for the base url, role arn etc. I think this would work as it works in the tests, so it seems Snowflake doesn't try to verify access to the underlying data.

I stuck with this though as not having storage locations with placeholder values seemed better long term, for example if Snowflake does implement verifications here in the future. I don't have a strong opinion though - happy to go with whatever you think is best.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll update the name of the function to CopySentinelStorageLocation for now

@sfc-gh-jmichalak
Copy link
Collaborator

sfc-gh-jmichalak commented Oct 22, 2024

Examples are missing - please add them to examples/resources/external_volume (import.sh and resource.tf, check other resources like masking policy). After this, please run make pre-push which should regenerate docs.

parsedExternalVolumeDescribed.Active = p.Value
case p.Name == "ALLOW_WRITES":
parsedExternalVolumeDescribed.AllowWrites = p.Value
case strings.Contains(p.Name, "STORAGE_LOCATION_"):
Copy link
Contributor Author

@jdoldis jdoldis Oct 23, 2024

Choose a reason for hiding this comment

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

One thing to check here - for azure storage locations the encryption_type will be set, although it's not set in the config. It's a special case where it's not a valid parameter, but is set on Snowflake side. This shouldn't cause any issues, as otherwise I think the tests would fail with unstable plans. But worth checking before merging.

@sfc-gh-jmichalak sfc-gh-jmichalak marked this pull request as ready for review October 25, 2024 10:07
@sfc-gh-jmichalak
Copy link
Collaborator

/ok-to-test sha=c4af02d4ee3a3b2213a95cd4946d3ad42dd747e9

Copy link

Integration tests failure for c4af02d4ee3a3b2213a95cd4946d3ad42dd747e9

Copy link
Collaborator

@sfc-gh-jmichalak sfc-gh-jmichalak left a comment

Choose a reason for hiding this comment

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

LGTM! The unresolved topics will be fixed on our side.

@sfc-gh-jmichalak sfc-gh-jmichalak enabled auto-merge (squash) October 25, 2024 12:42
@sfc-gh-jmichalak sfc-gh-jmichalak merged commit 64ba674 into Snowflake-Labs:main Oct 25, 2024
7 of 8 checks passed
@jdoldis
Copy link
Contributor Author

jdoldis commented Oct 25, 2024

Awesome, thanks @sfc-gh-jmichalak !

sfc-gh-jmichalak pushed a commit that referenced this pull request Nov 8, 2024
##
[0.98.0](v0.97.0...v0.98.0)
(2024-11-08)

Feature scope readiness for V1:
[link](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/v1-preparations/ESSENTIAL_GA_OBJECTS.MD)
([Roadmap
reference](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/ROADMAP.md#wrap-up-the-functional-scope)).
:exclamation: Migration guide: [v0.97.0 ->
v0.98.0](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/MIGRATION_GUIDE.md#v0970--v0980)

### 🎉 What's new
- New resources:
- authentication_policy
([#3098](#3098)),
references
[#2880](#2880)
- external_volume
([#3106](#3106)),
partially references
[#2980](#2980)
- stream_on_directory_table
([#3129](#3129))
- stream_on_view
([#3150](#3150))
- primary_connection, secondary_connection
([#3162](#3162))
- secret_with_basic_authentication, secret_with_generic_string,
secret_with_oauth_authorization_code_grant,
secret_with_oauth_client_credentials
([#3110](#3110)),
([#3141](#3141))
- New data sources:
- connections
([#3155](#3155)),
([#3173](#3173))
- secrets
([#3131](#3131))
- Reworked:
- provider configuration hierarchy
([#3166](#3166)),
references
[#1881](#1881),
[#2145](#2145),
[#2925](#2925),
[#2983](#2983),
[#3104](#3104)
- provider configuration fields
([#3152](#3152))
streams data source
([#3151](#3151))
- SDK upgrades:
- Upgrade tag SDK
([#3126](#3126))
- Recreate streams when they are stale
([#3129](#3129))
### 🔧  Misc
- Add object renaming research summary
([#3172](#3172))
- Test support for object renaming
([#3130](#3130)),
([#3147](#3147)),
([#3154](#3154))
- Add tests to issue
[#3117](#3117)
([#3133](#3133))
- New roadmap entry
([#3158](#3158))
- Test more authentication methods
([#3178](#3178))
- Minor fixes
([#3174](#3174))
### 🐛  Bug fixes
- Apply various fixes
([#3176](#3176)),
this addresses BCR 2024_08, references
[#2717](#2717),
[#3005](#3005),
[#3125](#3125),
[#3127](#3127),
[#3153](#3153)
- Connection and secret data sources tests
([#3177](#3177))
- Fix grant import docs
([#3183](#3183)),
resolves
[#3179](https://github.com/Snowflake-Labs/terraform-provider-snowflake/discussions/3179)
- Fix user resource import
([#3181](#3181))
- Handle external type changes in stream resources
([#3164](#3164))
- Do not use OR REPLACE on initial creation in resources with
copy_grants
([#3129](#3129))
- Address issue
[#2201](#2201)
by introducing new stream resources

Co-authored-by: snowflake-release-please[bot] <105954990+snowflake-release-please[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants