From b743cca31d7b26d4996167a4bf88011eaf88213e Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 20:55:42 +0500 Subject: [PATCH 1/8] fix: create security group rule with any protocol https://github.com/gophercloud/gophercloud/issues/2442 --- .../v2/extensions/security/rules/requests.go | 5 ++ .../security/rules/testing/requests_test.go | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 78b67b0df0..d9079dd96a 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -145,6 +145,11 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu r.Err = err return } + if m, mOk := b["security_group_rule"].(map[string]any); mOk { + if p, ok := m["protocol"]; ok && p == "any" { + m["protocol"] = nil + } + } resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 454399f306..7d9ceefdff 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -164,6 +164,66 @@ func TestCreate(t *testing.T) { th.AssertNoErr(t, err) } +func TestCreateAnyProtocol(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/v2.0/security-group-rules", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestHeader(t, r, "Accept", "application/json") + th.TestJSONRequest(t, r, ` +{ + "security_group_rule": { + "description": "test description of rule", + "direction": "ingress", + "port_range_min": 80, + "ethertype": "IPv4", + "port_range_max": 80, + "protocol": null, + "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" + } +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + + fmt.Fprintf(w, ` +{ + "security_group_rule": { + "description": "test description of rule", + "direction": "ingress", + "ethertype": "IPv4", + "id": "2bc0accf-312e-429a-956e-e4407625eb62", + "port_range_max": 80, + "port_range_min": 80, + "protocol": null, + "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", + "remote_ip_prefix": null, + "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", + "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550" + } +} + `) + }) + + opts := rules.CreateOpts{ + Description: "test description of rule", + Direction: "ingress", + PortRangeMin: 80, + EtherType: rules.EtherType4, + PortRangeMax: 80, + Protocol: "any", + RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", + SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", + } + _, err := rules.Create(context.TODO(), fake.ServiceClient(), opts).Extract() + th.AssertNoErr(t, err) +} + func TestRequiredCreateOpts(t *testing.T) { res := rules.Create(context.TODO(), fake.ServiceClient(), rules.CreateOpts{Direction: rules.DirIngress}) if res.Err == nil { From d3a0124321fb3feb3d97fce3f8bf8adf94f0d30f Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 21:07:47 +0500 Subject: [PATCH 2/8] use const --- openstack/networking/v2/extensions/security/rules/requests.go | 2 +- .../v2/extensions/security/rules/testing/requests_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index d9079dd96a..8fa5d9ee83 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -146,7 +146,7 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu return } if m, mOk := b["security_group_rule"].(map[string]any); mOk { - if p, ok := m["protocol"]; ok && p == "any" { + if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { m["protocol"] = nil } } diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 7d9ceefdff..3b44db3837 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -216,7 +216,7 @@ func TestCreateAnyProtocol(t *testing.T) { PortRangeMin: 80, EtherType: rules.EtherType4, PortRangeMax: 80, - Protocol: "any", + Protocol: rules.ProtocolAny, RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", } From 91bbaa36262372a92eeea8b74ceb941b6f092374 Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 23:11:12 +0500 Subject: [PATCH 3/8] move to ToSecGroupRuleCreateMap --- .../v2/extensions/security/rules/requests.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 8fa5d9ee83..cad532bd93 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -134,7 +134,16 @@ type CreateOpts struct { // ToSecGroupRuleCreateMap builds a request body from CreateOpts. func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]any, error) { - return gophercloud.BuildRequestBody(opts, "security_group_rule") + b, err := gophercloud.BuildRequestBody(opts, "security_group_rule") + if err != nil { + return nil, err + } + if m, mOk := b["security_group_rule"].(map[string]any); mOk { + if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { + m["protocol"] = nil + } + } + return b, err } // Create is an operation which adds a new security group rule and associates it @@ -145,11 +154,6 @@ func Create(ctx context.Context, c *gophercloud.ServiceClient, opts CreateOptsBu r.Err = err return } - if m, mOk := b["security_group_rule"].(map[string]any); mOk { - if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { - m["protocol"] = nil - } - } resp, err := c.Post(ctx, rootURL(c), b, &r.Body, nil) _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) return From 4cd0309af736a14151adcba13ddfa243ae0688ff Mon Sep 17 00:00:00 2001 From: whitefox Date: Wed, 24 Jul 2024 23:44:21 +0500 Subject: [PATCH 4/8] emoved redundant key check --- .../networking/v2/extensions/security/rules/requests.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index cad532bd93..55a6cde88f 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -2,6 +2,7 @@ package rules import ( "context" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/fwaas_v2/rules" "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" @@ -138,10 +139,8 @@ func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]any, error) { if err != nil { return nil, err } - if m, mOk := b["security_group_rule"].(map[string]any); mOk { - if p, ok := m["protocol"]; ok && p == string(ProtocolAny) { - m["protocol"] = nil - } + if m := b["security_group_rule"].(map[string]any); m["protocol"] == string(rules.ProtocolAny) { + m["protocol"] = nil } return b, err } From fc5f4178fc797b46b6c5b9ace78ff7a14d9ca6ff Mon Sep 17 00:00:00 2001 From: whitefox Date: Thu, 25 Jul 2024 00:34:18 +0500 Subject: [PATCH 5/8] extract ProtocolAny --- openstack/networking/v2/extensions/security/rules/results.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index cfdb27fa17..bcaea974ce 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -109,6 +109,9 @@ func (r commonResult) Extract() (*SecGroupRule, error) { SecGroupRule *SecGroupRule `json:"security_group_rule"` } err := r.ExtractInto(&s) + if err == nil && len(s.SecGroupRule.Protocol) == 0 { + s.SecGroupRule.Protocol = string(ProtocolAny) + } return s.SecGroupRule, err } From ab9a11ea83bb84c6e4d5a45cf5ef9f338f23a46f Mon Sep 17 00:00:00 2001 From: whitefox Date: Fri, 26 Jul 2024 22:57:11 +0500 Subject: [PATCH 6/8] protocol any to empty string --- .../v2/extensions/security/rules/requests.go | 13 ++----------- .../v2/extensions/security/rules/results.go | 3 --- .../security/rules/testing/requests_test.go | 2 -- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index 55a6cde88f..eaf6deab80 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -2,8 +2,6 @@ package rules import ( "context" - "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/fwaas_v2/rules" - "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) @@ -78,7 +76,7 @@ const ( ProtocolUDP RuleProtocol = "udp" ProtocolUDPLite RuleProtocol = "udplite" ProtocolVRRP RuleProtocol = "vrrp" - ProtocolAny RuleProtocol = "any" + ProtocolAny RuleProtocol = "" ) // CreateOptsBuilder allows extensions to add additional parameters to the @@ -135,14 +133,7 @@ type CreateOpts struct { // ToSecGroupRuleCreateMap builds a request body from CreateOpts. func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]any, error) { - b, err := gophercloud.BuildRequestBody(opts, "security_group_rule") - if err != nil { - return nil, err - } - if m := b["security_group_rule"].(map[string]any); m["protocol"] == string(rules.ProtocolAny) { - m["protocol"] = nil - } - return b, err + return gophercloud.BuildRequestBody(opts, "security_group_rule") } // Create is an operation which adds a new security group rule and associates it diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go index bcaea974ce..cfdb27fa17 100644 --- a/openstack/networking/v2/extensions/security/rules/results.go +++ b/openstack/networking/v2/extensions/security/rules/results.go @@ -109,9 +109,6 @@ func (r commonResult) Extract() (*SecGroupRule, error) { SecGroupRule *SecGroupRule `json:"security_group_rule"` } err := r.ExtractInto(&s) - if err == nil && len(s.SecGroupRule.Protocol) == 0 { - s.SecGroupRule.Protocol = string(ProtocolAny) - } return s.SecGroupRule, err } diff --git a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go index 3b44db3837..40372c298a 100644 --- a/openstack/networking/v2/extensions/security/rules/testing/requests_test.go +++ b/openstack/networking/v2/extensions/security/rules/testing/requests_test.go @@ -181,7 +181,6 @@ func TestCreateAnyProtocol(t *testing.T) { "port_range_min": 80, "ethertype": "IPv4", "port_range_max": 80, - "protocol": null, "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a" } @@ -200,7 +199,6 @@ func TestCreateAnyProtocol(t *testing.T) { "id": "2bc0accf-312e-429a-956e-e4407625eb62", "port_range_max": 80, "port_range_min": 80, - "protocol": null, "remote_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5", "remote_ip_prefix": null, "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a", From 17ab1a6bc8daa4abee25c26de8c39e5c9868f817 Mon Sep 17 00:00:00 2001 From: whitefox Date: Fri, 26 Jul 2024 23:52:25 +0500 Subject: [PATCH 7/8] revert newline --- openstack/networking/v2/extensions/security/rules/requests.go | 1 + 1 file changed, 1 insertion(+) diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go index eaf6deab80..f2ea9f2d16 100644 --- a/openstack/networking/v2/extensions/security/rules/requests.go +++ b/openstack/networking/v2/extensions/security/rules/requests.go @@ -2,6 +2,7 @@ package rules import ( "context" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/pagination" ) From f38fcef442834685d024f1422b20719f021e3705 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Wed, 18 Sep 2024 13:46:49 +0200 Subject: [PATCH 8/8] Prepare v2.1.1 --- CHANGELOG.md | 4 ++++ provider_client.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae5109cfe..41f9017aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.1.1 (2024-09-18) + +* [GH-3161](https://github.com/gophercloud/gophercloud/pull/3161) [v2] fix: create security group rule with any protocol + ## v2.1.0 (2024-07-24) * [GH-3078](https://github.com/gophercloud/gophercloud/pull/3078) [networking]: add BGP VPNs support diff --git a/provider_client.go b/provider_client.go index a4a8dce51d..e2cd3c2dad 100644 --- a/provider_client.go +++ b/provider_client.go @@ -13,7 +13,7 @@ import ( // DefaultUserAgent is the default User-Agent string set in the request header. const ( - DefaultUserAgent = "gophercloud/v2.1.0" + DefaultUserAgent = "gophercloud/v2.1.1" DefaultMaxBackoffRetries = 60 )