Merge pull request #124 from cezarsa/withzone

Add WithZone function to filter resources from a zone
diff --git a/cloudstack/cloudstack.go b/cloudstack/cloudstack.go
index 98f2014..06f3cff 100644
--- a/cloudstack/cloudstack.go
+++ b/cloudstack/cloudstack.go
@@ -525,6 +525,34 @@
 	}
 }
 
+// ZoneIDSetter is an interface that every type that can set a zone ID must implement
+type ZoneIDSetter interface {
+	SetZoneid(string)
+}
+
+// WithZone takes either a zone name or ID and sets the `zoneid` parameter
+func WithZone(zone string) OptionFunc {
+	return func(cs *CloudStackClient, p interface{}) error {
+		zs, ok := p.(ZoneIDSetter)
+
+		if !ok || zone == "" {
+			return nil
+		}
+
+		if !IsID(zone) {
+			id, _, err := cs.Zone.GetZoneID(zone)
+			if err != nil {
+				return err
+			}
+			zone = id
+		}
+
+		zs.SetZoneid(zone)
+
+		return nil
+	}
+}
+
 type APIDiscoveryService struct {
 	cs *CloudStackClient
 }
diff --git a/generate/generate.go b/generate/generate.go
index d2c2baf..81e4325 100644
--- a/generate/generate.go
+++ b/generate/generate.go
@@ -600,6 +600,34 @@
 	pn("	}")
 	pn("}")
 	pn("")
+	pn("// ZoneIDSetter is an interface that every type that can set a zone ID must implement")
+	pn("type ZoneIDSetter interface {")
+	pn("	SetZoneid(string)")
+	pn("}")
+	pn("")
+	pn("// WithZone takes either a zone name or ID and sets the `zoneid` parameter")
+	pn("func WithZone(zone string) OptionFunc {")
+	pn("	return func(cs *CloudStackClient, p interface{}) error {")
+	pn("		zs, ok := p.(ZoneIDSetter)")
+	pn("")
+	pn("		if !ok || zone == \"\" {")
+	pn("			return nil")
+	pn("		}")
+	pn("")
+	pn("		if !IsID(zone) {")
+	pn("			id, _, err := cs.Zone.GetZoneID(zone)")
+	pn("			if err != nil {")
+	pn("				return err")
+	pn("			}")
+	pn("			zone = id")
+	pn("		}")
+	pn("")
+	pn("		zs.SetZoneid(zone)")
+	pn("")
+	pn("		return nil")
+	pn("	}")
+	pn("}")
+	pn("")
 	for _, s := range as.services {
 		pn("type %s struct {", s.name)
 		pn("  cs *CloudStackClient")