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

provider/openstack: Add support for FWaaS routerinsertion extension #12589

Merged

Conversation

fatmcgav
Copy link
Contributor

@fatmcgav fatmcgav commented Mar 10, 2017

Add support for the Openstack FWaaS routerinsertion extension, as added to Gophercloud here: gophercloud/gophercloud#220

Fixes #12488

Todo:

  • Tidy up log lines and comments
  • Squash commits
  • Test?
  • Document

@fatmcgav
Copy link
Contributor Author

@jtopjian I thought it would be easier to create a PR, and can then use the review process :)

@jtopjian
Copy link
Contributor

jtopjian commented Mar 10, 2017

@fatmcgav Sounds good. Let me know when you'd like me to take a first pass :)

Edit: Ah, per #12488, I'll take a look now.

@fatmcgav
Copy link
Contributor Author

fatmcgav commented Mar 10, 2017 via email

@jtopjian
Copy link
Contributor

jtopjian commented Mar 11, 2017

@fatmcgav I forgot to hit the "start review" button, so I ended up cancelling it. Glad you got that one comment, though.

I was playing around with this and I think I found a cleaner way of going about it. Take a look here: jtopjian@346eb05

I think it works for Create, but haven't finished up the Update yet. There seems to be an issue in my test environment where firewalls are not being created, so I'll have to rebuild it.

Feel free to simply copy the code if you want to work with it further. I should have some time tomorrow to keep looking at this, too.

@fatmcgav
Copy link
Contributor Author

Ah, Yeh, that looks cleaner... That's how I thought it should work, but couldn't find the right combination...

Will give it a test later and confirm...

@jtopjian
Copy link
Contributor

Yeah, I tried a number of different combinations, too, until I landed on this one :)

One other thing I think I noticed is that if this extension is enabled, then Neutron will pass a router ID anyway. This is probably where the neutron firewall-create --no-routers option comes in. This probably maps to an empty array being sent in the request. The best way to do this would be to add a new argument to this Terraform resource of no_routers of type bool.

@fatmcgav
Copy link
Contributor Author

fatmcgav commented Mar 11, 2017

@jtopjian Yeh, I spotted the same... If I don't provide a value for associated_routers, then the firewall is automatically associated to all routers...
Passing an empty array on the POST data does result in a firewall with no associated routers.

So yeh, think will need a no_routers argument aswell...

@fatmcgav
Copy link
Contributor Author

Ah, so the next challenge is that 'router_ids' is stripped out by Gophercloud if it's empty :(
https://github.com/jtopjian/gophercloud/blob/82802e3903f673a84b07aa4604b68e4caa3c3ac5/openstack/networking/v2/extensions/fwaas/routerinsertion/requests.go#L43-L45

So guess either need to update Gophercloud, or overload the method in Terraform...
Thoughts?

@jtopjian
Copy link
Contributor

Can you confirm that --no-routers is equivalent to sending an empty array? If so, I'll fix that up in Gophercloud and we'll have to resume once it's patched.

@fatmcgav
Copy link
Contributor Author

Yeh, passing --no-routers in Neutron cli passes an empty array.
I'll pull a request example later for reference.

@jtopjian
Copy link
Contributor

Sounds good. I'll also add support for the RouterID in the results, too.

@fatmcgav
Copy link
Contributor Author

fatmcgav commented Mar 11, 2017 via email

@fatmcgav
Copy link
Contributor Author

Pending merge of gophercloud/gophercloud#292

@fatmcgav fatmcgav force-pushed the openstack_support_fwaas_routerinsertion branch from cec412c to b994923 Compare May 27, 2017 14:19
@fatmcgav
Copy link
Contributor Author

@jtopjian So this one is ready for another review... :)

Since gophercloud/gophercloud#292 was merged, I've updated to use the latest changes and added some additional acceptance tests, which all pass for me :)

==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/05/27 15:15:33 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/openstack -v -run=TestAccFWFirewallV1_* -timeout 120m
=== RUN   TestAccFWFirewallV1_importBasic
--- PASS: TestAccFWFirewallV1_importBasic (10.11s)
=== RUN   TestAccFWFirewallV1_basic
--- PASS: TestAccFWFirewallV1_basic (14.63s)
=== RUN   TestAccFWFirewallV1_timeout
--- PASS: TestAccFWFirewallV1_timeout (7.81s)
=== RUN   TestAccFWFirewallV1_router
--- PASS: TestAccFWFirewallV1_router (21.87s)
=== RUN   TestAccFWFirewallV1_no_router
--- PASS: TestAccFWFirewallV1_no_router (9.26s)
=== RUN   TestAccFWFirewallV1_router_update
--- PASS: TestAccFWFirewallV1_router_update (38.67s)
=== RUN   TestAccFWFirewallV1_router_remove
--- PASS: TestAccFWFirewallV1_router_remove (28.55s)
PASS
ok      github.com/hashicorp/terraform/builtin/providers/openstack      130.927s

Unfortunately all the commits have been rebased, as I had to fix a merge conflict as a result of #12863 - Once happy with the changes, I'll get it all squashed down into a couple of commits...

@fatmcgav
Copy link
Contributor Author

fatmcgav commented May 27, 2017

Hmm, so travis is failing the build with:

$ make vet
go vet $(go list ./... | grep -v /terraform/vendor/)
builtin/providers/openstack/resource_openstack_fw_firewall_v1.go:113: github.com/hashicorp/terraform/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/routerinsertion.CreateOptsExt composite literal uses unkeyed fields
builtin/providers/openstack/resource_openstack_fw_firewall_v1.go:122: github.com/hashicorp/terraform/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/routerinsertion.CreateOptsExt composite literal uses unkeyed fields
builtin/providers/openstack/resource_openstack_fw_firewall_v1.go:234: github.com/hashicorp/terraform/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/routerinsertion.UpdateOptsExt composite literal uses unkeyed fields
exit status 1

However when I run a make vet locally, I don't get the same failure 😕

@jtopjian / @stack72 Any ideas on how to fix the above error?

Edit: Actually, looking closer at the error, it appears the failure is in gophercloud rather than terraform... I'll take a look there... :)

@fatmcgav
Copy link
Contributor Author

fatmcgav commented May 27, 2017

So I've got a 'fix' for the vet failure... Not sure if it's the 'correct' solution though... :)

Copy link
Contributor

@jtopjian jtopjian left a comment

Choose a reason for hiding this comment

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

@fatmcgav Really nice work here!

I've left a few comments, all very minor.

In addition, I had no idea the Firewall tests were the way they currently are. They don't match the other test setups at all. If they were similar to the others, you would have probably been able to write easier tests. Let's leave everything as-is and I'll try to make some time to clean them up later.

Let me know if you have any questions.

if OS_IMAGE_ID == "" || OS_IMAGE_NAME == "" {
t.Fatal("OS_IMAGE_ID and OS_IMAGE_NAME must be set for acceptance tests")
if OS_IMAGE_ID == "" && OS_IMAGE_NAME == "" {
t.Fatal("OS_IMAGE_ID or OS_IMAGE_NAME must be set for acceptance tests")
Copy link
Contributor

Choose a reason for hiding this comment

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

While this is probably true, this is out of scope for this PR since it's not related to the router insertion feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I'll get it raised in a different PR...

},
associatedRoutersRaw := d.Get("associated_routers").(*schema.Set).List()
if len(associatedRoutersRaw) > 0 {
log.Printf("[DEBUG] Need to associate Firewall with router(s): %+v", associatedRoutersRaw)
Copy link
Contributor

Choose a reason for hiding this comment

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

How about: "Will attempt to associate firewall with router(s):..." ?

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

@@ -106,6 +146,7 @@ func resourceFWFirewallV1Create(d *schema.ResourceData, meta interface{}) error
}

_, err = stateConf.WaitForState()
log.Println("[DEBUG] Firewall is active.")
Copy link
Contributor

Choose a reason for hiding this comment

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

How about: "Firewall (ID) is active." ?

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

result := firewalls.Get(networkingClient, d.Id())

var firewall Firewall
err = result.ExtractInto(&firewall)
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a heads up that this might change in the future. What you have is the current working solution -- just something to be mindful of down the road.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, ok... Well atleast the tests should show us any breakage...

I guess I could collapse this into a single line, tagging the ExtractInto onto the end of the firewalls.Get... Thoughts?

@@ -57,6 +58,18 @@ func resourceFWFirewallV1() *schema.Resource {
ForceNew: true,
Computed: true,
},
"associated_routers": &schema.Schema{
Type: schema.TypeSet,
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the API return the associated routers as an array in the same order as what the user gave? If so, this can be a TypeList. But if the API takes it upon itself to re-order (for example, alphabetical), then TypeSet is the way to go.

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 not sure tbh... I'll give it a test with TypeList and see what it does...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So it looks like the API doesn't guarantee the ordering, as I switched to using TypeList and got a failure:

--- FAIL: TestAccFWFirewallV1_router_update (33.48s)
        testing.go:280: Step 1 error: After applying this step, the plan was not empty:

                DIFF:

                UPDATE: openstack_fw_firewall_v1.fw_1
                  associated_routers.0: "5eda6df1-0271-4468-a2eb-3e1e1a24596e" => "9ee2774f-a1af-494c-955e-bf37109c6bae"
                  associated_routers.1: "9ee2774f-a1af-494c-955e-bf37109c6bae" => "5eda6df1-0271-4468-a2eb-3e1e1a24596e"

So looks like got to stick to using TypeSet.

// FirewallCreateOpts represents the attributes used when creating a new firewall.
type FirewallCreateOpts struct {
firewalls.CreateOpts
firewalls.CreateOptsBuilder
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

I recently ran into this with a different type in another PR.

In addition to this, I wonder if this field should be explicitly labeled CreateOptsBuilder so this type of format can work? I haven't tried to modify the custom types here to support the field name. Just a thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeh, the go vet failure had me confused for a bit... So used that format here: https://github.com/hashicorp/terraform/pull/12589/files#diff-08dbfa227aa19c57ae3521114151c1c8R111

return nil, err
}

if base["value_specs"] != 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.

Just spotted another optimisation I can make, by extracting this out into its own function in util.go so that's it more reusable...

@@ -57,6 +58,18 @@ func resourceFWFirewallV1() *schema.Resource {
ForceNew: true,
Computed: true,
},
"associated_routers": &schema.Schema{
Type: schema.TypeSet,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So it looks like the API doesn't guarantee the ordering, as I switched to using TypeList and got a failure:

--- FAIL: TestAccFWFirewallV1_router_update (33.48s)
        testing.go:280: Step 1 error: After applying this step, the plan was not empty:

                DIFF:

                UPDATE: openstack_fw_firewall_v1.fw_1
                  associated_routers.0: "5eda6df1-0271-4468-a2eb-3e1e1a24596e" => "9ee2774f-a1af-494c-955e-bf37109c6bae"
                  associated_routers.1: "9ee2774f-a1af-494c-955e-bf37109c6bae" => "5eda6df1-0271-4468-a2eb-3e1e1a24596e"

So looks like got to stick to using TypeSet.

@fatmcgav
Copy link
Contributor Author

@jtopjian Is a1b5ce8 closer to what you were thinking as current?
I based the changes largely on the openstack_dns_zone_v2 tests...

@fatmcgav
Copy link
Contributor Author

From a commit squash POV, I'm thinking the following:

  • vendor: Add gophercloud/routerinsertion package.
  • provider/openstack: Add support for associating firewall instance with router(s).
  • website: Add documentation for associated_routersand no_routers arguments on openstack_fw_firewall_v1 resource.
  • provider/openstack: Add AddValueSpecs function and refactor existing
    uses.

@jtopjian
Copy link
Contributor

Is a1b5ce8 closer to what you were thinking as current?

Yep, that looks good to me :)

From a commit squash POV, I'm thinking the following:

Sure, that sounds good. Really, as long as the vendor commit is separate, anything else is fine.

I'll done one final sweep and test with a squashed set.

gophercloud/firewall to support router insertion
`openstack_fw_firewall_v1` resources with router(s).
Added `associated_routers` and `no_routers` arguments.
…rguments on `openstack_fw_firewall_v1` resource.
@fatmcgav fatmcgav force-pushed the openstack_support_fwaas_routerinsertion branch from afc163f to 5f5c5ec Compare May 30, 2017 08:01
@fatmcgav fatmcgav changed the title [WIP] provider/openstack: Add support for FWaaS routerinsertion extension provider/openstack: Add support for FWaaS routerinsertion extension May 30, 2017
@fatmcgav
Copy link
Contributor Author

@jtopjian Right, all squashed down into a healthier number of commits... :)

@jtopjian
Copy link
Contributor

jtopjian commented Jun 1, 2017

This looks good to me! Really nice work on this, @fatmcgav -- thank you :)

==> Checking that code complies with gofmt requirements...                               
go generate $(go list ./... | grep -v /terraform/vendor/)                                
2017/05/31 23:16:22 Generated command/internal_plugin_list.go                            
TF_ACC=1 go test ./builtin/providers/openstack -v -run=TestAccFWFirewallV1 -timeout 120m 
=== RUN   TestAccFWFirewallV1_importBasic                                                
--- PASS: TestAccFWFirewallV1_importBasic (8.84s)                                        
=== RUN   TestAccFWFirewallV1_basic                                                      
--- PASS: TestAccFWFirewallV1_basic (17.23s)                                             
=== RUN   TestAccFWFirewallV1_timeout                                                    
--- PASS: TestAccFWFirewallV1_timeout (8.19s)                                            
=== RUN   TestAccFWFirewallV1_router                                                     
--- PASS: TestAccFWFirewallV1_router (24.65s)                                            
=== RUN   TestAccFWFirewallV1_no_router                                                  
--- PASS: TestAccFWFirewallV1_no_router (9.46s)                                          
=== RUN   TestAccFWFirewallV1_router_update                                              
--- PASS: TestAccFWFirewallV1_router_update (37.96s)                                     
=== RUN   TestAccFWFirewallV1_router_remove                                              
--- PASS: TestAccFWFirewallV1_router_remove (29.20s)                                     
PASS                                                                                     
ok      github.com/hashicorp/terraform/builtin/providers/openstack      135.567s         

@jtopjian jtopjian merged commit 1da7fda into hashicorp:master Jun 1, 2017
@ghost
Copy link

ghost commented Apr 11, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

provider/openstack: Add support for FWaaS Router Insertion
2 participants