Bug Fix - Adding an allowed address pair wipes port security groups

Fix for cloud routes enabled instances will have their security groups
removed when the allowed address pair is added to the instance's port.

Upstream bug report is in:
https://github.com/gophercloud/gophercloud/issues/509

Upstream bug fix is in:
https://github.com/gophercloud/gophercloud/pull/510
pull/6/head
Davanum Srinivas 2017-09-01 09:34:24 -04:00
parent b6721bebea
commit 74a3d89ad4
99 changed files with 3091 additions and 1019 deletions

62
Godeps/Godeps.json generated
View File

@ -1585,127 +1585,127 @@
},
{
"ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/monitors",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/pools",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/vips",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gorilla/context",

View File

@ -404,31 +404,31 @@
},
{
"ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gregjones/httpcache",

View File

@ -176,31 +176,31 @@
},
{
"ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "c0406a133c4a74a838baf0ddff3c2fab21155fba"
"Rev": "2bf16b94fdd9b01557c4d076e567fe5cbbe5a961"
},
{
"ImportPath": "github.com/gregjones/httpcache",

View File

@ -9,12 +9,32 @@ ProviderClient representing an active session on that provider.
Its fields are the union of those recognized by each identity implementation and
provider.
An example of manually providing authentication information:
opts := gophercloud.AuthOptions{
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
Username: "{username}",
Password: "{password}",
TenantID: "{tenant_id}",
}
provider, err := openstack.AuthenticatedClient(opts)
An example of using AuthOptionsFromEnv(), where the environment variables can
be read from a file, such as a standard openrc file:
opts, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(opts)
*/
type AuthOptions struct {
// IdentityEndpoint specifies the HTTP endpoint that is required to work with
// the Identity API of the appropriate version. While it's ultimately needed by
// all of the identity services, it will often be populated by a provider-level
// function.
//
// The IdentityEndpoint is typically referred to as the "auth_url" or
// "OS_AUTH_URL" in the information provided by the cloud operator.
IdentityEndpoint string `json:"-"`
// Username is required if using Identity V2 API. Consult with your provider's
@ -39,7 +59,7 @@ type AuthOptions struct {
// If DomainID or DomainName are provided, they will also apply to TenantName.
// It is not currently possible to authenticate with Username and a Domain
// and scope to a Project in a different Domain by using TenantName. To
// accomplish that, the ProjectID will need to be provided to the TenantID
// accomplish that, the ProjectID will need to be provided as the TenantID
// option.
TenantID string `json:"tenantId,omitempty"`
TenantName string `json:"tenantName,omitempty"`
@ -50,10 +70,12 @@ type AuthOptions struct {
// false, it will not cache these settings, but re-authentication will not be
// possible. This setting defaults to false.
//
// NOTE: The reauth function will try to re-authenticate endlessly if left unchecked.
// The way to limit the number of attempts is to provide a custom HTTP client to the provider client
// and provide a transport that implements the RoundTripper interface and stores the number of failed retries.
// For an example of this, see here: https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311
// NOTE: The reauth function will try to re-authenticate endlessly if left
// unchecked. The way to limit the number of attempts is to provide a custom
// HTTP client to the provider client and provide a transport that implements
// the RoundTripper interface and stores the number of failed retries. For an
// example of this, see here:
// https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311
AllowReauth bool `json:"-"`
// TokenID allows users to authenticate (possibly as another user) with an
@ -316,7 +338,12 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
},
}, nil
} else if scope.DomainName != "" {
return nil, ErrScopeDomainName{}
// DomainName
return map[string]interface{}{
"domain": map[string]interface{}{
"name": &scope.DomainName,
},
}, nil
}
return nil, nil

View File

@ -3,11 +3,17 @@ Package gophercloud provides a multi-vendor interface to OpenStack-compatible
clouds. The library has a three-level hierarchy: providers, services, and
resources.
Provider structs represent the service providers that offer and manage a
collection of services. The IdentityEndpoint is typically refered to as
"auth_url" in information provided by the cloud operator. Additionally,
the cloud may refer to TenantID or TenantName as project_id and project_name.
These are defined like so:
Authenticating with Providers
Provider structs represent the cloud providers that offer and manage a
collection of services. You will generally want to create one Provider
client per OpenStack cloud.
Use your OpenStack credentials to create a Provider client. The
IdentityEndpoint is typically refered to as "auth_url" or "OS_AUTH_URL" in
information provided by the cloud operator. Additionally, the cloud may refer to
TenantID or TenantName as project_id and project_name. Credentials are
specified like so:
opts := gophercloud.AuthOptions{
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
@ -18,6 +24,16 @@ These are defined like so:
provider, err := openstack.AuthenticatedClient(opts)
You may also use the openstack.AuthOptionsFromEnv() helper function. This
function reads in standard environment variables frequently found in an
OpenStack `openrc` file. Again note that Gophercloud currently uses "tenant"
instead of "project".
opts, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(opts)
Service Clients
Service structs are specific to a provider and handle all of the logic and
operations for a particular OpenStack service. Examples of services include:
Compute, Object Storage, Block Storage. In order to define one, you need to
@ -27,6 +43,8 @@ pass in the parent provider, like so:
client := openstack.NewComputeV2(provider, opts)
Resources
Resource structs are the domain models that services make use of in order
to work with and represent the state of API resources:
@ -62,6 +80,12 @@ of results:
return true, nil
})
If you want to obtain the entire collection of pages without doing any
intermediary processing on each page, you can use the AllPages method:
allPages, err := servers.List(client, nil).AllPages()
allServers, err := servers.ExtractServers(allPages)
This top-level package contains utility functions and data types that are used
throughout the provider and service packages. Of particular note for end users
are the AuthOptions and EndpointOpts structs.

View File

@ -27,7 +27,7 @@ const (
// unambiguously identify one, and only one, endpoint within the catalog.
//
// Usually, these are passed to service client factory functions in a provider
// package, like "rackspace.NewComputeV2()".
// package, like "openstack.NewComputeV2()".
type EndpointOpts struct {
// Type [required] is the service type for the client (e.g., "compute",
// "object-store"). Generally, this will be supplied by the service client

View File

@ -393,13 +393,6 @@ func (e ErrScopeProjectIDAlone) Error() string {
return "ProjectID must be supplied alone in a Scope"
}
// ErrScopeDomainName indicates that a DomainName was provided alone in a Scope.
type ErrScopeDomainName struct{ BaseError }
func (e ErrScopeDomainName) Error() string {
return "DomainName must be supplied with a ProjectName or ProjectID in a Scope"
}
// ErrScopeEmpty indicates that no credentials were provided in a Scope.
type ErrScopeEmpty struct{ BaseError }

View File

@ -5,6 +5,7 @@ go_library(
srcs = [
"auth_env.go",
"client.go",
"doc.go",
"endpoint_location.go",
"errors.go",
],

View File

@ -8,10 +8,22 @@ import (
var nilOptions = gophercloud.AuthOptions{}
// AuthOptionsFromEnv fills out an identity.AuthOptions structure with the settings found on the various OpenStack
// OS_* environment variables. The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME,
// OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME. Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must
// have settings, or an error will result. OS_TENANT_ID and OS_TENANT_NAME are optional.
/*
AuthOptionsFromEnv fills out an identity.AuthOptions structure with the
settings found on the various OpenStack OS_* environment variables.
The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME,
OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME.
Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must have settings,
or an error will result. OS_TENANT_ID and OS_TENANT_NAME are optional.
To use this function, first set the OS_* environment variables (for example,
by sourcing an `openrc` file), then:
opts, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(opts)
*/
func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
authURL := os.Getenv("OS_AUTH_URL")
username := os.Getenv("OS_USERNAME")

View File

@ -16,10 +16,20 @@ const (
v30 = "v3.0"
)
// NewClient prepares an unauthenticated ProviderClient instance.
// Most users will probably prefer using the AuthenticatedClient function instead.
// This is useful if you wish to explicitly control the version of the identity service that's used for authentication explicitly,
// for example.
/*
NewClient prepares an unauthenticated ProviderClient instance.
Most users will probably prefer using the AuthenticatedClient function
instead.
This is useful if you wish to explicitly control the version of the identity
service that's used for authentication explicitly, for example.
A basic example of using this would be:
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.NewClient(ao.IdentityEndpoint)
client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{})
*/
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
u, err := url.Parse(endpoint)
if err != nil {
@ -45,10 +55,26 @@ func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
}, nil
}
// AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint specified by options, acquires a token, and
// returns a Client instance that's ready to operate.
// It first queries the root identity endpoint to determine which versions of the identity service are supported, then chooses
// the most recent identity service available to proceed.
/*
AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint
specified by the options, acquires a token, and returns a Provider Client
instance that's ready to operate.
If the full path to a versioned identity endpoint was specified (example:
http://example.com:5000/v3), that path will be used as the endpoint to query.
If a versionless endpoint was specified (example: http://example.com:5000/),
the endpoint will be queried to determine which versions of the identity service
are available, then chooses the most recent or most supported version.
Example:
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(ao)
client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
*/
func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
client, err := NewClient(options.IdentityEndpoint)
if err != nil {
@ -62,7 +88,8 @@ func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.Provider
return client, nil
}
// Authenticate or re-authenticate against the most recent identity service supported at the provided endpoint.
// Authenticate or re-authenticate against the most recent identity service
// supported at the provided endpoint.
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
versions := []*utils.Version{
{ID: v20, Priority: 20, Suffix: "/v2.0/"},
@ -179,7 +206,8 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
return nil
}
// NewIdentityV2 creates a ServiceClient that may be used to interact with the v2 identity service.
// NewIdentityV2 creates a ServiceClient that may be used to interact with the
// v2 identity service.
func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
endpoint := client.IdentityBase + "v2.0/"
clientType := "identity"
@ -199,7 +227,8 @@ func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp
}, nil
}
// NewIdentityV3 creates a ServiceClient that may be used to access the v3 identity service.
// NewIdentityV3 creates a ServiceClient that may be used to access the v3
// identity service.
func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
endpoint := client.IdentityBase + "v3/"
clientType := "identity"
@ -232,34 +261,40 @@ func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointO
return sc, nil
}
// NewObjectStorageV1 creates a ServiceClient that may be used with the v1 object storage package.
// NewObjectStorageV1 creates a ServiceClient that may be used with the v1
// object storage package.
func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "object-store")
}
// NewComputeV2 creates a ServiceClient that may be used with the v2 compute package.
// NewComputeV2 creates a ServiceClient that may be used with the v2 compute
// package.
func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "compute")
}
// NewNetworkV2 creates a ServiceClient that may be used with the v2 network package.
// NewNetworkV2 creates a ServiceClient that may be used with the v2 network
// package.
func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
sc, err := initClientOpts(client, eo, "network")
sc.ResourceBase = sc.Endpoint + "v2.0/"
return sc, err
}
// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 block storage service.
// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1
// block storage service.
func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "volume")
}
// NewBlockStorageV2 creates a ServiceClient that may be used to access the v2 block storage service.
// NewBlockStorageV2 creates a ServiceClient that may be used to access the v2
// block storage service.
func NewBlockStorageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "volumev2")
}
// NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service.
// NewSharedFileSystemV2 creates a ServiceClient that may be used to access the
// v2 shared file system service.
func NewSharedFileSystemV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "sharev2")
}
@ -270,7 +305,8 @@ func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (
return initClientOpts(client, eo, "cdn")
}
// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 orchestration service.
// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1
// orchestration service.
func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "orchestration")
}
@ -280,14 +316,16 @@ func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*
return initClientOpts(client, eo, "database")
}
// NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS service.
// NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS
// service.
func NewDNSV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
sc, err := initClientOpts(client, eo, "dns")
sc.ResourceBase = sc.Endpoint + "v2/"
return sc, err
}
// NewImageServiceV2 creates a ServiceClient that may be used to access the v2 image service.
// NewImageServiceV2 creates a ServiceClient that may be used to access the v2
// image service.
func NewImageServiceV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
sc, err := initClientOpts(client, eo, "image")
sc.ResourceBase = sc.Endpoint + "v2/"

View File

@ -4,7 +4,6 @@ go_library(
name = "go_default_library",
srcs = [
"doc.go",
"errors.go",
"requests.go",
"results.go",
"urls.go",

View File

@ -1,15 +1,52 @@
// Package extensions provides information and interaction with the different extensions available
// for an OpenStack service.
//
// The purpose of OpenStack API extensions is to:
//
// - Introduce new features in the API without requiring a version change.
// - Introduce vendor-specific niche functionality.
// - Act as a proving ground for experimental functionalities that might be included in a future
// version of the API.
//
// Extensions usually have tags that prevent conflicts with other extensions that define attributes
// or resources with the same names, and with core resources and attributes.
// Because an extension might not be supported by all plug-ins, its availability varies with deployments
// and the specific plug-in.
/*
Package extensions provides information and interaction with the different
extensions available for an OpenStack service.
The purpose of OpenStack API extensions is to:
- Introduce new features in the API without requiring a version change.
- Introduce vendor-specific niche functionality.
- Act as a proving ground for experimental functionalities that might be
included in a future version of the API.
Extensions usually have tags that prevent conflicts with other extensions that
define attributes or resources with the same names, and with core resources and
attributes. Because an extension might not be supported by all plug-ins, its
availability varies with deployments and the specific plug-in.
The results of this package vary depending on the type of Service Client used.
In the following examples, note how the only difference is the creation of the
Service Client.
Example of Retrieving Compute Extensions
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(ao)
computeClient, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
allPages, err := extensions.List(computeClient).Allpages()
allExtensions, err := extensions.ExtractExtensions(allPages)
for _, extension := range allExtensions{
fmt.Println("%+v\n", extension)
}
Example of Retrieving Network Extensions
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(ao)
networkClient, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
allPages, err := extensions.List(networkClient).Allpages()
allExtensions, err := extensions.ExtractExtensions(allPages)
for _, extension := range allExtensions{
fmt.Println("%+v\n", extension)
}
*/
package extensions

View File

@ -1 +0,0 @@
package extensions

4
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go generated vendored Executable file → Normal file
View File

@ -41,8 +41,8 @@ func (r ExtensionPage) IsEmpty() (bool, error) {
return len(is) == 0, err
}
// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the
// elements into a slice of Extension structs.
// ExtractExtensions accepts a Page struct, specifically an ExtensionPage
// struct, and extracts the elements into a slice of Extension structs.
// In other words, a generic collection is mapped into a relevant slice.
func ExtractExtensions(r pagination.Page) ([]Extension, error) {
var s struct {

View File

@ -1,3 +1,22 @@
// Package attachinterfaces provides the ability to manage network interfaces through
// nova-network
/*
Package attachinterfaces provides the ability to retrieve and manage network
interfaces through Nova.
Example of Listing a Server's Interfaces
serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f"
allPages, err := attachinterfaces.List(computeClient, serverID).AllPages()
if err != nil {
panic(err)
}
allInterfaces, err := attachinterfaces.ExtractInterfaces(allPages)
if err != nil {
panic(err)
}
for _, interface := range allInterfaces {
fmt.Printf("%+v\n", interface)
}
*/
package attachinterfaces

View File

@ -5,7 +5,7 @@ import (
"github.com/gophercloud/gophercloud/pagination"
)
// List makes a request against the nova API to list the servers interfaces.
// List makes a request against the nova API to list the server's 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)}

View File

@ -10,7 +10,7 @@ type FixedIP struct {
IPAddress string `json:"ip_address"`
}
// Interface represents a network interface on an instance.
// Interface represents a network interface on a server.
type Interface struct {
PortState string `json:"port_state"`
FixedIPs []FixedIP `json:"fixed_ips"`
@ -19,9 +19,12 @@ type Interface struct {
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.
// 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
}
@ -33,7 +36,7 @@ func (r InterfacePage) IsEmpty() (bool, error) {
}
// ExtractInterfaces interprets the results of a single page from a List() call,
// producing a map of interfaces.
// producing a slice of Interface structs.
func ExtractInterfaces(r pagination.Page) ([]Interface, error) {
var s struct {
Interfaces []Interface `json:"interfaceAttachments"`

View File

@ -1,3 +1,30 @@
// Package volumeattach provides the ability to attach and detach volumes
// to instances
/*
Package volumeattach provides the ability to attach and detach volumes
from servers.
Example to Attach a Volume
serverID := "7ac8686c-de71-4acb-9600-ec18b1a1ed6d"
volumeID := "87463836-f0e2-4029-abf6-20c8892a3103"
createOpts := volumeattach.CreateOpts{
Device: "/dev/vdc",
VolumeID: volumeID,
}
result, err := volumeattach.Create(computeClient, serverID, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Detach a Volume
serverID := "7ac8686c-de71-4acb-9600-ec18b1a1ed6d"
attachmentID := "ed081613-1c9b-4231-aa5e-ebfd4d87f983"
err := volumeattach.Delete(computeClient, serverID, attachmentID).ExtractErr()
if err != nil {
panic(err)
}
*/
package volumeattach

View File

@ -5,24 +5,26 @@ import (
"github.com/gophercloud/gophercloud/pagination"
)
// List returns a Pager that allows you to iterate over a collection of VolumeAttachments.
// List returns a Pager that allows you to iterate over a collection of
// VolumeAttachments.
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
return pagination.NewPager(client, listURL(client, serverID), func(r pagination.PageResult) pagination.Page {
return VolumeAttachmentPage{pagination.SinglePageBase(r)}
})
}
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
// CreateOpts struct in this package does.
// CreateOptsBuilder allows extensions to add parameters to the Create request.
type CreateOptsBuilder interface {
ToVolumeAttachmentCreateMap() (map[string]interface{}, error)
}
// CreateOpts specifies volume attachment creation or import parameters.
type CreateOpts struct {
// Device is the device that the volume will attach to the instance as. Omit for "auto"
// Device is the device that the volume will attach to the instance as.
// Omit for "auto".
Device string `json:"device,omitempty"`
// VolumeID is the ID of the volume to attach to the instance
// VolumeID is the ID of the volume to attach to the instance.
VolumeID string `json:"volumeId" required:"true"`
}
@ -31,7 +33,7 @@ func (opts CreateOpts) ToVolumeAttachmentCreateMap() (map[string]interface{}, er
return gophercloud.BuildRequestBody(opts, "volumeAttachment")
}
// Create requests the creation of a new volume attachment on the server
// Create requests the creation of a new volume attachment on the server.
func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToVolumeAttachmentCreateMap()
if err != nil {
@ -50,7 +52,8 @@ func Get(client *gophercloud.ServiceClient, serverID, attachmentID string) (r Ge
return
}
// Delete requests the deletion of a previous stored VolumeAttachment from the server.
// Delete requests the deletion of a previous stored VolumeAttachment from
// the server.
func Delete(client *gophercloud.ServiceClient, serverID, attachmentID string) (r DeleteResult) {
_, r.Err = client.Delete(deleteURL(client, serverID, attachmentID), nil)
return

View File

@ -5,35 +5,36 @@ import (
"github.com/gophercloud/gophercloud/pagination"
)
// VolumeAttachment controls the attachment of a volume to an instance.
// VolumeAttachment contains attachment information between a volume
// and server.
type VolumeAttachment struct {
// ID is a unique id of the attachment
// ID is a unique id of the attachment.
ID string `json:"id"`
// Device is what device the volume is attached as
// Device is what device the volume is attached as.
Device string `json:"device"`
// VolumeID is the ID of the attached volume
// VolumeID is the ID of the attached volume.
VolumeID string `json:"volumeId"`
// ServerID is the ID of the instance that has the volume attached
// ServerID is the ID of the instance that has the volume attached.
ServerID string `json:"serverId"`
}
// VolumeAttachmentPage stores a single, only page of VolumeAttachments
// VolumeAttachmentPage stores a single page all of VolumeAttachment
// results from a List call.
type VolumeAttachmentPage struct {
pagination.SinglePageBase
}
// IsEmpty determines whether or not a VolumeAttachmentsPage is empty.
// IsEmpty determines whether or not a VolumeAttachmentPage is empty.
func (page VolumeAttachmentPage) IsEmpty() (bool, error) {
va, err := ExtractVolumeAttachments(page)
return len(va) == 0, err
}
// ExtractVolumeAttachments interprets a page of results as a slice of
// VolumeAttachments.
// VolumeAttachment.
func ExtractVolumeAttachments(r pagination.Page) ([]VolumeAttachment, error) {
var s struct {
VolumeAttachments []VolumeAttachment `json:"volumeAttachments"`
@ -57,20 +58,20 @@ func (r VolumeAttachmentResult) Extract() (*VolumeAttachment, error) {
return s.VolumeAttachment, err
}
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
// as a VolumeAttachment.
// CreateResult is the response from a Create operation. Call its Extract method
// to interpret it as a VolumeAttachment.
type CreateResult struct {
VolumeAttachmentResult
}
// GetResult is the response from a Get operation. Call its Extract method to interpret it
// as a VolumeAttachment.
// GetResult is the response from a Get operation. Call its Extract method to
// interpret it as a VolumeAttachment.
type GetResult struct {
VolumeAttachmentResult
}
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
// the call succeeded or failed.
// DeleteResult is the response from a Delete operation. Call its ExtractErr
// method to determine if the call succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -1,7 +1,45 @@
// Package flavors provides information and interaction with the flavor API
// resource in the OpenStack Compute service.
//
// A flavor is an available hardware configuration for a server. Each flavor
// has a unique combination of disk space, memory capacity and priority for CPU
// time.
/*
Package flavors provides information and interaction with the flavor API
in the OpenStack Compute service.
A flavor is an available hardware configuration for a server. Each flavor
has a unique combination of disk space, memory capacity and priority for CPU
time.
Example to List Flavors
listOpts := flavors.ListOpts{
AccessType: flavors.PublicAccess,
}
allPages, err := flavors.ListDetail(computeClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allFlavors, err := flavors.ExtractFlavors(allPages)
if err != nil {
panic(err)
}
for _, flavor := range allFlavors {
fmt.Printf("%+v\n", flavor)
}
Example to Create a Flavor
createOpts := flavors.CreateOpts{
ID: "1",
Name: "m1.tiny",
Disk: gophercloud.IntToPointer(1),
RAM: 512,
VCPUs: 1,
RxTxFactor: 1.0,
}
flavor, err := flavors.Create(computeClient, createOpts).Extract()
if err != nil {
panic(err)
}
*/
package flavors

View File

@ -11,33 +11,45 @@ type ListOptsBuilder interface {
ToFlavorListQuery() (string, error)
}
// AccessType maps to OpenStack's Flavor.is_public field. Although the is_public field is boolean, the
// request options are ternary, which is why AccessType is a string. The following values are
// allowed:
//
// PublicAccess (the default): Returns public flavors and private flavors associated with that project.
// PrivateAccess (admin only): Returns private flavors, across all projects.
// AllAccess (admin only): Returns public and private flavors across all projects.
//
// The AccessType arguement is optional, and if it is not supplied, OpenStack returns the PublicAccess
// flavors.
/*
AccessType maps to OpenStack's Flavor.is_public field. Although the is_public
field is boolean, the request options are ternary, which is why AccessType is
a string. The following values are allowed:
The AccessType arguement is optional, and if it is not supplied, OpenStack
returns the PublicAccess flavors.
*/
type AccessType string
const (
PublicAccess AccessType = "true"
// PublicAccess returns public flavors and private flavors associated with
// that project.
PublicAccess AccessType = "true"
// PrivateAccess (admin only) returns private flavors, across all projects.
PrivateAccess AccessType = "false"
AllAccess AccessType = "None"
// AllAccess (admin only) returns public and private flavors across all
// projects.
AllAccess AccessType = "None"
)
// ListOpts helps control the results returned by the List() function.
// For example, a flavor with a minDisk field of 10 will not be returned if you specify MinDisk set to 20.
// Typically, software will use the last ID of the previous call to List to set the Marker for the current call.
/*
ListOpts filters the results returned by the List() function.
For example, a flavor with a minDisk field of 10 will not be returned if you
specify MinDisk set to 20.
Typically, software will use the last ID of the previous call to List to set
the Marker for the current call.
*/
type ListOpts struct {
// ChangesSince, if provided, instructs List to return only those things which have changed since the timestamp provided.
// ChangesSince, if provided, instructs List to return only those things which
// have changed since the timestamp provided.
ChangesSince string `q:"changes-since"`
// MinDisk and MinRAM, if provided, elides flavors which do not meet your criteria.
// MinDisk and MinRAM, if provided, elides flavors which do not meet your
// criteria.
MinDisk int `q:"minDisk"`
MinRAM int `q:"minRam"`
@ -45,11 +57,12 @@ type ListOpts struct {
// Marker instructs List where to start listing from.
Marker string `q:"marker"`
// Limit instructs List to refrain from sending excessively large lists of flavors.
// Limit instructs List to refrain from sending excessively large lists of
// flavors.
Limit int `q:"limit"`
// AccessType, if provided, instructs List which set of flavors to return. If IsPublic not provided,
// flavors for the current project are returned.
// AccessType, if provided, instructs List which set of flavors to return.
// If IsPublic not provided, flavors for the current project are returned.
AccessType AccessType `q:"is_public"`
}
@ -60,8 +73,8 @@ func (opts ListOpts) ToFlavorListQuery() (string, error) {
}
// ListDetail instructs OpenStack to provide a list of flavors.
// You may provide criteria by which List curtails its results for easier processing.
// See ListOpts for more details.
// You may provide criteria by which List curtails its results for easier
// processing.
func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := listURL(client)
if opts != nil {
@ -80,31 +93,42 @@ type CreateOptsBuilder interface {
ToFlavorCreateMap() (map[string]interface{}, error)
}
// CreateOpts is passed to Create to create a flavor
// Source:
// https://github.com/openstack/nova/blob/stable/newton/nova/api/openstack/compute/schemas/flavor_manage.py#L20
// CreateOpts specifies parameters used for creating a flavor.
type CreateOpts struct {
// Name is the name of the flavor.
Name string `json:"name" required:"true"`
// memory size, in MBs
RAM int `json:"ram" required:"true"`
// RAM is the memory of the flavor, measured in MB.
RAM int `json:"ram" required:"true"`
// VCPUs is the number of vcpus for the flavor.
VCPUs int `json:"vcpus" required:"true"`
// disk size, in GBs
Disk *int `json:"disk" required:"true"`
ID string `json:"id,omitempty"`
// non-zero, positive
Swap *int `json:"swap,omitempty"`
// Disk the amount of root disk space, measured in GB.
Disk *int `json:"disk" required:"true"`
// ID is a unique ID for the flavor.
ID string `json:"id,omitempty"`
// Swap is the amount of swap space for the flavor, measured in MB.
Swap *int `json:"swap,omitempty"`
// RxTxFactor alters the network bandwidth of a flavor.
RxTxFactor float64 `json:"rxtx_factor,omitempty"`
IsPublic *bool `json:"os-flavor-access:is_public,omitempty"`
// ephemeral disk size, in GBs, non-zero, positive
// IsPublic flags a flavor as being available to all projects or not.
IsPublic *bool `json:"os-flavor-access:is_public,omitempty"`
// Ephemeral is the amount of ephemeral disk space, measured in GB.
Ephemeral *int `json:"OS-FLV-EXT-DATA:ephemeral,omitempty"`
}
// ToFlavorCreateMap satisfies the CreateOptsBuilder interface
func (opts *CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) {
// ToFlavorCreateMap constructs a request body from CreateOpts.
func (opts CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "flavor")
}
// Create a flavor
// Create requests the creation of a new flavor.
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToFlavorCreateMap()
if err != nil {
@ -117,14 +141,21 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
return
}
// Get instructs OpenStack to provide details on a single flavor, identified by its ID.
// Use ExtractFlavor to convert its result into a Flavor.
// Get retrieves details of a single flavor. Use ExtractFlavor to convert its
// result into a Flavor.
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
return
}
// IDFromName is a convienience function that returns a flavor's ID given its name.
// Delete deletes the specified flavor ID.
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = client.Delete(deleteURL(client, id), nil)
return
}
// IDFromName is a convienience function that returns a flavor's ID given its
// name.
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
count := 0
id := ""

View File

@ -16,12 +16,20 @@ type CreateResult struct {
commonResult
}
// GetResult temporarily holds the response from a Get call.
// GetResult is the response of a Get operations. Call its Extract method to
// interpret it as a Flavor.
type GetResult struct {
commonResult
}
// Extract provides access to the individual Flavor returned by the Get and Create functions.
// DeleteResult is the result from a Delete operation. Call its ExtractErr
// method to determine if the call succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
// Extract provides access to the individual Flavor returned by the Get and
// Create functions.
func (r commonResult) Extract() (*Flavor, error) {
var s struct {
Flavor *Flavor `json:"flavor"`
@ -30,22 +38,30 @@ func (r commonResult) Extract() (*Flavor, error) {
return s.Flavor, err
}
// Flavor records represent (virtual) hardware configurations for server resources in a region.
// Flavor represent (virtual) hardware configurations for server resources
// in a region.
type Flavor struct {
// The Id field contains the flavor's unique identifier.
// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
// ID is the flavor's unique ID.
ID string `json:"id"`
// The Disk and RA< fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
// Disk is the amount of root disk, measured in GB.
Disk int `json:"disk"`
RAM int `json:"ram"`
// The Name field provides a human-readable moniker for the flavor.
Name string `json:"name"`
// RAM is the amount of memory, measured in MB.
RAM int `json:"ram"`
// Name is the name of the flavor.
Name string `json:"name"`
// RxTxFactor describes bandwidth alterations of the flavor.
RxTxFactor float64 `json:"rxtx_factor"`
// Swap indicates how much space is reserved for swap.
// If not provided, this field will be set to 0.
// Swap is the amount of swap space, measured in MB.
Swap int `json:"swap"`
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
VCPUs int `json:"vcpus"`
// IsPublic indicates whether the flavor is public.
IsPublic bool `json:"is_public"`
}
@ -82,18 +98,19 @@ func (r *Flavor) UnmarshalJSON(b []byte) error {
return nil
}
// FlavorPage contains a single page of the response from a List call.
// FlavorPage contains a single page of all flavors from a ListDetails call.
type FlavorPage struct {
pagination.LinkedPageBase
}
// IsEmpty determines if a page contains any results.
// IsEmpty determines if a FlavorPage contains any results.
func (page FlavorPage) IsEmpty() (bool, error) {
flavors, err := ExtractFlavors(page)
return len(flavors) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
// NextPageURL uses the response's embedded link reference to navigate to the
// next page of results.
func (page FlavorPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"flavors_links"`
@ -105,7 +122,8 @@ func (page FlavorPage) NextPageURL() (string, error) {
return gophercloud.ExtractNextURL(s.Links)
}
// ExtractFlavors provides access to the list of flavors in a page acquired from the List operation.
// ExtractFlavors provides access to the list of flavors in a page acquired
// from the ListDetail operation.
func ExtractFlavors(r pagination.Page) ([]Flavor, error) {
var s struct {
Flavors []Flavor `json:"flavors"`

View File

@ -15,3 +15,7 @@ func listURL(client *gophercloud.ServiceClient) string {
func createURL(client *gophercloud.ServiceClient) string {
return client.ServiceURL("flavors")
}
func deleteURL(client *gophercloud.ServiceClient, id string) string {
return client.ServiceURL("flavors", id)
}

View File

@ -1,7 +1,32 @@
// Package images provides information and interaction with the image API
// resource in the OpenStack Compute service.
//
// An image is a collection of files used to create or rebuild a server.
// Operators provide a number of pre-built OS images by default. You may also
// create custom images from cloud servers you have launched.
/*
Package images provides information and interaction with the images through
the OpenStack Compute service.
This API is deprecated and will be removed from a future version of the Nova
API service.
An image is a collection of files used to create or rebuild a server.
Operators provide a number of pre-built OS images by default. You may also
create custom images from cloud servers you have launched.
Example to List Images
listOpts := images.ListOpts{
Limit: 2,
}
allPages, err := images.ListDetail(computeClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allImages, err := images.ExtractImages(allPages)
if err != nil {
panic(err)
}
for _, image := range allImages {
fmt.Printf("%+v\n", image)
}
*/
package images

View File

@ -6,26 +6,33 @@ import (
)
// ListOptsBuilder allows extensions to add additional parameters to the
// List request.
// ListDetail request.
type ListOptsBuilder interface {
ToImageListQuery() (string, error)
}
// ListOpts contain options for limiting the number of Images returned from a call to ListDetail.
// ListOpts contain options filtering Images returned from a call to ListDetail.
type ListOpts struct {
// When the image last changed status (in date-time format).
// ChangesSince filters Images based on the last changed status (in date-time
// format).
ChangesSince string `q:"changes-since"`
// The number of Images to return.
// Limit limits the number of Images to return.
Limit int `q:"limit"`
// UUID of the Image at which to set a marker.
// Mark is an Image UUID at which to set a marker.
Marker string `q:"marker"`
// The name of the Image.
// Name is the name of the Image.
Name string `q:"name"`
// The name of the Server (in URL format).
// Server is the name of the Server (in URL format).
Server string `q:"server"`
// The current status of the Image.
// Status is the current status of the Image.
Status string `q:"status"`
// The value of the type of image (e.g. BASE, SERVER, ALL)
// Type is the type of image (e.g. BASE, SERVER, ALL).
Type string `q:"type"`
}
@ -50,8 +57,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat
})
}
// Get acquires additional detail about a specific image by ID.
// Use ExtractImage() to interpret the result as an openstack Image.
// Get returns data about a specific image by its ID.
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
return
@ -63,7 +69,8 @@ func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
return
}
// IDFromName is a convienience function that returns an image's ID given its name.
// IDFromName is a convienience function that returns an image's ID given its
// name.
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
count := 0
id := ""

View File

@ -5,12 +5,14 @@ import (
"github.com/gophercloud/gophercloud/pagination"
)
// GetResult temporarily stores a Get response.
// GetResult is the response from a Get operation. Call its Extract method to
// interpret it as an Image.
type GetResult struct {
gophercloud.Result
}
// DeleteResult represents the result of an image.Delete operation.
// DeleteResult is the result from a Delete operation. Call its ExtractErr
// method to determine if the call succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
@ -24,44 +26,53 @@ func (r GetResult) Extract() (*Image, error) {
return s.Image, err
}
// Image is used for JSON (un)marshalling.
// It provides a description of an OS image.
// Image represents an Image returned by the Compute API.
type Image struct {
// ID contains the image's unique identifier.
// ID is the unique ID of an image.
ID string
// Created is the date when the image was created.
Created string
// MinDisk and MinRAM specify the minimum resources a server must provide to be able to install the image.
// MinDisk is the minimum amount of disk a flavor must have to be able
// to create a server based on the image, measured in GB.
MinDisk int
MinRAM int
// MinRAM is the minimum amount of RAM a flavor must have to be able
// to create a server based on the image, measured in MB.
MinRAM int
// Name provides a human-readable moniker for the OS image.
Name string
// The Progress and Status fields indicate image-creation status.
// Any usable image will have 100% progress.
Progress int
Status string
// Status is the current status of the image.
Status string
// Update is the date when the image was updated.
Updated string
// Metadata provides free-form key/value pairs that further describe the
// image.
Metadata map[string]interface{}
}
// ImagePage contains a single page of results from a List operation.
// Use ExtractImages to convert it into a slice of usable structs.
// ImagePage contains a single page of all Images returne from a ListDetail
// operation. Use ExtractImages to convert it into a slice of usable structs.
type ImagePage struct {
pagination.LinkedPageBase
}
// IsEmpty returns true if a page contains no Image results.
// IsEmpty returns true if an ImagePage contains no Image results.
func (page ImagePage) IsEmpty() (bool, error) {
images, err := ExtractImages(page)
return len(images) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
// NextPageURL uses the response's embedded link reference to navigate to the
// next page of results.
func (page ImagePage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"images_links"`
@ -73,7 +84,8 @@ func (page ImagePage) NextPageURL() (string, error) {
return gophercloud.ExtractNextURL(s.Links)
}
// ExtractImages converts a page of List results into a slice of usable Image structs.
// ExtractImages converts a page of List results into a slice of usable Image
// structs.
func ExtractImages(r pagination.Page) ([]Image, error) {
var s struct {
Images []Image `json:"images"`

View File

@ -1,6 +1,115 @@
// Package servers provides information and interaction with the server API
// resource in the OpenStack Compute service.
//
// A server is a virtual machine instance in the compute system. In order for
// one to be provisioned, a valid flavor and image are required.
/*
Package servers provides information and interaction with the server API
resource in the OpenStack Compute service.
A server is a virtual machine instance in the compute system. In order for
one to be provisioned, a valid flavor and image are required.
Example to List Servers
listOpts := servers.ListOpts{
AllTenants: true,
}
allPages, err := servers.List(computeClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allServers, err := servers.ExtractServers(allPages)
if err != nil {
panic(err)
}
for _, server := range allServers {
fmt.Printf("%+v\n", server)
}
Example to Create a Server
createOpts := servers.CreateOpts{
Name: "server_name",
ImageRef: "image-uuid",
FlavorRef: "flavor-uuid",
}
server, err := servers.Create(computeClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Server
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
err := servers.Delete(computeClient, serverID).ExtractErr()
if err != nil {
panic(err)
}
Example to Force Delete a Server
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
err := servers.ForceDelete(computeClient, serverID).ExtractErr()
if err != nil {
panic(err)
}
Example to Reboot a Server
rebootOpts := servers.RebootOpts{
Type: servers.SoftReboot,
}
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
err := servers.Reboot(computeClient, serverID, rebootOpts).ExtractErr()
if err != nil {
panic(err)
}
Example to Rebuild a Server
rebuildOpts := servers.RebuildOpts{
Name: "new_name",
ImageID: "image-uuid",
}
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
server, err := servers.Rebuilt(computeClient, serverID, rebuildOpts).Extract()
if err != nil {
panic(err)
}
Example to Resize a Server
resizeOpts := servers.ResizeOpts{
FlavorRef: "flavor-uuid",
}
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
err := servers.Resize(computeClient, serverID, resizeOpts).ExtractErr()
if err != nil {
panic(err)
}
err = servers.ConfirmResize(computeClient, serverID).ExtractErr()
if err != nil {
panic(err)
}
Example to Snapshot a Server
snapshotOpts := servers.CreateImageOpts{
Name: "snapshot_name",
}
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
image, err := servers.CreateImage(computeClient, serverID, snapshotOpts).ExtractImageID()
if err != nil {
panic(err)
}
*/
package servers

View File

@ -21,13 +21,13 @@ type ListOptsBuilder interface {
// the server attributes you want to see returned. Marker and Limit are used
// for pagination.
type ListOpts struct {
// A time/date stamp for when the server last changed status.
// ChangesSince is a time/date stamp for when the server last changed status.
ChangesSince string `q:"changes-since"`
// Name of the image in URL format.
// Image is the name of the image in URL format.
Image string `q:"image"`
// Name of the flavor in URL format.
// Flavor is the name of the flavor in URL format.
Flavor string `q:"flavor"`
// Name of the server as a string; can be queried with regular expressions.
@ -36,22 +36,24 @@ type ListOpts struct {
// underlying database server implemented for Compute.
Name string `q:"name"`
// Value of the status of the server so that you can filter on "ACTIVE" for example.
// Status is the value of the status of the server so that you can filter on
// "ACTIVE" for example.
Status string `q:"status"`
// Name of the host as a string.
// Host is the name of the host as a string.
Host string `q:"host"`
// UUID of the server at which you want to set a marker.
// Marker is a UUID of the server at which you want to set a marker.
Marker string `q:"marker"`
// Integer value for the limit of values to return.
// Limit is an integer value for the limit of values to return.
Limit int `q:"limit"`
// Bool to show all tenants
// AllTenants is a bool to show all tenants.
AllTenants bool `q:"all_tenants"`
// List servers for a particular tenant. Setting "AllTenants = true" is required.
// TenantID lists servers for a particular tenant.
// Setting "AllTenants = true" is required.
TenantID string `q:"tenant_id"`
}
@ -76,15 +78,16 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
})
}
// CreateOptsBuilder describes struct types that can be accepted by the Create call.
// The CreateOpts struct in this package does.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToServerCreateMap() (map[string]interface{}, error)
}
// Network is used within CreateOpts to control a new server's network attachments.
// Network is used within CreateOpts to control a new server's network
// attachments.
type Network struct {
// UUID of a nova-network to attach to the newly provisioned server.
// UUID of a network to attach to the newly provisioned server.
// Required unless Port is provided.
UUID string
@ -92,19 +95,21 @@ type Network struct {
// Required unless UUID is provided.
Port string
// FixedIP [optional] specifies a fixed IPv4 address to be used on this network.
// FixedIP specifies a fixed IPv4 address to be used on this network.
FixedIP string
}
// Personality is an array of files that are injected into the server at launch.
type Personality []*File
// File is used within CreateOpts and RebuildOpts to inject a file into the server at launch.
// File implements the json.Marshaler interface, so when a Create or Rebuild operation is requested,
// json.Marshal will call File's MarshalJSON method.
// File is used within CreateOpts and RebuildOpts to inject a file into the
// server at launch.
// File implements the json.Marshaler interface, so when a Create or Rebuild
// operation is requested, json.Marshal will call File's MarshalJSON method.
type File struct {
// Path of the file
// Path of the file.
Path string
// Contents of the file. Maximum content size is 255 bytes.
Contents []byte
}
@ -126,13 +131,13 @@ type CreateOpts struct {
// Name is the name to assign to the newly launched server.
Name string `json:"name" required:"true"`
// ImageRef [optional; required if ImageName is not provided] is the ID or full
// URL to the image that contains the server's OS and initial state.
// ImageRef [optional; required if ImageName is not provided] is the ID or
// full URL to the image that contains the server's OS and initial state.
// Also optional if using the boot-from-volume extension.
ImageRef string `json:"imageRef"`
// ImageName [optional; required if ImageRef is not provided] is the name of the
// image that contains the server's OS and initial state.
// ImageName [optional; required if ImageRef is not provided] is the name of
// the image that contains the server's OS and initial state.
// Also optional if using the boot-from-volume extension.
ImageName string `json:"-"`
@ -144,7 +149,8 @@ type CreateOpts struct {
// the flavor that describes the server's specs.
FlavorName string `json:"-"`
// SecurityGroups lists the names of the security groups to which this server should belong.
// SecurityGroups lists the names of the security groups to which this server
// should belong.
SecurityGroups []string `json:"-"`
// UserData contains configuration information or scripts to use upon launch.
@ -155,10 +161,12 @@ type CreateOpts struct {
AvailabilityZone string `json:"availability_zone,omitempty"`
// Networks dictates how this server will be attached to available networks.
// By default, the server will be attached to all isolated networks for the tenant.
// By default, the server will be attached to all isolated networks for the
// tenant.
Networks []Network `json:"-"`
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the server.
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the
// server.
Metadata map[string]string `json:"metadata,omitempty"`
// Personality includes files to inject into the server at launch.
@ -169,7 +177,7 @@ type CreateOpts struct {
ConfigDrive *bool `json:"config_drive,omitempty"`
// AdminPass sets the root user password. If not set, a randomly-generated
// password will be created and returned in the rponse.
// password will be created and returned in the response.
AdminPass string `json:"adminPass,omitempty"`
// AccessIPv4 specifies an IPv4 address for the instance.
@ -183,7 +191,8 @@ type CreateOpts struct {
ServiceClient *gophercloud.ServiceClient `json:"-"`
}
// ToServerCreateMap assembles a request body based on the contents of a CreateOpts.
// ToServerCreateMap assembles a request body based on the contents of a
// CreateOpts.
func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
sc := opts.ServiceClient
opts.ServiceClient = nil
@ -277,13 +286,14 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
return
}
// Delete requests that a server previously provisioned be removed from your account.
// Delete requests that a server previously provisioned be removed from your
// account.
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = client.Delete(deleteURL(client, id), nil)
return
}
// ForceDelete forces the deletion of a server
// ForceDelete forces the deletion of a server.
func ForceDelete(client *gophercloud.ServiceClient, id string) (r ActionResult) {
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"forceDelete": ""}, nil, nil)
return
@ -297,12 +307,14 @@ func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
// UpdateOptsBuilder allows extensions to add additional attributes to the
// Update request.
type UpdateOptsBuilder interface {
ToServerUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts specifies the base attributes that may be updated on an existing server.
// UpdateOpts specifies the base attributes that may be updated on an existing
// server.
type UpdateOpts struct {
// Name changes the displayed name of the server.
// The server host name will *not* change.
@ -334,7 +346,8 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
return
}
// ChangeAdminPassword alters the administrator or root password for a specified server.
// ChangeAdminPassword alters the administrator or root password for a specified
// server.
func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) (r ActionResult) {
b := map[string]interface{}{
"changePassword": map[string]string{
@ -357,33 +370,38 @@ const (
PowerCycle = HardReboot
)
// RebootOptsBuilder is an interface that options must satisfy in order to be
// used when rebooting a server instance
// RebootOptsBuilder allows extensions to add additional parameters to the
// reboot request.
type RebootOptsBuilder interface {
ToServerRebootMap() (map[string]interface{}, error)
}
// RebootOpts satisfies the RebootOptsBuilder interface
// RebootOpts provides options to the reboot request.
type RebootOpts struct {
// Type is the type of reboot to perform on the server.
Type RebootMethod `json:"type" required:"true"`
}
// ToServerRebootMap allows RebootOpts to satisfiy the RebootOptsBuilder
// interface
// ToServerRebootMap builds a body for the reboot request.
func (opts *RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "reboot")
}
// Reboot requests that a given server reboot.
// Two methods exist for rebooting a server:
//
// HardReboot (aka PowerCycle) starts the server instance by physically cutting power to the machine, or if a VM,
// terminating it at the hypervisor level.
// It's done. Caput. Full stop.
// Then, after a brief while, power is rtored or the VM instance rtarted.
//
// SoftReboot (aka OSReboot) simply tells the OS to rtart under its own procedur.
// E.g., in Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to rtart the machine.
/*
Reboot requests that a given server reboot.
Two methods exist for rebooting a server:
HardReboot (aka PowerCycle) starts the server instance by physically cutting
power to the machine, or if a VM, terminating it at the hypervisor level.
It's done. Caput. Full stop.
Then, after a brief while, power is rtored or the VM instance restarted.
SoftReboot (aka OSReboot) simply tells the OS to restart under its own
procedure.
E.g., in Linux, asking it to enter runlevel 6, or executing
"sudo shutdown -r now", or by asking Windows to rtart the machine.
*/
func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder) (r ActionResult) {
b, err := opts.ToServerRebootMap()
if err != nil {
@ -394,31 +412,43 @@ func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder
return
}
// RebuildOptsBuilder is an interface that allows extensions to override the
// default behaviour of rebuild options
// RebuildOptsBuilder allows extensions to provide additional parameters to the
// rebuild request.
type RebuildOptsBuilder interface {
ToServerRebuildMap() (map[string]interface{}, error)
}
// RebuildOpts represents the configuration options used in a server rebuild
// operation
// operation.
type RebuildOpts struct {
// The server's admin password
// AdminPass is the server's admin password
AdminPass string `json:"adminPass,omitempty"`
// The ID of the image you want your server to be provisioned on
ImageID string `json:"imageRef"`
// ImageID is the ID of the image you want your server to be provisioned on.
ImageID string `json:"imageRef"`
// ImageName is readable name of an image.
ImageName string `json:"-"`
// Name to set the server to
Name string `json:"name,omitempty"`
// AccessIPv4 [optional] provides a new IPv4 address for the instance.
AccessIPv4 string `json:"accessIPv4,omitempty"`
// AccessIPv6 [optional] provides a new IPv6 address for the instance.
AccessIPv6 string `json:"accessIPv6,omitempty"`
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
// Metadata [optional] contains key-value pairs (up to 255 bytes each)
// to attach to the server.
Metadata map[string]string `json:"metadata,omitempty"`
// Personality [optional] includes files to inject into the server at launch.
// Rebuild will base64-encode file contents for you.
Personality Personality `json:"personality,omitempty"`
Personality Personality `json:"personality,omitempty"`
// ServiceClient will allow calls to be made to retrieve an image or
// flavor ID by name.
ServiceClient *gophercloud.ServiceClient `json:"-"`
}
@ -461,31 +491,34 @@ func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuild
return
}
// ResizeOptsBuilder is an interface that allows extensions to override the default structure of
// a Resize request.
// ResizeOptsBuilder allows extensions to add additional parameters to the
// resize request.
type ResizeOptsBuilder interface {
ToServerResizeMap() (map[string]interface{}, error)
}
// ResizeOpts represents the configuration options used to control a Resize operation.
// ResizeOpts represents the configuration options used to control a Resize
// operation.
type ResizeOpts struct {
// FlavorRef is the ID of the flavor you wish your server to become.
FlavorRef string `json:"flavorRef" required:"true"`
}
// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON request body for the
// Resize request.
// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON
// request body for the Resize request.
func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "resize")
}
// Resize instructs the provider to change the flavor of the server.
//
// Note that this implies rebuilding it.
//
// Unfortunately, one cannot pass rebuild parameters to the resize function.
// When the resize completes, the server will be in RESIZE_VERIFY state.
// While in this state, you can explore the use of the new server's configuration.
// If you like it, call ConfirmResize() to commit the resize permanently.
// Otherwise, call RevertResize() to restore the old configuration.
// While in this state, you can explore the use of the new server's
// configuration. If you like it, call ConfirmResize() to commit the resize
// permanently. Otherwise, call RevertResize() to restore the old configuration.
func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ActionResult) {
b, err := opts.ToServerResizeMap()
if err != nil {
@ -545,8 +578,8 @@ func Rescue(client *gophercloud.ServiceClient, id string, opts RescueOptsBuilder
return
}
// ResetMetadataOptsBuilder allows extensions to add additional parameters to the
// Reset request.
// ResetMetadataOptsBuilder allows extensions to add additional parameters to
// the Reset request.
type ResetMetadataOptsBuilder interface {
ToMetadataResetMap() (map[string]interface{}, error)
}
@ -554,20 +587,23 @@ type ResetMetadataOptsBuilder interface {
// MetadataOpts is a map that contains key-value pairs.
type MetadataOpts map[string]string
// ToMetadataResetMap assembles a body for a Reset request based on the contents of a MetadataOpts.
// ToMetadataResetMap assembles a body for a Reset request based on the contents
// of a MetadataOpts.
func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) {
return map[string]interface{}{"metadata": opts}, nil
}
// ToMetadataUpdateMap assembles a body for an Update request based on the contents of a MetadataOpts.
// ToMetadataUpdateMap assembles a body for an Update request based on the
// contents of a MetadataOpts.
func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) {
return map[string]interface{}{"metadata": opts}, nil
}
// ResetMetadata will create multiple new key-value pairs for the given server ID.
// Note: Using this operation will erase any already-existing metadata and create
// the new metadata provided. To keep any already-existing metadata, use the
// UpdateMetadatas or UpdateMetadata function.
// ResetMetadata will create multiple new key-value pairs for the given server
// ID.
// Note: Using this operation will erase any already-existing metadata and
// create the new metadata provided. To keep any already-existing metadata,
// use the UpdateMetadatas or UpdateMetadata function.
func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) (r ResetMetadataResult) {
b, err := opts.ToMetadataResetMap()
if err != nil {
@ -586,15 +622,15 @@ func Metadata(client *gophercloud.ServiceClient, id string) (r GetMetadataResult
return
}
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to the
// Create request.
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
// the Create request.
type UpdateMetadataOptsBuilder interface {
ToMetadataUpdateMap() (map[string]interface{}, error)
}
// UpdateMetadata updates (or creates) all the metadata specified by opts for the given server ID.
// This operation does not affect already-existing metadata that is not specified
// by opts.
// UpdateMetadata updates (or creates) all the metadata specified by opts for
// the given server ID. This operation does not affect already-existing metadata
// that is not specified by opts.
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) {
b, err := opts.ToMetadataUpdateMap()
if err != nil {
@ -616,7 +652,8 @@ type MetadatumOptsBuilder interface {
// MetadatumOpts is a map of length one that contains a key-value pair.
type MetadatumOpts map[string]string
// ToMetadatumCreateMap assembles a body for a Create request based on the contents of a MetadataumOpts.
// ToMetadatumCreateMap assembles a body for a Create request based on the
// contents of a MetadataumOpts.
func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) {
if len(opts) != 1 {
err := gophercloud.ErrInvalidInput{}
@ -632,7 +669,8 @@ func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string
return metadatum, key, nil
}
// CreateMetadatum will create or update the key-value pair with the given key for the given server ID.
// CreateMetadatum will create or update the key-value pair with the given key
// for the given server ID.
func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts MetadatumOptsBuilder) (r CreateMetadatumResult) {
b, key, err := opts.ToMetadatumCreateMap()
if err != nil {
@ -645,53 +683,60 @@ func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts Metadatu
return
}
// Metadatum requests the key-value pair with the given key for the given server ID.
// Metadatum requests the key-value pair with the given key for the given
// server ID.
func Metadatum(client *gophercloud.ServiceClient, id, key string) (r GetMetadatumResult) {
_, r.Err = client.Get(metadatumURL(client, id, key), &r.Body, nil)
return
}
// DeleteMetadatum will delete the key-value pair with the given key for the given server ID.
// DeleteMetadatum will delete the key-value pair with the given key for the
// given server ID.
func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) (r DeleteMetadatumResult) {
_, r.Err = client.Delete(metadatumURL(client, id, key), nil)
return
}
// ListAddresses makes a request against the API to list the servers IP addresses.
// ListAddresses makes a request against the API to list the servers IP
// addresses.
func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager {
return pagination.NewPager(client, listAddressesURL(client, id), func(r pagination.PageResult) pagination.Page {
return AddressPage{pagination.SinglePageBase(r)}
})
}
// ListAddressesByNetwork makes a request against the API to list the servers IP addresses
// for the given network.
// ListAddressesByNetwork makes a request against the API to list the servers IP
// addresses for the given network.
func ListAddressesByNetwork(client *gophercloud.ServiceClient, id, network string) pagination.Pager {
return pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), func(r pagination.PageResult) pagination.Page {
return NetworkAddressPage{pagination.SinglePageBase(r)}
})
}
// CreateImageOptsBuilder is the interface types must satisfy in order to be
// used as CreateImage options
// CreateImageOptsBuilder allows extensions to add additional parameters to the
// CreateImage request.
type CreateImageOptsBuilder interface {
ToServerCreateImageMap() (map[string]interface{}, error)
}
// CreateImageOpts satisfies the CreateImageOptsBuilder
// CreateImageOpts provides options to pass to the CreateImage request.
type CreateImageOpts struct {
// Name of the image/snapshot
// Name of the image/snapshot.
Name string `json:"name" required:"true"`
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the created image.
// Metadata contains key-value pairs (up to 255 bytes each) to attach to
// the created image.
Metadata map[string]string `json:"metadata,omitempty"`
}
// ToServerCreateImageMap formats a CreateImageOpts structure into a request body.
// ToServerCreateImageMap formats a CreateImageOpts structure into a request
// body.
func (opts CreateImageOpts) ToServerCreateImageMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "createImage")
}
// CreateImage makes a request against the nova API to schedule an image to be created of the server
// CreateImage makes a request against the nova API to schedule an image to be
// created of the server
func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageOptsBuilder) (r CreateImageResult) {
b, err := opts.ToServerCreateImageMap()
if err != nil {
@ -706,7 +751,8 @@ func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageO
return
}
// IDFromName is a convienience function that returns a server's ID given its name.
// IDFromName is a convienience function that returns a server's ID given its
// name.
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
count := 0
id := ""
@ -737,7 +783,8 @@ func IDFromName(client *gophercloud.ServiceClient, name string) (string, error)
}
}
// GetPassword makes a request against the nova API to get the encrypted administrative password.
// GetPassword makes a request against the nova API to get the encrypted
// administrative password.
func GetPassword(client *gophercloud.ServiceClient, serverId string) (r GetPasswordResult) {
_, r.Err = client.Get(passwordURL(client, serverId), &r.Body, nil)
return

View File

@ -32,54 +32,64 @@ func ExtractServersInto(r pagination.Page, v interface{}) error {
return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers")
}
// CreateResult temporarily contains the response from a Create call.
// CreateResult is the response from a Create operation. Call its Extract
// method to interpret it as a Server.
type CreateResult struct {
serverResult
}
// GetResult temporarily contains the response from a Get call.
// GetResult is the response from a Get operation. Call its Extract
// method to interpret it as a Server.
type GetResult struct {
serverResult
}
// UpdateResult temporarily contains the response from an Update call.
// UpdateResult is the response from an Update operation. Call its Extract
// method to interpret it as a Server.
type UpdateResult struct {
serverResult
}
// DeleteResult temporarily contains the response from a Delete call.
// DeleteResult is the response from a Delete operation. Call its ExtractErr
// method to determine if the call succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
// RebuildResult temporarily contains the response from a Rebuild call.
// RebuildResult is the response from a Rebuild operation. Call its Extract
// method to interpret it as a Server.
type RebuildResult struct {
serverResult
}
// ActionResult represents the result of server action operations, like reboot
// ActionResult represents the result of server action operations, like reboot.
// Call its ExtractErr method to determine if the action succeeded or failed.
type ActionResult struct {
gophercloud.ErrResult
}
// RescueResult represents the result of a server rescue operation
// RescueResult is the response from a Rescue operation. Call its ExtractErr
// method to determine if the call succeeded or failed.
type RescueResult struct {
ActionResult
}
// CreateImageResult represents the result of an image creation operation
// CreateImageResult is the response from a CreateImage operation. Call its
// ExtractImageID method to retrieve the ID of the newly created image.
type CreateImageResult struct {
gophercloud.Result
}
// GetPasswordResult represent the result of a get os-server-password operation.
// Call its ExtractPassword method to retrieve the password.
type GetPasswordResult struct {
gophercloud.Result
}
// ExtractPassword gets the encrypted password.
// If privateKey != nil the password is decrypted with the private key.
// If privateKey == nil the encrypted password is returned and can be decrypted with:
// If privateKey == nil the encrypted password is returned and can be decrypted
// with:
// echo '<pwd>' | base64 -D | openssl rsautl -decrypt -inkey <private_key>
func (r GetPasswordResult) ExtractPassword(privateKey *rsa.PrivateKey) (string, error) {
var s struct {
@ -107,7 +117,7 @@ func decryptPassword(encryptedPassword string, privateKey *rsa.PrivateKey) (stri
return string(password), nil
}
// ExtractImageID gets the ID of the newly created server image from the header
// ExtractImageID gets the ID of the newly created server image from the header.
func (r CreateImageResult) ExtractImageID() (string, error) {
if r.Err != nil {
return "", r.Err
@ -133,44 +143,73 @@ func (r RescueResult) Extract() (string, error) {
return s.AdminPass, err
}
// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account.
// Server represents a server/instance in the OpenStack cloud.
type Server struct {
// ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant.
// ID uniquely identifies this server amongst all other servers,
// including those not accessible to the current tenant.
ID string `json:"id"`
// TenantID identifies the tenant owning this server resource.
TenantID string `json:"tenant_id"`
// UserID uniquely identifies the user account owning the tenant.
UserID string `json:"user_id"`
// Name contains the human-readable name for the server.
Name string `json:"name"`
// Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created.
// Updated and Created contain ISO-8601 timestamps of when the state of the
// server last changed, and when it was created.
Updated time.Time `json:"updated"`
Created time.Time `json:"created"`
HostID string `json:"hostid"`
// Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
// HostID is the host where the server is located in the cloud.
HostID string `json:"hostid"`
// Status contains the current operational status of the server,
// such as IN_PROGRESS or ACTIVE.
Status string `json:"status"`
// Progress ranges from 0..100.
// A request made against the server completes only once Progress reaches 100.
Progress int `json:"progress"`
// AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration.
// AccessIPv4 and AccessIPv6 contain the IP addresses of the server,
// suitable for remote access for administration.
AccessIPv4 string `json:"accessIPv4"`
AccessIPv6 string `json:"accessIPv6"`
// Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
// Image refers to a JSON object, which itself indicates the OS image used to
// deploy the server.
Image map[string]interface{} `json:"-"`
// Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server.
// Flavor refers to a JSON object, which itself indicates the hardware
// configuration of the deployed server.
Flavor map[string]interface{} `json:"flavor"`
// Addresses includes a list of all IP addresses assigned to the server, keyed by pool.
// Addresses includes a list of all IP addresses assigned to the server,
// keyed by pool.
Addresses map[string]interface{} `json:"addresses"`
// Metadata includes a list of all user-specified key-value pairs attached to the server.
// Metadata includes a list of all user-specified key-value pairs attached
// to the server.
Metadata map[string]string `json:"metadata"`
// Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference.
// Links includes HTTP references to the itself, useful for passing along to
// other APIs that might want a server reference.
Links []interface{} `json:"links"`
// KeyName indicates which public key was injected into the server on launch.
KeyName string `json:"key_name"`
// AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place.
// AdminPass will generally be empty (""). However, it will contain the
// administrative password chosen when provisioning a new server without a
// set AdminPass setting in the first place.
// Note that this is the ONLY time this field will be valid.
AdminPass string `json:"adminPass"`
// SecurityGroups includes the security groups that this instance has applied to it
// SecurityGroups includes the security groups that this instance has applied
// to it.
SecurityGroups []map[string]interface{} `json:"security_groups"`
}
@ -200,9 +239,10 @@ func (r *Server) UnmarshalJSON(b []byte) error {
return err
}
// ServerPage 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 ExtractServers call.
// ServerPage 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 ExtractServers call.
type ServerPage struct {
pagination.LinkedPageBase
}
@ -213,7 +253,8 @@ func (r ServerPage) IsEmpty() (bool, error) {
return len(s) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
// NextPageURL uses the response's embedded link reference to navigate to the
// next page of results.
func (r ServerPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"servers_links"`
@ -225,49 +266,59 @@ func (r ServerPage) NextPageURL() (string, error) {
return gophercloud.ExtractNextURL(s.Links)
}
// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities.
// ExtractServers interprets the results of a single page from a List() call,
// producing a slice of Server entities.
func ExtractServers(r pagination.Page) ([]Server, error) {
var s []Server
err := ExtractServersInto(r, &s)
return s, err
}
// MetadataResult contains the result of a call for (potentially) multiple key-value pairs.
// MetadataResult contains the result of a call for (potentially) multiple
// key-value pairs. Call its Extract method to interpret it as a
// map[string]interface.
type MetadataResult struct {
gophercloud.Result
}
// GetMetadataResult temporarily contains the response from a metadata Get call.
// GetMetadataResult contains the result of a Get operation. Call its Extract
// method to interpret it as a map[string]interface.
type GetMetadataResult struct {
MetadataResult
}
// ResetMetadataResult temporarily contains the response from a metadata Reset call.
// ResetMetadataResult contains the result of a Reset operation. Call its
// Extract method to interpret it as a map[string]interface.
type ResetMetadataResult struct {
MetadataResult
}
// UpdateMetadataResult temporarily contains the response from a metadata Update call.
// UpdateMetadataResult contains the result of an Update operation. Call its
// Extract method to interpret it as a map[string]interface.
type UpdateMetadataResult struct {
MetadataResult
}
// MetadatumResult contains the result of a call for individual a single key-value pair.
// MetadatumResult contains the result of a call for individual a single
// key-value pair.
type MetadatumResult struct {
gophercloud.Result
}
// GetMetadatumResult temporarily contains the response from a metadatum Get call.
// GetMetadatumResult contains the result of a Get operation. Call its Extract
// method to interpret it as a map[string]interface.
type GetMetadatumResult struct {
MetadatumResult
}
// CreateMetadatumResult temporarily contains the response from a metadatum Create call.
// CreateMetadatumResult contains the result of a Create operation. Call its
// Extract method to interpret it as a map[string]interface.
type CreateMetadatumResult struct {
MetadatumResult
}
// DeleteMetadatumResult temporarily contains the response from a metadatum Delete call.
// DeleteMetadatumResult contains the result of a Delete operation. Call its
// ExtractErr method to determine if the call succeeded or failed.
type DeleteMetadatumResult struct {
gophercloud.ErrResult
}
@ -296,9 +347,10 @@ type Address struct {
Address string `json:"addr"`
}
// AddressPage abstracts the raw results of making a ListAddresses() 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 ExtractAddresses call.
// AddressPage abstracts the raw results of making a ListAddresses() 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 ExtractAddresses call.
type AddressPage struct {
pagination.SinglePageBase
}
@ -309,8 +361,8 @@ func (r AddressPage) IsEmpty() (bool, error) {
return len(addresses) == 0, err
}
// ExtractAddresses interprets the results of a single page from a ListAddresses() call,
// producing a map of addresses.
// ExtractAddresses interprets the results of a single page from a
// ListAddresses() call, producing a map of addresses.
func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
var s struct {
Addresses map[string][]Address `json:"addresses"`
@ -319,9 +371,11 @@ func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
return s.Addresses, err
}
// NetworkAddressPage abstracts the raw results of making a ListAddressesByNetwork() 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 ExtractAddresses call.
// NetworkAddressPage abstracts the raw results of making a
// ListAddressesByNetwork() 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 ExtractAddresses call.
type NetworkAddressPage struct {
pagination.SinglePageBase
}
@ -332,8 +386,8 @@ func (r NetworkAddressPage) IsEmpty() (bool, error) {
return len(addresses) == 0, err
}
// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call,
// producing a slice of addresses.
// ExtractNetworkAddresses interprets the results of a single page from a
// ListAddressesByNetwork() call, producing a slice of addresses.
func ExtractNetworkAddresses(r pagination.Page) ([]Address, error) {
var s map[string][]Address
err := (r.(NetworkAddressPage)).ExtractInto(&s)

View File

@ -2,8 +2,9 @@ package servers
import "github.com/gophercloud/gophercloud"
// WaitForStatus will continually poll a server until it successfully transitions to a specified
// status. It will do this for at most the number of seconds specified.
// WaitForStatus will continually poll a server until it successfully
// transitions to a specified status. It will do this for at most the number
// of seconds specified.
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
return gophercloud.WaitFor(secs, func() (bool, error) {
current, err := Get(c, id).Extract()

View File

@ -0,0 +1,14 @@
/*
Package openstack contains resources for the individual OpenStack projects
supported in Gophercloud. It also includes functions to authenticate to an
OpenStack cloud and for provisioning various service-level clients.
Example of Creating a Service Client
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(ao)
client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
*/
package openstack

View File

@ -6,12 +6,16 @@ import (
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
)
// V2EndpointURL discovers the endpoint URL for a specific service from a ServiceCatalog acquired
// during the v2 identity service. The specified EndpointOpts are used to identify a unique,
// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided
// criteria and when none do. The minimum that can be specified is a Type, but you will also often
// need to specify a Name and/or a Region depending on what's available on your OpenStack
// deployment.
/*
V2EndpointURL discovers the endpoint URL for a specific service from a
ServiceCatalog acquired during the v2 identity service.
The specified EndpointOpts are used to identify a unique, unambiguous endpoint
to return. It's an error both when multiple endpoints match the provided
criteria and when none do. The minimum that can be specified is a Type, but you
will also often need to specify a Name and/or a Region depending on what's
available on your OpenStack deployment.
*/
func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
// Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided.
var endpoints = make([]tokens2.Endpoint, 0, 1)
@ -54,12 +58,16 @@ func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpt
return "", err
}
// V3EndpointURL discovers the endpoint URL for a specific service from a Catalog acquired
// during the v3 identity service. The specified EndpointOpts are used to identify a unique,
// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided
// criteria and when none do. The minimum that can be specified is a Type, but you will also often
// need to specify a Name and/or a Region depending on what's available on your OpenStack
// deployment.
/*
V3EndpointURL discovers the endpoint URL for a specific service from a Catalog
acquired during the v3 identity service.
The specified EndpointOpts are used to identify a unique, unambiguous endpoint
to return. It's an error both when multiple endpoints match the provided
criteria and when none do. The minimum that can be specified is a Type, but you
will also often need to specify a Name and/or a Region depending on what's
available on your OpenStack deployment.
*/
func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
// Extract Endpoints from the catalog entries that match the requested Type, Interface,
// Name if provided, and Region if provided.

View File

@ -1,7 +1,65 @@
// Package tenants provides information and interaction with the
// tenants API resource for the OpenStack Identity service.
//
// See http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
// and http://developer.openstack.org/api-ref-identity-v2.html#admin-tenants
// for more information.
/*
Package tenants provides information and interaction with the
tenants API resource for the OpenStack Identity service.
See http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
and http://developer.openstack.org/api-ref-identity-v2.html#admin-tenants
for more information.
Example to List Tenants
listOpts := tenants.ListOpts{
Limit: 2,
}
allPages, err := tenants.List(identityClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allTenants, err := tenants.ExtractTenants(allPages)
if err != nil {
panic(err)
}
for _, tenant := range allTenants {
fmt.Printf("%+v\n", tenant)
}
Example to Create a Tenant
createOpts := tenants.CreateOpts{
Name: "tenant_name",
Description: "this is a tenant",
Enabled: gophercloud.Enabled,
}
tenant, err := tenants.Create(identityClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Tenant
tenantID := "e6db6ed6277c461a853458589063b295"
updateOpts := tenants.UpdateOpts{
Description: "this is a new description",
Enabled: gophercloud.Disabled,
}
tenant, err := tenants.Update(identityClient, tenantID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Tenant
tenantID := "e6db6ed6277c461a853458589063b295"
err := tenants.Delete(identitYClient, tenantID).ExtractErr()
if err != nil {
panic(err)
}
*/
package tenants

View File

@ -9,6 +9,7 @@ import (
type ListOpts struct {
// Marker is the ID of the last Tenant on the previous page.
Marker string `q:"marker"`
// Limit specifies the page size.
Limit int `q:"limit"`
}
@ -32,18 +33,22 @@ func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager {
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.
// CreateOptsBuilder enables extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToTenantCreateMap() (map[string]interface{}, error)
}
// ToTenantCreateMap assembles a request body based on the contents of a CreateOpts.
// 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")
}
@ -67,17 +72,21 @@ func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
// UpdateOptsBuilder allows extensions to add additional parameters 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.
// UpdateOpts specifies the base attributes that may be updated on an existing
// tenant.
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"`
}
@ -100,7 +109,7 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
return
}
// Delete is the operation responsible for permanently deleting an API tenant.
// Delete is the operation responsible for permanently deleting a tenant.
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = client.Delete(deleteURL(client, id), nil)
return

View File

@ -43,7 +43,8 @@ func (r TenantPage) NextPageURL() (string, error) {
return gophercloud.ExtractNextURL(s.Links)
}
// ExtractTenants returns a slice of Tenants contained in a single page of results.
// ExtractTenants returns a slice of Tenants contained in a single page of
// results.
func ExtractTenants(r pagination.Page) ([]Tenant, error) {
var s struct {
Tenants []Tenant `json:"tenants"`
@ -56,7 +57,7 @@ type tenantResult struct {
gophercloud.Result
}
// Extract interprets any tenantResults as a tenant.
// Extract interprets any tenantResults as a Tenant.
func (r tenantResult) Extract() (*Tenant, error) {
var s struct {
Tenant *Tenant `json:"tenant"`
@ -65,22 +66,26 @@ func (r tenantResult) Extract() (*Tenant, error) {
return s.Tenant, err
}
// GetResult temporarily contains the response from the Get call.
// GetResult is the response from a Get request. Call its Extract method to
// interpret it as a Tenant.
type GetResult struct {
tenantResult
}
// CreateResult temporarily contains the reponse from the Create call.
// CreateResult is the response from a Create request. Call its Extract method
// to interpret it as a Tenant.
type CreateResult struct {
tenantResult
}
// DeleteResult temporarily contains the response from the Delete call.
// DeleteResult is the response from a Get request. Call its ExtractErr method
// to determine if the call succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
// UpdateResult temporarily contains the response from the Update call.
// UpdateResult is the response from a Update request. Call its Extract method
// to interpret it as a Tenant.
type UpdateResult struct {
tenantResult
}

View File

@ -1,5 +1,46 @@
// Package tokens provides information and interaction with the token API
// resource for the OpenStack Identity service.
// For more information, see:
// http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
/*
Package tokens provides information and interaction with the token API
resource for the OpenStack Identity service.
For more information, see:
http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
Example to Create an Unscoped Token from a Password
authOpts := gophercloud.AuthOptions{
Username: "user",
Password: "pass"
}
token, err := tokens.Create(identityClient, authOpts).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token from a Tenant ID and Password
authOpts := gophercloud.AuthOptions{
Username: "user",
Password: "password",
TenantID: "fc394f2ab2df4114bde39905f800dc57"
}
token, err := tokens.Create(identityClient, authOpts).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token from a Tenant Name and Password
authOpts := gophercloud.AuthOptions{
Username: "user",
Password: "password",
TenantName: "tenantname"
}
token, err := tokens.Create(identityClient, authOpts).ExtractToken()
if err != nil {
panic(err)
}
*/
package tokens

View File

@ -2,17 +2,21 @@ package tokens
import "github.com/gophercloud/gophercloud"
// PasswordCredentialsV2 represents the required options to authenticate
// with a username and password.
type PasswordCredentialsV2 struct {
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
}
// TokenCredentialsV2 represents the required options to authenticate
// with a token.
type TokenCredentialsV2 struct {
ID string `json:"id,omitempty" required:"true"`
}
// AuthOptionsV2 wraps a gophercloud AuthOptions in order to adhere to the AuthOptionsBuilder
// interface.
// AuthOptionsV2 wraps a gophercloud AuthOptions in order to adhere to the
// AuthOptionsBuilder interface.
type AuthOptionsV2 struct {
PasswordCredentials *PasswordCredentialsV2 `json:"passwordCredentials,omitempty" xor:"TokenCredentials"`
@ -23,15 +27,16 @@ type AuthOptionsV2 struct {
TenantID string `json:"tenantId,omitempty"`
TenantName string `json:"tenantName,omitempty"`
// TokenCredentials allows users to authenticate (possibly as another user) with an
// authentication token ID.
// TokenCredentials allows users to authenticate (possibly as another user)
// with an authentication token ID.
TokenCredentials *TokenCredentialsV2 `json:"token,omitempty" xor:"PasswordCredentials"`
}
// AuthOptionsBuilder describes any argument that may be passed to the Create call.
// AuthOptionsBuilder allows extensions to add additional parameters to the
// token create request.
type AuthOptionsBuilder interface {
// ToTokenCreateMap assembles the Create request body, returning an error if parameters are
// missing or inconsistent.
// ToTokenCreateMap assembles the Create request body, returning an error
// if parameters are missing or inconsistent.
ToTokenV2CreateMap() (map[string]interface{}, error)
}
@ -47,8 +52,7 @@ type AuthOptions struct {
TokenID string
}
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
// interface in the v2 tokens package
// ToTokenV2CreateMap builds a token request body from the given AuthOptions.
func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
v2Opts := AuthOptionsV2{
TenantID: opts.TenantID,
@ -74,9 +78,9 @@ func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
}
// Create authenticates to the identity service and attempts to acquire a Token.
// If successful, the CreateResult
// Generally, rather than interact with this call directly, end users should call openstack.AuthenticatedClient(),
// which abstracts all of the gory details about navigating service catalogs and such.
// Generally, rather than interact with this call directly, end users should
// call openstack.AuthenticatedClient(), which abstracts all of the gory details
// about navigating service catalogs and such.
func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) (r CreateResult) {
b, err := auth.ToTokenV2CreateMap()
if err != nil {

View File

@ -7,20 +7,24 @@ import (
"github.com/gophercloud/gophercloud/openstack/identity/v2/tenants"
)
// Token provides only the most basic information related to an authentication token.
// Token provides only the most basic information related to an authentication
// token.
type Token struct {
// ID provides the primary means of identifying a user to the OpenStack API.
// OpenStack defines this field as an opaque value, so do not depend on its content.
// It is safe, however, to compare for equality.
// OpenStack defines this field as an opaque value, so do not depend on its
// content. It is safe, however, to compare for equality.
ID string
// ExpiresAt provides a timestamp in ISO 8601 format, indicating when the authentication token becomes invalid.
// After this point in time, future API requests made using this authentication token will respond with errors.
// Either the caller will need to reauthenticate manually, or more preferably, the caller should exploit automatic re-authentication.
// ExpiresAt provides a timestamp in ISO 8601 format, indicating when the
// authentication token becomes invalid. After this point in time, future
// API requests made using this authentication token will respond with
// errors. Either the caller will need to reauthenticate manually, or more
// preferably, the caller should exploit automatic re-authentication.
// See the AuthOptions structure for more details.
ExpiresAt time.Time
// Tenant provides information about the tenant to which this token grants access.
// Tenant provides information about the tenant to which this token grants
// access.
Tenant tenants.Tenant
}
@ -38,13 +42,17 @@ type User struct {
}
// Endpoint represents a single API endpoint offered by a service.
// It provides the public and internal URLs, if supported, along with a region specifier, again if provided.
// It provides the public and internal URLs, if supported, along with a region
// specifier, again if provided.
//
// The significance of the Region field will depend upon your provider.
//
// In addition, the interface offered by the service will have version information associated with it
// through the VersionId, VersionInfo, and VersionList fields, if provided or supported.
// In addition, the interface offered by the service will have version
// information associated with it through the VersionId, VersionInfo, and
// VersionList fields, if provided or supported.
//
// In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
// In all cases, fields which aren't supported by the provider and service
// combined will assume a zero-value ("").
type Endpoint struct {
TenantID string `json:"tenantId"`
PublicURL string `json:"publicURL"`
@ -56,38 +64,44 @@ type Endpoint struct {
VersionList string `json:"versionList"`
}
// CatalogEntry provides a type-safe interface to an Identity API V2 service catalog listing.
// Each class of service, such as cloud DNS or block storage services, will have a single
// CatalogEntry representing it.
// CatalogEntry provides a type-safe interface to an Identity API V2 service
// catalog listing.
//
// Note: when looking for the desired service, try, whenever possible, to key off the type field.
// Otherwise, you'll tie the representation of the service to a specific provider.
// Each class of service, such as cloud DNS or block storage services, will have
// a single CatalogEntry representing it.
//
// Note: when looking for the desired service, try, whenever possible, to key
// off the type field. Otherwise, you'll tie the representation of the service
// to a specific provider.
type CatalogEntry struct {
// Name will contain the provider-specified name for the service.
Name string `json:"name"`
// Type will contain a type string if OpenStack defines a type for the service.
// Otherwise, for provider-specific services, the provider may assign their own type strings.
// Type will contain a type string if OpenStack defines a type for the
// service. Otherwise, for provider-specific services, the provider may assign
// their own type strings.
Type string `json:"type"`
// Endpoints will let the caller iterate over all the different endpoints that may exist for
// the service.
// Endpoints will let the caller iterate over all the different endpoints that
// may exist for the service.
Endpoints []Endpoint `json:"endpoints"`
}
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
// ServiceCatalog provides a view into the service catalog from a previous,
// successful authentication.
type ServiceCatalog struct {
Entries []CatalogEntry
}
// 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.
// CreateResult is the response from a Create request. Use ExtractToken() to
// interpret it as a Token, or ExtractServiceCatalog() to interpret it as a
// service catalog.
type CreateResult struct {
gophercloud.Result
}
// GetResult is the deferred response from a Get call, which is the same with a Created token.
// Use ExtractUser() to interpret it as a User.
// GetResult is the deferred response from a Get call, which is the same with a
// Created token. Use ExtractUser() to interpret it as a User.
type GetResult struct {
CreateResult
}
@ -121,7 +135,8 @@ func (r CreateResult) ExtractToken() (*Token, error) {
}, nil
}
// 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) {
var s struct {
Access struct {

View File

@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"requests.go",
"results.go",
],

View File

@ -0,0 +1,26 @@
/*
Package trusts enables management of OpenStack Identity Trusts.
Example to Create a Token with Username, Password, and Trust ID
var trustToken struct {
tokens.Token
trusts.TokenExt
}
authOptions := tokens.AuthOptions{
UserID: "username",
Password: "password",
}
createOpts := trusts.AuthOptsExt{
AuthOptionsBuilder: authOptions,
TrustID: "de0945a",
}
err := tokens.Create(identityClient, createOpts).ExtractInto(&trustToken)
if err != nil {
panic(err)
}
*/
package trusts

View File

@ -2,15 +2,20 @@ package trusts
import "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
// AuthOptsExt extends the base Identity v3 tokens AuthOpts with a TrustID.
type AuthOptsExt struct {
tokens.AuthOptionsBuilder
// TrustID is the ID of the trust.
TrustID string `json:"id"`
}
// ToTokenV3CreateMap builds a create request body from the AuthOpts.
func (opts AuthOptsExt) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
return opts.AuthOptionsBuilder.ToTokenV3CreateMap(scope)
}
// ToTokenV3ScopeMap builds a scope from AuthOpts.
func (opts AuthOptsExt) ToTokenV3ScopeMap() (map[string]interface{}, error) {
b, err := opts.AuthOptionsBuilder.ToTokenV3ScopeMap()
if err != nil {

View File

@ -1,13 +1,17 @@
package trusts
// TrusteeUser represents the trusted user ID of a trust.
type TrusteeUser struct {
ID string `json:"id"`
}
// TrustorUser represents the trusting user ID of a trust.
type TrustorUser struct {
ID string `json:"id"`
}
// Trust represents a delegated authorization request between two
// identities.
type Trust struct {
ID string `json:"id"`
Impersonation bool `json:"impersonation"`
@ -17,6 +21,7 @@ type Trust struct {
RedelegationCount int `json:"redelegation_count"`
}
// TokenExt represents an extension of the base token result.
type TokenExt struct {
Trust Trust `json:"OS-TRUST:trust"`
}

View File

@ -1,6 +1,108 @@
// Package tokens provides information and interaction with the token API
// resource for the OpenStack Identity service.
//
// For more information, see:
// http://developer.openstack.org/api-ref-identity-v3.html#tokens-v3
/*
Package tokens provides information and interaction with the token API
resource for the OpenStack Identity service.
For more information, see:
http://developer.openstack.org/api-ref-identity-v3.html#tokens-v3
Example to Create a Token From a Username and Password
authOptions := tokens.AuthOptions{
UserID: "username",
Password: "password",
}
token, err := tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token From a Username, Password, and Domain
authOptions := tokens.AuthOptions{
UserID: "username",
Password: "password",
DomainID: "default",
}
token, err := tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
authOptions = tokens.AuthOptions{
UserID: "username",
Password: "password",
DomainName: "default",
}
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token From a Token
authOptions := tokens.AuthOptions{
TokenID: "token_id",
}
token, err := tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token from a Username and Password with Project ID Scope
scope := tokens.Scope{
ProjectID: "0fe36e73809d46aeae6705c39077b1b3",
}
authOptions := tokens.AuthOptions{
Scope: &scope,
UserID: "username",
Password: "password",
}
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token from a Username and Password with Domain ID Scope
scope := tokens.Scope{
DomainID: "default",
}
authOptions := tokens.AuthOptions{
Scope: &scope,
UserID: "username",
Password: "password",
}
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
Example to Create a Token from a Username and Password with Project Name Scope
scope := tokens.Scope{
ProjectName: "project_name",
DomainID: "default",
}
authOptions := tokens.AuthOptions{
Scope: &scope,
UserID: "username",
Password: "password",
}
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
if err != nil {
panic(err)
}
*/
package tokens

View File

@ -10,20 +10,22 @@ type Scope struct {
DomainName string
}
// AuthOptionsBuilder describes any argument that may be passed to the Create call.
// AuthOptionsBuilder provides the ability for extensions to add additional
// parameters to AuthOptions. Extensions must satisfy all required methods.
type AuthOptionsBuilder interface {
// ToTokenV3CreateMap assembles the Create request body, returning an error if parameters are
// missing or inconsistent.
// ToTokenV3CreateMap assembles the Create request body, returning an error
// if parameters are missing or inconsistent.
ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error)
ToTokenV3ScopeMap() (map[string]interface{}, error)
CanReauth() bool
}
// AuthOptions represents options for authenticating a user.
type AuthOptions struct {
// IdentityEndpoint specifies the HTTP endpoint that is required to work with
// the Identity API of the appropriate version. While it's ultimately needed by
// all of the identity services, it will often be populated by a provider-level
// function.
// the Identity API of the appropriate version. While it's ultimately needed
// by all of the identity services, it will often be populated by a
// provider-level function.
IdentityEndpoint string `json:"-"`
// Username is required if using Identity V2 API. Consult with your provider's
@ -39,11 +41,11 @@ type AuthOptions struct {
DomainID string `json:"-"`
DomainName string `json:"name,omitempty"`
// AllowReauth should be set to true if you grant permission for Gophercloud to
// cache your credentials in memory, and to allow Gophercloud to attempt to
// re-authenticate automatically if/when your token expires. If you set it to
// false, it will not cache these settings, but re-authentication will not be
// possible. This setting defaults to false.
// AllowReauth should be set to true if you grant permission for Gophercloud
// to cache your credentials in memory, and to allow Gophercloud to attempt
// to re-authenticate automatically if/when your token expires. If you set
// it to false, it will not cache these settings, but re-authentication will
// not be possible. This setting defaults to false.
AllowReauth bool `json:"-"`
// TokenID allows users to authenticate (possibly as another user) with an
@ -53,6 +55,7 @@ type AuthOptions struct {
Scope Scope `json:"-"`
}
// ToTokenV3CreateMap builds a request body from AuthOptions.
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
gophercloudAuthOpts := gophercloud.AuthOptions{
Username: opts.Username,
@ -67,6 +70,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
}
// ToTokenV3CreateMap builds a scope request body from AuthOptions.
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
if opts.Scope.ProjectName != "" {
// ProjectName provided: either DomainID or DomainName must also be supplied.
@ -125,7 +129,12 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
},
}, nil
} else if opts.Scope.DomainName != "" {
return nil, gophercloud.ErrScopeDomainName{}
// DomainName
return map[string]interface{}{
"domain": map[string]interface{}{
"name": &opts.Scope.DomainName,
},
}, nil
}
return nil, nil
@ -141,7 +150,8 @@ func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[
}
}
// Create authenticates and either generates a new token, or changes the Scope of an existing token.
// Create authenticates and either generates a new token, or changes the Scope
// of an existing token.
func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResult) {
scope, err := opts.ToTokenV3ScopeMap()
if err != nil {

View File

@ -17,37 +17,45 @@ type Endpoint struct {
URL string `json:"url"`
}
// CatalogEntry provides a type-safe interface to an Identity API V3 service catalog listing.
// Each class of service, such as cloud DNS or block storage services, could have multiple
// CatalogEntry representing it (one by interface type, e.g public, admin or internal).
// CatalogEntry provides a type-safe interface to an Identity API V3 service
// catalog listing. Each class of service, such as cloud DNS or block storage
// services, could have multiple CatalogEntry representing it (one by interface
// type, e.g public, admin or internal).
//
// Note: when looking for the desired service, try, whenever possible, to key off the type field.
// Otherwise, you'll tie the representation of the service to a specific provider.
// Note: when looking for the desired service, try, whenever possible, to key
// off the type field. Otherwise, you'll tie the representation of the service
// to a specific provider.
type CatalogEntry struct {
// Service ID
ID string `json:"id"`
// Name will contain the provider-specified name for the service.
Name string `json:"name"`
// Type will contain a type string if OpenStack defines a type for the service.
// Otherwise, for provider-specific services, the provider may assign their own type strings.
// Type will contain a type string if OpenStack defines a type for the
// service. Otherwise, for provider-specific services, the provider may
// assign their own type strings.
Type string `json:"type"`
// Endpoints will let the caller iterate over all the different endpoints that may exist for
// the service.
// Endpoints will let the caller iterate over all the different endpoints that
// may exist for the service.
Endpoints []Endpoint `json:"endpoints"`
}
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
// ServiceCatalog provides a view into the service catalog from a previous,
// successful authentication.
type ServiceCatalog struct {
Entries []CatalogEntry `json:"catalog"`
}
// Domain provides information about the domain to which this token grants access.
// 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.
// User represents a user resource that exists in the Identity Service.
type User struct {
Domain Domain `json:"domain"`
ID string `json:"id"`
@ -67,7 +75,8 @@ type Project struct {
Name string `json:"name"`
}
// commonResult is the deferred result of a Create or a Get call.
// commonResult is the response from a request. A commonResult has various
// methods which can be used to extract different details about the result.
type commonResult struct {
gophercloud.Result
}
@ -92,7 +101,8 @@ func (r commonResult) ExtractToken() (*Token, error) {
return &s, err
}
// 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 commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
var s ServiceCatalog
err := r.ExtractInto(&s)
@ -126,27 +136,31 @@ func (r commonResult) ExtractProject() (*Project, error) {
return s.Project, err
}
// 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.
// CreateResult is the response from a Create request. Use ExtractToken()
// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
// as a service catalog.
type CreateResult struct {
commonResult
}
// GetResult is the deferred response from a Get call.
// GetResult is the response from a Get request. Use ExtractToken()
// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
// as a service catalog.
type GetResult struct {
commonResult
}
// RevokeResult is the deferred response from a Revoke call.
// RevokeResult is response from a Revoke request.
type RevokeResult struct {
commonResult
}
// Token is a string that grants a user access to a controlled set of services in an OpenStack provider.
// Each Token is valid for a set length of time.
// Token is a string that grants a user access to a controlled set of services
// in an OpenStack provider. Each Token is valid for a set length of time.
type Token struct {
// ID is the issued token.
ID string `json:"id"`
// ExpiresAt is the timestamp at which this token will no longer be accepted.
ExpiresAt time.Time `json:"expires_at"`
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,71 @@
/*
package floatingips enables management and retrieval of Floating IPs from the
OpenStack Networking service.
Example to List Floating IPs
listOpts := floatingips.ListOpts{
FloatingNetworkID: "a6917946-38ab-4ffd-a55a-26c0980ce5ee",
}
allPages, err := floatingips.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allFIPs, err := floatingips.ExtractFloatingIPs(allPages)
if err != nil {
panic(err)
}
for _, fip := range allFIPs {
fmt.Printf("%+v\n", fip)
}
Example to Create a Floating IP
createOpts := floatingips.CreateOpts{
FloatingNetworkID: "a6917946-38ab-4ffd-a55a-26c0980ce5ee",
}
fip, err := floatingips.Create(networkingClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Floating IP
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
portID := "76d0a61b-b8e5-490c-9892-4cf674f2bec8"
updateOpts := floatingips.UpdateOpts{
PortID: &portID,
}
fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Disassociate a Floating IP with a Port
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
updateOpts := floatingips.UpdateOpts{
PortID: nil,
}
fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Floating IP
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
err := floatingips.Delete(networkClient, fipID).ExtractErr()
if err != nil {
panic(err)
}
*/
package floatingips

View File

@ -39,8 +39,8 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// CreateOptsBuilder is the interface type must satisfy to be used as Create
// options.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToFloatingIPCreateMap() (map[string]interface{}, error)
}
@ -79,10 +79,10 @@ func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) {
// return 404 error code.
//
// You must also configure an IP address for the port associated with the PortID
// you have provided - this is what the FixedIP refers to: an IP fixed to a port.
// Because a port might be associated with multiple IP addresses, you can use
// the FixedIP field to associate a particular IP address rather than have the
// API assume for you. If you specify an IP address that is not valid, the
// you have provided - this is what the FixedIP refers to: an IP fixed to a
// port. Because a port might be associated with multiple IP addresses, you can
// use the FixedIP field to associate a particular IP address rather than have
// the API assume for you. If you specify an IP address that is not valid, the
// operation will fail and return a 400 error code. If the PortID and FixedIP
// are already associated with another resource, the operation will fail and
// returns a 409 error code.
@ -102,8 +102,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is the interface type must satisfy to be used as Update
// options.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToFloatingIPUpdateMap() (map[string]interface{}, error)
}

View File

@ -12,30 +12,32 @@ import (
// floating IPs can only be defined on networks where the `router:external'
// attribute (provided by the external network extension) is set to True.
type FloatingIP struct {
// Unique identifier for the floating IP instance.
// ID is the unique identifier for the floating IP instance.
ID string `json:"id"`
// UUID of the external network where the floating IP is to be created.
// FloatingNetworkID is the UUID of the external network where the floating
// IP is to be created.
FloatingNetworkID string `json:"floating_network_id"`
// Address of the floating IP on the external network.
// FloatingIP is the address of the floating IP on the external network.
FloatingIP string `json:"floating_ip_address"`
// UUID of the port on an internal network that is associated with the floating IP.
// PortID is the UUID of the port on an internal network that is associated
// with the floating IP.
PortID string `json:"port_id"`
// The specific IP address of the internal port which should be associated
// with the floating IP.
// FixedIP is the specific IP address of the internal port which should be
// associated with the floating IP.
FixedIP string `json:"fixed_ip_address"`
// Owner of the floating IP. Only admin users can specify a tenant identifier
// other than its own.
// TenantID is the Owner of the floating IP. Only admin users can specify a
// tenant identifier other than its own.
TenantID string `json:"tenant_id"`
// The condition of the API resource.
// Status is the condition of the API resource.
Status string `json:"status"`
//The ID of the router used for this Floating-IP
// RouterID is the ID of the router used for this floating IP.
RouterID string `json:"router_id"`
}
@ -43,7 +45,7 @@ type commonResult struct {
gophercloud.Result
}
// Extract a result and extracts a FloatingIP resource.
// Extract will extract a FloatingIP resource from a result.
func (r commonResult) Extract() (*FloatingIP, error) {
var s struct {
FloatingIP *FloatingIP `json:"floatingip"`
@ -52,22 +54,26 @@ func (r commonResult) Extract() (*FloatingIP, error) {
return s.FloatingIP, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a FloatingIP.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a FloatingIP.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a FloatingIP.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of an update operation.
// DeleteResult represents the result of an update operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
@ -78,9 +84,9 @@ type FloatingIPPage struct {
pagination.LinkedPageBase
}
// NextPageURL is invoked when a paginated collection of floating IPs has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
// NextPageURL is invoked when a paginated collection of floating IPs has
// reached the end of a page and the pager seeks to traverse over a new one.
// In order to do this, it needs to construct the next page's URL.
func (r FloatingIPPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"floatingips_links"`
@ -92,15 +98,15 @@ func (r FloatingIPPage) NextPageURL() (string, error) {
return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a NetworkPage struct is empty.
// IsEmpty checks whether a FloatingIPPage struct is empty.
func (r FloatingIPPage) IsEmpty() (bool, error) {
is, err := ExtractFloatingIPs(r)
return len(is) == 0, err
}
// ExtractFloatingIPs accepts a Page struct, specifically a FloatingIPPage struct,
// and extracts the elements into a slice of FloatingIP structs. In other words,
// a generic collection is mapped into a relevant slice.
// ExtractFloatingIPs accepts a Page struct, specifically a FloatingIPPage
// struct, and extracts the elements into a slice of FloatingIP structs. In
// other words, a generic collection is mapped into a relevant slice.
func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) {
var s struct {
FloatingIPs []FloatingIP `json:"floatingips"`

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,108 @@
/*
Package routers enables management and retrieval of Routers from the OpenStack
Networking service.
Example to List Routers
listOpts := routers.ListOpts{}
allPages, err := routers.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allRouters, err := routers.ExtractRouters(allPages)
if err != nil {
panic(err)
}
for _, router := range allRoutes {
fmt.Printf("%+v\n", router)
}
Example to Create a Router
iTrue := true
gwi := routers.GatewayInfo{
NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b",
}
createOpts := routers.CreateOpts{
Name: "router_1",
AdminStateUp: &iTrue,
GatewayInfo: &gwi,
}
router, err := routers.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Router
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
routes := []routers.Route{{
DestinationCIDR: "40.0.1.0/24",
NextHop: "10.1.0.10",
}}
updateOpts := routers.UpdateOpts{
Name: "new_name",
Routes: routes,
}
router, err := routers.Update(networkClient, routerID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Remove all Routes from a Router
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
routes := []routers.Route{}
updateOpts := routers.UpdateOpts{
Routes: routes,
}
router, err := routers.Update(networkClient, routerID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Router
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
err := routers.Delete(networkClient, routerID).ExtractErr()
if err != nil {
panic(err)
}
Example to Add an Interface to a Router
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
intOpts := routers.AddInterfaceOpts{
SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1",
}
interface, err := routers.AddInterface(networkClient, routerID, intOpts).Extract()
if err != nil {
panic(err)
}
Example to Remove an Interface from a Router
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
intOpts := routers.RemoveInterfaceOpts{
SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1",
}
interface, err := routers.RemoveInterface(networkClient, routerID, intOpts).Extract()
if err != nil {
panic(err)
}
*/
package routers

View File

@ -40,10 +40,8 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToRouterCreateMap() (map[string]interface{}, error)
}
@ -58,6 +56,7 @@ type CreateOpts struct {
GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"`
}
// ToRouterCreateMap builds a create request body from CreateOpts.
func (opts CreateOpts) ToRouterCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "router")
}
@ -86,6 +85,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToRouterUpdateMap() (map[string]interface{}, error)
}
@ -99,6 +100,7 @@ type UpdateOpts struct {
Routes []Route `json:"routes"`
}
// ToRouterUpdateMap builds an update body based on UpdateOpts.
func (opts UpdateOpts) ToRouterUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "router")
}
@ -126,21 +128,19 @@ func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
return
}
// AddInterfaceOptsBuilder is what types must satisfy to be used as AddInterface
// options.
// AddInterfaceOptsBuilder allows extensions to add additional parameters to
// the AddInterface request.
type AddInterfaceOptsBuilder interface {
ToRouterAddInterfaceMap() (map[string]interface{}, error)
}
// AddInterfaceOpts allow you to work with operations that either add
// an internal interface from a router.
// AddInterfaceOpts represents the options for adding an interface to a router.
type AddInterfaceOpts struct {
SubnetID string `json:"subnet_id,omitempty" xor:"PortID"`
PortID string `json:"port_id,omitempty" xor:"SubnetID"`
}
// ToRouterAddInterfaceMap allows InterfaceOpts to satisfy the InterfaceOptsBuilder
// interface
// ToRouterAddInterfaceMap builds a request body from AddInterfaceOpts.
func (opts AddInterfaceOpts) ToRouterAddInterfaceMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "")
}
@ -178,21 +178,21 @@ func AddInterface(c *gophercloud.ServiceClient, id string, opts AddInterfaceOpts
return
}
// RemoveInterfaceOptsBuilder is what types must satisfy to be used as RemoveInterface
// options.
// RemoveInterfaceOptsBuilder allows extensions to add additional parameters to
// the RemoveInterface request.
type RemoveInterfaceOptsBuilder interface {
ToRouterRemoveInterfaceMap() (map[string]interface{}, error)
}
// RemoveInterfaceOpts allow you to work with operations that either add or remote
// an internal interface from a router.
// RemoveInterfaceOpts represents options for removing an interface from
// a router.
type RemoveInterfaceOpts struct {
SubnetID string `json:"subnet_id,omitempty" or:"PortID"`
PortID string `json:"port_id,omitempty" or:"SubnetID"`
}
// ToRouterRemoveInterfaceMap allows RemoveInterfaceOpts to satisfy the RemoveInterfaceOptsBuilder
// interface
// ToRouterRemoveInterfaceMap builds a request body based on
// RemoveInterfaceOpts.
func (opts RemoveInterfaceOpts) ToRouterRemoveInterfaceMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "")
}

View File

@ -26,28 +26,30 @@ type Route struct {
// whenever a router is associated with a subnet, a port for that router
// interface is added to the subnet's network.
type Router struct {
// Indicates whether or not a router is currently operational.
// Status indicates whether or not a router is currently operational.
Status string `json:"status"`
// Information on external gateway for the router.
// GateayInfo provides information on external gateway for the router.
GatewayInfo GatewayInfo `json:"external_gateway_info"`
// Administrative state of the router.
// AdminStateUp is the administrative state of the router.
AdminStateUp bool `json:"admin_state_up"`
// Whether router is disitrubted or not..
// Distributed is whether router is disitrubted or not.
Distributed bool `json:"distributed"`
// Human readable name for the router. Does not have to be unique.
// Name is the human readable name for the router. It does not have to be
// unique.
Name string `json:"name"`
// Unique identifier for the router.
// ID is the unique identifier for the router.
ID string `json:"id"`
// Owner of the router. Only admin users can specify a tenant identifier
// other than its own.
// TenantID is the owner of the router. Only admin users can specify a tenant
// identifier other than its own.
TenantID string `json:"tenant_id"`
// Routes are a collection of static routes that the router will host.
Routes []Route `json:"routes"`
}
@ -101,22 +103,26 @@ func (r commonResult) Extract() (*Router, error) {
return s.Router, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Router.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Router.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Router.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its ExtractErr
// method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
@ -125,21 +131,22 @@ type DeleteResult struct {
// mentioned above, in order for a router to forward to a subnet, it needs an
// interface.
type InterfaceInfo struct {
// The ID of the subnet which this interface is associated with.
// SubnetID is the ID of the subnet which this interface is associated with.
SubnetID string `json:"subnet_id"`
// The ID of the port that is a part of the subnet.
// PortID is the ID of the port that is a part of the subnet.
PortID string `json:"port_id"`
// The UUID of the interface.
// ID is the UUID of the interface.
ID string `json:"id"`
// Owner of the interface.
// TenantID is the owner of the interface.
TenantID string `json:"tenant_id"`
}
// InterfaceResult represents the result of interface operations, such as
// AddInterface() and RemoveInterface().
// AddInterface() and RemoveInterface(). Call its Extract method to interpret
// the result as a InterfaceInfo.
type InterfaceResult struct {
gophercloud.Result
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,59 @@
/*
Package members provides information and interaction with Members of the
Load Balancer as a Service extension for the OpenStack Networking service.
Example to List Members
listOpts := members.ListOpts{
ProtocolPort: 80,
}
allPages, err := members.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allMembers, err := members.ExtractMembers(allPages)
if err != nil {
panic(err)
}
for _, member := range allMembers {
fmt.Printf("%+v\n", member)
}
Example to Create a Member
createOpts := members.CreateOpts{
Address: "192.168.2.14",
ProtocolPort: 80,
PoolID: "0b266a12-0fdf-4434-bd11-649d84e54bd5"
}
member, err := members.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Member
memberID := "46592c54-03f7-40ef-9cdf-b1fcf2775ddf"
updateOpts := members.UpdateOpts{
AdminStateUp: gophercloud.Disabled,
}
member, err := members.Update(networkClient, memberID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Member
memberID := "46592c54-03f7-40ef-9cdf-b1fcf2775ddf"
err := members.Delete(networkClient, memberID).ExtractErr()
if err != nil {
panic(err)
}
*/
package members

View File

@ -26,10 +26,10 @@ type ListOpts struct {
}
// List returns a Pager which allows you to iterate over a collection of
// pools. It accepts a ListOpts struct, which allows you to filter and sort
// members. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
//
// Default policy settings return only those pools that are owned by the
// Default policy settings return only those members that are owned by the
// tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
q, err := gophercloud.BuildQueryString(&opts)
@ -42,23 +42,29 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToLBMemberCreateMap() (map[string]interface{}, error)
}
// CreateOpts contains all the values needed to create a new pool member.
type CreateOpts struct {
// The IP address of the member.
// Address is the IP address of the member.
Address string `json:"address" required:"true"`
// The port on which the application is hosted.
// ProtocolPort is the port on which the application is hosted.
ProtocolPort int `json:"protocol_port" required:"true"`
// The pool to which this member will belong.
// PoolID is the pool to which this member will belong.
PoolID string `json:"pool_id" required:"true"`
// Only required if the caller has an admin role and wants to create a pool
// for another tenant.
// TenantID is only required if the caller has an admin role and wants
// to create a pool for another tenant.
TenantID string `json:"tenant_id,omitempty"`
}
// ToLBMemberCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToLBMemberCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "member")
}
@ -81,6 +87,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToLBMemberUpdateMap() (map[string]interface{}, error)
}
@ -91,6 +99,7 @@ type UpdateOpts struct {
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToLBMemberUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToLBMemberUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "member")
}

View File

@ -7,29 +7,30 @@ import (
// Member represents the application running on a backend server.
type Member struct {
// The status of the member. Indicates whether the member is operational.
// Status is the status of the member. Indicates whether the member
// is operational.
Status string
// Weight of member.
// Weight is the weight of member.
Weight int
// The administrative state of the member, which is up (true) or down (false).
// AdminStateUp is the administrative state of the member, which is up
// (true) or down (false).
AdminStateUp bool `json:"admin_state_up"`
// Owner of the member. Only an administrative user can specify a tenant ID
// other than its own.
// TenantID is the owner of the member.
TenantID string `json:"tenant_id"`
// The pool to which the member belongs.
// PoolID is the pool to which the member belongs.
PoolID string `json:"pool_id"`
// The IP address of the member.
// Address is the IP address of the member.
Address string
// The port on which the application is hosted.
// ProtocolPort is the port on which the application is hosted.
ProtocolPort int `json:"protocol_port"`
// The unique ID for the member.
// ID is the unique ID for the member.
ID string
}
@ -74,7 +75,7 @@ type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a router.
// Extract is a function that accepts a result and extracts a member.
func (r commonResult) Extract() (*Member, error) {
var s struct {
Member *Member `json:"member"`
@ -83,22 +84,26 @@ func (r commonResult) Extract() (*Member, error) {
return s.Member, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Member.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Member.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Member.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the result succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,63 @@
/*
Package monitors provides information and interaction with the Monitors
of the Load Balancer as a Service extension for the OpenStack Networking
Service.
Example to List Monitors
listOpts: monitors.ListOpts{
Type: "HTTP",
}
allPages, err := monitors.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allMonitors, err := monitors.ExtractMonitors(allPages)
if err != nil {
panic(err)
}
for _, monitor := range allMonitors {
fmt.Printf("%+v\n", monitor)
}
Example to Create a Monitor
createOpts := monitors.CreateOpts{
Type: "HTTP",
Delay: 20,
Timeout: 20,
MaxRetries: 5,
URLPath: "/check",
ExpectedCodes: "200-299",
}
monitor, err := monitors.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Monitor
monitorID := "681aed03-aadb-43ae-aead-b9016375650a"
updateOpts := monitors.UpdateOpts{
Timeout: 30,
}
monitor, err := monitors.Update(networkClient, monitorID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Member
monitorID := "681aed03-aadb-43ae-aead-b9016375650a"
err := monitors.Delete(networkClient, monitorID).ExtractErr()
if err != nil {
panic(err)
}
*/
package monitors

View File

@ -31,10 +31,10 @@ type ListOpts struct {
}
// List returns a Pager which allows you to iterate over a collection of
// routers. It accepts a ListOpts struct, which allows you to filter and sort
// monitors. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
//
// Default policy settings return only those routers that are owned by the
// Default policy settings return only those monitors that are owned by the
// tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
q, err := gophercloud.BuildQueryString(&opts)
@ -47,7 +47,7 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// MonitorType is the type for all the types of LB monitors
// MonitorType is the type for all the types of LB monitors.
type MonitorType string
// Constants that represent approved monitoring types.
@ -58,42 +58,52 @@ const (
TypeHTTPS MonitorType = "HTTPS"
)
// CreateOptsBuilder is what types must satisfy to be used as Create
// options.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToLBMonitorCreateMap() (map[string]interface{}, error)
}
// CreateOpts contains all the values needed to create a new health monitor.
type CreateOpts struct {
// Required. The type of probe, which is PING, TCP, HTTP, or HTTPS, that is
// sent by the load balancer to verify the member state.
// MonitorType is the type of probe, which is PING, TCP, HTTP, or HTTPS,
// that is sent by the load balancer to verify the member state.
Type MonitorType `json:"type" required:"true"`
// Required. The time, in seconds, between sending probes to members.
// Delay is the time, in seconds, between sending probes to members.
Delay int `json:"delay" required:"true"`
// Required. Maximum number of seconds for a monitor to wait for a ping reply
// before it times out. The value must be less than the delay value.
// Timeout is the maximum number of seconds for a monitor to wait for a ping
// reply before it times out. The value must be less than the delay value.
Timeout int `json:"timeout" required:"true"`
// Required. Number of permissible ping failures before changing the member's
// status to INACTIVE. Must be a number between 1 and 10.
// MaxRetries is the number of permissible ping failures before changing the
// member's status to INACTIVE. Must be a number between 1 and 10.
MaxRetries int `json:"max_retries" required:"true"`
// Required for HTTP(S) types. URI path that will be accessed if monitor type
// is HTTP or HTTPS.
// URLPath is the URI path that will be accessed if monitor type
// is HTTP or HTTPS. Required for HTTP(S) types.
URLPath string `json:"url_path,omitempty"`
// Required for HTTP(S) types. The HTTP method used for requests by the
// monitor. If this attribute is not specified, it defaults to "GET".
// HTTPMethod is the HTTP method used for requests by the monitor. If this
// attribute is not specified, it defaults to "GET". Required for HTTP(S)
// types.
HTTPMethod string `json:"http_method,omitempty"`
// Required for HTTP(S) types. Expected HTTP codes for a passing HTTP(S)
// monitor. You can either specify a single status like "200", or a range
// like "200-202".
// ExpectedCodes is the expected HTTP codes for a passing HTTP(S) monitor
// You can either specify a single status like "200", or a range like
// "200-202". Required for HTTP(S) types.
ExpectedCodes string `json:"expected_codes,omitempty"`
// Required for admins. Indicates the owner of the VIP.
TenantID string `json:"tenant_id,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
// TenantID is only required if the caller has an admin role and wants
// to create a pool for another tenant.
TenantID string `json:"tenant_id,omitempty"`
// AdminStateUp denotes whether the monitor is administratively up or down.
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToLBMonitorCreateMap allows CreateOpts to satisfy the CreateOptsBuilder
// interface
// ToLBMonitorCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToLBMonitorCreateMap() (map[string]interface{}, error) {
if opts.Type == TypeHTTP || opts.Type == TypeHTTPS {
if opts.URLPath == "" {
@ -146,39 +156,45 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is what types must satisfy to be used as Update
// options.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToLBMonitorUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts contains all the values needed to update an existing virtual IP.
// UpdateOpts contains all the values needed to update an existing monitor.
// Attributes not listed here but appear in CreateOpts are immutable and cannot
// be updated.
type UpdateOpts struct {
// The time, in seconds, between sending probes to members.
// Delay is the time, in seconds, between sending probes to members.
Delay int `json:"delay,omitempty"`
// Maximum number of seconds for a monitor to wait for a ping reply
// before it times out. The value must be less than the delay value.
// Timeout is the maximum number of seconds for a monitor to wait for a ping
// reply before it times out. The value must be less than the delay value.
Timeout int `json:"timeout,omitempty"`
// Number of permissible ping failures before changing the member's
// status to INACTIVE. Must be a number between 1 and 10.
// MaxRetries is the number of permissible ping failures before changing the
// member's status to INACTIVE. Must be a number between 1 and 10.
MaxRetries int `json:"max_retries,omitempty"`
// URI path that will be accessed if monitor type
// URLPath is the URI path that will be accessed if monitor type
// is HTTP or HTTPS.
URLPath string `json:"url_path,omitempty"`
// The HTTP method used for requests by the
// monitor. If this attribute is not specified, it defaults to "GET".
// HTTPMethod is the HTTP method used for requests by the monitor. If this
// attribute is not specified, it defaults to "GET".
HTTPMethod string `json:"http_method,omitempty"`
// Expected HTTP codes for a passing HTTP(S)
// monitor. You can either specify a single status like "200", or a range
// like "200-202".
// ExpectedCodes is the expected HTTP codes for a passing HTTP(S) monitor
// You can either specify a single status like "200", or a range like
// "200-202".
ExpectedCodes string `json:"expected_codes,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
// AdminStateUp denotes whether the monitor is administratively up or down.
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToLBMonitorUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder
// interface
// ToLBMonitorUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToLBMonitorUpdateMap() (map[string]interface{}, error) {
if opts.Delay > 0 && opts.Timeout > 0 && opts.Delay < opts.Timeout {
err := gophercloud.ErrInvalidInput{}
@ -190,7 +206,8 @@ func (opts UpdateOpts) ToLBMonitorUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "health_monitor")
}
// Update is an operation which modifies the attributes of the specified monitor.
// Update is an operation which modifies the attributes of the specified
// monitor.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
b, err := opts.ToLBMonitorUpdateMap()
if err != nil {

View File

@ -21,46 +21,47 @@ import (
// won't participate in its pool's load balancing. In other words, ALL monitors
// must declare the member to be healthy for it to stay ACTIVE.
type Monitor struct {
// The unique ID for the VIP.
// ID is the unique ID for the Monitor.
ID string
// Monitor name. Does not have to be unique.
// Name is the monitor name. Does not have to be unique.
Name string
// Owner of the VIP. Only an administrative user can specify a tenant ID
// other than its own.
// TenantID is the owner of the Monitor.
TenantID string `json:"tenant_id"`
// The type of probe sent by the load balancer to verify the member state,
// which is PING, TCP, HTTP, or HTTPS.
// Type is the type of probe sent by the load balancer to verify the member
// state, which is PING, TCP, HTTP, or HTTPS.
Type string
// The time, in seconds, between sending probes to members.
// Delay is the time, in seconds, between sending probes to members.
Delay int
// The maximum number of seconds for a monitor to wait for a connection to be
// established before it times out. This value must be less than the delay value.
// Timeout is the maximum number of seconds for a monitor to wait for a
// connection to be established before it times out. This value must be less
// than the delay value.
Timeout int
// Number of allowed connection failures before changing the status of the
// member to INACTIVE. A valid value is from 1 to 10.
// MaxRetries is the number of allowed connection failures before changing the
// status of the member to INACTIVE. A valid value is from 1 to 10.
MaxRetries int `json:"max_retries"`
// The HTTP method that the monitor uses for requests.
// HTTPMethod is the HTTP method that the monitor uses for requests.
HTTPMethod string `json:"http_method"`
// The HTTP path of the request sent by the monitor to test the health of a
// member. Must be a string beginning with a forward slash (/).
// URLPath is the HTTP path of the request sent by the monitor to test the
// health of a member. Must be a string beginning with a forward slash (/).
URLPath string `json:"url_path"`
// Expected HTTP codes for a passing HTTP(S) monitor.
// ExpectedCodes is the expected HTTP codes for a passing HTTP(S) monitor.
ExpectedCodes string `json:"expected_codes"`
// The administrative state of the health monitor, which is up (true) or down (false).
// AdminStateUp is the administrative state of the health monitor, which is up
// (true) or down (false).
AdminStateUp bool `json:"admin_state_up"`
// The status of the health monitor. Indicates whether the health monitor is
// operational.
// Status is the status of the health monitor. Indicates whether the health
// monitor is operational.
Status string
}
@ -115,22 +116,26 @@ func (r commonResult) Extract() (*Monitor, error) {
return s.Monitor, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Monitor.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Monitor.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Monitor.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its Extract
// method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,81 @@
/*
Package pools provides information and interaction with the Pools of the
Load Balancing as a Service extension for the OpenStack Networking service.
Example to List Pools
listOpts := pools.ListOpts{
SubnetID: "d9bd223b-f1a9-4f98-953b-df977b0f902d",
}
allPages, err := pools.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allPools, err := pools.ExtractPools(allPages)
if err != nil {
panic(err)
}
for _, pool := range allPools {
fmt.Printf("%+v\n", pool)
}
Example to Create a Pool
createOpts := pools.CreateOpts{
LBMethod: pools.LBMethodRoundRobin,
Protocol: "HTTP",
Name: "Example pool",
SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9",
Provider: "haproxy",
}
pool, err := pools.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Pool
poolID := "166db5e6-c72a-4d77-8776-3573e27ae271"
updateOpts := pools.UpdateOpts{
LBMethod: pools.LBMethodLeastConnections,
}
pool, err := pools.Update(networkClient, poolID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Pool
poolID := "166db5e6-c72a-4d77-8776-3573e27ae271"
err := pools.Delete(networkClient, poolID).ExtractErr()
if err != nil {
panic(err)
}
Example to Associate a Monitor to a Pool
poolID := "166db5e6-c72a-4d77-8776-3573e27ae271"
monitorID := "8bbfbe1c-6faa-4d97-abdb-0df6c90df70b"
pool, err := pools.AssociateMonitor(networkClient, poolID, monitorID).Extract()
if err != nil {
panic(err)
}
Example to Disassociate a Monitor from a Pool
poolID := "166db5e6-c72a-4d77-8776-3573e27ae271"
monitorID := "8bbfbe1c-6faa-4d97-abdb-0df6c90df70b"
pool, err := pools.DisassociateMonitor(networkClient, poolID, monitorID).Extract()
if err != nil {
panic(err)
}
*/
package pools

View File

@ -43,10 +43,10 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// LBMethod is a type used for possible load balancing methods
// LBMethod is a type used for possible load balancing methods.
type LBMethod string
// LBProtocol is a type used for possible load balancing protocols
// LBProtocol is a type used for possible load balancing protocols.
type LBProtocol string
// Supported attributes for create/update operations.
@ -59,8 +59,8 @@ const (
ProtocolHTTPS LBProtocol = "HTTPS"
)
// CreateOptsBuilder is the interface types must satisfy to be used as options
// for the Create function
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToLBPoolCreateMap() (map[string]interface{}, error)
}
@ -69,25 +69,29 @@ type CreateOptsBuilder interface {
type CreateOpts struct {
// Name of the pool.
Name string `json:"name" required:"true"`
// The protocol used by the pool members, you can use either
// Protocol used by the pool members, you can use either
// ProtocolTCP, ProtocolHTTP, or ProtocolHTTPS.
Protocol LBProtocol `json:"protocol" required:"true"`
// Only required if the caller has an admin role and wants to create a pool
// for another tenant.
// TenantID is only required if the caller has an admin role and wants
// to create a pool for another tenant.
TenantID string `json:"tenant_id,omitempty"`
// The network on which the members of the pool will be located. Only members
// that are on this network can be added to the pool.
// SubnetID is the network on which the members of the pool will be located.
// Only members that are on this network can be added to the pool.
SubnetID string `json:"subnet_id,omitempty"`
// The algorithm used to distribute load between the members of the pool. The
// current specification supports LBMethodRoundRobin and
// LBMethod is the algorithm used to distribute load between the members of
// the pool. The current specification supports LBMethodRoundRobin and
// LBMethodLeastConnections as valid values for this attribute.
LBMethod LBMethod `json:"lb_method" required:"true"`
// The provider of the pool
// Provider of the pool.
Provider string `json:"provider,omitempty"`
}
// ToLBPoolCreateMap allows CreateOpts to satisfy the CreateOptsBuilder interface
// ToLBPoolCreateMap builds a request body based on CreateOpts.
func (opts CreateOpts) ToLBPoolCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "pool")
}
@ -110,8 +114,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is the interface types must satisfy to be used as options
// for the Update function
// UpdateOptsBuilder allows extensions to add additional parameters ot the
// Update request.
type UpdateOptsBuilder interface {
ToLBPoolUpdateMap() (map[string]interface{}, error)
}
@ -120,13 +124,14 @@ type UpdateOptsBuilder interface {
type UpdateOpts struct {
// Name of the pool.
Name string `json:"name,omitempty"`
// The algorithm used to distribute load between the members of the pool. The
// current specification supports LBMethodRoundRobin and
// LBMethod is the algorithm used to distribute load between the members of
// the pool. The current specification supports LBMethodRoundRobin and
// LBMethodLeastConnections as valid values for this attribute.
LBMethod LBMethod `json:"lb_method,omitempty"`
}
// ToLBPoolUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder interface
// ToLBPoolUpdateMap builds a request body based on UpdateOpts.
func (opts UpdateOpts) ToLBPoolUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "pool")
}

View File

@ -11,47 +11,48 @@ import (
// method to handle the new requests or connections received on the VIP address.
// There is only one pool per virtual IP.
type Pool struct {
// The status of the pool. Indicates whether the pool is operational.
// Status of the pool. Indicates whether the pool is operational.
Status string
// The load-balancer algorithm, which is round-robin, least-connections, and
// so on. This value, which must be supported, is dependent on the provider.
// Round-robin must be supported.
// LBMethod is the load-balancer algorithm, which is round-robin,
// least-connections, and so on. This value, which must be supported, is
// dependent on the provider.
LBMethod string `json:"lb_method"`
// The protocol of the pool, which is TCP, HTTP, or HTTPS.
// Protocol of the pool, which is TCP, HTTP, or HTTPS.
Protocol string
// Description for the pool.
Description string
// The IDs of associated monitors which check the health of the pool members.
// MonitorIDs are the IDs of associated monitors which check the health of
// the pool members.
MonitorIDs []string `json:"health_monitors"`
// The network on which the members of the pool will be located. Only members
// that are on this network can be added to the pool.
// SubnetID is the network on which the members of the pool will be located.
// Only members that are on this network can be added to the pool.
SubnetID string `json:"subnet_id"`
// Owner of the pool. Only an administrative user can specify a tenant ID
// other than its own.
// TenantID is the owner of the pool.
TenantID string `json:"tenant_id"`
// The administrative state of the pool, which is up (true) or down (false).
// AdminStateUp is the administrative state of the pool, which is up
// (true) or down (false).
AdminStateUp bool `json:"admin_state_up"`
// Pool name. Does not have to be unique.
// Name of the pool.
Name string
// List of member IDs that belong to the pool.
// MemberIDs is the list of member IDs that belong to the pool.
MemberIDs []string `json:"members"`
// The unique ID for the pool.
// ID is the unique ID for the pool.
ID string
// The ID of the virtual IP associated with this pool
// VIPID is the ID of the virtual IP associated with this pool.
VIPID string `json:"vip_id"`
// The provider
// The provider.
Provider string
}
@ -81,7 +82,7 @@ func (r PoolPage) IsEmpty() (bool, error) {
return len(is) == 0, err
}
// ExtractPools accepts a Page struct, specifically a RouterPage struct,
// ExtractPools accepts a Page struct, specifically a PoolPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractPools(r pagination.Page) ([]Pool, error) {
@ -105,27 +106,32 @@ func (r commonResult) Extract() (*Pool, error) {
return s.Pool, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Pool.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Pool.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Pool.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to interpret it as a Pool.
type DeleteResult struct {
gophercloud.ErrResult
}
// AssociateResult represents the result of an association operation.
// AssociateResult represents the result of an association operation. Call its Extract
// method to interpret it as a Pool.
type AssociateResult struct {
commonResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,65 @@
/*
Package vips provides information and interaction with the Virtual IPs of the
Load Balancing as a Service extension for the OpenStack Networking service.
Example to List Virtual IPs
listOpts := vips.ListOpts{
SubnetID: "d9bd223b-f1a9-4f98-953b-df977b0f902d",
}
allPages, err := vips.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allVIPs, err := vips.ExtractVIPs(allPages)
if err != nil {
panic(err)
}
for _, vip := range allVIPs {
fmt.Printf("%+v\n", vip)
}
Example to Create a Virtual IP
createOpts := vips.CreateOpts{
Protocol: "HTTP",
Name: "NewVip",
AdminStateUp: gophercloud.Enabled,
SubnetID: "8032909d-47a1-4715-90af-5153ffe39861",
PoolID: "61b1f87a-7a21-4ad3-9dda-7f81d249944f",
ProtocolPort: 80,
Persistence: &vips.SessionPersistence{Type: "SOURCE_IP"},
}
vip, err := vips.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Virtual IP
vipID := "93f1bad4-0423-40a8-afac-3fc541839912"
i1000 := 1000
updateOpts := vips.UpdateOpts{
ConnLimit: &i1000,
Persistence: &vips.SessionPersistence{Type: "SOURCE_IP"},
}
vip, err := vips.Update(networkClient, vipID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Virtual IP
vipID := "93f1bad4-0423-40a8-afac-3fc541839912"
err := vips.Delete(networkClient, vipID).ExtractErr()
if err != nil {
panic(err)
}
*/
package vips

View File

@ -29,10 +29,10 @@ type ListOpts struct {
}
// List returns a Pager which allows you to iterate over a collection of
// routers. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
// Virtual IPs. It accepts a ListOpts struct, which allows you to filter and
// sort the returned collection for greater efficiency.
//
// Default policy settings return only those routers that are owned by the
// Default policy settings return only those virtual IPs that are owned by the
// tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
q, err := gophercloud.BuildQueryString(&opts)
@ -45,43 +45,54 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// CreateOptsBuilder is what types must satisfy to be used as Create
// options.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create Request.
type CreateOptsBuilder interface {
ToVIPCreateMap() (map[string]interface{}, error)
}
// CreateOpts contains all the values needed to create a new virtual IP.
type CreateOpts struct {
// Human-readable name for the VIP. Does not have to be unique.
// Name is the human-readable name for the VIP. Does not have to be unique.
Name string `json:"name" required:"true"`
// The network on which to allocate the VIP's address. A tenant can
// only create VIPs on networks authorized by policy (e.g. networks that
// SubnetID is the network on which to allocate the VIP's address. A tenant
// can only create VIPs on networks authorized by policy (e.g. networks that
// belong to them or networks that are shared).
SubnetID string `json:"subnet_id" required:"true"`
// The protocol - can either be TCP, HTTP or HTTPS.
// Protocol - can either be TCP, HTTP or HTTPS.
Protocol string `json:"protocol" required:"true"`
// The port on which to listen for client traffic.
// ProtocolPort is the port on which to listen for client traffic.
ProtocolPort int `json:"protocol_port" required:"true"`
// The ID of the pool with which the VIP is associated.
// PoolID is the ID of the pool with which the VIP is associated.
PoolID string `json:"pool_id" required:"true"`
// Required for admins. Indicates the owner of the VIP.
// TenantID is only required if the caller has an admin role and wants
// to create a pool for another tenant.
TenantID string `json:"tenant_id,omitempty"`
// The IP address of the VIP.
// Address is the IP address of the VIP.
Address string `json:"address,omitempty"`
// Human-readable description for the VIP.
// Description is the human-readable description for the VIP.
Description string `json:"description,omitempty"`
// Persistence is the the of session persistence to use.
// Omit this field to prevent session persistence.
Persistence *SessionPersistence `json:"session_persistence,omitempty"`
// The maximum number of connections allowed for the VIP.
// ConnLimit is the maximum number of connections allowed for the VIP.
ConnLimit *int `json:"connection_limit,omitempty"`
// The administrative state of the VIP. A valid value is true (UP)
// or false (DOWN).
// AdminStateUp is the administrative state of the VIP. A valid value is
// true (UP) or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToVIPCreateMap allows CreateOpts to satisfy the CreateOptsBuilder
// interface
// ToVIPCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToVIPCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "vip")
}
@ -113,8 +124,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is what types must satisfy to be used as Update
// options.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToVIPUpdateMap() (map[string]interface{}, error)
}
@ -123,22 +134,28 @@ type UpdateOptsBuilder interface {
// Attributes not listed here but appear in CreateOpts are immutable and cannot
// be updated.
type UpdateOpts struct {
// Human-readable name for the VIP. Does not have to be unique.
// Name is the human-readable name for the VIP. Does not have to be unique.
Name *string `json:"name,omitempty"`
// The ID of the pool with which the VIP is associated.
// PoolID is the ID of the pool with which the VIP is associated.
PoolID *string `json:"pool_id,omitempty"`
// Human-readable description for the VIP.
// Description is the human-readable description for the VIP.
Description *string `json:"description,omitempty"`
// Persistence is the the of session persistence to use.
// Omit this field to prevent session persistence.
Persistence *SessionPersistence `json:"session_persistence,omitempty"`
// The maximum number of connections allowed for the VIP.
// ConnLimit is the maximum number of connections allowed for the VIP.
ConnLimit *int `json:"connection_limit,omitempty"`
// The administrative state of the VIP. A valid value is true (UP)
// or false (DOWN).
// AdminStateUp is the administrative state of the VIP. A valid value is
// true (UP) or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToVIPUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder interface
// ToVIPUpdateMap builds a request body based on UpdateOpts.
func (opts UpdateOpts) ToVIPUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "vip")
}

View File

@ -21,10 +21,10 @@ import (
// requests carrying the same cookie value will be handled by the
// same member of the pool.
type SessionPersistence struct {
// The type of persistence mode
// Type is the type of persistence mode.
Type string `json:"type"`
// Name of cookie if persistence mode is set appropriately
// CookieName is the name of cookie if persistence mode is set appropriately.
CookieName string `json:"cookie_name,omitempty"`
}
@ -34,54 +34,55 @@ type SessionPersistence struct {
// This entity is sometimes known in LB products under the name of a "virtual
// server", a "vserver" or a "listener".
type VirtualIP struct {
// The unique ID for the VIP.
// ID is the unique ID for the VIP.
ID string `json:"id"`
// Owner of the VIP. Only an admin user can specify a tenant ID other than its own.
// TenantID is the owner of the VIP.
TenantID string `json:"tenant_id"`
// Human-readable name for the VIP. Does not have to be unique.
// Name is the human-readable name for the VIP. Does not have to be unique.
Name string `json:"name"`
// Human-readable description for the VIP.
// Description is the human-readable description for the VIP.
Description string `json:"description"`
// The ID of the subnet on which to allocate the VIP address.
// SubnetID is the ID of the subnet on which to allocate the VIP address.
SubnetID string `json:"subnet_id"`
// The IP address of the VIP.
// Address is the IP address of the VIP.
Address string `json:"address"`
// The protocol of the VIP address. A valid value is TCP, HTTP, or HTTPS.
// Protocol of the VIP address. A valid value is TCP, HTTP, or HTTPS.
Protocol string `json:"protocol"`
// The port on which to listen to client traffic that is associated with the
// VIP address. A valid value is from 0 to 65535.
// ProtocolPort is the port on which to listen to client traffic that is
// associated with the VIP address. A valid value is from 0 to 65535.
ProtocolPort int `json:"protocol_port"`
// The ID of the pool with which the VIP is associated.
// PoolID is the ID of the pool with which the VIP is associated.
PoolID string `json:"pool_id"`
// The ID of the port which belongs to the load balancer
// PortID is the ID of the port which belongs to the load balancer.
PortID string `json:"port_id"`
// Indicates whether connections in the same session will be processed by the
// same pool member or not.
// Persistence indicates whether connections in the same session will be
// processed by the same pool member or not.
Persistence SessionPersistence `json:"session_persistence"`
// The maximum number of connections allowed for the VIP. Default is -1,
// meaning no limit.
// ConnLimit is the maximum number of connections allowed for the VIP.
// Default is -1, meaning no limit.
ConnLimit int `json:"connection_limit"`
// The administrative state of the VIP. A valid value is true (UP) or false (DOWN).
// AdminStateUp is the administrative state of the VIP. A valid value is
// true (UP) or false (DOWN).
AdminStateUp bool `json:"admin_state_up"`
// The status of the VIP. Indicates whether the VIP is operational.
// Status is the status of the VIP. Indicates whether the VIP is operational.
Status string `json:"status"`
}
// VIPPage is the page returned by a pager when traversing over a
// collection of routers.
// collection of virtual IPs.
type VIPPage struct {
pagination.LinkedPageBase
}
@ -121,7 +122,7 @@ type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a router.
// Extract is a function that accepts a result and extracts a VirtualIP.
func (r commonResult) Extract() (*VirtualIP, error) {
var s struct {
VirtualIP *VirtualIP `json:"vip" json:"vip"`
@ -130,22 +131,26 @@ func (r commonResult) Extract() (*VirtualIP, error) {
return s.VirtualIP, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a VirtualIP
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a VirtualIP
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a VirtualIP
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,63 @@
/*
Package listeners provides information and interaction with Listeners of the
LBaaS v2 extension for the OpenStack Networking service.
Example to List Listeners
listOpts := listeners.ListOpts{
LoadbalancerID : "ca430f80-1737-4712-8dc6-3f640d55594b",
}
allPages, err := listeners.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allListeners, err := listeners.ExtractListeners(allPages)
if err != nil {
panic(err)
}
for _, listener := range allListeners {
fmt.Printf("%+v\n", listener)
}
Example to Create a Listener
createOpts := listeners.CreateOpts{
Protocol: "TCP",
Name: "db",
LoadbalancerID: "79e05663-7f03-45d2-a092-8b94062f22ab",
AdminStateUp: gophercloud.Enabled,
DefaultPoolID: "41efe233-7591-43c5-9cf7-923964759f9e",
ProtocolPort: 3306,
}
listener, err := listeners.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Listener
listenerID := "d67d56a6-4a86-4688-a282-f46444705c64"
i1001 := 1001
updateOpts := listeners.UpdateOpts{
ConnLimit: &i1001,
}
listener, err := listeners.Update(networkClient, listenerID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Listener
listenerID := "d67d56a6-4a86-4688-a282-f46444705c64"
err := listeners.Delete(networkClient, listenerID).ExtractErr()
if err != nil {
panic(err)
}
*/
package listeners

View File

@ -5,6 +5,7 @@ import (
"github.com/gophercloud/gophercloud/pagination"
)
// Type Protocol represents a listener protocol.
type Protocol string
// Supported attributes for create/update operations.
@ -48,10 +49,10 @@ func (opts ListOpts) ToListenerListQuery() (string, error) {
}
// List returns a Pager which allows you to iterate over a collection of
// routers. It accepts a ListOpts struct, which allows you to filter and sort
// listeners. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
//
// Default policy settings return only those routers that are owned by the
// Default policy settings return only those listeners that are owned by the
// tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := rootURL(c)
@ -67,43 +68,51 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
})
}
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToListenerCreateMap() (map[string]interface{}, error)
}
// CreateOpts is the common options struct used in this package's Create
// operation.
// CreateOpts represents options for creating a listener.
type CreateOpts struct {
// The load balancer on which to provision this listener.
LoadbalancerID string `json:"loadbalancer_id" required:"true"`
// The protocol - can either be TCP, HTTP or HTTPS.
Protocol Protocol `json:"protocol" required:"true"`
// The port on which to listen for client traffic.
ProtocolPort int `json:"protocol_port" required:"true"`
// Indicates the owner of the Listener. Required for admins.
// TenantID is only required if the caller has an admin role and wants
// to create a pool for another tenant.
TenantID string `json:"tenant_id,omitempty"`
// Human-readable name for the Listener. Does not have to be unique.
Name string `json:"name,omitempty"`
// The ID of the default pool with which the Listener is associated.
DefaultPoolID string `json:"default_pool_id,omitempty"`
// Human-readable description for the Listener.
Description string `json:"description,omitempty"`
// The maximum number of connections allowed for the Listener.
ConnLimit *int `json:"connection_limit,omitempty"`
// A reference to a container of TLS secrets.
// A reference to a Barbican container of TLS secrets.
DefaultTlsContainerRef string `json:"default_tls_container_ref,omitempty"`
// A list of references to TLS secrets.
SniContainerRefs []string `json:"sni_container_refs,omitempty"`
// The administrative state of the Listener. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToListenerCreateMap casts a CreateOpts struct to a map.
// ToListenerCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToListenerCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "listener")
}
@ -131,38 +140,41 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToListenerUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts is the common options struct used in this package's Update
// operation.
// UpdateOpts represents options for updating a Listener.
type UpdateOpts struct {
// Human-readable name for the Listener. Does not have to be unique.
Name string `json:"name,omitempty"`
// Human-readable description for the Listener.
Description string `json:"description,omitempty"`
// The maximum number of connections allowed for the Listener.
ConnLimit *int `json:"connection_limit,omitempty"`
// A reference to a container of TLS secrets.
// A reference to a Barbican container of TLS secrets.
DefaultTlsContainerRef string `json:"default_tls_container_ref,omitempty"`
// A list of references to TLS secrets.
// A list of references to TLS secrets.
SniContainerRefs []string `json:"sni_container_refs,omitempty"`
// The administrative state of the Listener. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToListenerUpdateMap casts a UpdateOpts struct to a map.
// ToListenerUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToListenerUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "listener")
}
// Update is an operation which modifies the attributes of the specified Listener.
// Update is an operation which modifies the attributes of the specified
// Listener.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) {
b, err := opts.ToListenerUpdateMap()
if err != nil {

View File

@ -16,40 +16,53 @@ type LoadBalancerID struct {
type Listener struct {
// The unique ID for the Listener.
ID string `json:"id"`
// Owner of the Listener. Only an admin user can specify a tenant ID other than its own.
// Owner of the Listener.
TenantID string `json:"tenant_id"`
// Human-readable name for the Listener. Does not have to be unique.
Name string `json:"name"`
// Human-readable description for the Listener.
Description string `json:"description"`
// The protocol to loadbalance. A valid value is TCP, HTTP, or HTTPS.
Protocol string `json:"protocol"`
// The port on which to listen to client traffic that is associated with the
// Loadbalancer. A valid value is from 0 to 65535.
ProtocolPort int `json:"protocol_port"`
// The UUID of default pool. Must have compatible protocol with listener.
DefaultPoolID string `json:"default_pool_id"`
// A list of load balancer IDs.
Loadbalancers []LoadBalancerID `json:"loadbalancers"`
// The maximum number of connections allowed for the Loadbalancer. Default is -1,
// meaning no limit.
// The maximum number of connections allowed for the Loadbalancer.
// Default is -1, meaning no limit.
ConnLimit int `json:"connection_limit"`
// The list of references to TLS secrets.
SniContainerRefs []string `json:"sni_container_refs"`
// Optional. A reference to a container of TLS secrets.
// A reference to a Barbican container of TLS secrets.
DefaultTlsContainerRef string `json:"default_tls_container_ref"`
// The administrative state of the Listener. A valid value is true (UP) or false (DOWN).
AdminStateUp bool `json:"admin_state_up"`
Pools []pools.Pool `json:"pools"`
AdminStateUp bool `json:"admin_state_up"`
// Pools are the pools which are part of this listener.
Pools []pools.Pool `json:"pools"`
}
// ListenerPage is the page returned by a pager when traversing over a
// collection of routers.
// collection of listeners.
type ListenerPage struct {
pagination.LinkedPageBase
}
// NextPageURL is invoked when a paginated collection of routers has reached
// NextPageURL is invoked when a paginated collection of listeners has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
func (r ListenerPage) NextPageURL() (string, error) {
@ -63,7 +76,7 @@ func (r ListenerPage) NextPageURL() (string, error) {
return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a RouterPage struct is empty.
// IsEmpty checks whether a ListenerPage struct is empty.
func (r ListenerPage) IsEmpty() (bool, error) {
is, err := ExtractListeners(r)
return len(is) == 0, err
@ -84,7 +97,7 @@ type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a router.
// Extract is a function that accepts a result and extracts a listener.
func (r commonResult) Extract() (*Listener, error) {
var s struct {
Listener *Listener `json:"listener"`
@ -93,22 +106,26 @@ func (r commonResult) Extract() (*Listener, error) {
return s.Listener, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Listener.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Listener.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Listener.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,71 @@
/*
Package loadbalancers provides information and interaction with Load Balancers
of the LBaaS v2 extension for the OpenStack Networking service.
Example to List Load Balancers
listOpts := loadbalancers.ListOpts{
Provider: "haproxy",
}
allPages, err := loadbalancers.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allLoadbalancers, err := loadbalancers.ExtractLoadBalancers(allPages)
if err != nil {
panic(err)
}
for _, lb := range allLoadbalancers {
fmt.Printf("%+v\n", lb)
}
Example to Create a Load Balancer
createOpts := loadbalancers.CreateOpts{
Name: "db_lb",
AdminStateUp: gophercloud.Enabled,
VipSubnetID: "9cedb85d-0759-4898-8a4b-fa5a5ea10086",
VipAddress: "10.30.176.48",
Flavor: "medium",
Provider: "haproxy",
}
lb, err := loadbalancers.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Load Balancer
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
i1001 := 1001
updateOpts := loadbalancers.UpdateOpts{
Name: "new-name",
}
lb, err := loadbalancers.Update(networkClient, lbID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Load Balancers
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
err := loadbalancers.Delete(networkClient, lbID).ExtractErr()
if err != nil {
panic(err)
}
Example to Get the Status of a Load Balancer
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
status, err := loadbalancers.GetStatuses(networkClient, LBID).Extract()
if err != nil {
panic(err)
}
*/
package loadbalancers

View File

@ -42,11 +42,11 @@ func (opts ListOpts) ToLoadBalancerListQuery() (string, error) {
}
// List returns a Pager which allows you to iterate over a collection of
// routers. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
// load balancers. It accepts a ListOpts struct, which allows you to filter
// and sort the returned collection for greater efficiency.
//
// Default policy settings return only those routers that are owned by the
// tenant who submits the request, unless an admin user submits the request.
// Default policy settings return only those load balancers that are owned by
// the tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := rootURL(c)
if opts != nil {
@ -61,10 +61,8 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
})
}
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToLoadBalancerCreateMap() (map[string]interface{}, error)
}
@ -72,29 +70,36 @@ type CreateOptsBuilder interface {
// CreateOpts is the common options struct used in this package's Create
// operation.
type CreateOpts struct {
// Optional. Human-readable name for the Loadbalancer. Does not have to be unique.
// Human-readable name for the Loadbalancer. Does not have to be unique.
Name string `json:"name,omitempty"`
// Optional. Human-readable description for the Loadbalancer.
// Human-readable description for the Loadbalancer.
Description string `json:"description,omitempty"`
// Required. The network on which to allocate the Loadbalancer's address. A tenant can
// only create Loadbalancers on networks authorized by policy (e.g. networks that
// belong to them or networks that are shared).
// The network on which to allocate the Loadbalancer's address. A tenant can
// only create Loadbalancers on networks authorized by policy (e.g. networks
// that belong to them or networks that are shared).
VipSubnetID string `json:"vip_subnet_id" required:"true"`
// Required for admins. The UUID of the tenant who owns the Loadbalancer.
// Only administrative users can specify a tenant UUID other than their own.
// The UUID of the tenant who owns the Loadbalancer. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// Optional. The IP address of the Loadbalancer.
// The IP address of the Loadbalancer.
VipAddress string `json:"vip_address,omitempty"`
// Optional. The administrative state of the Loadbalancer. A valid value is true (UP)
// The administrative state of the Loadbalancer. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
// Optional. The UUID of a flavor.
// The UUID of a flavor.
Flavor string `json:"flavor,omitempty"`
// Optional. The name of the provider.
// The name of the provider.
Provider string `json:"provider,omitempty"`
}
// ToLoadBalancerCreateMap casts a CreateOpts struct to a map.
// ToLoadBalancerCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToLoadBalancerCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "loadbalancer")
}
@ -103,9 +108,6 @@ func (opts CreateOpts) ToLoadBalancerCreateMap() (map[string]interface{}, error)
// configuration defined in the CreateOpts struct. Once the request is
// validated and progress has started on the provisioning process, a
// CreateResult will be returned.
//
// Users with an admin role can create loadbalancers on behalf of other tenants by
// specifying a TenantID attribute different than their own.
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToLoadBalancerCreateMap()
if err != nil {
@ -122,10 +124,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToLoadBalancerUpdateMap() (map[string]interface{}, error)
}
@ -133,21 +133,24 @@ type UpdateOptsBuilder interface {
// UpdateOpts is the common options struct used in this package's Update
// operation.
type UpdateOpts struct {
// Optional. Human-readable name for the Loadbalancer. Does not have to be unique.
// Human-readable name for the Loadbalancer. Does not have to be unique.
Name string `json:"name,omitempty"`
// Optional. Human-readable description for the Loadbalancer.
// Human-readable description for the Loadbalancer.
Description string `json:"description,omitempty"`
// Optional. The administrative state of the Loadbalancer. A valid value is true (UP)
// The administrative state of the Loadbalancer. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToLoadBalancerUpdateMap casts a UpdateOpts struct to a map.
// ToLoadBalancerUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToLoadBalancerUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "loadbalancer")
}
// Update is an operation which modifies the attributes of the specified LoadBalancer.
// Update is an operation which modifies the attributes of the specified
// LoadBalancer.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) {
b, err := opts.ToLoadBalancerUpdateMap()
if err != nil {
@ -160,12 +163,14 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateR
return
}
// Delete will permanently delete a particular LoadBalancer based on its unique ID.
// Delete will permanently delete a particular LoadBalancer based on its
// unique ID.
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = c.Delete(resourceURL(c, id), nil)
return
}
// GetStatuses will return the status of a particular LoadBalancer.
func GetStatuses(c *gophercloud.ServiceClient, id string) (r GetStatusesResult) {
_, r.Err = c.Get(statusRootURL(c, id), &r.Body, nil)
return

View File

@ -6,50 +6,67 @@ import (
"github.com/gophercloud/gophercloud/pagination"
)
// LoadBalancer is the primary load balancing configuration object that specifies
// the virtual IP address on which client traffic is received, as well
// LoadBalancer is the primary load balancing configuration object that
// specifies the virtual IP address on which client traffic is received, as well
// as other details such as the load balancing method to be use, protocol, etc.
type LoadBalancer struct {
// Human-readable description for the Loadbalancer.
Description string `json:"description"`
// The administrative state of the Loadbalancer. A valid value is true (UP) or false (DOWN).
// The administrative state of the Loadbalancer.
// A valid value is true (UP) or false (DOWN).
AdminStateUp bool `json:"admin_state_up"`
// Owner of the LoadBalancer. Only an admin user can specify a tenant ID other than its own.
// Owner of the LoadBalancer.
TenantID string `json:"tenant_id"`
// The provisioning status of the LoadBalancer. This value is ACTIVE, PENDING_CREATE or ERROR.
// The provisioning status of the LoadBalancer.
// This value is ACTIVE, PENDING_CREATE or ERROR.
ProvisioningStatus string `json:"provisioning_status"`
// The IP address of the Loadbalancer.
VipAddress string `json:"vip_address"`
// The UUID of the port associated with the IP address.
VipPortID string `json:"vip_port_id"`
// The UUID of the subnet on which to allocate the virtual IP for the Loadbalancer address.
// The UUID of the subnet on which to allocate the virtual IP for the
// Loadbalancer address.
VipSubnetID string `json:"vip_subnet_id"`
// The unique ID for the LoadBalancer.
ID string `json:"id"`
// The operating status of the LoadBalancer. This value is ONLINE or OFFLINE.
OperatingStatus string `json:"operating_status"`
// Human-readable name for the LoadBalancer. Does not have to be unique.
Name string `json:"name"`
// The UUID of a flavor if set.
Flavor string `json:"flavor"`
// The name of the provider.
Provider string `json:"provider"`
Provider string `json:"provider"`
// Listeners are the listeners related to this Loadbalancer.
Listeners []listeners.Listener `json:"listeners"`
}
// StatusTree represents the status of a loadbalancer.
type StatusTree struct {
Loadbalancer *LoadBalancer `json:"loadbalancer"`
}
// LoadBalancerPage is the page returned by a pager when traversing over a
// collection of routers.
// collection of load balancers.
type LoadBalancerPage struct {
pagination.LinkedPageBase
}
// NextPageURL is invoked when a paginated collection of routers has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
// NextPageURL is invoked when a paginated collection of load balancers has
// reached the end of a page and the pager seeks to traverse over a new one.
// In order to do this, it needs to construct the next page's URL.
func (r LoadBalancerPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"loadbalancers_links"`
@ -67,9 +84,9 @@ func (p LoadBalancerPage) IsEmpty() (bool, error) {
return len(is) == 0, err
}
// ExtractLoadBalancers accepts a Page struct, specifically a LoadbalancerPage struct,
// and extracts the elements into a slice of LoadBalancer structs. In other words,
// a generic collection is mapped into a relevant slice.
// ExtractLoadBalancers accepts a Page struct, specifically a LoadbalancerPage
// struct, and extracts the elements into a slice of LoadBalancer structs. In
// other words, a generic collection is mapped into a relevant slice.
func ExtractLoadBalancers(r pagination.Page) ([]LoadBalancer, error) {
var s struct {
LoadBalancers []LoadBalancer `json:"loadbalancers"`
@ -82,7 +99,7 @@ type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a router.
// Extract is a function that accepts a result and extracts a loadbalancer.
func (r commonResult) Extract() (*LoadBalancer, error) {
var s struct {
LoadBalancer *LoadBalancer `json:"loadbalancer"`
@ -91,11 +108,14 @@ func (r commonResult) Extract() (*LoadBalancer, error) {
return s.LoadBalancer, err
}
// GetStatusesResult represents the result of a GetStatuses operation.
// Call its Extract method to interpret it as a StatusTree.
type GetStatusesResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a Loadbalancer.
// Extract is a function that accepts a result and extracts the status of
// a Loadbalancer.
func (r GetStatusesResult) Extract() (*StatusTree, error) {
var s struct {
Statuses *StatusTree `json:"statuses"`
@ -104,22 +124,26 @@ func (r GetStatusesResult) Extract() (*StatusTree, error) {
return s.Statuses, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a LoadBalancer.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a LoadBalancer.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a LoadBalancer.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,69 @@
/*
Package monitors provides information and interaction with Monitors
of the LBaaS v2 extension for the OpenStack Networking service.
Example to List Monitors
listOpts := monitors.ListOpts{
PoolID: "c79a4468-d788-410c-bf79-9a8ef6354852",
}
allPages, err := monitors.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allMonitors, err := monitors.ExtractMonitors(allPages)
if err != nil {
panic(err)
}
for _, monitor := range allMonitors {
fmt.Printf("%+v\n", monitor)
}
Example to Create a Monitor
createOpts := monitors.CreateOpts{
Type: "HTTP",
Name: "db",
PoolID: "84f1b61f-58c4-45bf-a8a9-2dafb9e5214d",
Delay: 20,
Timeout: 10,
MaxRetries: 5,
URLPath: "/check",
ExpectedCodes: "200-299",
}
monitor, err := monitors.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Monitor
monitorID := "d67d56a6-4a86-4688-a282-f46444705c64"
updateOpts := monitors.UpdateOpts{
Name: "NewHealthmonitorName",
Delay: 3,
Timeout: 20,
MaxRetries: 10,
URLPath: "/another_check",
ExpectedCodes: "301",
}
monitor, err := monitors.Update(networkClient, monitorID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Monitor
monitorID := "d67d56a6-4a86-4688-a282-f46444705c64"
err := monitors.Delete(networkClient, monitorID).ExtractErr()
if err != nil {
panic(err)
}
*/
package monitors

View File

@ -79,10 +79,8 @@ var (
errDelayMustGETimeout = fmt.Errorf("Delay must be greater than or equal to timeout")
)
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateOptsBuilder allows extensions to add additional parameters to the
// List request.
type CreateOptsBuilder interface {
ToMonitorCreateMap() (map[string]interface{}, error)
}
@ -90,37 +88,50 @@ type CreateOptsBuilder interface {
// CreateOpts is the common options struct used in this package's Create
// operation.
type CreateOpts struct {
// Required. The Pool to Monitor.
// The Pool to Monitor.
PoolID string `json:"pool_id" required:"true"`
// Required. The type of probe, which is PING, TCP, HTTP, or HTTPS, that is
// The type of probe, which is PING, TCP, HTTP, or HTTPS, that is
// sent by the load balancer to verify the member state.
Type string `json:"type" required:"true"`
// Required. The time, in seconds, between sending probes to members.
// The time, in seconds, between sending probes to members.
Delay int `json:"delay" required:"true"`
// Required. Maximum number of seconds for a Monitor to wait for a ping reply
// Maximum number of seconds for a Monitor to wait for a ping reply
// before it times out. The value must be less than the delay value.
Timeout int `json:"timeout" required:"true"`
// Required. Number of permissible ping failures before changing the member's
// Number of permissible ping failures before changing the member's
// status to INACTIVE. Must be a number between 1 and 10.
MaxRetries int `json:"max_retries" required:"true"`
// Required for HTTP(S) types. URI path that will be accessed if Monitor type
// is HTTP or HTTPS.
// URI path that will be accessed if Monitor type is HTTP or HTTPS.
// Required for HTTP(S) types.
URLPath string `json:"url_path,omitempty"`
// Required for HTTP(S) types. The HTTP method used for requests by the
// Monitor. If this attribute is not specified, it defaults to "GET".
// The HTTP method used for requests by the Monitor. If this attribute
// is not specified, it defaults to "GET". Required for HTTP(S) types.
HTTPMethod string `json:"http_method,omitempty"`
// Required for HTTP(S) types. Expected HTTP codes for a passing HTTP(S)
// Monitor. You can either specify a single status like "200", or a range
// like "200-202".
// Expected HTTP codes for a passing HTTP(S) Monitor. You can either specify
// a single status like "200", or a range like "200-202". Required for HTTP(S)
// types.
ExpectedCodes string `json:"expected_codes,omitempty"`
// Indicates the owner of the Loadbalancer. Required for admins.
// The UUID of the tenant who owns the Monitor. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// Optional. The Name of the Monitor.
Name string `json:"name,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
// The Name of the Monitor.
Name string `json:"name,omitempty"`
// The administrative state of the Monitor. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToMonitorCreateMap casts a CreateOpts struct to a map.
// ToMonitorCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToMonitorCreateMap() (map[string]interface{}, error) {
b, err := gophercloud.BuildRequestBody(opts, "healthmonitor")
if err != nil {
@ -173,10 +184,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToMonitorUpdateMap() (map[string]interface{}, error)
}
@ -184,35 +193,45 @@ type UpdateOptsBuilder interface {
// UpdateOpts is the common options struct used in this package's Update
// operation.
type UpdateOpts struct {
// Required. The time, in seconds, between sending probes to members.
// The time, in seconds, between sending probes to members.
Delay int `json:"delay,omitempty"`
// Required. Maximum number of seconds for a Monitor to wait for a ping reply
// Maximum number of seconds for a Monitor to wait for a ping reply
// before it times out. The value must be less than the delay value.
Timeout int `json:"timeout,omitempty"`
// Required. Number of permissible ping failures before changing the member's
// Number of permissible ping failures before changing the member's
// status to INACTIVE. Must be a number between 1 and 10.
MaxRetries int `json:"max_retries,omitempty"`
// Required for HTTP(S) types. URI path that will be accessed if Monitor type
// is HTTP or HTTPS.
// URI path that will be accessed if Monitor type is HTTP or HTTPS.
// Required for HTTP(S) types.
URLPath string `json:"url_path,omitempty"`
// Required for HTTP(S) types. The HTTP method used for requests by the
// Monitor. If this attribute is not specified, it defaults to "GET".
// The HTTP method used for requests by the Monitor. If this attribute
// is not specified, it defaults to "GET". Required for HTTP(S) types.
HTTPMethod string `json:"http_method,omitempty"`
// Required for HTTP(S) types. Expected HTTP codes for a passing HTTP(S)
// Monitor. You can either specify a single status like "200", or a range
// like "200-202".
// Expected HTTP codes for a passing HTTP(S) Monitor. You can either specify
// a single status like "200", or a range like "200-202". Required for HTTP(S)
// types.
ExpectedCodes string `json:"expected_codes,omitempty"`
// Optional. The Name of the Monitor.
Name string `json:"name,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
// The Name of the Monitor.
Name string `json:"name,omitempty"`
// The administrative state of the Monitor. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToMonitorUpdateMap casts a UpdateOpts struct to a map.
// ToMonitorUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToMonitorUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "healthmonitor")
}
// Update is an operation which modifies the attributes of the specified Monitor.
// Update is an operation which modifies the attributes of the specified
// Monitor.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
b, err := opts.ToMonitorUpdateMap()
if err != nil {

View File

@ -31,8 +31,7 @@ type Monitor struct {
// The Name of the Monitor.
Name string `json:"name"`
// Only an administrative user can specify a tenant ID
// other than its own.
// TenantID is the owner of the Monitor.
TenantID string `json:"tenant_id"`
// The type of probe sent by the load balancer to verify the member state,
@ -43,7 +42,8 @@ type Monitor struct {
Delay int `json:"delay"`
// The maximum number of seconds for a monitor to wait for a connection to be
// established before it times out. This value must be less than the delay value.
// established before it times out. This value must be less than the delay
// value.
Timeout int `json:"timeout"`
// Number of allowed connection failures before changing the status of the
@ -60,7 +60,8 @@ type Monitor struct {
// Expected HTTP codes for a passing HTTP(S) monitor.
ExpectedCodes string `json:"expected_codes"`
// The administrative state of the health monitor, which is up (true) or down (false).
// The administrative state of the health monitor, which is up (true) or
// down (false).
AdminStateUp bool `json:"admin_state_up"`
// The status of the health monitor. Indicates whether the health monitor is
@ -123,22 +124,26 @@ func (r commonResult) Extract() (*Monitor, error) {
return s.Monitor, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Monitor.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Monitor.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Monitor.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the result succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,124 @@
/*
Package pools provides information and interaction with Pools and
Members of the LBaaS v2 extension for the OpenStack Networking service.
Example to List Pools
listOpts := pools.ListOpts{
LoadbalancerID: "c79a4468-d788-410c-bf79-9a8ef6354852",
}
allPages, err := pools.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allPools, err := pools.ExtractMonitors(allPages)
if err != nil {
panic(err)
}
for _, pools := range allPools {
fmt.Printf("%+v\n", pool)
}
Example to Create a Pool
createOpts := pools.CreateOpts{
LBMethod: pools.LBMethodRoundRobin,
Protocol: "HTTP",
Name: "Example pool",
LoadbalancerID: "79e05663-7f03-45d2-a092-8b94062f22ab",
}
pool, err := pools.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Pool
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
updateOpts := pools.UpdateOpts{
Name: "new-name",
}
pool, err := pools.Update(networkClient, poolID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Pool
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
err := pools.Delete(networkClient, poolID).ExtractErr()
if err != nil {
panic(err)
}
Example to List Pool Members
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
listOpts := pools.ListMemberOpts{
ProtocolPort: 80,
}
allPages, err := pools.ListMembers(networkClient, poolID, listOpts).AllPages()
if err != nil {
panic(err)
}
allMembers, err := pools.ExtractMembers(allPages)
if err != nil {
panic(err)
}
for _, member := allMembers {
fmt.Printf("%+v\n", member)
}
Example to Create a Member
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
createOpts := pools.CreateMemberOpts{
Name: "db",
SubnetID: "1981f108-3c48-48d2-b908-30f7d28532c9",
Address: "10.0.2.11",
ProtocolPort: 80,
Weight: 10,
}
member, err := pools.CreateMember(networkClient, poolID, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Member
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
memberID := "64dba99f-8af8-4200-8882-e32a0660f23e"
updateOpts := pools.UpdateMemberOpts{
Name: "new-name",
Weight: 4,
}
member, err := pools.UpdateMember(networkClient, poolID, memberID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Member
poolID := "d67d56a6-4a86-4688-a282-f46444705c64"
memberID := "64dba99f-8af8-4200-8882-e32a0660f23e"
err := pools.DeleteMember(networkClient, poolID, memberID).ExtractErr()
if err != nil {
panic(err)
}
*/
package pools

View File

@ -71,10 +71,8 @@ const (
ProtocolHTTPS Protocol = "HTTPS"
)
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToPoolCreateMap() (map[string]interface{}, error)
}
@ -86,30 +84,39 @@ type CreateOpts struct {
// current specification supports LBMethodRoundRobin, LBMethodLeastConnections
// and LBMethodSourceIp as valid values for this attribute.
LBMethod LBMethod `json:"lb_algorithm" required:"true"`
// The protocol used by the pool members, you can use either
// ProtocolTCP, ProtocolHTTP, or ProtocolHTTPS.
Protocol Protocol `json:"protocol" required:"true"`
// The Loadbalancer on which the members of the pool will be associated with.
// Note: one of LoadbalancerID or ListenerID must be provided.
// Note: one of LoadbalancerID or ListenerID must be provided.
LoadbalancerID string `json:"loadbalancer_id,omitempty" xor:"ListenerID"`
// The Listener on which the members of the pool will be associated with.
// Note: one of LoadbalancerID or ListenerID must be provided.
// Note: one of LoadbalancerID or ListenerID must be provided.
ListenerID string `json:"listener_id,omitempty" xor:"LoadbalancerID"`
// Only required if the caller has an admin role and wants to create a pool
// for another tenant.
// The UUID of the tenant who owns the Pool. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// Name of the pool.
Name string `json:"name,omitempty"`
// Human-readable description for the pool.
Description string `json:"description,omitempty"`
// Persistence is the session persistence of the pool.
// Omit this field to prevent session persistence.
Persistence *SessionPersistence `json:"session_persistence,omitempty"`
// The administrative state of the Pool. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToPoolCreateMap casts a CreateOpts struct to a map.
// ToPoolCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToPoolCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "pool")
}
@ -132,10 +139,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// UpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToPoolUpdateMap() (map[string]interface{}, error)
}
@ -145,18 +150,21 @@ type UpdateOptsBuilder interface {
type UpdateOpts struct {
// Name of the pool.
Name string `json:"name,omitempty"`
// Human-readable description for the pool.
Description string `json:"description,omitempty"`
// The algorithm used to distribute load between the members of the pool. The
// current specification supports LBMethodRoundRobin, LBMethodLeastConnections
// and LBMethodSourceIp as valid values for this attribute.
LBMethod LBMethod `json:"lb_algorithm,omitempty"`
// The administrative state of the Pool. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToPoolUpdateMap casts a UpdateOpts struct to a map.
// ToPoolUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToPoolUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "pool")
}
@ -186,11 +194,11 @@ type ListMembersOptsBuilder interface {
ToMembersListQuery() (string, error)
}
// ListMembersOpts allows the filtering and sorting of paginated collections through
// the API. Filtering is achieved by passing in struct field values that map to
// the Member attributes you want to see returned. SortKey allows you to
// sort by a particular Member attribute. SortDir sets the direction, and is
// either `asc' or `desc'. Marker and Limit are used for pagination.
// ListMembersOpts allows the filtering and sorting of paginated collections
// through the API. Filtering is achieved by passing in struct field values
// that map to the Member attributes you want to see returned. SortKey allows
// you to sort by a particular Member attribute. SortDir sets the direction,
// and is either `asc' or `desc'. Marker and Limit are used for pagination.
type ListMembersOpts struct {
Name string `q:"name"`
Weight int `q:"weight"`
@ -212,8 +220,8 @@ func (opts ListMembersOpts) ToMembersListQuery() (string, error) {
}
// ListMembers returns a Pager which allows you to iterate over a collection of
// members. It accepts a ListMembersOptsBuilder, which allows you to filter and sort
// the returned collection for greater efficiency.
// members. It accepts a ListMembersOptsBuilder, which allows you to filter and
// sort the returned collection for greater efficiency.
//
// Default policy settings return only those members that are owned by the
// tenant who submits the request, unless an admin user submits the request.
@ -231,10 +239,8 @@ func ListMembers(c *gophercloud.ServiceClient, poolID string, opts ListMembersOp
})
}
// CreateMemberOptsBuilder is the interface options structs have to satisfy in order
// to be used in the CreateMember operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateMemberOptsBuilder allows extensions to add additional parameters to the
// CreateMember request.
type CreateMemberOptsBuilder interface {
ToMemberCreateMap() (map[string]interface{}, error)
}
@ -242,29 +248,35 @@ type CreateMemberOptsBuilder interface {
// CreateMemberOpts is the common options struct used in this package's CreateMember
// operation.
type CreateMemberOpts struct {
// Required. The IP address of the member to receive traffic from the load balancer.
// The IP address of the member to receive traffic from the load balancer.
Address string `json:"address" required:"true"`
// Required. The port on which to listen for client traffic.
// The port on which to listen for client traffic.
ProtocolPort int `json:"protocol_port" required:"true"`
// Optional. Name of the Member.
// Name of the Member.
Name string `json:"name,omitempty"`
// Only required if the caller has an admin role and wants to create a Member
// for another tenant.
// The UUID of the tenant who owns the Member. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// Optional. A positive integer value that indicates the relative portion of
// traffic that this member should receive from the pool. For example, a
// member with a weight of 10 receives five times as much traffic as a member
// with a weight of 2.
// A positive integer value that indicates the relative portion of traffic
// that this member should receive from the pool. For example, a member with
// a weight of 10 receives five times as much traffic as a member with a
// weight of 2.
Weight int `json:"weight,omitempty"`
// Optional. If you omit this parameter, LBaaS uses the vip_subnet_id
// parameter value for the subnet UUID.
// If you omit this parameter, LBaaS uses the vip_subnet_id parameter value
// for the subnet UUID.
SubnetID string `json:"subnet_id,omitempty"`
// Optional. The administrative state of the Pool. A valid value is true (UP)
// The administrative state of the Pool. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToMemberCreateMap casts a CreateOpts struct to a map.
// ToMemberCreateMap builds a request body from CreateMemberOpts.
func (opts CreateMemberOpts) ToMemberCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "member")
}
@ -286,10 +298,8 @@ func GetMember(c *gophercloud.ServiceClient, poolID string, memberID string) (r
return
}
// MemberUpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// UpdateMemberOptsBuilder allows extensions to add additional parameters to the
// List request.
type UpdateMemberOptsBuilder interface {
ToMemberUpdateMap() (map[string]interface{}, error)
}
@ -297,19 +307,21 @@ type UpdateMemberOptsBuilder interface {
// UpdateMemberOpts is the common options struct used in this package's Update
// operation.
type UpdateMemberOpts struct {
// Optional. Name of the Member.
// Name of the Member.
Name string `json:"name,omitempty"`
// Optional. A positive integer value that indicates the relative portion of
// traffic that this member should receive from the pool. For example, a
// member with a weight of 10 receives five times as much traffic as a member
// with a weight of 2.
// A positive integer value that indicates the relative portion of traffic
// that this member should receive from the pool. For example, a member with
// a weight of 10 receives five times as much traffic as a member with a
// weight of 2.
Weight int `json:"weight,omitempty"`
// Optional. The administrative state of the Pool. A valid value is true (UP)
// The administrative state of the Pool. A valid value is true (UP)
// or false (DOWN).
AdminStateUp *bool `json:"admin_state_up,omitempty"`
}
// ToMemberUpdateMap casts a UpdateOpts struct to a map.
// ToMemberUpdateMap builds a request body from UpdateMemberOpts.
func (opts UpdateMemberOpts) ToMemberUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "member")
}
@ -327,7 +339,8 @@ func UpdateMember(c *gophercloud.ServiceClient, poolID string, memberID string,
return
}
// DisassociateMember will remove and disassociate a Member from a particular Pool.
// DisassociateMember will remove and disassociate a Member from a particular
// Pool.
func DeleteMember(c *gophercloud.ServiceClient, poolID string, memberID string) (r DeleteMemberResult) {
_, r.Err = c.Delete(memberResourceURL(c, poolID, memberID), nil)
return

View File

@ -22,17 +22,19 @@ import (
// requests carrying the same cookie value will be handled by the
// same Member of the Pool.
type SessionPersistence struct {
// The type of persistence mode
// The type of persistence mode.
Type string `json:"type"`
// Name of cookie if persistence mode is set appropriately
// Name of cookie if persistence mode is set appropriately.
CookieName string `json:"cookie_name,omitempty"`
}
// LoadBalancerID represents a load balancer.
type LoadBalancerID struct {
ID string `json:"id"`
}
// ListenerID represents a listener.
type ListenerID struct {
ID string `json:"id"`
}
@ -46,36 +48,50 @@ type Pool struct {
// so on. This value, which must be supported, is dependent on the provider.
// Round-robin must be supported.
LBMethod string `json:"lb_algorithm"`
// The protocol of the Pool, which is TCP, HTTP, or HTTPS.
Protocol string `json:"protocol"`
// Description for the Pool.
Description string `json:"description"`
// A list of listeners objects IDs.
Listeners []ListenerID `json:"listeners"` //[]map[string]interface{}
// A list of member objects IDs.
Members []Member `json:"members"`
// The ID of associated health monitor.
MonitorID string `json:"healthmonitor_id"`
// The network on which the members of the Pool will be located. Only members
// that are on this network can be added to the Pool.
SubnetID string `json:"subnet_id"`
// Owner of the Pool. Only an administrative user can specify a tenant ID
// other than its own.
// Owner of the Pool.
TenantID string `json:"tenant_id"`
// The administrative state of the Pool, which is up (true) or down (false).
AdminStateUp bool `json:"admin_state_up"`
// Pool name. Does not have to be unique.
Name string `json:"name"`
// The unique ID for the Pool.
ID string `json:"id"`
// A list of load balancer objects IDs.
Loadbalancers []LoadBalancerID `json:"loadbalancers"`
// Indicates whether connections in the same session will be processed by the
// same Pool member or not.
Persistence SessionPersistence `json:"session_persistence"`
// The provider
Provider string `json:"provider"`
Monitor monitors.Monitor `json:"healthmonitor"`
// The load balancer provider.
Provider string `json:"provider"`
// The Monitor associated with this Pool.
Monitor monitors.Monitor `json:"healthmonitor"`
}
// PoolPage is the page returned by a pager when traversing over a
@ -105,7 +121,7 @@ func (r PoolPage) IsEmpty() (bool, error) {
}
// ExtractPools accepts a Page struct, specifically a PoolPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// and extracts the elements into a slice of Pool structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractPools(r pagination.Page) ([]Pool, error) {
var s struct {
@ -119,7 +135,7 @@ type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a router.
// Extract is a function that accepts a result and extracts a pool.
func (r commonResult) Extract() (*Pool, error) {
var s struct {
Pool *Pool `json:"pool"`
@ -128,22 +144,26 @@ func (r commonResult) Extract() (*Pool, error) {
return s.Pool, err
}
// CreateResult represents the result of a Create operation.
// CreateResult represents the result of a Create operation. Call its Extract
// method to interpret the result as a Pool.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a Get operation.
// GetResult represents the result of a Get operation. Call its Extract
// method to interpret the result as a Pool.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an Update operation.
// UpdateResult represents the result of an Update operation. Call its Extract
// method to interpret the result as a Pool.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a Delete operation.
// DeleteResult represents the result of a Delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
@ -152,21 +172,28 @@ type DeleteResult struct {
type Member struct {
// Name of the Member.
Name string `json:"name"`
// Weight of Member.
Weight int `json:"weight"`
// The administrative state of the member, which is up (true) or down (false).
AdminStateUp bool `json:"admin_state_up"`
// Owner of the Member. Only an administrative user can specify a tenant ID
// other than its own.
// Owner of the Member.
TenantID string `json:"tenant_id"`
// parameter value for the subnet UUID.
// Parameter value for the subnet UUID.
SubnetID string `json:"subnet_id"`
// The Pool to which the Member belongs.
PoolID string `json:"pool_id"`
// The IP address of the Member.
Address string `json:"address"`
// The port on which the application is hosted.
ProtocolPort int `json:"protocol_port"`
// The unique ID for the Member.
ID string `json:"id"`
}
@ -197,8 +224,8 @@ func (r MemberPage) IsEmpty() (bool, error) {
return len(is) == 0, err
}
// ExtractMembers accepts a Page struct, specifically a RouterPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// ExtractMembers accepts a Page struct, specifically a MemberPage struct,
// and extracts the elements into a slice of Members structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractMembers(r pagination.Page) ([]Member, error) {
var s struct {
@ -212,7 +239,7 @@ type commonMemberResult struct {
gophercloud.Result
}
// ExtractMember is a function that accepts a result and extracts a router.
// ExtractMember is a function that accepts a result and extracts a member.
func (r commonMemberResult) Extract() (*Member, error) {
var s struct {
Member *Member `json:"member"`
@ -222,21 +249,25 @@ func (r commonMemberResult) Extract() (*Member, error) {
}
// CreateMemberResult represents the result of a CreateMember operation.
// Call its Extract method to interpret it as a Member.
type CreateMemberResult struct {
commonMemberResult
}
// GetMemberResult represents the result of a GetMember operation.
// Call its Extract method to interpret it as a Member.
type GetMemberResult struct {
commonMemberResult
}
// UpdateMemberResult represents the result of an UpdateMember operation.
// Call its Extract method to interpret it as a Member.
type UpdateMemberResult struct {
commonMemberResult
}
// DeleteMemberResult represents the result of a DeleteMember operation.
// Call its ExtractErr method to determine if the request succeeded or failed.
type DeleteMemberResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,58 @@
/*
Package groups provides information and interaction with Security Groups
for the OpenStack Networking service.
Example to List Security Groups
listOpts := groups.ListOpts{
TenantID: "966b3c7d36a24facaf20b7e458bf2192",
}
allPages, err := groups.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allGroups, err := groups.ExtractGroups(allPages)
if err != nil {
panic(err)
}
for _, group := range allGroups {
fmt.Printf("%+v\n", group)
}
Example to Create a Security Group
createOpts := groups.CreateOpts{
Name: "group_name",
Description: "A Security Group",
}
group, err := groups.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Security Group
groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
updateOpts := groups.UpdateOpts{
Name: "new_name",
}
group, err := groups.Update(networkClient, groupID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Security Group
groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
err := groups.Delete(networkClient, groupID).ExtractErr()
if err != nil {
panic(err)
}
*/
package groups

View File

@ -7,7 +7,7 @@ import (
// ListOpts allows the filtering and sorting of paginated collections through
// the API. Filtering is achieved by passing in struct field values that map to
// the floating IP attributes you want to see returned. SortKey allows you to
// the group attributes you want to see returned. SortKey allows you to
// sort by a particular network attribute. SortDir sets the direction, and is
// either `asc' or `desc'. Marker and Limit are used for pagination.
type ListOpts struct {
@ -34,20 +34,26 @@ func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
})
}
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToSecGroupCreateMap() (map[string]interface{}, error)
}
// CreateOpts contains all the values needed to create a new security group.
type CreateOpts struct {
// Required. Human-readable name for the Security Group. Does not have to be unique.
// Human-readable name for the Security Group. Does not have to be unique.
Name string `json:"name" required:"true"`
// Required for admins. Indicates the owner of the Security Group.
// The UUID of the tenant who owns the Group. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// Optional. Describes the security group.
// Describes the security group.
Description string `json:"description,omitempty"`
}
// ToSecGroupCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "security_group")
}
@ -64,18 +70,23 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
return
}
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToSecGroupUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts contains all the values needed to update an existing security group.
// UpdateOpts contains all the values needed to update an existing security
// group.
type UpdateOpts struct {
// Human-readable name for the Security Group. Does not have to be unique.
Name string `json:"name,omitempty"`
// Optional. Describes the security group.
// Describes the security group.
Description string `json:"description,omitempty"`
}
// ToSecGroupUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "security_group")
}
@ -100,13 +111,15 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// Delete will permanently delete a particular security group based on its unique ID.
// Delete will permanently delete a particular security group based on its
// unique ID.
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = c.Delete(resourceURL(c, id), nil)
return
}
// IDFromName is a convenience function that returns a security group's ID given its name.
// IDFromName is a convenience function that returns a security group's ID,
// given its name.
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
count := 0
id := ""

View File

@ -11,8 +11,8 @@ type SecGroup struct {
// The UUID for the security group.
ID string
// Human-readable name for the security group. Might not be unique. Cannot be
// named "default" as that is automatically created for a tenant.
// Human-readable name for the security group. Might not be unique.
// Cannot be named "default" as that is automatically created for a tenant.
Name string
// The security group description.
@ -22,8 +22,7 @@ type SecGroup struct {
// traffic entering and leaving the group.
Rules []rules.SecGroupRule `json:"security_group_rules"`
// Owner of the security group. Only admin users can specify a TenantID
// other than their own.
// Owner of the security group.
TenantID string `json:"tenant_id"`
}
@ -78,22 +77,26 @@ func (r commonResult) Extract() (*SecGroup, error) {
return s.SecGroup, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a SecGroup.
type CreateResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a SecGroup.
type UpdateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a SecGroup.
type GetResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -3,6 +3,7 @@ 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",

View File

@ -0,0 +1,50 @@
/*
Package rules provides information and interaction with Security Group Rules
for the OpenStack Networking service.
Example to List Security Groups Rules
listOpts := rules.ListOpts{
Protocol: "tcp",
}
allPages, err := rules.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allRules, err := rules.ExtractRules(allPages)
if err != nil {
panic(err)
}
for _, rule := range allRules {
fmt.Printf("%+v\n", rule)
}
Example to Create a Security Group Rule
createOpts := rules.CreateOpts{
Direction: "ingress",
PortRangeMin: 80,
EtherType: rules.EtherType4,
PortRangeMax: 80,
Protocol: "tcp",
RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5",
SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a",
}
rule, err := rules.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Security Group Rule
ruleID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
err := rules.Delete(networkClient, ruleID).ExtractErr()
if err != nil {
panic(err)
}
*/
package rules

View File

@ -7,9 +7,9 @@ import (
// ListOpts allows the filtering and sorting of paginated collections through
// the API. Filtering is achieved by passing in struct field values that map to
// the security group attributes you want to see returned. SortKey allows you to
// sort by a particular network attribute. SortDir sets the direction, and is
// either `asc' or `desc'. Marker and Limit are used for pagination.
// the security group rule attributes you want to see returned. SortKey allows
// you to sort by a particular network attribute. SortDir sets the direction,
// and is either `asc' or `desc'. Marker and Limit are used for pagination.
type ListOpts struct {
Direction string `q:"direction"`
EtherType string `q:"ethertype"`
@ -74,48 +74,56 @@ const (
ProtocolVRRP RuleProtocol = "vrrp"
)
// CreateOptsBuilder is what types must satisfy to be used as Create
// options.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToSecGroupRuleCreateMap() (map[string]interface{}, error)
}
// CreateOpts contains all the values needed to create a new security group rule.
// CreateOpts contains all the values needed to create a new security group
// rule.
type CreateOpts struct {
// Required. Must be either "ingress" or "egress": the direction in which the
// security group rule is applied.
// Must be either "ingress" or "egress": the direction in which the security
// group rule is applied.
Direction RuleDirection `json:"direction" required:"true"`
// Required. Must be "IPv4" or "IPv6", and addresses represented in CIDR must
// match the ingress or egress rules.
// Must be "IPv4" or "IPv6", and addresses represented in CIDR must match the
// ingress or egress rules.
EtherType RuleEtherType `json:"ethertype" required:"true"`
// Required. The security group ID to associate with this security group rule.
// The security group ID to associate with this security group rule.
SecGroupID string `json:"security_group_id" required:"true"`
// Optional. The maximum port number in the range that is matched by the
// security group rule. The PortRangeMin attribute constrains the PortRangeMax
// attribute. If the protocol is ICMP, this value must be an ICMP type.
// The maximum port number in the range that is matched by the security group
// rule. The PortRangeMin attribute constrains the PortRangeMax attribute. If
// the protocol is ICMP, this value must be an ICMP type.
PortRangeMax int `json:"port_range_max,omitempty"`
// Optional. The minimum port number in the range that is matched by the
// security group rule. If the protocol is TCP or UDP, this value must be
// less than or equal to the value of the PortRangeMax attribute. If the
// protocol is ICMP, this value must be an ICMP type.
// The minimum port number in the range that is matched by the security group
// rule. If the protocol is TCP or UDP, this value must be less than or equal
// to the value of the PortRangeMax attribute. If the protocol is ICMP, this
// value must be an ICMP type.
PortRangeMin int `json:"port_range_min,omitempty"`
// Optional. The protocol that is matched by the security group rule. Valid
// values are "tcp", "udp", "icmp" or an empty string.
// The protocol that is matched by the security group rule. Valid values are
// "tcp", "udp", "icmp" or an empty string.
Protocol RuleProtocol `json:"protocol,omitempty"`
// Optional. The remote group ID to be associated with this security group
// rule. You can specify either RemoteGroupID or RemoteIPPrefix.
// The remote group ID to be associated with this security group rule. You can
// specify either RemoteGroupID or RemoteIPPrefix.
RemoteGroupID string `json:"remote_group_id,omitempty"`
// Optional. The remote IP prefix to be associated with this security group
// rule. You can specify either RemoteGroupID or RemoteIPPrefix. This
// attribute matches the specified IP prefix as the source IP address of the
// IP packet.
// The remote IP prefix to be associated with this security group rule. You can
// specify either RemoteGroupID or RemoteIPPrefix. This attribute matches the
// specified IP prefix as the source IP address of the IP packet.
RemoteIPPrefix string `json:"remote_ip_prefix,omitempty"`
// Required for admins. Indicates the owner of the VIP.
// The UUID of the tenant who owns the Rule. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
}
// ToSecGroupRuleCreateMap allows CreateOpts to satisfy the CreateOptsBuilder
// interface
// ToSecGroupRuleCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "security_group_rule")
}
@ -138,7 +146,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// Delete will permanently delete a particular security group rule based on its unique ID.
// Delete will permanently delete a particular security group rule based on its
// unique ID.
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = c.Delete(resourceURL(c, id), nil)
return

View File

@ -102,17 +102,20 @@ func (r commonResult) Extract() (*SecGroupRule, error) {
return s.SecGroupRule, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a SecGroupRule.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a SecGroupRule.
type GetResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}

View File

@ -1,8 +1,73 @@
// Package ports contains functionality for working with Neutron port resources.
// A port represents a virtual switch port on a logical network switch. Virtual
// instances attach their interfaces into ports. The logical port also defines
// the MAC address and the IP address(es) to be assigned to the interfaces
// plugged into them. When IP addresses are associated to a port, this also
// implies the port is associated with a subnet, as the IP address was taken
// from the allocation pool for a specific subnet.
/*
Package ports contains functionality for working with Neutron port resources.
A port represents a virtual switch port on a logical network switch. Virtual
instances attach their interfaces into ports. The logical port also defines
the MAC address and the IP address(es) to be assigned to the interfaces
plugged into them. When IP addresses are associated to a port, this also
implies the port is associated with a subnet, as the IP address was taken
from the allocation pool for a specific subnet.
Example to List Ports
listOpts := ports.ListOpts{
DeviceID: "b0b89efe-82f8-461d-958b-adbf80f50c7d",
}
allPages, err := ports.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allPorts, err := ports.ExtractPorts(allPages)
if err != nil {
panic(err)
}
for _, port := range allPorts {
fmt.Printf("%+v\n", port)
}
Example to Create a Port
createOtps := ports.CreateOpts{
Name: "private-port",
AdminStateUp: &asu,
NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7",
FixedIPs: []ports.IP{
{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
},
SecurityGroups: &[]string{"foo"},
AllowedAddressPairs: []ports.AddressPair{
{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
},
}
port, err := ports.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Port
portID := "c34bae2b-7641-49b6-bf6d-d8e473620ed8"
updateOpts := ports.UpdateOpts{
Name: "new_name",
SecurityGroups: &[]string{},
}
port, err := ports.Update(networkClient, portID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Port
portID := "c34bae2b-7641-49b6-bf6d-d8e473620ed8"
err := ports.Delete(networkClient, portID).ExtractErr()
if err != nil {
panic(err)
}
*/
package ports

View File

@ -65,10 +65,8 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}
// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToPortCreateMap() (map[string]interface{}, error)
}
@ -83,11 +81,11 @@ type CreateOpts struct {
DeviceID string `json:"device_id,omitempty"`
DeviceOwner string `json:"device_owner,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
SecurityGroups []string `json:"security_groups,omitempty"`
SecurityGroups *[]string `json:"security_groups,omitempty"`
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
}
// ToPortCreateMap casts a CreateOpts struct to a map.
// ToPortCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "port")
}
@ -104,26 +102,24 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
return
}
// UpdateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Update operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToPortUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts represents the attributes used when updating an existing port.
type UpdateOpts struct {
Name string `json:"name,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
FixedIPs interface{} `json:"fixed_ips,omitempty"`
DeviceID string `json:"device_id,omitempty"`
DeviceOwner string `json:"device_owner,omitempty"`
SecurityGroups []string `json:"security_groups"`
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
Name string `json:"name,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
FixedIPs interface{} `json:"fixed_ips,omitempty"`
DeviceID string `json:"device_id,omitempty"`
DeviceOwner string `json:"device_owner,omitempty"`
SecurityGroups *[]string `json:"security_groups,omitempty"`
AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"`
}
// ToPortUpdateMap casts an UpdateOpts struct to a map.
// ToPortUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "port")
}
@ -148,7 +144,8 @@ func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
return
}
// IDFromName is a convenience function that returns a port's ID given its name.
// IDFromName is a convenience function that returns a port's ID,
// given its name.
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
count := 0
id := ""

View File

@ -18,22 +18,26 @@ func (r commonResult) Extract() (*Port, error) {
return s.Port, err
}
// CreateResult represents the result of a create operation.
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Port.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Port.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Port.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
@ -55,28 +59,41 @@ type AddressPair struct {
type Port struct {
// UUID for the port.
ID string `json:"id"`
// Network that this port is associated with.
NetworkID string `json:"network_id"`
// Human-readable name for the port. Might not be unique.
Name string `json:"name"`
// Administrative state of port. If false (down), port does not forward packets.
// Administrative state of port. If false (down), port does not forward
// packets.
AdminStateUp bool `json:"admin_state_up"`
// Indicates whether network is currently operational. Possible values include
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values.
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional
// values.
Status string `json:"status"`
// Mac address to use on this port.
MACAddress string `json:"mac_address"`
// Specifies IP addresses for the port thus associating the port itself with
// the subnets where the IP addresses are picked from
FixedIPs []IP `json:"fixed_ips"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
// Owner of network.
TenantID string `json:"tenant_id"`
// Identifies the entity (e.g.: dhcp agent) using this port.
DeviceOwner string `json:"device_owner"`
// Specifies the IDs of any security groups associated with a port.
SecurityGroups []string `json:"security_groups"`
// Identifies the device (e.g., virtual server) using this port.
DeviceID string `json:"device_id"`
// Identifies the list of IP addresses the port will recognize/accept
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
}

View File

@ -10,10 +10,28 @@ import (
"time"
)
// BuildRequestBody builds a map[string]interface from the given `struct`. If
// parent is not the empty string, the final map[string]interface returned will
// encapsulate the built one
//
/*
BuildRequestBody builds a map[string]interface from the given `struct`. If
parent is not an empty string, the final map[string]interface returned will
encapsulate the built one. For example:
disk := 1
createOpts := flavors.CreateOpts{
ID: "1",
Name: "m1.tiny",
Disk: &disk,
RAM: 512,
VCPUs: 1,
RxTxFactor: 1.0,
}
body, err := gophercloud.BuildRequestBody(createOpts, "flavor")
The above example can be run as-is, however it is recommended to look at how
BuildRequestBody is used within Gophercloud to more fully understand how it
fits within the request process as a whole rather than use it directly as shown
above.
*/
func BuildRequestBody(opts interface{}, parent string) (map[string]interface{}, error) {
optsValue := reflect.ValueOf(opts)
if optsValue.Kind() == reflect.Ptr {

View File

@ -224,9 +224,8 @@ type HeaderResult struct {
Result
}
// ExtractHeader will return the http.Header and error from the HeaderResult.
//
// header, err := objects.Create(client, "my_container", objects.CreateOpts{}).ExtractHeader()
// ExtractInto allows users to provide an object into which `Extract` will
// extract the http.Header headers of the result.
func (r HeaderResult) ExtractInto(to interface{}) error {
if r.Err != nil {
return r.Err