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

[feature] Network Policy Resource #271

Merged

Conversation

grahamplace
Copy link
Contributor

Adds support for managing Snowflake Network Policy objects via the new snowflake_network_policy resource type.

Test Plan

  • acceptance tests
  • tested built provider locally with trial Snowflake account

References

@grahamplace grahamplace requested a review from a team as a code owner October 9, 2020 17:05
@grahamplace grahamplace requested review from ryanking and removed request for a team October 9, 2020 17:05
Copy link
Contributor

@ryanking ryanking left a comment

Choose a reason for hiding this comment

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

Thanks! This looks great.

A few minor bits of feedback and this should be good to go.

Thanks for writing acceptance tests.

pkg/provider/provider.go Outdated Show resolved Hide resolved
pkg/resources/network_policy.go Outdated Show resolved Hide resolved
name = "%v"
comment = "%v"
allowed_ip_list = ["192.168.0.100/24", "29.254.123.20"]
blocked_ip_list = ["192.168.0.101"]
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably include testing adding to users 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.

I've added a users list to the test network policy resource definition (and a dummy user resource definition) so at least the user-granting code should be executing during this acceptance test now.

However, (as far as I can tell) I have to define:
ImportStateVerifyIgnore: []string{"set_for_account", "users"},

because nowhere in ReadNetworkPolicy is there:
data.Set("set_for_account", ...) or
data.Set("users", ...)

This is the case because there doesn't appear to be a way in Snowflake to do "get all users with this Network Policy set" or "tell me if this network policy is set for the Snowflake account". Neither SHOW nor DESC returns any information about the active/applied status of a given Network Policy:

Is it acceptable to leave those out of ReadNetworkPolicy (and thus having to include them in ImportStateVerifyIgnore)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FWIW this is why I had to write this resource with ForceNew: true for those two fields, with the "exclusive assignment" explanation in the docs — the simplest way I could figure out how to deal with this is to just always destroy/recreate and re-grant to users or re-set on account

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah that makes sense!

Thinking about this a bit more, I think we should consider separating the attachment to a separate resource. This should allow us to avoid the scenario where we need to recreate the network policy resource every time one of the attachments changes. Of course the attachments may need to be recreated, but that might be tolerable. What do you think?

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'm on board with this — a separate attachment resource was my original plan, but I moved away from it because I (erroneously) observed that if you dropped a network policy, the users with that policy set continued to be restricted by the policy. Hence, I thought we needed to keep the attachment tightly coupled with the resource.

However, I tested this understanding again and it turns out there's just a bit of lag (not more than a minute) between dropping the network policy and the user then being able to open a session from any IP address

So this approach should work. I'll update PR

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 guess one thing to think about is that if we do this, the snowflake_network_policy_attachment resource wouldn't behave like the similar *_grant resources (e.g. warehouse/database/etc) and create exclusive attachments

Because there's not a way of getting existing attachments from SHOW/DESCing network policies/users/accounts, a network policy could be attached to a user outside of Terraform, and then changes to the snowflake_network_policy_attachment wouldn't destroy that attachment. That's probably fine? We should just document it

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah I think that is fine given the limitations we are working with.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done — the one thing I'm unsure about is ReadNetworkPolicyAttachment — given above limitations, there's no way to actually implement schema.ReadFunc for the attachment resource. I don't think I actually need ReadNetworkPolicyAttachment implemented for this, but InternalValidate fails without it. To get around that, I just implemented a dummy func 🤷

lmk if there's a better way to handle this!

pkg/resources/network_policy_test.go Outdated Show resolved Hide resolved
pkg/resources/network_policy.go Outdated Show resolved Hide resolved
@ryanking
Copy link
Contributor

ryanking commented Oct 9, 2020

Note that I am seeing some acceptance test failures, running make test-acceptance locally -

=== RUN   TestAccNetworkPolicy
    testing.go:683: Step 0 error: errors during apply:
        
        Error: 000606 (57P03): No active warehouse selected in the current session.  Select an active warehouse with the 'use warehouse' command.
        
        
          on /var/folders/ly/qwpw0g113mz15651mkc9wd400000gr/T/tf-test836548438/main.tf line 2:
          (source code not available)
        
        
    testing.go:744: Error destroying resource! WARNING: Dangling resources
        may exist. The full state and error is shown below.
        
        Error: errors during refresh: 000606 (57P03): No active warehouse selected in the current session.  Select an active warehouse with the 'use warehouse' command.
        
        
        State: <nil>

It seems that the select query needs a warehouse, which means we would need to add that to the provider configuration. In the past we've mostly avoided that and instead dealt with the the annoyances of working with just show and describe, which don't need a warehouse.

@grahamplace
Copy link
Contributor Author

Note that I am seeing some acceptance test failures, running make test-acceptance locally -

=== RUN   TestAccNetworkPolicy
    testing.go:683: Step 0 error: errors during apply:
        
        Error: 000606 (57P03): No active warehouse selected in the current session.  Select an active warehouse with the 'use warehouse' command.
        
        
          on /var/folders/ly/qwpw0g113mz15651mkc9wd400000gr/T/tf-test836548438/main.tf line 2:
          (source code not available)
        
        
    testing.go:744: Error destroying resource! WARNING: Dangling resources
        may exist. The full state and error is shown below.
        
        Error: errors during refresh: 000606 (57P03): No active warehouse selected in the current session.  Select an active warehouse with the 'use warehouse' command.
        
        
        State: <nil>

It seems that the select query needs a warehouse, which means we would need to add that to the provider configuration. In the past we've mostly avoided that and instead dealt with the the annoyances of working with just show and describe, which don't need a warehouse.

Similar to my reply on your other comment — the issue here is that Snowflake's implementation of Network Policies is weird/somewhat different than other object types.

More specifically in this case, I think we have to do the RESULT_SCAN approach I used (which is the cause of acceptance tests user requiring a warehouse). This is because there is no way to SHOW/DESC the information about a single Network Policy in Snowflake SQL:

  • DESC is limited to a single Network Policy, but it only returns the IP address lists:
    image

  • SHOW only allows SHOW NETWORK POLICIES — for some reason, unlike other object types, the output cannot be limited to a single Network Policy object via LIKE. Adding a LIKE does not limit the returned data:
    image

Thus, in order to get the current comment on the Network Policy in question, the SHOW output has to be cut down to just name = "mypolicy" via a second query that uses RESULT_SCAN('original_query_id')

I worked around this by setting DEFAULT_WAREHOUSE on the Travis user. Not ideal obviously, but I don't have other ideas for how to implement ReadNetworkPolicy without the RESULT_SCAN approach given limitations outlined above. Open to ideas!

@grahamplace
Copy link
Contributor Author

^ while writing that I realized that I can probably just refactor to do the SHOW/DESC post-processing in Go instead of in Snowflake SQL, thus bypassing the RESULT_SCAN and the need for a Warehouse

Still posted as it's useful context, but I'll take a stab at that refactor now

@grahamplace
Copy link
Contributor Author

Okay, updated and ready for another look @ryanking!

@aidan-melen
Copy link

thanks for working on this feature @grahamplace and @ryanking!

Copy link
Contributor

@alldoami alldoami left a comment

Choose a reason for hiding this comment

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

Ran test-acceptancec-ci locally and passed all the test! Thanks for the work! 🥳 I'll let @ryanking take one more look, but LGTM!

@grahamplace
Copy link
Contributor Author

Thanks for the review @alldoami! Per Ryan's suggestion, I still need to refactor this to move the attachment into a separate resource. That work is on my todo list for today, so hopefully I can put that change up and tag you both for another look

@grahamplace
Copy link
Contributor Author

Done! Ready for another look @ryanking @alldoami 🙂 Would appreciate input on this bit:
#271 (comment)

Copy link
Contributor

@ryanking ryanking left a comment

Choose a reason for hiding this comment

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

I am currently getting acceptance test failures too:

pkg/resources/network_policy_attachment_acceptance_test.go:12:6: TestAccNetworkPolicyAttachment redeclared in this block
	previous declaration at pkg/resources/network_policy_acceptance_test.go:12:40
pkg/resources/network_policy_attachment_acceptance_test.go:40:6: networkPolicyAttachmentConfig redeclared in this block
	previous declaration at pkg/resources/network_policy_acceptance_test.go:40:55

{
ResourceName: "snowflake_network_policy_attachment.test",
ImportState: true,
ImportStateVerify: false,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason for this to be false?

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 set this to false while developing because I wasn't able to get it to work, I thought due to the inability to actually implement ReadNetworkPolicyAttachment

But it looks like it works now so switching it back to 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.

annnd I was wrong -- it's actually still not working:

=== RUN   TestAccNetworkPolicyAttachment
    TestAccNetworkPolicyAttachment: testing.go:683: Step 1 error: ImportStateVerify attributes not equivalent. Difference is shown below. Top is actual, bottom is expected.

        (map[string]string) {
        }


        (map[string]string) (len=5) {
         (string) (len=19) "network_policy_name": (string) (len=10) "uowauijhoy",
         (string) (len=15) "set_for_account": (string) (len=5) "false",
         (string) (len=7) "users.#": (string) (len=1) "2",
         (string) (len=16) "users.2494182523": (string) (len=10) "test-user1",
         (string) (len=16) "users.3213322168": (string) (len=10) "test-user2"
        }

--- FAIL: TestAccNetworkPolicyAttachment (7.03s)

I think because ReadNetworkPolicyAttachment isn't really implemented?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just confirming you saw this last comment/commit @ryanking? Does the merge mean you're fine skipping ImportStateVerify given Snowflake limitations that prevent us from show/desc'ing anything about a policy attachment on users/account?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah its fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Awesome, thanks for all the help getting this merged!

@grahamplace
Copy link
Contributor Author

I am currently getting acceptance test failures too:

pkg/resources/network_policy_attachment_acceptance_test.go:12:6: TestAccNetworkPolicyAttachment redeclared in this block
	previous declaration at pkg/resources/network_policy_acceptance_test.go:12:40
pkg/resources/network_policy_attachment_acceptance_test.go:40:6: networkPolicyAttachmentConfig redeclared in this block
	previous declaration at pkg/resources/network_policy_acceptance_test.go:40:55

Ah oops, I accidentally overwrote network_policy_acceptance_test.go with network_policy_attachment_acceptance_test.go, should be corrected now

@ryanking ryanking merged commit 4dd6077 into Snowflake-Labs:main Oct 23, 2020
gjv9491 pushed a commit to gjv9491/terraform-provider-snowflake that referenced this pull request Mar 19, 2021
Adds support for managing Snowflake Network Policy objects via the new `snowflake_network_policy` resource type.

<!-- detail ways in which this PR has been tested or needs to be tested -->
* [x] acceptance tests
<!-- add more below if you think they are relevant -->
* [x] tested built provider locally with trial Snowflake account

<!-- issues documentation links, etc  -->
* Issue: Snowflake-Labs#221
* https://docs.snowflake.com/en/sql-reference/sql/create-network-policy.html
anton-chekanov pushed a commit to anton-chekanov/terraform-provider-snowflake that referenced this pull request Jan 25, 2022
Adds support for managing Snowflake Network Policy objects via the new `snowflake_network_policy` resource type.

## Test Plan
<!-- detail ways in which this PR has been tested or needs to be tested -->
* [x] acceptance tests
<!-- add more below if you think they are relevant -->
* [x] tested built provider locally with trial Snowflake account

## References
<!-- issues documentation links, etc  -->
* Issue: Snowflake-Labs#221
* https://docs.snowflake.com/en/sql-reference/sql/create-network-policy.html
daniepett pushed a commit to daniepett/terraform-provider-snowflake that referenced this pull request Feb 9, 2022
Adds support for managing Snowflake Network Policy objects via the new `snowflake_network_policy` resource type.

<!-- detail ways in which this PR has been tested or needs to be tested -->
* [x] acceptance tests
<!-- add more below if you think they are relevant -->
* [x] tested built provider locally with trial Snowflake account

<!-- issues documentation links, etc  -->
* Issue: Snowflake-Labs#221
* https://docs.snowflake.com/en/sql-reference/sql/create-network-policy.html
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.

4 participants