Commit ba463062 authored by FengyunPan's avatar FengyunPan

Update gophercloud to support list interfaces of OpenStack instance

parent f6cb2fce
...@@ -1577,123 +1577,127 @@ ...@@ -1577,123 +1577,127 @@
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud", "ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack", "ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions", "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes", "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes", "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions", "ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach", "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors", "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images", "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers", "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/monitors", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/monitors",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/pools", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/pools",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/vips", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/vips",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports", "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/pagination", "ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gorilla/context", "ImportPath": "github.com/gorilla/context",
...@@ -1802,6 +1806,7 @@ ...@@ -1802,6 +1806,7 @@
}, },
{ {
"ImportPath": "github.com/inconshreveable/mousetrap", "ImportPath": "github.com/inconshreveable/mousetrap",
"Comment": "v1.0",
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
}, },
{ {
......
...@@ -34,6 +34,7 @@ go_library( ...@@ -34,6 +34,7 @@ go_library(
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts:go_default_library",
......
...@@ -31,6 +31,7 @@ import ( ...@@ -31,6 +31,7 @@ import (
"github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack"
apiversions_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions" apiversions_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions"
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts" "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts"
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
...@@ -444,6 +445,26 @@ func getAddressByName(client *gophercloud.ServiceClient, name types.NodeName) (s ...@@ -444,6 +445,26 @@ func getAddressByName(client *gophercloud.ServiceClient, name types.NodeName) (s
return addrs[0].Address, nil return addrs[0].Address, nil
} }
// getAttachedInterfacesByID returns the node interfaces of the specified instance.
func getAttachedInterfacesByID(client *gophercloud.ServiceClient, serviceID string) ([]attachinterfaces.Interface, error) {
var interfaces []attachinterfaces.Interface
pager := attachinterfaces.List(client, serviceID)
err := pager.EachPage(func(page pagination.Page) (bool, error) {
s, err := attachinterfaces.ExtractInterfaces(page)
if err != nil {
return false, err
}
interfaces = append(interfaces, s...)
return true, nil
})
if err != nil {
return interfaces, err
}
return interfaces, nil
}
func (os *OpenStack) Clusters() (cloudprovider.Clusters, bool) { func (os *OpenStack) Clusters() (cloudprovider.Clusters, bool) {
return nil, false return nil, false
} }
......
...@@ -404,31 +404,31 @@ ...@@ -404,31 +404,31 @@
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud", "ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack", "ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/pagination", "ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
......
...@@ -172,31 +172,31 @@ ...@@ -172,31 +172,31 @@
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud", "ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack", "ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/gophercloud/gophercloud/pagination", "ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "ed590d9afe113c6107cd60717b196155e6579e78" "Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
}, },
{ {
"ImportPath": "github.com/hashicorp/golang-lru", "ImportPath": "github.com/hashicorp/golang-lru",
......
...@@ -39,6 +39,7 @@ filegroup( ...@@ -39,6 +39,7 @@ filegroup(
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:all-srcs",
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:all-srcs",
"//vendor/github.com/gophercloud/gophercloud/openstack/common/extensions:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/common/extensions:all-srcs",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces:all-srcs",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach:all-srcs",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors:all-srcs",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images:all-srcs", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images:all-srcs",
......
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"requests.go",
"results.go",
"urls.go",
],
tags = ["automanaged"],
deps = [
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
// Package attachinterfaces provides the ability to manage network interfaces through
// nova-network
package attachinterfaces
package attachinterfaces
import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
// List makes a request against the nova API to list the servers interfaces.
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
return pagination.NewPager(client, listInterfaceURL(client, serverID), func(r pagination.PageResult) pagination.Page {
return InterfacePage{pagination.SinglePageBase(r)}
})
}
package attachinterfaces
import (
"github.com/gophercloud/gophercloud/pagination"
)
// FixedIP represents a Fixed IP Address.
type FixedIP struct {
SubnetID string `json:"subnet_id"`
IPAddress string `json:"ip_address"`
}
// Interface represents a network interface on an instance.
type Interface struct {
PortState string `json:"port_state"`
FixedIPs []FixedIP `json:"fixed_ips"`
PortID string `json:"port_id"`
NetID string `json:"net_id"`
MACAddr string `json:"mac_addr"`
}
// InterfacePage abstracts the raw results of making a List() request against the API.
// As OpenStack extensions may freely alter the response bodies of structures returned
// to the client, you may only safely access the data provided through the ExtractInterfaces call.
type InterfacePage struct {
pagination.SinglePageBase
}
// IsEmpty returns true if an InterfacePage contains no interfaces.
func (r InterfacePage) IsEmpty() (bool, error) {
interfaces, err := ExtractInterfaces(r)
return len(interfaces) == 0, err
}
// ExtractInterfaces interprets the results of a single page from a List() call,
// producing a map of interfaces.
func ExtractInterfaces(r pagination.Page) ([]Interface, error) {
var s struct {
Interfaces []Interface `json:"interfaceAttachments"`
}
err := (r.(InterfacePage)).ExtractInto(&s)
return s.Interfaces, err
}
package attachinterfaces
import "github.com/gophercloud/gophercloud"
func listInterfaceURL(client *gophercloud.ServiceClient, serverID string) string {
return client.ServiceURL("servers", serverID, "os-interface")
}
...@@ -50,6 +50,9 @@ type ListOpts struct { ...@@ -50,6 +50,9 @@ type ListOpts struct {
// Bool to show all tenants // Bool to show all tenants
AllTenants bool `q:"all_tenants"` AllTenants bool `q:"all_tenants"`
// List servers for a particular tenant. Setting "AllTenants = true" is required.
TenantID string `q:"tenant_id"`
} }
// ToServerListQuery formats a ListOpts into a query string. // ToServerListQuery formats a ListOpts into a query string.
......
...@@ -27,3 +27,81 @@ func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager { ...@@ -27,3 +27,81 @@ func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager {
return TenantPage{pagination.LinkedPageBase{PageResult: r}} return TenantPage{pagination.LinkedPageBase{PageResult: r}}
}) })
} }
// CreateOpts represents the options needed when creating new tenant.
type CreateOpts struct {
// Name is the name of the tenant.
Name string `json:"name" required:"true"`
// Description is the description of the tenant.
Description string `json:"description,omitempty"`
// Enabled sets the tenant status to enabled or disabled.
Enabled *bool `json:"enabled,omitempty"`
}
// CreateOptsBuilder describes struct types that can be accepted by the Create call.
type CreateOptsBuilder interface {
ToTenantCreateMap() (map[string]interface{}, error)
}
// ToTenantCreateMap assembles a request body based on the contents of a CreateOpts.
func (opts CreateOpts) ToTenantCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "tenant")
}
// Create is the operation responsible for creating new tenant.
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToTenantCreateMap()
if err != nil {
r.Err = err
return
}
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 201},
})
return
}
// Get requests details on a single tenant by ID.
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
return
}
// UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
type UpdateOptsBuilder interface {
ToTenantUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts specifies the base attributes that may be updated on an existing server.
type UpdateOpts struct {
// Name is the name of the tenant.
Name string `json:"name,omitempty"`
// Description is the description of the tenant.
Description string `json:"description,omitempty"`
// Enabled sets the tenant status to enabled or disabled.
Enabled *bool `json:"enabled,omitempty"`
}
// ToTenantUpdateMap formats an UpdateOpts structure into a request body.
func (opts UpdateOpts) ToTenantUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "tenant")
}
// Update is the operation responsible for updating exist tenants by their TenantID.
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
b, err := opts.ToTenantUpdateMap()
if err != nil {
r.Err = err
return
}
_, r.Err = client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200},
})
return
}
// Delete is the operation responsible for permanently deleting an API tenant.
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = client.Delete(deleteURL(client, id), nil)
return
}
...@@ -51,3 +51,36 @@ func ExtractTenants(r pagination.Page) ([]Tenant, error) { ...@@ -51,3 +51,36 @@ func ExtractTenants(r pagination.Page) ([]Tenant, error) {
err := (r.(TenantPage)).ExtractInto(&s) err := (r.(TenantPage)).ExtractInto(&s)
return s.Tenants, err return s.Tenants, err
} }
type tenantResult struct {
gophercloud.Result
}
// Extract interprets any tenantResults as a tenant.
func (r tenantResult) Extract() (*Tenant, error) {
var s struct {
Tenant *Tenant `json:"tenant"`
}
err := r.ExtractInto(&s)
return s.Tenant, err
}
// GetResult temporarily contains the response from the Get call.
type GetResult struct {
tenantResult
}
// CreateResult temporarily contains the reponse from the Create call.
type CreateResult struct {
tenantResult
}
// DeleteResult temporarily contains the response from the Delete call.
type DeleteResult struct {
gophercloud.ErrResult
}
// UpdateResult temporarily contains the response from the Update call.
type UpdateResult struct {
tenantResult
}
...@@ -5,3 +5,19 @@ import "github.com/gophercloud/gophercloud" ...@@ -5,3 +5,19 @@ import "github.com/gophercloud/gophercloud"
func listURL(client *gophercloud.ServiceClient) string { func listURL(client *gophercloud.ServiceClient) string {
return client.ServiceURL("tenants") return client.ServiceURL("tenants")
} }
func getURL(client *gophercloud.ServiceClient, tenantID string) string {
return client.ServiceURL("tenants", tenantID)
}
func createURL(client *gophercloud.ServiceClient) string {
return client.ServiceURL("tenants")
}
func deleteURL(client *gophercloud.ServiceClient, tenantID string) string {
return client.ServiceURL("tenants", tenantID)
}
func updateURL(client *gophercloud.ServiceClient, tenantID string) string {
return client.ServiceURL("tenants", tenantID)
}
...@@ -182,7 +182,7 @@ func Get(c *gophercloud.ServiceClient, token string) (r GetResult) { ...@@ -182,7 +182,7 @@ func Get(c *gophercloud.ServiceClient, token string) (r GetResult) {
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) { func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
resp, err := c.Request("HEAD", tokenURL(c), &gophercloud.RequestOpts{ resp, err := c.Request("HEAD", tokenURL(c), &gophercloud.RequestOpts{
MoreHeaders: subjectTokenHeaders(c, token), MoreHeaders: subjectTokenHeaders(c, token),
OkCodes: []int{200, 204, 400, 401, 403, 404}, OkCodes: []int{200, 204, 404},
}) })
if err != nil { if err != nil {
return false, err return false, err
......
...@@ -41,6 +41,32 @@ type ServiceCatalog struct { ...@@ -41,6 +41,32 @@ type ServiceCatalog struct {
Entries []CatalogEntry `json:"catalog"` Entries []CatalogEntry `json:"catalog"`
} }
// Domain provides information about the domain to which this token grants access.
type Domain struct {
ID string `json:"id"`
Name string `json:"name"`
}
// User represents a user resource that exists on the API.
type User struct {
Domain Domain `json:"domain"`
ID string `json:"id"`
Name string `json:"name"`
}
// Role provides information about roles to which User is authorized.
type Role struct {
ID string `json:"id"`
Name string `json:"name"`
}
// Project provides information about project to which User is authorized.
type Project struct {
Domain Domain `json:"domain"`
ID string `json:"id"`
Name string `json:"name"`
}
// commonResult is the deferred result of a Create or a Get call. // commonResult is the deferred result of a Create or a Get call.
type commonResult struct { type commonResult struct {
gophercloud.Result gophercloud.Result
...@@ -67,12 +93,39 @@ func (r commonResult) ExtractToken() (*Token, error) { ...@@ -67,12 +93,39 @@ func (r commonResult) ExtractToken() (*Token, error) {
} }
// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token. // ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) { func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
var s ServiceCatalog var s ServiceCatalog
err := r.ExtractInto(&s) err := r.ExtractInto(&s)
return &s, err return &s, err
} }
// ExtractUser returns the User that is the owner of the Token.
func (r commonResult) ExtractUser() (*User, error) {
var s struct {
User *User `json:"user"`
}
err := r.ExtractInto(&s)
return s.User, err
}
// ExtractRoles returns Roles to which User is authorized.
func (r commonResult) ExtractRoles() ([]Role, error) {
var s struct {
Roles []Role `json:"roles"`
}
err := r.ExtractInto(&s)
return s.Roles, err
}
// ExtractProject returns Project to which User is authorized.
func (r commonResult) ExtractProject() (*Project, error) {
var s struct {
Project *Project `json:"project"`
}
err := r.ExtractInto(&s)
return s.Project, err
}
// CreateResult defers the interpretation of a created token. // CreateResult defers the interpretation of a created token.
// Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog. // Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog.
type CreateResult struct { type CreateResult struct {
......
...@@ -22,6 +22,7 @@ type ListOpts struct { ...@@ -22,6 +22,7 @@ type ListOpts struct {
SortKey string `q:"sort_key"` SortKey string `q:"sort_key"`
SortDir string `q:"sort_dir"` SortDir string `q:"sort_dir"`
RouterID string `q:"router_id"` RouterID string `q:"router_id"`
Status string `q:"status"`
} }
// List returns a Pager which allows you to iterate over a collection of // List returns a Pager which allows you to iterate over a collection of
......
...@@ -78,6 +78,53 @@ func (r Result) extractIntoPtr(to interface{}, label string) error { ...@@ -78,6 +78,53 @@ func (r Result) extractIntoPtr(to interface{}, label string) error {
return err return err
} }
toValue := reflect.ValueOf(to)
if toValue.Kind() == reflect.Ptr {
toValue = toValue.Elem()
}
switch toValue.Kind() {
case reflect.Slice:
typeOfV := toValue.Type().Elem()
if typeOfV.Kind() == reflect.Struct {
if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous {
newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0)
newType := reflect.New(typeOfV).Elem()
for _, v := range m[label].([]interface{}) {
b, err := json.Marshal(v)
if err != nil {
return err
}
for i := 0; i < newType.NumField(); i++ {
s := newType.Field(i).Addr().Interface()
err = json.NewDecoder(bytes.NewReader(b)).Decode(s)
if err != nil {
return err
}
}
newSlice = reflect.Append(newSlice, newType)
}
toValue.Set(newSlice)
}
}
case reflect.Struct:
typeOfV := toValue.Type()
if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous {
for i := 0; i < toValue.NumField(); i++ {
toField := toValue.Field(i)
if toField.Kind() == reflect.Struct {
s := toField.Addr().Interface()
err = json.NewDecoder(bytes.NewReader(b)).Decode(s)
if err != nil {
return err
}
}
}
}
}
err = json.Unmarshal(b, &to) err = json.Unmarshal(b, &to)
return err return err
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment