more error types for compute v2
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests.go b/openstack/compute/v2/extensions/bootfromvolume/requests.go
index 6c063be..7171afa 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests.go
@@ -1,7 +1,7 @@
package bootfromvolume
import (
- "errors"
+ "fmt"
"strconv"
"github.com/gophercloud/gophercloud"
@@ -62,7 +62,10 @@
}
if len(opts.BlockDevice) == 0 {
- return nil, errors.New("Required fields UUID and SourceType not set.")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "bootfromvolume.ToServerCreateMap"
+ err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice"
+ return nil, err
}
serverMap := base["server"].(map[string]interface{})
@@ -71,7 +74,10 @@
for i, bd := range opts.BlockDevice {
if string(bd.SourceType) == "" {
- return nil, errors.New("SourceType must be one of: volume, image, snapshot.")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "bootfromvolume.ToServerCreateMap"
+ err.Argument = fmt.Sprintf("bootfromvolume.CreateOptsExt.BlockDevice[%d].SourceType", i)
+ return nil, err
}
blockDevice[i] = make(map[string]interface{})
diff --git a/openstack/compute/v2/extensions/defsecrules/requests.go b/openstack/compute/v2/extensions/defsecrules/requests.go
index fc3e3a8..5e2d686 100644
--- a/openstack/compute/v2/extensions/defsecrules/requests.go
+++ b/openstack/compute/v2/extensions/defsecrules/requests.go
@@ -1,8 +1,6 @@
package defsecrules
import (
- "errors"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -40,21 +38,33 @@
// ToRuleCreateMap builds the create rule options into a serializable format.
func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) {
- rule := make(map[string]interface{})
-
if opts.FromPort == 0 {
- return rule, errors.New("A FromPort must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "defsecrules.ToRuleCreateMap"
+ err.Argument = "defsecrules.CreateOpts.FromPort"
+ return nil, err
}
if opts.ToPort == 0 {
- return rule, errors.New("A ToPort must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "defsecrules.ToRuleCreateMap"
+ err.Argument = "defsecrules.CreateOpts.ToPort"
+ return nil, err
}
if opts.IPProtocol == "" {
- return rule, errors.New("A IPProtocol must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "defsecrules.ToRuleCreateMap"
+ err.Argument = "defsecrules.CreateOpts.IPProtocol"
+ return nil, err
}
if opts.CIDR == "" {
- return rule, errors.New("A CIDR must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "defsecrules.ToRuleCreateMap"
+ err.Argument = "defsecrules.CreateOpts.CIDR"
+ return nil, err
}
+ rule := make(map[string]interface{})
+
rule["from_port"] = opts.FromPort
rule["to_port"] = opts.ToPort
rule["ip_protocol"] = opts.IPProtocol
diff --git a/openstack/compute/v2/extensions/diskconfig/requests.go b/openstack/compute/v2/extensions/diskconfig/requests.go
index 3fd9c9e..19798d7 100644
--- a/openstack/compute/v2/extensions/diskconfig/requests.go
+++ b/openstack/compute/v2/extensions/diskconfig/requests.go
@@ -1,8 +1,7 @@
package diskconfig
import (
- "errors"
-
+ "github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
)
@@ -23,19 +22,6 @@
Manual DiskConfig = "MANUAL"
)
-// ErrInvalidDiskConfig is returned if an invalid string is specified for a DiskConfig option.
-var ErrInvalidDiskConfig = errors.New("DiskConfig must be either diskconfig.Auto or diskconfig.Manual.")
-
-// Validate ensures that a DiskConfig contains an appropriate value.
-func (config DiskConfig) validate() error {
- switch config {
- case Auto, Manual:
- return nil
- default:
- return ErrInvalidDiskConfig
- }
-}
-
// CreateOptsExt adds a DiskConfig option to the base CreateOpts.
type CreateOptsExt struct {
servers.CreateOptsBuilder
@@ -71,8 +57,11 @@
// ToServerRebuildMap adds the diskconfig option to the base server rebuild options.
func (opts RebuildOptsExt) ToServerRebuildMap() (map[string]interface{}, error) {
- err := opts.DiskConfig.validate()
- if err != nil {
+ if opts.DiskConfig != Auto && opts.DiskConfig != Manual {
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "diskconfig.ToServerRebuildMap"
+ err.Argument = "diskconfig.RebuildOptsExt.DiskConfig"
+ err.Info = "Must be either diskconfig.Auto or diskconfig.Manual"
return nil, err
}
@@ -97,8 +86,11 @@
// ToServerResizeMap adds the diskconfig option to the base server creation options.
func (opts ResizeOptsExt) ToServerResizeMap() (map[string]interface{}, error) {
- err := opts.DiskConfig.validate()
- if err != nil {
+ if opts.DiskConfig != Auto && opts.DiskConfig != Manual {
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "diskconfig.ToServerResizeMap"
+ err.Argument = "diskconfig.ResizeOptsExt.DiskConfig"
+ err.Info = "Must be either diskconfig.Auto or diskconfig.Manual"
return nil, err
}
diff --git a/openstack/compute/v2/extensions/floatingips/requests.go b/openstack/compute/v2/extensions/floatingips/requests.go
index d99033e..00b2520 100644
--- a/openstack/compute/v2/extensions/floatingips/requests.go
+++ b/openstack/compute/v2/extensions/floatingips/requests.go
@@ -1,8 +1,6 @@
package floatingips
import (
- "errors"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -41,7 +39,10 @@
// ToFloatingIPCreateMap constructs a request body from CreateOpts.
func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) {
if opts.Pool == "" {
- return nil, errors.New("Missing field required for floating IP creation: Pool")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "floatingips.ToFloatingIPCreateMap"
+ err.Argument = "floatingips.CreateOpts.Pool"
+ return nil, err
}
return map[string]interface{}{"pool": opts.Pool}, nil
@@ -50,11 +51,17 @@
// ToAssociateMap constructs a request body from AssociateOpts.
func (opts AssociateOpts) ToAssociateMap() (map[string]interface{}, error) {
if opts.ServerID == "" {
- return nil, errors.New("Required field missing for floating IP association: ServerID")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "floatingips.ToAssociateMap"
+ err.Argument = "floatingips.AssociateOpts.ServerID"
+ return nil, err
}
if opts.FloatingIP == "" {
- return nil, errors.New("Required field missing for floating IP association: FloatingIP")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "floatingips.ToAssociateMap"
+ err.Argument = "floatingips.AssociateOpts.FloatingIP"
+ return nil, err
}
associateInfo := map[string]interface{}{
diff --git a/openstack/compute/v2/extensions/keypairs/requests.go b/openstack/compute/v2/extensions/keypairs/requests.go
index af05a8e..b9b32ee 100644
--- a/openstack/compute/v2/extensions/keypairs/requests.go
+++ b/openstack/compute/v2/extensions/keypairs/requests.go
@@ -1,8 +1,6 @@
package keypairs
import (
- "errors"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
"github.com/gophercloud/gophercloud/pagination"
@@ -58,7 +56,10 @@
// ToKeyPairCreateMap constructs a request body from CreateOpts.
func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) {
if opts.Name == "" {
- return nil, errors.New("Missing field required for keypair creation: Name")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "keypairs.ToKeyPairCreateMap"
+ err.Argument = "keypairs.CreateOpts.Name"
+ return nil, err
}
keypair := make(map[string]interface{})
diff --git a/openstack/compute/v2/extensions/schedulerhints/requests.go b/openstack/compute/v2/extensions/schedulerhints/requests.go
index d9aa733..5713e72 100644
--- a/openstack/compute/v2/extensions/schedulerhints/requests.go
+++ b/openstack/compute/v2/extensions/schedulerhints/requests.go
@@ -1,11 +1,11 @@
package schedulerhints
import (
- "fmt"
"net"
"regexp"
"strings"
+ "github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
)
@@ -47,7 +47,12 @@
if opts.Group != "" {
if !uuidRegex.MatchString(opts.Group) {
- return nil, fmt.Errorf("Group must be a UUID")
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+ err.Argument = "schedulerhints.SchedulerHints.Group"
+ err.Value = opts.Group
+ err.Info = "Group must be a UUID"
+ return nil, err
}
sh["group"] = opts.Group
}
@@ -55,7 +60,12 @@
if len(opts.DifferentHost) > 0 {
for _, diffHost := range opts.DifferentHost {
if !uuidRegex.MatchString(diffHost) {
- return nil, fmt.Errorf("The hosts in DifferentHost must be in UUID format.")
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+ err.Argument = "schedulerhints.SchedulerHints.DifferentHost"
+ err.Value = opts.DifferentHost
+ err.Info = "The hosts must be in UUID format."
+ return nil, err
}
}
sh["different_host"] = opts.DifferentHost
@@ -64,7 +74,12 @@
if len(opts.SameHost) > 0 {
for _, sameHost := range opts.SameHost {
if !uuidRegex.MatchString(sameHost) {
- return nil, fmt.Errorf("The hosts in SameHost must be in UUID format.")
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+ err.Argument = "schedulerhints.SchedulerHints.SameHost"
+ err.Value = opts.SameHost
+ err.Info = "The hosts must be in UUID format."
+ return nil, err
}
}
sh["same_host"] = opts.SameHost
@@ -83,7 +98,12 @@
*/
if len(opts.Query) > 0 {
if len(opts.Query) < 3 {
- return nil, fmt.Errorf("Query must be a conditional statement in the format of [op,variable,value]")
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+ err.Argument = "schedulerhints.SchedulerHints.Query"
+ err.Value = opts.Query
+ err.Info = "Must be a conditional statement in the format of [op,variable,value]"
+ return nil, err
}
sh["query"] = opts.Query
}
@@ -94,7 +114,12 @@
if opts.BuildNearHostIP != "" {
if _, _, err := net.ParseCIDR(opts.BuildNearHostIP); err != nil {
- return nil, fmt.Errorf("BuildNearHostIP must be a valid subnet in the form 192.168.1.1/24")
+ err := gophercloud.ErrInvalidInput{}
+ err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+ err.Argument = "schedulerhints.SchedulerHints.BuildNearHostIP"
+ err.Value = opts.BuildNearHostIP
+ err.Info = "Must be a valid subnet in the form 192.168.1.1/24"
+ return nil, err
}
ipParts := strings.Split(opts.BuildNearHostIP, "/")
sh["build_near_host_ip"] = ipParts[0]
diff --git a/openstack/compute/v2/extensions/secgroups/requests.go b/openstack/compute/v2/extensions/secgroups/requests.go
index 758ba09..a0bb025 100644
--- a/openstack/compute/v2/extensions/secgroups/requests.go
+++ b/openstack/compute/v2/extensions/secgroups/requests.go
@@ -1,8 +1,6 @@
package secgroups
import (
- "errors"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -46,20 +44,21 @@
ToSecGroupCreateMap() (map[string]interface{}, error)
}
-var (
- errName = errors.New("Name is a required field")
- errDesc = errors.New("Description is a required field")
-)
-
// ToSecGroupCreateMap builds the create options into a serializable format.
func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
sg := make(map[string]interface{})
if opts.Name == "" {
- return sg, errName
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToSecGroupCreateMap"
+ err.Argument = "secgroups.CreateOpts.Name"
+ return nil, err
}
if opts.Description == "" {
- return sg, errDesc
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToSecGroupCreateMap"
+ err.Argument = "secgroups.CreateOpts.Description"
+ return nil, err
}
sg["name"] = opts.Name
@@ -98,10 +97,16 @@
sg := make(map[string]interface{})
if opts.Name == "" {
- return sg, errName
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToSecGroupUpdateMap"
+ err.Argument = "secgroups.UpdateOpts.Name"
+ return nil, err
}
if opts.Description == "" {
- return sg, errDesc
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToSecGroupUpdateMap"
+ err.Argument = "secgroups.UpdateOpts.Description"
+ return nil, err
}
sg["name"] = opts.Name
@@ -176,24 +181,39 @@
// ToRuleCreateMap builds the create rule options into a serializable format.
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
- rule := make(map[string]interface{})
-
if opts.ParentGroupID == "" {
- return rule, errors.New("A ParentGroupID must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToRuleCreateMap"
+ err.Argument = "secgroups.CreateRuleOpts.ParentGroupID"
+ return nil, err
}
if opts.FromPort == 0 {
- return rule, errors.New("A FromPort must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToRuleCreateMap"
+ err.Argument = "secgroups.CreateRuleOpts.FromPort"
+ return nil, err
}
if opts.ToPort == 0 {
- return rule, errors.New("A ToPort must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToRuleCreateMap"
+ err.Argument = "secgroups.CreateRuleOpts.ToPort"
+ return nil, err
}
if opts.IPProtocol == "" {
- return rule, errors.New("A IPProtocol must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToRuleCreateMap"
+ err.Argument = "secgroups.CreateRuleOpts.IPProtocol"
+ return nil, err
}
if opts.CIDR == "" && opts.FromGroupID == "" {
- return rule, errors.New("A CIDR or FromGroupID must be set")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "secgroups.ToRuleCreateMap"
+ err.Argument = "secgroups.CreateRuleOpts.CIDR/secgroups.CreateRuleOpts.FromGroupID"
+ return nil, err
}
+ rule := make(map[string]interface{})
+
rule["parent_group_id"] = opts.ParentGroupID
rule["from_port"] = opts.FromPort
rule["to_port"] = opts.ToPort
diff --git a/openstack/compute/v2/extensions/servergroups/requests.go b/openstack/compute/v2/extensions/servergroups/requests.go
index e3b2493..212edac 100644
--- a/openstack/compute/v2/extensions/servergroups/requests.go
+++ b/openstack/compute/v2/extensions/servergroups/requests.go
@@ -1,8 +1,6 @@
package servergroups
import (
- "errors"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -32,11 +30,17 @@
// ToServerGroupCreateMap constructs a request body from CreateOpts.
func (opts CreateOpts) ToServerGroupCreateMap() (map[string]interface{}, error) {
if opts.Name == "" {
- return nil, errors.New("Missing field required for server group creation: Name")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "servergroups.ToServerGroupCreateMap"
+ err.Argument = "servergroups.CreateOpts.Name"
+ return nil, err
}
if len(opts.Policies) < 1 {
- return nil, errors.New("Missing field required for server group creation: Policies")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "servergroups.ToServerGroupCreateMap"
+ err.Argument = "servergroups.CreateOpts.Policies"
+ return nil, err
}
serverGroup := make(map[string]interface{})
diff --git a/openstack/compute/v2/extensions/volumeattach/requests.go b/openstack/compute/v2/extensions/volumeattach/requests.go
index 17cb72e..c2bc2ee 100644
--- a/openstack/compute/v2/extensions/volumeattach/requests.go
+++ b/openstack/compute/v2/extensions/volumeattach/requests.go
@@ -1,8 +1,6 @@
package volumeattach
import (
- "errors"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -32,7 +30,10 @@
// ToVolumeAttachmentCreateMap constructs a request body from CreateOpts.
func (opts CreateOpts) ToVolumeAttachmentCreateMap() (map[string]interface{}, error) {
if opts.VolumeID == "" {
- return nil, errors.New("Missing field required for volume attachment creation: VolumeID")
+ err := gophercloud.ErrMissingInput{}
+ err.Function = "volumeattach.ToVolumeAttachmentCreateMap"
+ err.Argument = "volumeattach.CreateOpts.VolumeID"
+ return nil, err
}
volumeAttachment := make(map[string]interface{})