func (os *OpenStack) ListPorts(networkID, deviceOwner string) ([]ports.Port, error) {
	var results []ports.Port
	opts := ports.ListOpts{
		NetworkID:   networkID,
		DeviceOwner: deviceOwner,
	}
	pager := ports.List(os.network, opts)
	err := pager.EachPage(func(page pagination.Page) (bool, error) {
		portList, err := ports.ExtractPorts(page)
		if err != nil {
			glog.Errorf("Get openstack ports error: %v", err)
			return false, err
		}
		for _, port := range portList {
			results = append(results, port)
		}
		return true, err
	})
	if err != nil {
		return nil, err
	}
	return results, nil
}
List all ports in the network
package common
import (
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"strings"
	"time"
	"code.google.com/p/gcfg"
	"github.com/docker/distribution/uuid"
	"github.com/golang/glog"
	"github.com/gophercloud/gophercloud"
	"github.com/gophercloud/gophercloud/openstack"
	"github.com/gophercloud/gophercloud/openstack/identity/v2/tenants"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/monitors"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/pools"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/vips"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/portsbinding"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
	"github.com/gophercloud/gophercloud/pagination"
	"github.com/hyperhq/kubestack/pkg/plugins"
	provider "github.com/hyperhq/kubestack/pkg/types"
	_ "github.com/hyperhq/kubestack/pkg/plugins/openvswitch"
)
const (
	podNamePrefix     = "kube"
	securitygroupName = "kube-securitygroup-default"
	hostnameMaxLen    = 63
	ServiceAffinityNone     = "None"
	ServiceAffinityClientIP = "ClientIP"
)
var (
	adminStateUp = true
	ErrNotFound        = errors.New("NotFound")
	ErrMultipleResults = errors.New("MultipleResults")
)
type MyDuration struct {
	time.Duration
}
func (d *MyDuration) UnmarshalText(text []byte) error {
	res, err := time.ParseDuration(string(text))
	if err != nil {
		return err
	}
	d.Duration = res
	return nil
}
type LoadBalancerOpts struct {
	LBMethod          string     `gcfg:"lb-method"`
	CreateMonitor     bool       `gcfg:"create-monitor"`
	MonitorDelay      MyDuration `gcfg:"monitor-delay"`
	MonitorTimeout    MyDuration `gcfg:"monitor-timeout"`
	MonitorMaxRetries uint       `gcfg:"monitor-max-retries"`
}
type PluginOpts struct {
	PluginName        string `gcfg:"plugin-name"`
	IntegrationBridge string `gcfg:"integration-bridge"`
}
type OpenStack struct {
	network    *gophercloud.ServiceClient
	identity   *gophercloud.ServiceClient
	provider   *gophercloud.ProviderClient
	region     string
	lbOpts     LoadBalancerOpts
	pluginOpts PluginOpts
	ExtNetID   string
	Plugin     plugins.PluginInterface
}
type Config struct {
	Global struct {
		AuthUrl         string `gcfg:"auth-url"`
		Username        string `gcfg:"username"`
		UserId          string `gcfg:"user-id"`
		Password        string `gcfg: "password"`
		TokenID         string `gcfg:"token-id"`
		TenantId        string `gcfg:"tenant-id"`
		TenantName      string `gcfg:"tenant-name"`
		DomainId        string `gcfg:"domain-id"`
		DomainName      string `gcfg:"domain-name"`
		Region          string `gcfg:"region"`
		ExtNetID        string `gcfg:"ext-net-id"`
		KeystoneVersion string `gcfg:"keystone-version"`
	}
	LoadBalancer LoadBalancerOpts
	Plugin       PluginOpts
}
func (cfg Config) toAuthOptions() gophercloud.AuthOptions {
	return gophercloud.AuthOptions{
		IdentityEndpoint: cfg.Global.AuthUrl,
		Username:         cfg.Global.Username,
		UserID:           cfg.Global.UserId,
		Password:         cfg.Global.Password,
		TokenID:          cfg.Global.TokenID,
		TenantID:         cfg.Global.TenantId,
		TenantName:       cfg.Global.TenantName,
		DomainName:       cfg.Global.DomainName,
		AllowReauth: true,
	}
}
func NewOpenStack(config io.Reader) (*OpenStack, error) {
	var cfg Config
	err := gcfg.ReadInto(&cfg, config)
	if err != nil {
		glog.Warning("Failed to parse openstack configure file: %v", err)
		return nil, err
	}
	provider, err := openstack.AuthenticatedClient(cfg.toAuthOptions())
	if err != nil {
		glog.Warning("Failed to auth openstack: %v", err)
		return nil, err
	}
	var identity *gophercloud.ServiceClient
	if cfg.Global.KeystoneVersion == "3" {
		identity, err = openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{
			Availability: gophercloud.AvailabilityAdmin,
		})
	} else {
		identity, err = openstack.NewIdentityV2(provider, gophercloud.EndpointOpts{
			Availability: gophercloud.AvailabilityAdmin,
		})
	}
	if err != nil {
		glog.Warning("Failed to find identity endpoint")
		return nil, err
	}
	network, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
		Region: cfg.Global.Region,
	})
	if err != nil {
		glog.Warning("Failed to find neutron endpoint: %v", err)
		return nil, err
	}
	os := OpenStack{
		identity:   identity,
		network:    network,
		provider:   provider,
		region:     cfg.Global.Region,
		lbOpts:     cfg.LoadBalancer,
		pluginOpts: cfg.Plugin,
		ExtNetID:   cfg.Global.ExtNetID,
	}
	if cfg.Plugin.PluginName != "" {
		integrationBriage := "br-int"
		if cfg.Plugin.IntegrationBridge != "" {
			integrationBriage = cfg.Plugin.IntegrationBridge
		}
		plugin, _ := plugins.GetNetworkPlugin(cfg.Plugin.PluginName)
		if plugin != nil {
			plugin.Init(integrationBriage)
			os.Plugin = plugin
		}
	}
	return &os, nil
}
func getHostName() string {
	host, err := os.Hostname()
	if err != nil {
		return ""
	}
	return host
}
func (os *OpenStack) getOpenStackNetworkByID(id string) (*networks.Network, error) {
	opts := networks.ListOpts{ID: id}
	return os.getOpenStackNetwork(&opts)
}
func (os *OpenStack) getOpenStackNetworkByName(name string) (*networks.Network, error) {
	opts := networks.ListOpts{Name: name}
	return os.getOpenStackNetwork(&opts)
}
func (os *OpenStack) getOpenStackNetwork(opts *networks.ListOpts) (*networks.Network, error) {
	var osNetwork *networks.Network
	pager := networks.List(os.network, *opts)
	err := pager.EachPage(func(page pagination.Page) (bool, error) {
		networkList, e := networks.ExtractNetworks(page)
		if len(networkList) > 1 {
			return false, ErrMultipleResults
		}
		if len(networkList) == 1 {
			osNetwork = &networkList[0]
		}
		return true, e
	})
	if err == nil && osNetwork == nil {
		return nil, ErrNotFound
	}
	return osNetwork, err
}
func (os *OpenStack) getProviderSubnet(osSubnetID string) (*provider.Subnet, error) {
	s, err := subnets.Get(os.network, osSubnetID).Extract()
	if err != nil {
		glog.Errorf("Get openstack subnet failed: %v", err)
		return nil, err
	}
	var routes []*provider.Route
	for _, r := range s.HostRoutes {
		route := provider.Route{
			Nexthop:         r.NextHop,
			DestinationCIDR: r.DestinationCIDR,
		}
		routes = append(routes, &route)
	}
	providerSubnet := provider.Subnet{
		Uid:        s.ID,
		Cidr:       s.CIDR,
		Gateway:    s.GatewayIP,
		Name:       s.Name,
		Dnsservers: s.DNSNameservers,
		Routes:     routes,
	}
	return &providerSubnet, nil
}
func (os *OpenStack) GetNetworkByID(networkID string) (*provider.Network, error) {
	osNetwork, err := os.getOpenStackNetworkByID(networkID)
	if err != nil {
		glog.Errorf("Get openstack network failed: %v", err)
		return nil, err
	}
	return os.OSNetworktoProviderNetwork(osNetwork)
}
func (os *OpenStack) GetNetwork(networkName string) (*provider.Network, error) {
	osNetwork, err := os.getOpenStackNetworkByName(networkName)
	if err != nil {
		glog.Errorf("Get openstack network failed: %v", err)
		return nil, err
	}
	return os.OSNetworktoProviderNetwork(osNetwork)
}
func (os *OpenStack) OSNetworktoProviderNetwork(osNetwork *networks.Network) (*provider.Network, error) {
	var providerNetwork provider.Network
	var providerSubnets []*provider.Subnet
	providerNetwork.Name = osNetwork.Name
	providerNetwork.Uid = osNetwork.ID
	providerNetwork.Status = os.ToProviderStatus(osNetwork.Status)
	providerNetwork.TenantID = osNetwork.TenantID
	for _, subnetID := range osNetwork.Subnets {
		s, err := os.getProviderSubnet(subnetID)
		if err != nil {
			return nil, err
		}
		providerSubnets = append(providerSubnets, s)
	}
	providerNetwork.Subnets = providerSubnets
	return &providerNetwork, nil
}
func (os *OpenStack) ToProviderStatus(status string) string {
	switch status {
	case "ACTIVE":
		return "Active"
	case "BUILD":
		return "Pending"
	case "DOWN", "ERROR":
		return "Failed"
	default:
		return "Failed"
	}
	return "Failed"
}
func (os *OpenStack) CreateNetwork(network *provider.Network) error {
	if len(network.Subnets) == 0 {
		return errors.New("Subnets is null")
	}
	opts := networks.CreateOpts{
		Name:         network.Name,
		AdminStateUp: &adminStateUp,
		TenantID:     network.TenantID,
	}
	osNet, err := networks.Create(os.network, opts).Extract()
	if err != nil {
		glog.Errorf("Create openstack network %s failed: %v", network.Name, err)
		return err
	}
	routerOpts := routers.CreateOpts{
		Name:        network.Name,
		TenantID:    network.TenantID,
		GatewayInfo: &routers.GatewayInfo{NetworkID: os.ExtNetID},
	}
	osRouter, err := routers.Create(os.network, routerOpts).Extract()
	if err != nil {
		glog.Errorf("Create openstack router %s failed: %v", network.Name, err)
		delErr := os.DeleteNetwork(network.Name)
		if delErr != nil {
			glog.Errorf("Delete openstack network %s failed: %v", network.Name, delErr)
		}
		return err
	}
	networkID := osNet.ID
	network.Status = os.ToProviderStatus(osNet.Status)
	network.Uid = osNet.ID
	for _, sub := range network.Subnets {
		subnetOpts := subnets.CreateOpts{
			NetworkID:      networkID,
			CIDR:           sub.Cidr,
			Name:           sub.Name,
			IPVersion:      gophercloud.IPv4,
			TenantID:       network.TenantID,
			GatewayIP:      &sub.Gateway,
			DNSNameservers: sub.Dnsservers,
		}
		s, err := subnets.Create(os.network, subnetOpts).Extract()
		if err != nil {
			glog.Errorf("Create openstack subnet %s failed: %v", sub.Name, err)
			delErr := os.DeleteNetwork(network.Name)
			if delErr != nil {
				glog.Errorf("Delete openstack network %s failed: %v", network.Name, delErr)
			}
			return err
		}
		opts := routers.AddInterfaceOpts{
			SubnetID: s.ID,
		}
		_, err = routers.AddInterface(os.network, osRouter.ID, opts).Extract()
		if err != nil {
			glog.Errorf("Create openstack subnet %s failed: %v", sub.Name, err)
			delErr := os.DeleteNetwork(network.Name)
			if delErr != nil {
				glog.Errorf("Delete openstack network %s failed: %v", network.Name, delErr)
			}
			return err
		}
	}
	return nil
}
func (os *OpenStack) UpdateNetwork(network *provider.Network) error {
	return nil
}
func (os *OpenStack) getRouterByName(name string) (*routers.Router, error) {
	var result *routers.Router
	opts := routers.ListOpts{Name: name}
	pager := routers.List(os.network, opts)
	err := pager.EachPage(func(page pagination.Page) (bool, error) {
		routerList, e := routers.ExtractRouters(page)
		if len(routerList) > 1 {
			return false, ErrMultipleResults
		} else if len(routerList) == 1 {
			result = &routerList[0]
		}
		return true, e
	})
	if err != nil {
		return nil, err
	}
	return result, nil
}
func (os *OpenStack) DeleteNetwork(networkName string) error {
	osNetwork, err := os.getOpenStackNetworkByName(networkName)
	if err != nil {
		glog.Errorf("Get openstack network failed: %v", err)
		return err
	}
	if osNetwork != nil {
		opts := ports.ListOpts{NetworkID: osNetwork.ID}
		pager := ports.List(os.network, opts)
		err := pager.EachPage(func(page pagination.Page) (bool, error) {
			portList, err := ports.ExtractPorts(page)
			if err != nil {
				glog.Errorf("Get openstack ports error: %v", err)
				return false, err
			}
			for _, port := range portList {
				if port.DeviceOwner == "network:router_interface" {
					continue
				}
				err = ports.Delete(os.network, port.ID).ExtractErr()
				if err != nil {
					glog.Warningf("Delete port %v failed: %v", port.ID, err)
				}
			}
			return true, nil
		})
		if err != nil {
			glog.Errorf("Delete ports error: %v", err)
		}
		router, err := os.getRouterByName(networkName)
		if err != nil {
			glog.Errorf("Get openstack router %s error: %v", networkName, err)
			return err
		}
		for _, subnet := range osNetwork.Subnets {
			if router != nil {
				opts := routers.RemoveInterfaceOpts{SubnetID: subnet}
				_, err := routers.RemoveInterface(os.network, router.ID, opts).Extract()
				if err != nil {
					glog.Errorf("Get openstack router %s error: %v", networkName, err)
					return err
				}
			}
			err = subnets.Delete(os.network, subnet).ExtractErr()
			if err != nil {
				glog.Errorf("Delete openstack subnet %s error: %v", subnet, err)
				return err
			}
		}
		if router != nil {
			err = routers.Delete(os.network, router.ID).ExtractErr()
			if err != nil {
				glog.Errorf("Delete openstack router %s error: %v", router.ID, err)
				return err
			}
		}
		err = networks.Delete(os.network, osNetwork.ID).ExtractErr()
		if err != nil {
			glog.Errorf("Delete openstack network %s error: %v", osNetwork.ID, err)
			return err
		}
	}
	return nil
}