Error handling on struct to map mappings
diff --git a/openstack/networking/v2/extensions/fwaas/firewalls/errors.go b/openstack/networking/v2/extensions/fwaas/firewalls/errors.go
new file mode 100644
index 0000000..dd92bb2
--- /dev/null
+++ b/openstack/networking/v2/extensions/fwaas/firewalls/errors.go
@@ -0,0 +1,11 @@
+package firewalls
+
+import "fmt"
+
+func err(str string) error {
+ return fmt.Errorf("%s", str)
+}
+
+var (
+ errPolicyRequired = err("A policy ID is required")
+)
diff --git a/openstack/networking/v2/extensions/fwaas/firewalls/requests.go b/openstack/networking/v2/extensions/fwaas/firewalls/requests.go
index a1df87b..455cf79 100644
--- a/openstack/networking/v2/extensions/fwaas/firewalls/requests.go
+++ b/openstack/networking/v2/extensions/fwaas/firewalls/requests.go
@@ -67,42 +67,46 @@
PolicyID string
}
-// ToPolicyCreateMap casts a CreateOpts struct to a map.
-func (opts CreateOpts) ToPolicyCreateMap() map[string]interface{} {
- p := make(map[string]interface{})
+// ToFirewallCreateMap casts a CreateOpts struct to a map.
+func (opts CreateOpts) ToFirewallCreateMap() (map[string]interface{}, error) {
+ if opts.PolicyID == "" {
+ return nil, errPolicyRequired
+ }
+
+ f := make(map[string]interface{})
if opts.TenantID != "" {
- p["tenant_id"] = opts.TenantID
+ f["tenant_id"] = opts.TenantID
}
if opts.Name != "" {
- p["name"] = opts.Name
+ f["name"] = opts.Name
}
if opts.Description != "" {
- p["description"] = opts.Description
+ f["description"] = opts.Description
}
if opts.Shared != nil {
- p["shared"] = *opts.Shared
+ f["shared"] = *opts.Shared
}
if opts.AdminStateUp != nil {
- p["admin_state_up"] = *opts.AdminStateUp
+ f["admin_state_up"] = *opts.AdminStateUp
}
if opts.PolicyID != "" {
- p["firewall_policy_id"] = opts.PolicyID
+ f["firewall_policy_id"] = opts.PolicyID
}
- return p
+ return map[string]interface{}{"firewall": f}, nil
}
// Create accepts a CreateOpts struct and uses the values to create a new firewall
func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
+ var res CreateResult
- type request struct {
- Firewall map[string]interface{} `json:"firewall"`
+ reqBody, err := opts.ToFirewallCreateMap()
+ if err != nil {
+ res.Err = err
+ return res
}
- reqBody := request{Firewall: opts.ToPolicyCreateMap()}
-
- var res CreateResult
_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
MoreHeaders: c.AuthenticatedHeaders(),
ReqBody: &reqBody,
@@ -133,40 +137,40 @@
PolicyID string
}
-// ToPolicyUpdateMap casts a CreateOpts struct to a map.
-func (opts UpdateOpts) ToPolicyUpdateMap() map[string]interface{} {
- p := make(map[string]interface{})
+// ToFirewallUpdateMap casts a CreateOpts struct to a map.
+func (opts UpdateOpts) ToFirewallUpdateMap() (map[string]interface{}, error) {
+ f := make(map[string]interface{})
if opts.Name != nil {
- p["name"] = *opts.Name
+ f["name"] = *opts.Name
}
if opts.Description != nil {
- p["description"] = *opts.Description
+ f["description"] = *opts.Description
}
if opts.Shared != nil {
- p["shared"] = *opts.Shared
+ f["shared"] = *opts.Shared
}
if opts.AdminStateUp != nil {
- p["admin_state_up"] = *opts.AdminStateUp
+ f["admin_state_up"] = *opts.AdminStateUp
}
if opts.PolicyID != "" {
- p["firewall_policy_id"] = opts.PolicyID
+ f["firewall_policy_id"] = opts.PolicyID
}
- return p
+ return map[string]interface{}{"firewall": f}, nil
}
// Update allows firewalls to be updated.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
+ var res UpdateResult
- type request struct {
- Firewall map[string]interface{} `json:"firewall"`
+ reqBody, err := opts.ToFirewallUpdateMap()
+ if err != nil {
+ res.Err = err
+ return res
}
- reqBody := request{Firewall: opts.ToPolicyUpdateMap()}
-
// Send request to API
- var res UpdateResult
_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
MoreHeaders: c.AuthenticatedHeaders(),
ReqBody: &reqBody,
diff --git a/openstack/networking/v2/extensions/fwaas/policies/requests.go b/openstack/networking/v2/extensions/fwaas/policies/requests.go
index fec7c2e..21e45dd 100644
--- a/openstack/networking/v2/extensions/fwaas/policies/requests.go
+++ b/openstack/networking/v2/extensions/fwaas/policies/requests.go
@@ -61,7 +61,7 @@
}
// ToPolicyCreateMap casts a CreateOpts struct to a map.
-func (opts CreateOpts) ToPolicyCreateMap() map[string]interface{} {
+func (opts CreateOpts) ToPolicyCreateMap() (map[string]interface{}, error) {
p := make(map[string]interface{})
if opts.TenantID != "" {
@@ -83,19 +83,19 @@
p["firewall_rules"] = opts.Rules
}
- return p
+ return map[string]interface{}{"firewall_policy": p}, nil
}
// Create accepts a CreateOpts struct and uses the values to create a new firewall policy
func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
+ var res CreateResult
- type request struct {
- Policy map[string]interface{} `json:"firewall_policy"`
+ reqBody, err := opts.ToPolicyCreateMap()
+ if err != nil {
+ res.Err = err
+ return res
}
- reqBody := request{Policy: opts.ToPolicyCreateMap()}
-
- var res CreateResult
_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
MoreHeaders: c.AuthenticatedHeaders(),
ReqBody: &reqBody,
@@ -127,7 +127,7 @@
}
// ToPolicyUpdateMap casts a CreateOpts struct to a map.
-func (opts UpdateOpts) ToPolicyUpdateMap() map[string]interface{} {
+func (opts UpdateOpts) ToPolicyUpdateMap() (map[string]interface{}, error) {
p := make(map[string]interface{})
if opts.Name != nil {
@@ -146,20 +146,20 @@
p["firewall_rules"] = opts.Rules
}
- return p
+ return map[string]interface{}{"firewall_policy": p}, nil
}
// Update allows firewall policies to be updated.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
+ var res UpdateResult
- type request struct {
- Policy map[string]interface{} `json:"firewall_policy"`
+ reqBody, err := opts.ToPolicyUpdateMap()
+ if err != nil {
+ res.Err = err
+ return res
}
- reqBody := request{Policy: opts.ToPolicyUpdateMap()}
-
// Send request to API
- var res UpdateResult
_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
MoreHeaders: c.AuthenticatedHeaders(),
ReqBody: &reqBody,
diff --git a/openstack/networking/v2/extensions/fwaas/rules/errors.go b/openstack/networking/v2/extensions/fwaas/rules/errors.go
new file mode 100644
index 0000000..0b29d39
--- /dev/null
+++ b/openstack/networking/v2/extensions/fwaas/rules/errors.go
@@ -0,0 +1,12 @@
+package rules
+
+import "fmt"
+
+func err(str string) error {
+ return fmt.Errorf("%s", str)
+}
+
+var (
+ errProtocolRequired = err("A protocol is required (tcp, udp, icmp or any)")
+ errActionRequired = err("An action is required (allow or deny)")
+)
diff --git a/openstack/networking/v2/extensions/fwaas/rules/requests.go b/openstack/networking/v2/extensions/fwaas/rules/requests.go
index 18e37ad..cefbf86 100644
--- a/openstack/networking/v2/extensions/fwaas/rules/requests.go
+++ b/openstack/networking/v2/extensions/fwaas/rules/requests.go
@@ -78,7 +78,15 @@
}
// ToRuleCreateMap casts a CreateOpts struct to a map.
-func (opts CreateOpts) ToRuleCreateMap() map[string]interface{} {
+func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) {
+ if opts.Protocol == "" {
+ return nil, errProtocolRequired
+ }
+
+ if opts.Action == "" {
+ return nil, errActionRequired
+ }
+
r := make(map[string]interface{})
r["protocol"] = opts.Protocol
@@ -115,19 +123,19 @@
r["enabled"] = *opts.Enabled
}
- return r
+ return map[string]interface{}{"firewall_rule": r}, nil
}
// Create accepts a CreateOpts struct and uses the values to create a new firewall rule
func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
+ var res CreateResult
- type request struct {
- Rule map[string]interface{} `json:"firewall_rule"`
+ reqBody, err := opts.ToRuleCreateMap()
+ if err != nil {
+ res.Err = err
+ return res
}
- reqBody := request{Rule: opts.ToRuleCreateMap()}
-
- var res CreateResult
_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
MoreHeaders: c.AuthenticatedHeaders(),
ReqBody: &reqBody,
@@ -165,7 +173,7 @@
}
// ToRuleUpdateMap casts a UpdateOpts struct to a map.
-func (opts UpdateOpts) ToRuleUpdateMap() map[string]interface{} {
+func (opts UpdateOpts) ToRuleUpdateMap() (map[string]interface{}, error) {
r := make(map[string]interface{})
if opts.Protocol != "" {
@@ -222,20 +230,20 @@
r["enabled"] = *opts.Enabled
}
- return r
+ return map[string]interface{}{"firewall_rule": r}, nil
}
// Update allows firewall policies to be updated.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
+ var res UpdateResult
- type request struct {
- Rule map[string]interface{} `json:"firewall_rule"`
+ reqBody, err := opts.ToRuleUpdateMap()
+ if err != nil {
+ res.Err = err
+ return res
}
- reqBody := request{Rule: opts.ToRuleUpdateMap()}
-
// Send request to API
- var res UpdateResult
_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
MoreHeaders: c.AuthenticatedHeaders(),
ReqBody: &reqBody,